Created
August 24, 2014 15:19
-
-
Save MikeMKH/63046f7fedad076a3f2a to your computer and use it in GitHub Desktop.
Coin Changer kata with AngularJS using lodash
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var app = angular.module('coinChangerApp', []); | |
// based on http://snippetrepo.com/snippets/lodash-in-angularjs | |
app.factory('_', ['$window', | |
function($window) { | |
return $window._; | |
} | |
]); | |
app.controller('CoinChangerCtrl', ['$scope', '_', | |
function($scope) { | |
$scope.changeFor = function(coins, amount) { | |
if (_.isEmpty(coins)) return []; | |
return _.reduce(coins, function(m, coin) { | |
m.change.push(Math.floor(m.amount / coin)); | |
m.amount %= coin; | |
return m; | |
}, { | |
amount: amount, | |
change: [] | |
}).change; | |
}; | |
} | |
]); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe('Testing a Hello World controller', function() { | |
var $scope = null; | |
var ctrl = null; | |
var _ = null; | |
//you need to indicate your module in a test | |
beforeEach(module('coinChangerApp')); | |
beforeEach(inject(function($rootScope, $controller, $window) { | |
$scope = $rootScope.$new(); | |
_ = $window._; | |
ctrl = $controller('CoinChangerCtrl', { | |
$scope: $scope | |
}); | |
})); | |
describe('given no coins', function() { | |
var noCoinsFor; | |
beforeEach(function() { | |
noCoinsFor = _.curry($scope.changeFor)([]); | |
}); | |
it('should return nothing for 0 cents', function() { | |
expect(noCoinsFor(0)).toEqual([]); | |
}); | |
it('should return nothing for 99 cents', function() { | |
expect(noCoinsFor(99)).toEqual([]); | |
}); | |
}); | |
describe('given pennies', function(){ | |
var penniesFor; | |
beforeEach(function(){ | |
penniesFor = _.curry($scope.changeFor)([1]); | |
}); | |
it('should return nothing for 0 cents', function(){ | |
expect(penniesFor(0)).toEqual([0]); | |
}); | |
it('should return 1 penny for 1 cents', function(){ | |
expect(penniesFor(1)).toEqual([1]); | |
}); | |
it('should return 2 pennies for 2 cents', function(){ | |
expect(penniesFor(2)).toEqual([2]); | |
}); | |
}); | |
describe('given nickels and pennies', function(){ | |
var nickelsPenniesFor; | |
beforeEach(function(){ | |
nickelsPenniesFor = _.curry($scope.changeFor)([5, 1]); | |
}); | |
it('should return nothing for 0 cents', function(){ | |
expect(nickelsPenniesFor(0)).toEqual([0, 0]); | |
}); | |
it('should return 1 penny for 1 cents', function(){ | |
expect(nickelsPenniesFor(1)).toEqual([0, 1]); | |
}); | |
it('should return 1 nickel and 1 penny for 6 cents', function(){ | |
expect(nickelsPenniesFor(6)).toEqual([1, 1]); | |
}); | |
}); | |
describe('given quarters, dimes, nickels, and pennies', function(){ | |
var changeFor; | |
beforeEach(function(){ | |
changeFor = _.curry($scope.changeFor)([25, 10, 5, 1]); | |
}); | |
it('should return nothing for 0 cents', function(){ | |
expect(changeFor(0)).toEqual([0, 0, 0, 0]); | |
}); | |
it('should return 1 penny for 1 cents', function(){ | |
expect(changeFor(1)).toEqual([0, 0, 0, 1]); | |
}); | |
it('should return 3 quarters, 2 dimes, 0 nickels and 4 pennies for 99 cents', function(){ | |
expect(changeFor(99)).toEqual([3, 2, 0, 4]); | |
}); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html ng-app="coinChangerApp"> | |
<head> | |
<meta charset="utf-8" /> | |
<title>AngularJS test</title> | |
<link rel="stylesheet" href="style.css" /> | |
<script data-require="angular.js" data-semver="1.2.16" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script> | |
<script data-require="lodash.js@*" data-semver="2.4.1" src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script> | |
<script src="app.js"></script> | |
</head> | |
<body ng-controller="CoinChangerCtrl" ng-init="coins = [25, 10, 5, 1]"> | |
<div>Make change for</div> | |
<input ng-model="value"> | |
<table ng-if="value"> | |
<thead> | |
<tr> | |
<td>Coin value</td> | |
<td>Number of coins</td> | |
</tr> | |
</thead> | |
<tbody ng-repeat="coin in changeFor(coins, value) track by $index"> | |
<tr> | |
<td>{{coins[$index]}}</td> | |
<td>{{coin}}</td> | |
</tr> | |
</tbody> | |
</table> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
var jasmineEnv = jasmine.getEnv(); | |
jasmineEnv.updateInterval = 250; | |
/** | |
Create the `HTMLReporter`, which Jasmine calls to provide results of each spec and each suite. The Reporter is responsible for presenting results to the user. | |
*/ | |
var htmlReporter = new jasmine.HtmlReporter(); | |
jasmineEnv.addReporter(htmlReporter); | |
/** | |
Delegate filtering of specs to the reporter. Allows for clicking on single suites or specs in the results to only run a subset of the suite. | |
*/ | |
jasmineEnv.specFilter = function(spec) { | |
return htmlReporter.specFilter(spec); | |
}; | |
/** | |
Run all of the tests when the page finishes loading - and make sure to run any previous `onload` handler | |
### Test Results | |
Scroll down to see the results of all of these specs. | |
*/ | |
var currentWindowOnload = window.onload; | |
window.onload = function() { | |
if (currentWindowOnload) { | |
currentWindowOnload(); | |
} | |
//document.querySelector('.version').innerHTML = jasmineEnv.versionString(); | |
execJasmine(); | |
}; | |
function execJasmine() { | |
jasmineEnv.execute(); | |
} | |
})(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* restore "body" styling that were changes by "jasmine.css"... */ | |
body { background-color: white; padding: 0; margin: 8px; } | |
/* ... but remain the "jasmine.css" styling for the Jasmine reporting */ | |
.jasmine_reporter { background-color: #eeeeee; padding: 0; margin: 0; } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html ng-app="coinChangerApp"> | |
<head> | |
<meta charset="utf-8" /> | |
<title>AngularJS test</title> | |
<link data-require="jasmine" data-semver="2.0.0" rel="stylesheet" href="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.css" /> | |
<script data-require="json2" data-semver="0.0.2012100-8" src="//cdnjs.cloudflare.com/ajax/libs/json2/20121008/json2.js"></script> | |
<script data-require="jasmine" data-semver="2.0.0" src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.js"></script> | |
<script data-require="jasmine" data-semver="2.0.0" src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine-html.js"></script> | |
<script data-require="jasmine@*" data-semver="2.0.0" src="//cdn.jsdelivr.net/jasmine/2.0.0/boot.js"></script> | |
<script data-require="angular.js" data-semver="1.2.16" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script> | |
<script data-require="angular-mocks" data-semver="1.2.16" src="https://code.angularjs.org/1.2.16/angular-mocks.js"></script> | |
<script data-require="lodash.js@*" data-semver="2.4.1" src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script> | |
<link rel="stylesheet" href="style.css" /> | |
<script src="app.js"></script> | |
<script src="appSpec.js"></script> | |
<script src="jasmineBootstrap.js"></script> | |
<!-- bootstraps Jasmine --> | |
</head> | |
<body> | |
<div id="HTMLReporter" class="jasmine_reporter"></div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See also my blog post: http://comp-phil.blogspot.com/2014/08/functional-programming-all-things-or.html and Plunker: http://plnkr.co/edit/3BPe7k which go with this gist.