Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@

# Thoughter

Definitely not a Twitter clone.
This project was created for Iron Yard Students to practice Unit testing with
Karma, Mocha and Chai.

## How to use:

App uses grunt as a dev dependency. Grunt is configured to copy app js html and
scss files into build directory. Prior to copying js files are linted and tested
using js hint and karma.

## To set up:

1. Fork directory from https://github.com/ElizabethBoles/thoughter
2. Run ```npm install``` in your terminal which downloads necessary app dependencies
and developer dependencies (jQuery, Grunt and Grunt task managers).
3. Run ```Grunt build``` to create build directory which then can be used to view app
in preferred browser.

Testing code and Grunt configuration created by Elizabeth Boles.
117 changes: 117 additions & 0 deletions gruntfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
module.exports = function configureGrunt(gruntConfig){
gruntConfig.initConfig({
clean: [ 'build/' ],//cleaning

copy: {

copythehtml: {
files: [
{
cwd: 'src/',//to get into source
src: [ '*.html' ],//anything that has a html at end
dest: 'build/',//copy file and put that copy in this build dir
expand: true
}
]
},
copythejs: {
files: [
{
cwd: 'src/js/',
src: ['*.js'],
dest: 'build/js/', // slash at the end means i want you to find the js and go in it and thats where i want you to put the files
expand: true
}
]
},
copythejquery: {//copying dependency files into js build folder so my app has proper linkage
files: [
{
cwd: 'node_modules/jquery/dist/',
src: ['jquery.js'],//jquery is js
dest: 'build/js/vendor/',//so now we know the jquery file will be copied into our build/js/vendor folder//then when you run it you can see its created on right
expand: true
}
]
}
},

sass: {//within the sass what we're creating is a task that looks for
//all our sass/css and then compiling all of it into one pile called
//style.css and putting our style.css file in our build directory
//style.css will only ever be in the build
all: {//
//
files: {
//dest/source
//dest - where were gunna put whatever we say is our source into
//> creates a new file called style.css and puts in our main.scss
//and everything that exports into it
'build/style.css' : 'src/sass/main.scss'
}
}

},

jshint: {//linting

appjs: {
options: {
jshintrc: '.jshintrc'
},
files: {
src: [ 'src/**/*.js' ]
}
}

},

karma: {//testing
//configuring karma with grunt letting grunt know that karma works
//with mocha and chai frame works and to launch testing within karma browser
all: {
options: {
frameworks: [ 'mocha', 'chai' ],
browsers: [ 'Chrome' ],
singleRun: true,
files: [//test all of the files that end in extension .js
//when i use my sinnon server find node modules file with that code
//and test code is written my test/specs folder with any file that has
//a .js extention
'src/**/*.js',
'node_modules/sinon/pkg/sinon-2.0.0.js',
'test/specs/**/*.js'
],
preprocessors: {//what files we want to be pre processed
'src/**/*.js': ['coverage'],//all the files were testing
//want coverage plug in to watch during those tests
//then generate a summary
//coverage is the plug in and dots is part of how they report
//back
},
reporters: ['dots', 'coverage'],//in that summary i want
//dots which shows me the number of tests and a color
//indication of whether or not they passed
coverageReporter: {
type: 'text-summary'//so it doesnt come out looking all codey
//makes it look clean in terminal
}
}
}

}


});
require('load-grunt-tasks')(gruntConfig);
//whenever i run grunt build in my terminal do these things in this order
//out of convention building our build directory
//we dont want to put anything in our build directory thats broken
//thats why first jshint to make sure theres no syntax errors and then why
//i test my files next to make sure nothing breaks and then if those two pass
//i know i have good code so i can copy those files and put into build directory
//the clean task deletes the whole build directory and is the first task that runs
//build = running all of these tasks. you can name it whatever
gruntConfig.registerTask( 'build', [ 'clean', 'jshint', 'karma', 'copy', 'sass' ] );
//gruntConfig.registerTask( 'watch', ['build']);
};
39 changes: 39 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "dandatesting",
"version": "1.0.0",
"description": "",
"main": "thoughter/src/js/recent-thoughts.js",
"scripts": {
"test": "karma start thought.conf.js"
},
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/ElizabethBoles/thoughter.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/ElizabethBoles/thoughter/issues"
},
"homepage": "https://github.com/ElizabethBoles/thoughter#readme",
"devDependencies": {
"chai": "^3.5.0",
"grunt": "^1.0.1",
"grunt-contrib-clean": "^1.0.0",
"grunt-contrib-copy": "^1.0.0",
"grunt-contrib-jshint": "^1.1.0",
"grunt-contrib-sass": "^1.0.0",
"grunt-karma": "^2.0.0",
"karma": "^1.5.0",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^2.0.0",
"karma-coverage": "^1.1.1",
"karma-mocha": "^1.3.0",
"load-grunt-tasks": "^3.5.2",
"mocha": "^3.2.0",
"sinon": "^2.0.0"
},
"dependencies": {
"jquery": "^3.2.0"
}
}
4 changes: 3 additions & 1 deletion src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ <h1>Thoughter</h1>
<!-- TODO! -->

