Skip to content

Commit fd173e6

Browse files
drpicoxpetebacondarwin
authored andcommitted
refactor(ngMock.$componentController): use $injector instead of adding new code to angular.min.js
Closes angular#13732
1 parent 4e1b36c commit fd173e6

File tree

3 files changed

+129
-7
lines changed

3 files changed

+129
-7
lines changed

src/ng/compile.js

+1-4
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
928928
return this;
929929
};
930930

931-
this.$$componentControllers = createMap();
932931
/**
933932
* @ngdoc method
934933
* @name $compileProvider#component
@@ -1054,8 +1053,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
10541053
*/
10551054
this.component = function registerComponent(name, options) {
10561055
var controller = options.controller || function() {};
1057-
var ident = identifierForController(options.controller) || options.controllerAs || '$ctrl';
1058-
this.$$componentControllers[name] = { controller: controller, ident: ident};
10591056

10601057
function factory($injector) {
10611058
function makeInjectable(fn) {
@@ -1071,7 +1068,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
10711068
var template = (!options.template && !options.templateUrl ? '' : options.template);
10721069
return {
10731070
controller: controller,
1074-
controllerAs: ident,
1071+
controllerAs: identifierForController(options.controller) || options.controllerAs || '$ctrl',
10751072
template: makeInjectable(template),
10761073
templateUrl: makeInjectable(options.templateUrl),
10771074
transclude: options.transclude,

src/ngMock/angular-mocks.js

+18-3
Original file line numberDiff line numberDiff line change
@@ -2183,10 +2183,25 @@ angular.mock.$ControllerDecorator = ['$delegate', function($delegate) {
21832183
*/
21842184
angular.mock.$ComponentControllerProvider = ['$compileProvider', function($compileProvider) {
21852185
return {
2186-
$get: ['$controller', function($controller) {
2186+
$get: ['$controller','$injector', function($controller,$injector) {
21872187
return function $componentController(componentName, locals, bindings, ident) {
2188-
var controllerInfo = $compileProvider.$$componentControllers[componentName];
2189-
return $controller(controllerInfo.controller, locals, bindings, ident || controllerInfo.ident);
2188+
// get all directives associated to the component name
2189+
var directives = $injector.get(componentName + 'Directive');
2190+
// look for those directives that are components
2191+
var candidateDirectives = directives.filter(function(directiveInfo) {
2192+
// components have controller, controllerAs and restrict:'E' compatible
2193+
return directiveInfo.controller && directiveInfo.controllerAs && directiveInfo.restrict.indexOf('E') >= 0;
2194+
});
2195+
// check if valid directives found
2196+
if (candidateDirectives.length === 0) {
2197+
throw new Error('No component found');
2198+
}
2199+
if (candidateDirectives.length > 1) {
2200+
throw new Error('Too many components found');
2201+
}
2202+
// get the info of the component
2203+
var directiveInfo = candidateDirectives[0];
2204+
return $controller(directiveInfo.controller, locals, bindings, ident || directiveInfo.controllerAs);
21902205
};
21912206
}]
21922207
};

test/ngMock/angular-mocksSpec.js

+110
Original file line numberDiff line numberDiff line change
@@ -1938,6 +1938,116 @@ describe('ngMock', function() {
19381938
expect($scope.testCtrl).toBe(ctrl);
19391939
});
19401940
});
1941+
1942+
it('should instantiate the controller of the restrict:\'E\' component if there are more directives with the same name but not \'E\' restrictness', function() {
1943+
function TestController() {
1944+
this.r = 6779;
1945+
}
1946+
module(function($compileProvider) {
1947+
$compileProvider.directive('test', function() {
1948+
return { restrict: 'A' };
1949+
});
1950+
$compileProvider.component('test', {
1951+
controller: TestController
1952+
});
1953+
});
1954+
inject(function($componentController, $rootScope) {
1955+
var ctrl = $componentController('test', { $scope: {} });
1956+
expect(ctrl).toEqual({ r: 6779 });
1957+
});
1958+
});
1959+
1960+
it('should instantiate the controller of the restrict:\'E\' component if there are more directives with the same name and \'E\' restrictness but no controller', function() {
1961+
function TestController() {
1962+
this.r = 22926;
1963+
}
1964+
module(function($compileProvider) {
1965+
$compileProvider.directive('test', function() {
1966+
return { restrict: 'E' };
1967+
});
1968+
$compileProvider.component('test', {
1969+
controller: TestController
1970+
});
1971+
});
1972+
inject(function($componentController, $rootScope) {
1973+
var ctrl = $componentController('test', { $scope: {} });
1974+
expect(ctrl).toEqual({ r: 22926 });
1975+
});
1976+
});
1977+
1978+
it('should instantiate the controller of the directive with controller if there are more directives', function() {
1979+
function TestController() {
1980+
this.r = 18842;
1981+
}
1982+
module(function($compileProvider) {
1983+
$compileProvider.directive('test', function() {
1984+
return { };
1985+
});
1986+
$compileProvider.directive('test', function() {
1987+
return {
1988+
controller: TestController,
1989+
controllerAs: '$ctrl'
1990+
};
1991+
});
1992+
});
1993+
inject(function($componentController, $rootScope) {
1994+
var ctrl = $componentController('test', { $scope: {} });
1995+
expect(ctrl).toEqual({ r: 18842 });
1996+
});
1997+
});
1998+
1999+
it('should fail if there is no directive with restrict:\'E\' compatible and controller', function() {
2000+
function TestController() {
2001+
this.r = 31145;
2002+
}
2003+
module(function($compileProvider) {
2004+
$compileProvider.directive('test', function() {
2005+
return {
2006+
restrict: 'AC',
2007+
controller: TestController
2008+
};
2009+
});
2010+
$compileProvider.directive('test', function() {
2011+
return {
2012+
restrict: 'E',
2013+
controller: TestController
2014+
};
2015+
});
2016+
$compileProvider.directive('test', function() {
2017+
return { restrict: 'E' };
2018+
});
2019+
});
2020+
inject(function($componentController, $rootScope) {
2021+
expect(function() {
2022+
$componentController('test', { $scope: {} });
2023+
}).toThrow('No component found');
2024+
});
2025+
});
2026+
2027+
it('should fail if there more than two components with same name', function() {
2028+
function TestController($scope, a, b) {
2029+
this.$scope = $scope;
2030+
this.a = a;
2031+
this.b = b;
2032+
}
2033+
module(function($compileProvider) {
2034+
$compileProvider.directive('test', function() {
2035+
return {
2036+
controller: TestController,
2037+
controllerAs: '$ctrl'
2038+
};
2039+
});
2040+
$compileProvider.component('test', {
2041+
controller: TestController
2042+
});
2043+
});
2044+
inject(function($componentController, $rootScope) {
2045+
expect(function() {
2046+
var $scope = {};
2047+
$componentController('test', { $scope: $scope, a: 'A', b: 'B' }, { x: 'X', y: 'Y' });
2048+
}).toThrow('Too many components found');
2049+
});
2050+
});
19412051
});
19422052
});
19432053

0 commit comments

Comments
 (0)