setup prelesson
This commit is contained in:
parent
4cbbea66e5
commit
b772e81bf8
9
.babelrc
9
.babelrc
@ -1,10 +1,3 @@
|
||||
{
|
||||
"presets": ["es2015-webpack", "stage-2"],
|
||||
"env": {
|
||||
"test": {
|
||||
"plugins": [
|
||||
["__coverage__", {"ignore": "*.test.*"}]
|
||||
]
|
||||
}
|
||||
}
|
||||
"presets": ["es2015-webpack", "stage-2"]
|
||||
}
|
||||
|
||||
@ -10,12 +10,5 @@
|
||||
"valid-jsdoc": 0,
|
||||
"vars-on-top": 0,
|
||||
"complexity": [2, 6],
|
||||
},
|
||||
"globals": {
|
||||
"jasmine": false,
|
||||
"describe": false,
|
||||
"it": false,
|
||||
"beforeEach": false,
|
||||
"expect": false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
const webpackConfig = require('./webpack.config')({test: true})
|
||||
process.env.BABEL_ENV = 'test' // so we load the correct babel plugins
|
||||
require('babel-register')
|
||||
|
||||
module.exports = function setKarmaConfig(config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine'],
|
||||
files: ['src/**/*.test.js'],
|
||||
exclude: [],
|
||||
preprocessors: {
|
||||
'src/**/*.test.js': ['webpack'],
|
||||
},
|
||||
webpack: webpackConfig,
|
||||
webpackMiddleware: {noInfo: true},
|
||||
reporters: ['progress', 'coverage'],
|
||||
coverageReporter: {
|
||||
reporters: [
|
||||
{type: 'lcov', dir: 'coverage/', subdir: '.'},
|
||||
{type: 'json', dir: 'coverage/', subdir: '.'},
|
||||
{type: 'text-summary'},
|
||||
],
|
||||
},
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
browsers: ['Firefox'],
|
||||
singleRun: true,
|
||||
})
|
||||
}
|
||||
12
package.json
12
package.json
@ -9,7 +9,6 @@
|
||||
"babel-core": "6.8.0",
|
||||
"babel-eslint": "6.0.4",
|
||||
"babel-loader": "6.2.4",
|
||||
"babel-plugin-__coverage__": "0.111111.11",
|
||||
"babel-preset-es2015-webpack": "6.4.1",
|
||||
"babel-preset-stage-2": "6.5.0",
|
||||
"cpy-cli": "1.0.0",
|
||||
@ -18,13 +17,6 @@
|
||||
"eslint-config-kentcdodds": "6.2.1",
|
||||
"eslint-loader": "1.3.0",
|
||||
"ghooks": "1.2.1",
|
||||
"jasmine-core": "2.4.1",
|
||||
"karma": "0.13.22",
|
||||
"karma-chrome-launcher": "1.0.1",
|
||||
"karma-coverage": "1.0.0",
|
||||
"karma-firefox-launcher": "1.0.0",
|
||||
"karma-jasmine": "1.0.2",
|
||||
"karma-webpack": "1.7.0",
|
||||
"npm-run-all": "1.8.0",
|
||||
"opt-cli": "1.4.2",
|
||||
"rimraf": "2.5.2",
|
||||
@ -39,9 +31,7 @@
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "karma start",
|
||||
"watch:test": "karma start --auto-watch --no-single-run",
|
||||
"validate": "npm-run-all --parallel validate-webpack:* lint test",
|
||||
"validate": "npm-run-all --parallel validate-webpack:* lint",
|
||||
"validate-webpack:dev": "webpack-validator webpack.config.js --env.dev",
|
||||
"validate-webpack:prod": "webpack-validator webpack.config.js --env.prod",
|
||||
"clean-dist": "rimraf dist",
|
||||
|
||||
@ -1,404 +0,0 @@
|
||||
import Controller from './controller'
|
||||
|
||||
describe('controller', () => {
|
||||
var subject, model, view
|
||||
|
||||
var setUpModel = function(todos) {
|
||||
model.read.and.callFake(function(query, callback) {
|
||||
callback = callback || query
|
||||
callback(todos)
|
||||
})
|
||||
|
||||
model.getCount.and.callFake(function(callback) {
|
||||
|
||||
var todoCounts = {
|
||||
active: todos.filter(function(todo) {
|
||||
return !todo.completed
|
||||
}).length,
|
||||
completed: todos.filter(function(todo) {
|
||||
return !!todo.completed
|
||||
}).length,
|
||||
total: todos.length
|
||||
}
|
||||
|
||||
callback(todoCounts)
|
||||
})
|
||||
|
||||
model.remove.and.callFake(function(id, callback) {
|
||||
callback()
|
||||
})
|
||||
|
||||
model.create.and.callFake(function(title, callback) {
|
||||
callback()
|
||||
})
|
||||
|
||||
model.update.and.callFake(function(id, updateData, callback) {
|
||||
callback()
|
||||
})
|
||||
}
|
||||
|
||||
var createViewStub = () => {
|
||||
var eventRegistry = {}
|
||||
return {
|
||||
render: jasmine.createSpy('render'),
|
||||
bind: function(event, handler) {
|
||||
eventRegistry[event] = handler
|
||||
},
|
||||
trigger: function(event, parameter) {
|
||||
eventRegistry[event](parameter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
model = jasmine.createSpyObj('model', ['read', 'getCount', 'remove', 'create', 'update'])
|
||||
view = createViewStub()
|
||||
subject = new Controller(model, view)
|
||||
})
|
||||
|
||||
it('should show entries on start-up', () => {
|
||||
setUpModel([])
|
||||
|
||||
subject.setView('')
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('showEntries', [])
|
||||
})
|
||||
|
||||
describe('routing', () => {
|
||||
|
||||
it('should show all entries without a route', () => {
|
||||
var todo = {title: 'my todo'}
|
||||
setUpModel([todo])
|
||||
|
||||
subject.setView('')
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('showEntries', [todo])
|
||||
})
|
||||
|
||||
it('should show all entries without "all" route', () => {
|
||||
var todo = {title: 'my todo'}
|
||||
setUpModel([todo])
|
||||
|
||||
subject.setView('#/')
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('showEntries', [todo])
|
||||
})
|
||||
|
||||
it('should show active entries', () => {
|
||||
var todo = {title: 'my todo', completed: false}
|
||||
setUpModel([todo])
|
||||
|
||||
subject.setView('#/active')
|
||||
|
||||
expect(model.read).toHaveBeenCalledWith({completed: false}, jasmine.any(Function))
|
||||
expect(view.render).toHaveBeenCalledWith('showEntries', [todo])
|
||||
})
|
||||
|
||||
it('should show completed entries', () => {
|
||||
var todo = {title: 'my todo', completed: true}
|
||||
setUpModel([todo])
|
||||
|
||||
subject.setView('#/completed')
|
||||
|
||||
expect(model.read).toHaveBeenCalledWith({completed: true}, jasmine.any(Function))
|
||||
expect(view.render).toHaveBeenCalledWith('showEntries', [todo])
|
||||
})
|
||||
})
|
||||
|
||||
it('should show the content block when todos exists', () => {
|
||||
setUpModel([{title: 'my todo', completed: true}])
|
||||
|
||||
subject.setView('')
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('contentBlockVisibility', {
|
||||
visible: true
|
||||
})
|
||||
})
|
||||
|
||||
it('should hide the content block when no todos exists', () => {
|
||||
setUpModel([])
|
||||
|
||||
subject.setView('')
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('contentBlockVisibility', {
|
||||
visible: false
|
||||
})
|
||||
})
|
||||
|
||||
it('should check the toggle all button, if all todos are completed', () => {
|
||||
setUpModel([{title: 'my todo', completed: true}])
|
||||
|
||||
subject.setView('')
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('toggleAll', {
|
||||
checked: true
|
||||
})
|
||||
})
|
||||
|
||||
it('should set the "clear completed" button', () => {
|
||||
var todo = {id: 42, title: 'my todo', completed: true}
|
||||
setUpModel([todo])
|
||||
|
||||
subject.setView('')
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('clearCompletedButton', {
|
||||
completed: 1,
|
||||
visible: true
|
||||
})
|
||||
})
|
||||
|
||||
it('should highlight "All" filter by default', () => {
|
||||
setUpModel([])
|
||||
|
||||
subject.setView('')
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('setFilter', '')
|
||||
})
|
||||
|
||||
it('should highlight "Active" filter when switching to active view', () => {
|
||||
setUpModel([])
|
||||
|
||||
subject.setView('#/active')
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('setFilter', 'active')
|
||||
})
|
||||
|
||||
describe('toggle all', () => {
|
||||
it('should toggle all todos to completed', () => {
|
||||
var todos = [{
|
||||
id: 42,
|
||||
title: 'my todo',
|
||||
completed: false
|
||||
}, {
|
||||
id: 21,
|
||||
title: 'another todo',
|
||||
completed: false
|
||||
}]
|
||||
|
||||
setUpModel(todos)
|
||||
subject.setView('')
|
||||
|
||||
view.trigger('toggleAll', {completed: true})
|
||||
|
||||
expect(model.update).toHaveBeenCalledWith(42, {completed: true}, jasmine.any(Function))
|
||||
expect(model.update).toHaveBeenCalledWith(21, {completed: true}, jasmine.any(Function))
|
||||
})
|
||||
|
||||
it('should update the view', () => {
|
||||
var todos = [{
|
||||
id: 42,
|
||||
title: 'my todo',
|
||||
completed: true
|
||||
}]
|
||||
|
||||
setUpModel(todos)
|
||||
subject.setView('')
|
||||
|
||||
view.trigger('toggleAll', {completed: false})
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('elementComplete', {id: 42, completed: false})
|
||||
})
|
||||
})
|
||||
|
||||
describe('new todo', () => {
|
||||
it('should add a new todo to the model', () => {
|
||||
setUpModel([])
|
||||
|
||||
subject.setView('')
|
||||
|
||||
view.trigger('newTodo', 'a new todo')
|
||||
|
||||
expect(model.create).toHaveBeenCalledWith('a new todo', jasmine.any(Function))
|
||||
})
|
||||
|
||||
it('should add a new todo to the view', () => {
|
||||
setUpModel([])
|
||||
|
||||
subject.setView('')
|
||||
|
||||
view.render.calls.reset()
|
||||
model.read.calls.reset()
|
||||
model.read.and.callFake(function(callback) {
|
||||
callback([{
|
||||
title: 'a new todo',
|
||||
completed: false
|
||||
}])
|
||||
})
|
||||
|
||||
view.trigger('newTodo', 'a new todo')
|
||||
|
||||
expect(model.read).toHaveBeenCalled()
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('showEntries', [{
|
||||
title: 'a new todo',
|
||||
completed: false
|
||||
}])
|
||||
})
|
||||
|
||||
it('should clear the input field when a new todo is added', () => {
|
||||
setUpModel([])
|
||||
|
||||
subject.setView('')
|
||||
|
||||
view.trigger('newTodo', 'a new todo')
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('clearNewTodo')
|
||||
})
|
||||
})
|
||||
|
||||
describe('element removal', () => {
|
||||
it('should remove an entry from the model', () => {
|
||||
var todo = {id: 42, title: 'my todo', completed: true}
|
||||
setUpModel([todo])
|
||||
|
||||
subject.setView('')
|
||||
view.trigger('itemRemove', {id: 42})
|
||||
|
||||
expect(model.remove).toHaveBeenCalledWith(42, jasmine.any(Function))
|
||||
})
|
||||
|
||||
it('should remove an entry from the view', () => {
|
||||
var todo = {id: 42, title: 'my todo', completed: true}
|
||||
setUpModel([todo])
|
||||
|
||||
subject.setView('')
|
||||
view.trigger('itemRemove', {id: 42})
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('removeItem', 42)
|
||||
})
|
||||
|
||||
it('should update the element count', () => {
|
||||
var todo = {id: 42, title: 'my todo', completed: true}
|
||||
setUpModel([todo])
|
||||
|
||||
subject.setView('')
|
||||
view.trigger('itemRemove', {id: 42})
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('updateElementCount', 0)
|
||||
})
|
||||
})
|
||||
|
||||
describe('remove completed', () => {
|
||||
it('should remove a completed entry from the model', () => {
|
||||
var todo = {id: 42, title: 'my todo', completed: true}
|
||||
setUpModel([todo])
|
||||
|
||||
subject.setView('')
|
||||
view.trigger('removeCompleted')
|
||||
|
||||
expect(model.read).toHaveBeenCalledWith({completed: true}, jasmine.any(Function))
|
||||
expect(model.remove).toHaveBeenCalledWith(42, jasmine.any(Function))
|
||||
})
|
||||
|
||||
it('should remove a completed entry from the view', () => {
|
||||
var todo = {id: 42, title: 'my todo', completed: true}
|
||||
setUpModel([todo])
|
||||
|
||||
subject.setView('')
|
||||
view.trigger('removeCompleted')
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('removeItem', 42)
|
||||
})
|
||||
})
|
||||
|
||||
describe('element complete toggle', () => {
|
||||
it('should update the model', () => {
|
||||
var todo = {id: 21, title: 'my todo', completed: false}
|
||||
setUpModel([todo])
|
||||
subject.setView('')
|
||||
|
||||
view.trigger('itemToggle', {id: 21, completed: true})
|
||||
|
||||
expect(model.update).toHaveBeenCalledWith(21, {completed: true}, jasmine.any(Function))
|
||||
})
|
||||
|
||||
it('should update the view', () => {
|
||||
var todo = {id: 42, title: 'my todo', completed: true}
|
||||
setUpModel([todo])
|
||||
subject.setView('')
|
||||
|
||||
view.trigger('itemToggle', {id: 42, completed: false})
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('elementComplete', {id: 42, completed: false})
|
||||
})
|
||||
})
|
||||
|
||||
describe('edit item', () => {
|
||||
it('should switch to edit mode', () => {
|
||||
var todo = {id: 21, title: 'my todo', completed: false}
|
||||
setUpModel([todo])
|
||||
|
||||
subject.setView('')
|
||||
|
||||
view.trigger('itemEdit', {id: 21})
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('editItem', {id: 21, title: 'my todo'})
|
||||
})
|
||||
|
||||
it('should leave edit mode on done', () => {
|
||||
var todo = {id: 21, title: 'my todo', completed: false}
|
||||
setUpModel([todo])
|
||||
|
||||
subject.setView('')
|
||||
|
||||
view.trigger('itemEditDone', {id: 21, title: 'new title'})
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('editItemDone', {id: 21, title: 'new title'})
|
||||
})
|
||||
|
||||
it('should persist the changes on done', () => {
|
||||
var todo = {id: 21, title: 'my todo', completed: false}
|
||||
setUpModel([todo])
|
||||
|
||||
subject.setView('')
|
||||
|
||||
view.trigger('itemEditDone', {id: 21, title: 'new title'})
|
||||
|
||||
expect(model.update).toHaveBeenCalledWith(21, {title: 'new title'}, jasmine.any(Function))
|
||||
})
|
||||
|
||||
it('should remove the element from the model when persisting an empty title', () => {
|
||||
var todo = {id: 21, title: 'my todo', completed: false}
|
||||
setUpModel([todo])
|
||||
|
||||
subject.setView('')
|
||||
|
||||
view.trigger('itemEditDone', {id: 21, title: ''})
|
||||
|
||||
expect(model.remove).toHaveBeenCalledWith(21, jasmine.any(Function))
|
||||
})
|
||||
|
||||
it('should remove the element from the view when persisting an empty title', () => {
|
||||
var todo = {id: 21, title: 'my todo', completed: false}
|
||||
setUpModel([todo])
|
||||
|
||||
subject.setView('')
|
||||
|
||||
view.trigger('itemEditDone', {id: 21, title: ''})
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('removeItem', 21)
|
||||
})
|
||||
|
||||
it('should leave edit mode on cancel', () => {
|
||||
var todo = {id: 21, title: 'my todo', completed: false}
|
||||
setUpModel([todo])
|
||||
|
||||
subject.setView('')
|
||||
|
||||
view.trigger('itemEditCancel', {id: 21})
|
||||
|
||||
expect(view.render).toHaveBeenCalledWith('editItemDone', {id: 21, title: 'my todo'})
|
||||
})
|
||||
|
||||
it('should not persist the changes on cancel', () => {
|
||||
var todo = {id: 21, title: 'my todo', completed: false}
|
||||
setUpModel([todo])
|
||||
|
||||
subject.setView('')
|
||||
|
||||
view.trigger('itemEditCancel', {id: 21})
|
||||
|
||||
expect(model.update).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
})
|
||||
Loading…
x
Reference in New Issue
Block a user