<script src='/js/vendor/jquery.js'></script>
<script src='/js/app.js'></script>
<script src='js/new-thought.js'></script>
<script src='js/recent-thoughts.js'></script>

</body>
</html>
2 changes: 1 addition & 1 deletion src/js/new-thought.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
console.error('Looks like a bad status code:', res.status);
return Promise.reject('Sorry, but there was a problem with your request.');
} else {
return res.json()
return res.json();
}
});
};
Expand Down
22 changes: 17 additions & 5 deletions src/js/recent-thoughts.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,38 @@
'use strict';

window.thoughter = window.thoughter || {};
//name space

/**
* Shows the provided thought data on the page in the `.recent` element
*
* @param {Array} thoughts The array of thought objects to display
*this function takes an array as an arg and does a lot of dom manipulation
*so what we're gunna test is whethere or not the corrext dom manip is happening
* @return {void}
*/
window.thoughter.showRecent = function showRecent(thoughts = []) {
if (!Array.isArray(thoughts)) {
return;
}

recent = document.querySelector('.recent');
//element(ex section/main) with a class of recent
//trying to find something with the class of recent
let recent = document.querySelector('.recent');
//when it finds something with the class of recent
thoughts.forEach(function showThought(thought) {
//for each thought do the stuff down here
//if each thought does not have thought.content, thought.createTime
//or a thought.id then return and dont do that stuff
if (!thought.content || !thought.createTime || !thought.id) {
return;
return;//dont want to go down cus ill get an error
}

//it creates for each thought a new article element and then
//appends it to the recent element
let thoughtUI = document.createElement('article');
thoughtUI.classList.add('panel');
thoughtUI.classList.add('panel-info');
thoughtUI.setAttribute('id', 'thought-' + thought.id);
//66
thoughtUI.innerHTML = `<header class='panel-heading'>Posted ${thoughts.createTime}</header>
<main class='panel-body'>
<p>${thought.content}</p>
Expand All @@ -38,7 +48,9 @@
* @param {Number} count How many thoughts to limit to, must be a positive number (defaults to 10)
* @return {Promise} The resolved promise will have the data array as the argument
*/
window.thoughter.getRecent = function getRecent(count = 10) {
window.thoughter.getRecent = function getRecent(numb = 10) {
let count = numb;

if (typeof(count) !== 'number' || count < 1) {
return Promise.reject('Sorry, but the count must be a positive number');
}
Expand Down
1 change: 0 additions & 1 deletion src/sass/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@
@import 'variables';
@import 'header';
@import 'login';
@import 'new-thought';
@import 'recent';
134 changes: 134 additions & 0 deletions test/specs/recent-thoughts.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
(function() {
'use strict';
//this is where i created the 3 thoughts
let expect = window.chai.expect;
//because lazy
let hi = {};
hi.content = 'hi';
hi.createTime = new Date();
hi.id = 'xxxx';
let bye = {};
bye.content = 'bye';
bye.createTime = new Date();
bye.id = 'yyyy';
let hibye = {};
hibye.content = 'hibye';
hibye.createTime = new Date();
hibye.id = 'zzzz';

describe('recent-thoughts.js', function() {
//describes recent-thoughts.js file
it('should know that the nameSpace exists', function(){
//name spaces are an object so we want it to be an object
expect(window.thoughter).to.be.a('object');
});

describe('showRecent function', function() {
//describes first function im testing
//which is .showRecent
//going to need a fixture for this test suite
//create an element with a class of recent
beforeEach(function() {
//everything im doing in my before and after is not connected
//to the recent-thoughts.js
//but im getting the info from recent-thoughts.js
//and im trying to recreate what it's trying to do
let mainTag = document.createElement('main');
//before i run this test making sure there is an
//existing element with a class of recent
//when i run my test line 20 will work because i created
//the element with the class of recent
mainTag.classList.add('recent');
//document.createElement('body');
document.querySelector('body').appendChild(mainTag);
});
//now im removing it -idempoden
//if i dont remove it as i go to my other tests having that
//fixture there might cause failures
afterEach(function() {
let mainTag = document.querySelector('main');
mainTag.parentNode.removeChild(mainTag);
//after each test assertion in this describe i find
//a main/tag element and remove it
});
//keep on same cus its not imbeded in fn
it('should create a new article element for every thought', function(){
window.thoughter.showRecent([hi, bye, hibye]);//3 thoughts
//create a variable so i dont have to type doc.querselect everytime
let recentElement = document.querySelector('.recent');
//testing that the recent element has children and that it has more
//then one
expect(recentElement.childNodes.length).to.equal(3);
//selected recent element dug into child nodes got length of child nodes
//and tested if the length was equal to the amount of thoughts i gave the fn
//console.log(window.thoughter.showRecent);
//want to test that articles are being created
//console.info(document.querySelector('.recent'));
//expect(recentElement.childNodes[1].id).to.equal('thought-yyyy');
//console.log(recentElement.childNodes[1]);
//tapping into first article
});
it('should pass an array with 1obj', function(){
let recentElement = document.querySelector('main.recent');
window.thoughter.showRecent([hi]);
expect(recentElement.childNodes.length).to.equal(1);
});
it('should pass in an empty array', function(){
let article = document.querySelector('main.recent');
window.thoughter.showRecent([]);
expect(article.length).to.equal();
});
});
//where new describe begins - 3rd one
//every function has its own describe
describe('get recent', function(){
let server;

beforeEach(function(){
server = sinon.fakeServer.create();
server.autoRespond = true;
server.respondWith(
'GET',
'http://thoughter.herokuapp.com/api/Thoughts?filter={"order":"createTime DESC","limit":3}',
[
200,
{ 'Content-Type': 'application/json' },
//moching out what the fetch returns in its response
'["hi", "bye", "hibye"]'
]
//the function that im testing fetches at a specific url so to test that fetch
//setting up a fake server connected to that specific url so that the real
//function hits server and not the API
//
);
});

afterEach(function() {
server.restore();
});
it('should return data back from server', function(){
let result = window.thoughter.getRecent();
// expect( result ).to.be.an('object');
expect(result.then).to.be.a('function');
expect(result.catch).to.be.a('function');

result
.then(function(data) {
expect(data).to.be.an('array');
expect(data.length).to.equal(3);
//expect data and we know data is an
//array and has a length of 3
//expect the first index in the data array
//to equal hi and it should equal hi because
//thats what i told my moc server to type
expect(data[0]).to.equal('hi');
tellMochaWeAreDone();
})
.catch(function(err) {
tellMochaWeAreDone(err);
});
});
});

});
}());
Loading