-
-
Save johnnncodes/a3bb97c0a9cb3f2ea55e to your computer and use it in GitHub Desktop.
This file contains 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
'use strict'; | |
/** | |
* | |
* An Angular Jasmine testing utility | |
* | |
* @copyright 2013 Chris Sattinger | |
* MIT License | |
* | |
* automatically injects these services: | |
* '$httpBackend', '$rootScope', '$controller', '$compile' | |
describe('app.controllers', function() { | |
var s = new Speedball( | |
[ | |
// require these modules | |
'app.services' | |
], [ | |
// load these services to s.{Account} | |
'Comments', | |
'$routeParams', | |
]); | |
describe('CommentsCtrl', function() { | |
var data = [{ | |
"comment": "hi", | |
'user': { | |
_id: 'userid' | |
} | |
}]; | |
it('should fetch comments', function() { | |
// this is what we expect the controller to fetch | |
// and we supply the data it should get | |
s.willGET('/capsules/1/comments', data); | |
// call the control | |
s.$routeParams.id = 1; | |
s.controller('CommentsCtrl'); | |
// having executed the controller | |
// we can test the s.$scope | |
expect(s.$scope.comments).toEqualData(data); | |
}); | |
}); | |
}); | |
**/ | |
function Speedball(modules, injections, spies, templates) { | |
var self = this; | |
var moduleParams = {}; | |
// preloading templates as compiled modules using karma's html2js preprocessor | |
if(templates) { | |
angular.forEach(templates, function(templateURLs, baseTemplatePath) { | |
angular.forEach(templateURLs, function(templateURL) { | |
// where karma preprocessor loaded it into | |
var full = baseTemplatePath + templateURL; | |
// module name is full/path/to/the.html | |
modules.push(full); | |
}); | |
}); | |
} | |
angular.forEach(modules, function(module) { | |
moduleParams[module] = [module]; | |
}); | |
angular.forEach(spies, function(spy) { | |
var module = spy[0], | |
service = spy[1], | |
methods = spy[2]; | |
if(!moduleParams[module]) { | |
moduleParams[module] = [module]; | |
} | |
moduleParams[module].push(function($provide) { | |
$provide.decorator(service, function ($delegate) { | |
angular.forEach(methods, function(method) { | |
$delegate[method] = jasmine.createSpy(); | |
}); | |
return $delegate; | |
}); | |
}); | |
}); | |
// modules need to be sorted. do the spy ones first | |
if(!injections) { | |
injections = []; | |
} | |
injections = injections.concat(['$httpBackend', '$rootScope', '$controller', '$compile', '$templateCache']); | |
beforeEach(function() { | |
angular.forEach(moduleParams, function(moduleParam) { | |
module.apply(undefined, moduleParam); | |
}); | |
this.addMatchers({ | |
toEqualData: function(expected) { | |
return angular.equals(this.actual, expected); | |
} | |
}); | |
}); | |
beforeEach(inject(function($injector) { | |
angular.forEach(injections, function(name) { | |
self[name] = $injector.get(name); | |
}); | |
// always make a $scope | |
self.$scope = self.$rootScope.$new(); | |
if(templates) { | |
angular.forEach(templates, function(templateURLs, baseTemplatePath) { | |
angular.forEach(templateURLs, function(templateURL) { | |
var full = baseTemplatePath + templateURL; | |
// copy it ... | |
var template = self.$templateCache.get(full); | |
// to the URL the directive will request it at | |
self.$templateCache.put(templateURL, template); | |
}); | |
}); | |
} | |
})); | |
// always verify all requests | |
this.verifyRequests(); | |
} | |
Speedball.prototype.verifyRequests = function() { | |
var self = this; | |
afterEach(function() { | |
self.$httpBackend.verifyNoOutstandingExpectation(); | |
self.$httpBackend.verifyNoOutstandingRequest(); | |
// window.localStorage.clear(); | |
}); | |
}; | |
Speedball.prototype.willGET = function(url, response, statusCode) { | |
this.$httpBackend | |
.expectGET(url) | |
.respond(statusCode || 200, response); | |
}; | |
Speedball.prototype.willPOST = function(url, post, response, statusCode) { | |
this.$httpBackend | |
.expectPOST(url, post) | |
.respond(statusCode || 201, response); | |
}; | |
Speedball.prototype.willPUT = function(url, post, response, statusCode) { | |
this.$httpBackend | |
.expectPUT(url, post) | |
.respond(statusCode || 200, response); | |
}; | |
Speedball.prototype.flush = function() { | |
this.$httpBackend.flush(); | |
}; | |
// make controller and flush expected requests | |
Speedball.prototype.controller = function(controllerName, dontFlush) { | |
var ctlr = this.$controller(controllerName, {$scope: this.$scope}); | |
if(!dontFlush) { | |
this.flush(); | |
} | |
return ctlr; | |
}; | |
/** | |
* | |
* For pre-loading templates for directive testing | |
* | |
* because angular mock $httpBackend will intercept all requests | |
* you need a way to let the directive fetch its template. | |
* | |
* in your karma.conf add the partials to your files list: | |
* // load partials for testing directives | |
* // using html2js preprocessor | |
* 'app/partials/*.html', | |
* | |
* and add the karma preprocessor: | |
* // generate js files from html templates to expose them during testing. | |
* preprocessors = { | |
* 'app/partials/*.html': 'html2js' | |
* }; | |
* | |
* then add those templates to the speedball: | |
* | |
* templates: { | |
* 'phoneapp/yapp/': [ | |
* 'partials/capsule-summary.html' | |
* ] | |
* } | |
* | |
* now you will be able to compile directives | |
**/ | |
Speedball.prototype.directive = function(html, scopeVars, testFunc) { | |
var htmlEl = angular.element(html), el, self = this, directiveScope; | |
if(scopeVars) { | |
angular.forEach(scopeVars, function(v, k) { | |
self.$scope[k] = v; | |
}); | |
} | |
el = this.$compile(htmlEl)(this.$scope); | |
this.$scope.$digest(); | |
this.$scope.$apply(); | |
if(testFunc) { | |
// children scope is that inner scope created by the directive | |
// else it uses the scope it was given by parent | |
// warning: this may not be perfect yet | |
directiveScope = el.children().scope() || el.scope(); | |
testFunc(el, directiveScope); | |
} | |
return el; | |
}; | |
Speedball.prototype.debug = function(obj) { | |
try { | |
// circular references are popular in angular | |
// but they cannot be printed | |
console.log(JSON.stringify(obj)); | |
} catch(err) { | |
console.log('' + obj + '::'); | |
for (var key in obj) { | |
if (obj.hasOwnProperty(key)) { | |
console.log(key + '=' + obj[key]); | |
} | |
} | |
} | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment