Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
feat(ngMocks): cleanup $inject annotations after each test
Browse files Browse the repository at this point in the history
this will help in detecting unannotated functions both in apps and angular core in case only part of the tests are run with strictDi
  • Loading branch information
shahata authored and petebacondarwin committed Jan 28, 2015
1 parent 2ece1c9 commit 0baa17a
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 3 deletions.
4 changes: 2 additions & 2 deletions src/auto/injector.js
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ function createInjector(modulesToLoad, strictDi) {
}

var args = [],
$inject = annotate(fn, strictDi, serviceName),
$inject = createInjector.$$annotate(fn, strictDi, serviceName),
length, i,
key;

Expand Down Expand Up @@ -839,7 +839,7 @@ function createInjector(modulesToLoad, strictDi) {
invoke: invoke,
instantiate: instantiate,
get: getService,
annotate: annotate,
annotate: createInjector.$$annotate,
has: function(name) {
return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name);
}
Expand Down
14 changes: 14 additions & 0 deletions src/ngMock/angular-mocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -2127,18 +2127,32 @@ angular.mock.$RootScopeDecorator = ['$delegate', function($delegate) {
if (window.jasmine || window.mocha) {

var currentSpec = null,
annotatedFunctions,
isSpecRunning = function() {
return !!currentSpec;
};

angular.mock.$$annotate = angular.injector.$$annotate;
angular.injector.$$annotate = function(fn) {
if (typeof fn === 'function' && !fn.$inject) {
annotatedFunctions.push(fn);

This comment has been minimized.

Copy link
@jeffbcross

jeffbcross Jan 30, 2015

Contributor

@shahata There was one internal test that errored on this line because annotatedFunctions was undefined. The cause was that the application created a separate injector to get one-off access to ngResource in a base class that was just used as a base class to other classes. We worked around it by not needing to create the injector at all, but I wonder if there's a legitimate bug here.

This comment has been minimized.

Copy link
@shahata

shahata Feb 1, 2015

Author Contributor

@jeffbcross yeah, this would indeed throw if annotate is somehow called before the first beforeEach. Is this the case you experienced? It can be fixed simply by initializing this variable to be an empty array.

}
return angular.mock.$$annotate.apply(this, arguments);
};


(window.beforeEach || window.setup)(function() {
annotatedFunctions = [];
currentSpec = this;
});

(window.afterEach || window.teardown)(function() {
var injector = currentSpec.$injector;

annotatedFunctions.forEach(function(fn) {
delete fn.$inject;
});

angular.forEach(currentSpec.$modules, function(module) {
if (module && module.$$hashKey) {
module.$$hashKey = undefined;
Expand Down
6 changes: 5 additions & 1 deletion test/auto/injectorSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,11 @@ describe('injector', function() {


it('should publish annotate API', function() {
expect(injector.annotate).toBe(annotate);
expect(angular.mock.$$annotate).toBe(annotate);
spyOn(angular.mock, '$$annotate').andCallThrough();
function fn() {}
injector.annotate(fn);
expect(angular.mock.$$annotate).toHaveBeenCalledWith(fn);
});
});

Expand Down
33 changes: 33 additions & 0 deletions test/ngMock/angular-mocksSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,39 @@ describe('ngMock', function() {
expect(testFn.$$hashKey).toBeUndefined();
});
});

describe('$inject cleanup', function() {
function testFn() {

}

it('should add $inject when invoking test function', inject(function($injector) {
$injector.invoke(testFn);
expect(testFn.$inject).toBeDefined();
}));

it('should cleanup $inject after previous test', function() {
expect(testFn.$inject).toBeUndefined();
});

it('should add $inject when annotating test function', inject(function($injector) {
$injector.annotate(testFn);
expect(testFn.$inject).toBeDefined();
}));

it('should cleanup $inject after previous test', function() {
expect(testFn.$inject).toBeUndefined();
});

it('should invoke an already annotated function', inject(function($injector) {
testFn.$inject = [];
$injector.invoke(testFn);
}));

it('should not cleanup $inject after previous test', function() {
expect(testFn.$inject).toBeDefined();
});
});
});

describe('in DSL', function() {
Expand Down

0 comments on commit 0baa17a

Please sign in to comment.