Tyson Gern @tygern
gulp
— gulp-karmagrunt
— grunt-karmagulp
— generator-gulp-angulargrunt
— generator-angularAccording to Kent Beck...
Write a short failing test
Make the test pass in the simplest way possible
Eliminate duplication introduced in the previous step
Documents behavior of code
// adds one to the passed in value
function increment(number) {
return number + 2;
}
Leads to simple design
Allows frequent refactoring
Quickly add features
javascript testing framework
Function addStrings
that adds integers passed as strings.
describe('addStrings', function () {
});
describe('addStrings', function () {
it('correctly adds two numbers', function () {
});
});
describe('addStrings', function () {
it('correctly adds two numbers', function () {
expect(addStrings('3', '5')).toEqual(8);
});
});
describe('addStrings', function () {
it('correctly adds two numbers', function () {
expect(addStrings('3', '5')).toEqual(8);
expect(addStrings('4', '6')).toEqual(10);
});
});
describe('addStrings', function () {
it('correctly adds two numbers', function () {
expect(addStrings('3', '5')).toEqual(8);
expect(addStrings('4', '6')).toEqual(10);
});
});
ReferenceError: addStrings is not defined
describe('addStrings', function () {
it('correctly adds two numbers', function () {
expect(addStrings('3', '5')).toEqual(8);
expect(addStrings('4', '6')).toEqual(10);
});
});
function addStrings() {
}
describe('addStrings', function () {
it('correctly adds two numbers', function () {
expect(addStrings('3', '5')).toEqual(8);
expect(addStrings('4', '6')).toEqual(10);
});
});
function addStrings() {
}
Expected undefined to equal 8.
describe('addStrings', function () {
it('correctly adds two numbers', function () {
expect(addStrings('3', '5')).toEqual(8);
expect(addStrings('4', '6')).toEqual(10);
});
});
function addStrings() {
return 8;
}
describe('addStrings', function () {
it('correctly adds two numbers', function () {
expect(addStrings('3', '5')).toEqual(8);
expect(addStrings('4', '6')).toEqual(10);
});
});
function addStrings() {
return 8;
}
Expected 8 to equal 10.
describe('addStrings', function () {
it('correctly adds two numbers', function () {
expect(addStrings('3', '5')).toEqual(8);
expect(addStrings('4', '6')).toEqual(10);
});
});
function addStrings(first, second) {
return parseInt(first) + parseInt(second);
}
describe('addStrings', function () {
it('correctly adds two numbers', function () {
expect(addStrings('3', '5')).toEqual(8);
expect(addStrings('4', '6')).toEqual(10);
});
});
function addStrings(first, second) {
return parseInt(first) + parseInt(second);
}
Handle bad data. Count non-numbers as 0.
describe('addStrings', function () {
//...
it('treats non-numbers as 0', function () {
});
});
function addStrings(first, second) {
return parseInt(first) + parseInt(second);
}
describe('addStrings', function () {
//...
it('treats non-numbers as 0', function () {
expect(addStrings('a', '6')).toEqual(6);
});
});
function addStrings(first, second) {
return parseInt(first) + parseInt(second);
}
describe('addStrings', function () {
//...
it('treats non-numbers as 0', function () {
expect(addStrings('a', '6')).toEqual(6);
expect(addStrings('2', '')).toEqual(2);
});
});
function addStrings(first, second) {
return parseInt(first) + parseInt(second);
}
describe('addStrings', function () {
//...
it('treats non-numbers as 0', function () {
expect(addStrings('a', '6')).toEqual(6);
expect(addStrings('2', '')).toEqual(2);
});
});
function addStrings(first, second) {
return parseInt(first) + parseInt(second);
}
Expected NaN to equal 6.
describe('addStrings', function () {
//...
it('treats non-numbers as 0', function () {
expect(addStrings('a', '6')).toEqual(6);
expect(addStrings('2', '')).toEqual(2);
});
});
function addStrings(first, second) {
var firstNumber = parseInt(first);
if(isNaN(firstNumber)) {
firstNumber = 0;
}
return firstNumber + parseInt(second);
}
describe('addStrings', function () {
//...
it('treats non-numbers as 0', function () {
expect(addStrings('a', '6')).toEqual(6);
expect(addStrings('2', '')).toEqual(2);
});
});
function addStrings(first, second) {
var firstNumber = parseInt(first);
if(isNaN(firstNumber)) {
firstNumber = 0;
}
return firstNumber + parseInt(second);
}
Expected NaN to equal 2.
describe('addStrings', function () {
//...
it('treats non-numbers as 0', function () {
expect(addStrings('a', '6')).toEqual(6);
expect(addStrings('2', '')).toEqual(2);
});
});
function addStrings(first, second) {
var firstNumber = parseInt(first);
if(isNaN(firstNumber)) {
firstNumber = 0;
}
var secondNumber = parseInt(second);
if(isNaN(secondNumber)) {
secondNumber = 0;
}
return firstNumber + secondNumber;
}
describe('addStrings', function () {
//...
it('treats non-numbers as 0', function () {
expect(addStrings('a', '6')).toEqual(6);
expect(addStrings('2', '')).toEqual(2);
});
});
function addStrings(first, second) {
var firstNumber = parseInt(first);
if(isNaN(firstNumber)) {
firstNumber = 0;
}
var secondNumber = parseInt(second);
if(isNaN(secondNumber)) {
secondNumber = 0;
}
return firstNumber + secondNumber;
}
describe('addStrings', function () {
//...
it('treats non-numbers as 0', function () {
expect(addStrings('a', '6')).toEqual(6);
expect(addStrings('2', '')).toEqual(2);
});
});
function addStrings(first, second) {
var firstNumber = parseInt(first);
if(isNaN(firstNumber)) {
firstNumber = 0;
}
var secondNumber = parseInt(second);
if(isNaN(secondNumber)) {
secondNumber = 0;
}
return firstNumber + secondNumber;
}
describe('addStrings', function () {
//...
it('treats non-numbers as 0', function () {
expect(addStrings('a', '6')).toEqual(6);
expect(addStrings('2', '')).toEqual(2);
});
});
function addStrings(first, second) {
function parseNumber(string) {
var number = parseInt(string);
return isNaN(number) ? 0 : number;
}
return parseNumber(first) + parseNumber(second);
}
describe('addStrings', function () {
//...
it('treats non-numbers as 0', function () {
expect(addStrings('a', '6')).toEqual(6);
expect(addStrings('2', '')).toEqual(2);
});
});
function addStrings(first, second) {
function parseNumber(string) {
var number = parseInt(string);
return isNaN(number) ? 0 : number;
}
return parseNumber(first) + parseNumber(second);
}
javascript web framework
$scope
Angular synchronizes controllers and views with $scope
.
{{message}}
+
angular.module('messaging')
.controller('messaging.flashController', function ($scope) {
$scope.message = 'hello';
});
=
hello
Angular uses dependency injection to provide objects with collaborators.
angular.module('messaging')
.controller('messaging.flashController', function($scope,
messagingService) {
});
Modules allow building application with modules.
angular.module('users', []); // greeterApplication
angular.module('twitterAdapter', []); // / \
angular.module('messaging', [ // / \
'twitterAdapter' // / \
]); // messaging users
// |
angular.module('greeterApplication', [ // |
'users', // |
'messaging' // twitterAdapter
]); //
Start to build greeterApplication
Show initial greeting when the page loads
{{message}}
describe('messaging.flashController', function () {
beforeEach(module('messaging'));
// tests go here
});
describe('messaging.flashController', function () {
var $scope;
beforeEach(module('messaging'));
beforeEach(inject(function ($rootScope) {
$scope = $rootScope.$new();
}));
// tests go here
});
describe('messaging.flashController', function () {
var $scope;
beforeEach(module('messaging'));
beforeEach(inject(function ($rootScope, $controller) {
$scope = $rootScope.$new();
$controller('messaging.flashController', {
$scope: $scope
});
}));
// tests go here
});
describe('messaging.flashController', function () {
var $scope, messagingService;
beforeEach(module('messaging'));
beforeEach(inject(function (..., _messagingService_) {
$scope = $rootScope.$new();
messagingService = _messagingService_;
spyOn(messagingService, 'getMessage').and.returnValue('Hi!');
$controller('messaging.flashController', {
$scope: $scope,
messagingService: messagingService
});
}));
// tests go here
});
describe('messaging.flashController', function () {
// setup
describe('when the controller loads', function () {
it('sets the message', function () {
});
});
});
describe('messaging.flashController', function () {
// setup
describe('when the controller loads', function () {
it('sets the message', function () {
expect($scope.message).toEqual('Hi!');
});
});
});
describe('messaging.flashController', function () {
// setup
describe('when the controller loads', function () {
it('sets the message', function () {
expect($scope.message).toEqual('Hi!');
expect(messagingService.getMessage)
.toHaveBeenCalledWith('initial');
});
});
});
describe('messaging.flashController', function () {
// setup
describe('when the controller loads', function () {
it('sets the message', function () {
expect($scope.message).toEqual('Hi!');
expect(messagingService.getMessage)
.toHaveBeenCalledWith('initial');
});
});
});
Expected undefined to equal 'Hi!'.
describe('messaging.flashController', function () {
// setup
describe('when the controller loads', function () {
it('sets the message', function () {
expect($scope.message).toEqual('Hi!');
expect(messagingService.getMessage)
.toHaveBeenCalledWith('initial');
});
});
});
Expected spy getMessage to have been called with [ 'initial' ] but it was never called.
angular.module('messaging')
.controller('messaging.flashController', function($scope,
messagingService) {
});
angular.module('messaging')
.controller('messaging.flashController', function($scope,
messagingService) {
$scope.message = messagingService.getMessage('initial');
});
angular.module('messaging')
.controller('messaging.flashController', function($scope,
messagingService) {
$scope.message = messagingService.getMessage('initial');
});
angular.module('messaging')
.controller('messaging.flashController', function($scope,
messagingService) {
$scope.message = messagingService.getMessage('initial');
});
angular.module('messaging')
.controller('messaging.flashController', function($scope,
messagingService) {
$scope.message = messagingService.getMessage('initial');
});
Change the message to prompt the user after 5 seconds
{{message}}
describe('messaging.flashController', function () {
// tests and setup
describe('after waiting 5 seconds', function () {
it('shows the \'prompt\' message', function () {
});
});
});
describe('messaging.flashController', function () {
// tests and setup
describe('after waiting 5 seconds', function () {
it('shows the \'prompt\' message', function () {
$scope.message = '';
$timeout.flush(4900);
expect($scope.message).toEqual('');
});
});
});
describe('messaging.flashController', function () {
// tests and setup
describe('after waiting 5 seconds', function () {
it('shows the \'prompt\' message', function () {
$scope.message = '';
$timeout.flush(4900);
expect($scope.message).toEqual('');
$timeout.flush(200);
expect($scope.message).toEqual('Hi!');
expect(messagingService.getMessage)
.toHaveBeenCalledWith('prompt');
});
});
});
describe('messaging.flashController', function () {
// tests and setup
describe('after waiting 5 seconds', function () {
it('shows the \'prompt\' message', function () {
$scope.message = '';
$timeout.flush(4900);
expect($scope.message).toEqual('');
$timeout.flush(200);
expect($scope.message).toEqual('Hi!');
expect(messagingService.getMessage)
.toHaveBeenCalledWith('prompt');
});
});
});
Expected '' to equal 'Hi!'.
describe('messaging.flashController', function () {
// tests and setup
describe('after waiting 5 seconds', function () {
it('shows the \'prompt\' message', function () {
$scope.message = '';
$timeout.flush(4900);
expect($scope.message).toEqual('');
$timeout.flush(200);
expect($scope.message).toEqual('Hi!');
expect(messagingService.getMessage)
.toHaveBeenCalledWith('prompt');
});
});
});
Expected spy getMessage to have been...
angular.module('messaging')
.controller('messaging.flashController', function($scope,
$timeout,
messagingService) {
$scope.message = messagingService.getMessage('initial');
});
angular.module('messaging')
.controller('messaging.flashController', function($scope,
$timeout,
messagingService) {
$scope.message = messagingService.getMessage('initial');
$timeout(function () {
$scope.message = messagingService.getMessage('prompt');
}, 5000);
});
angular.module('messaging')
.controller('messaging.flashController', function($scope,
$timeout,
messagingService) {
$scope.message = messagingService.getMessage('initial');
$timeout(function () {
$scope.message = messagingService.getMessage('prompt');
}, 5000);
});
angular.module('messaging')
.controller('messaging.flashController', function($scope,
$timeout,
messagingService) {
$scope.message = messagingService.getMessage('initial');
$timeout(function () {
$scope.message = messagingService.getMessage('prompt');
}, 5000);
});
angular.module('messaging')
.controller('messaging.flashController', function($scope,
$timeout,
messagingService) {
function setMessage(type) {
$scope.message = messagingService.getMessage(type);
}
setMessage('initial');
$timeout(function () {
setMessage('prompt');
}, 5000);
});
angular.module('messaging')
.controller('messaging.flashController', function($scope,
$timeout,
messagingService) {
function setMessage(type) {
$scope.message = messagingService.getMessage(type);
}
setMessage('initial');
$timeout(function () {
setMessage('prompt');
}, 5000);
});
Show the current user
Welcome {{currentUser}}!
{{message}}
describe('users.currentController', function () {
var $scope, usersService, deferred;
beforeEach(module('users'));
beforeEach(inject(function ($rootScope, $controller, $q,
_usersService_) {
$scope = $rootScope.$new();
usersService = _usersService_;
$controller('users.currentController', {
$scope: $scope,
usersService: usersService
});
}));
// tests go here
});
describe('users.currentController', function () {
var $scope, usersService, deferred;
beforeEach(module('users'));
beforeEach(inject(function ($rootScope, $controller, $q,
_usersService_) {
$scope = $rootScope.$new();
usersService = _usersService_;
deferred = $q.defer();
$controller('users.currentController', {
$scope: $scope,
usersService: usersService
});
}));
// tests go here
});
describe('users.currentController', function () {
var $scope, usersService, deferred;
beforeEach(module('users'));
beforeEach(inject(function ($rootScope, $controller, $q,
_usersService_) {
$scope = $rootScope.$new();
usersService = _usersService_;
deferred = $q.defer();
spyOn(usersService, 'getCurrent')
.and.returnValue(deferred.promise);
$controller('users.currentController', {
$scope: $scope,
usersService: usersService
});
}));
// tests go here
});
describe('when the controller loads', function () {
it('sets the current user', function () {
});
});
describe('when the controller loads', function () {
it('sets the current user', function () {
expect($scope.currentUser).toEqual('Loading');
});
});
describe('when the controller loads', function () {
it('sets the current user', function () {
expect($scope.currentUser).toEqual('Loading');
deferred.resolve('@walken20');
});
});
describe('when the controller loads', function () {
it('sets the current user', function () {
expect($scope.currentUser).toEqual('Loading');
deferred.resolve('@walken20');
$scope.$apply();
});
});
describe('when the controller loads', function () {
it('sets the current user', function () {
expect($scope.currentUser).toEqual('Loading');
deferred.resolve('@walken20');
$scope.$apply();
expect($scope.currentUser).toEqual('@walken20');
});
});
describe('when the controller loads', function () {
it('sets the current user', function () {
expect($scope.currentUser).toEqual('Loading');
deferred.resolve('@walken20');
$scope.$apply();
expect($scope.currentUser).toEqual('@walken20');
});
});
Expected undefined to equal 'Loading'.
describe('when the controller loads', function () {
it('sets the current user', function () {
expect($scope.currentUser).toEqual('Loading');
deferred.resolve('@walken20');
$scope.$apply();
expect($scope.currentUser).toEqual('@walken20');
});
});
Expected undefined to equal '@walken20'.
angular.module('users')
.controller('users.currentController', function($scope,
usersService) {
});
angular.module('users')
.controller('users.currentController', function($scope,
usersService) {
$scope.currentUser = 'Loading';
});
angular.module('users')
.controller('users.currentController', function($scope,
usersService) {
$scope.currentUser = 'Loading';
usersService.getCurrent().then(function (result) {
$scope.currentUser = result;
});
});
angular.module('users')
.controller('users.currentController', function($scope,
usersService) {
$scope.currentUser = 'Loading';
usersService.getCurrent().then(function (result) {
$scope.currentUser = result;
});
});
angular.module('users')
.controller('users.currentController', function($scope,
usersService) {
$scope.currentUser = 'Loading';
usersService.getCurrent().then(function (result) {
$scope.currentUser = result;
});
});
angular.module('users')
.controller('users.currentController', function($scope,
usersService) {
function setCurrentUser(user) {
$scope.currentUser = user;
}
setCurrentUser('Loading');
usersService.getCurrent().then(setCurrentUser);
});
angular.module('users')
.controller('users.currentController', function($scope,
usersService) {
function setCurrentUser(user) {
$scope.currentUser = user;
}
setCurrentUser('Loading');
usersService.getCurrent().then(setCurrentUser);
});