/* jshint -W079 */ var specHelper = (function() {
var service = { fakeLogger: fakeLogger, fakeRouteProvider: fakeRouteProvider, fakeStateProvider: fakeStateProvider, injector: injector, verifyNoOutstandingHttpRequests: verifyNoOutstandingHttpRequests }; return service; function fakeLogger($provide) { $provide.value('logger', sinon.stub({ info: function() {}, error: function() {}, warning: function() {}, success: function() {} })); } function fakeStateProvider($provide) { /** * Stub out the $stateProvider so we avoid * all routing calls, including the default state * which runs on every test otherwise. * Make sure this goes before the inject in the spec. */ $provide.provider('$state', function() { /* jshint validthis:true */ this.state = sinon.stub(); this.$get = function() { return { // current: {}, // fake before each test as needed // state: {} // fake before each test as needed // more? You'll know when it fails :-) }; }; }); $provide.provider('$urlRouter', function() { /* jshint validthis:true */ this.otherwise = sinon.stub(); this.$get = function() { return { // current: {}, // fake before each test as needed // states: {} // fake before each test as needed // more? You'll know when it fails :-) }; }; }); } function fakeRouteProvider($provide) { /** * Stub out the $routeProvider so we avoid * all routing calls, including the default route * which runs on every test otherwise. * Make sure this goes before the inject in the spec. */ $provide.provider('$route', function() { /* jshint validthis:true */ this.when = sinon.stub(); this.otherwise = sinon.stub(); this.$get = function() { return { // current: {}, // fake before each test as needed // routes: {} // fake before each test as needed // more? You'll know when it fails :-) }; }; }); } /** * Inspired by Angular; that's how they get the parms for injection */ function getFnParams (fn) { var fnText; var argDecl; var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m; var FN_ARG_SPLIT = /,/; var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/; var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; var params = []; if (fn.length) { fnText = fn.toString().replace(STRIP_COMMENTS, ''); argDecl = fnText.match(FN_ARGS); angular.forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) { arg.replace(FN_ARG, function(all, underscore, name) { params.push(name); }); }); } return params; } function injector () { var annotation, body = '', cleanupBody = '', mustAnnotate = false, params; if (typeof arguments[0] === 'function') { params = getFnParams(arguments[0]); } // else from here on assume that arguments are all strings else if (angular.isArray(arguments[0])) { params = arguments[0]; } else { params = Array.prototype.slice.call(arguments); } annotation = params.join('\',\''); // might need to annotate angular.forEach(params, function(name, ix) { var _name, pathName = name.split('.'), pathLen = pathName.length; if (pathLen > 1) { // name is a path like 'block.foo'. Can't use as identifier // assume last segment should be identifier name, e.g. 'foo' name = pathName[pathLen - 1]; mustAnnotate = true; } _name = '_' + name + '_'; params[ix] = _name; body += name + '=' + _name + ';'; cleanupBody += 'delete window.' + name + ';'; // todo: tolerate component names that are invalid JS identifiers, e.g. 'burning man' }); var fn = 'function(' + params.join(',') + '){' + body + '}'; if (mustAnnotate) { fn = '[\'' + annotation + '\',' + fn + ']'; } var exp = 'inject(' + fn + ');' + 'afterEach(function(){' + cleanupBody + '});'; // remove from window. //Function(exp)(); // the assigned vars will be global. `afterEach` will remove them /* jshint evil:true */ new Function(exp)(); // Alternative that would not touch window but would require eval()!! // Don't do `Function(exp)()` and don't do afterEach cleanup // Instead do .. // return exp; // // Then caller must say something like: // eval(specHelper.injector('$log', 'foo')); } function verifyNoOutstandingHttpRequests () { afterEach(inject(function($httpBackend) { $httpBackend.verifyNoOutstandingExpectation(); $httpBackend.verifyNoOutstandingRequest(); })); }
})();