fix(ivy): provided Injector should be instantiated by its factory (#27456)

(FW-777)

When an Injector is provided, R3Injector instantiates it by calling its
constructor instead of its factory, not resolving dependencies.
With this fix, the ngInjectorDef is checked and the factory is correctly
used if it is found.

PR Close #27456
This commit is contained in:
Marc Laval
2018-12-04 14:34:43 +01:00
committed by Igor Minar
parent 486f69fcac
commit 8973f12ee4
6 changed files with 68 additions and 52 deletions

View File

@ -44,63 +44,59 @@ describe('setUpLocationSync', () => {
`);
});
fixmeIvy('FW-777: R3Injector doesn\'t support injectors as a provider') &&
it('should get the $rootScope from AngularJS and set an $on watch on $locationChangeStart',
() => {
const $rootScope = jasmine.createSpyObj('$rootScope', ['$on']);
it('should get the $rootScope from AngularJS and set an $on watch on $locationChangeStart',
() => {
const $rootScope = jasmine.createSpyObj('$rootScope', ['$on']);
upgradeModule.$injector.get.and.callFake(
(name: string) => (name === '$rootScope') && $rootScope);
upgradeModule.$injector.get.and.callFake(
(name: string) => (name === '$rootScope') && $rootScope);
setUpLocationSync(upgradeModule);
setUpLocationSync(upgradeModule);
expect($rootScope.$on).toHaveBeenCalledTimes(1);
expect($rootScope.$on)
.toHaveBeenCalledWith('$locationChangeStart', jasmine.any(Function));
});
expect($rootScope.$on).toHaveBeenCalledTimes(1);
expect($rootScope.$on).toHaveBeenCalledWith('$locationChangeStart', jasmine.any(Function));
});
fixmeIvy('FW-777: R3Injector doesn\'t support injectors as a provider') &&
it('should navigate by url every time $locationChangeStart is broadcasted', () => {
const url = 'https://google.com';
const pathname = '/custom/route';
const normalizedPathname = 'foo';
const query = '?query=1&query2=3';
const hash = '#new/hash';
const $rootScope = jasmine.createSpyObj('$rootScope', ['$on']);
it('should navigate by url every time $locationChangeStart is broadcasted', () => {
const url = 'https://google.com';
const pathname = '/custom/route';
const normalizedPathname = 'foo';
const query = '?query=1&query2=3';
const hash = '#new/hash';
const $rootScope = jasmine.createSpyObj('$rootScope', ['$on']);
upgradeModule.$injector.get.and.returnValue($rootScope);
LocationMock.normalize.and.returnValue(normalizedPathname);
upgradeModule.$injector.get.and.returnValue($rootScope);
LocationMock.normalize.and.returnValue(normalizedPathname);
setUpLocationSync(upgradeModule);
setUpLocationSync(upgradeModule);
const callback = $rootScope.$on.calls.argsFor(0)[1];
callback({}, url + pathname + query + hash, '');
const callback = $rootScope.$on.calls.argsFor(0)[1];
callback({}, url + pathname + query + hash, '');
expect(LocationMock.normalize).toHaveBeenCalledTimes(1);
expect(LocationMock.normalize).toHaveBeenCalledWith(pathname);
expect(LocationMock.normalize).toHaveBeenCalledTimes(1);
expect(LocationMock.normalize).toHaveBeenCalledWith(pathname);
expect(RouterMock.navigateByUrl).toHaveBeenCalledTimes(1);
expect(RouterMock.navigateByUrl).toHaveBeenCalledWith(normalizedPathname + query + hash);
});
expect(RouterMock.navigateByUrl).toHaveBeenCalledTimes(1);
expect(RouterMock.navigateByUrl).toHaveBeenCalledWith(normalizedPathname + query + hash);
});
fixmeIvy('FW-777: R3Injector doesn\'t support injectors as a provider') &&
it('should work correctly on browsers that do not start pathname with `/`', () => {
const anchorProto = HTMLAnchorElement.prototype;
const originalDescriptor = Object.getOwnPropertyDescriptor(anchorProto, 'pathname');
Object.defineProperty(anchorProto, 'pathname', {get: () => 'foo/bar'});
it('should work correctly on browsers that do not start pathname with `/`', () => {
const anchorProto = HTMLAnchorElement.prototype;
const originalDescriptor = Object.getOwnPropertyDescriptor(anchorProto, 'pathname');
Object.defineProperty(anchorProto, 'pathname', {get: () => 'foo/bar'});
try {
const $rootScope = jasmine.createSpyObj('$rootScope', ['$on']);
upgradeModule.$injector.get.and.returnValue($rootScope);
try {
const $rootScope = jasmine.createSpyObj('$rootScope', ['$on']);
upgradeModule.$injector.get.and.returnValue($rootScope);
setUpLocationSync(upgradeModule);
setUpLocationSync(upgradeModule);
const callback = $rootScope.$on.calls.argsFor(0)[1];
callback({}, '', '');
const callback = $rootScope.$on.calls.argsFor(0)[1];
callback({}, '', '');
expect(LocationMock.normalize).toHaveBeenCalledWith('/foo/bar');
} finally {
Object.defineProperty(anchorProto, 'pathname', originalDescriptor !);
}
});
expect(LocationMock.normalize).toHaveBeenCalledWith('/foo/bar');
} finally {
Object.defineProperty(anchorProto, 'pathname', originalDescriptor !);
}
});
});