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

Commit 72b96ef

Browse files
drpicoxpetebacondarwin
authored andcommitted
refact(ngMock.$componentController): use $injector instead of adding new code to angular.min.js
Closes #13742
1 parent 90975db commit 72b96ef

File tree

3 files changed

+138
-7
lines changed

3 files changed

+138
-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
@@ -1052,8 +1051,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
10521051
*/
10531052
this.component = function registerComponent(name, options) {
10541053
var controller = options.controller || function() {};
1055-
var ident = identifierForController(options.controller) || options.controllerAs || '$ctrl';
1056-
this.$$componentControllers[name] = { controller: controller, ident: ident};
10571054

10581055
function factory($injector) {
10591056
function makeInjectable(fn) {
@@ -1069,7 +1066,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
10691066
var template = (!options.template && !options.templateUrl ? '' : options.template);
10701067
return {
10711068
controller: controller,
1072-
controllerAs: ident,
1069+
controllerAs: identifierForController(options.controller) || options.controllerAs || '$ctrl',
10731070
template: makeInjectable(template),
10741071
templateUrl: makeInjectable(options.templateUrl),
10751072
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'
2193+
return directiveInfo.controller && directiveInfo.controllerAs && directiveInfo.restrict === 'E';
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

+119
Original file line numberDiff line numberDiff line change
@@ -1938,6 +1938,125 @@ 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 restricted to \'E\'', 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 restricted to \'E\' 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, controllerAs and restrict:\'E\' 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+
restrict: 'E',
1989+
controller: TestController,
1990+
controllerAs: '$ctrl'
1991+
};
1992+
});
1993+
});
1994+
inject(function($componentController, $rootScope) {
1995+
var ctrl = $componentController('test', { $scope: {} });
1996+
expect(ctrl).toEqual({ r: 18842 });
1997+
});
1998+
});
1999+
2000+
it('should fail if there is no directive with restrict:\'E\' and controller', function() {
2001+
function TestController() {
2002+
this.r = 31145;
2003+
}
2004+
module(function($compileProvider) {
2005+
$compileProvider.directive('test', function() {
2006+
return {
2007+
restrict: 'AC',
2008+
controller: TestController
2009+
};
2010+
});
2011+
$compileProvider.directive('test', function() {
2012+
return {
2013+
restrict: 'E',
2014+
controller: TestController
2015+
};
2016+
});
2017+
$compileProvider.directive('test', function() {
2018+
return {
2019+
restrict: 'EA',
2020+
controller: TestController,
2021+
controllerAs: '$ctrl'
2022+
};
2023+
});
2024+
$compileProvider.directive('test', function() {
2025+
return { restrict: 'E' };
2026+
});
2027+
});
2028+
inject(function($componentController, $rootScope) {
2029+
expect(function() {
2030+
$componentController('test', { $scope: {} });
2031+
}).toThrow('No component found');
2032+
});
2033+
});
2034+
2035+
it('should fail if there more than two components with same name', function() {
2036+
function TestController($scope, a, b) {
2037+
this.$scope = $scope;
2038+
this.a = a;
2039+
this.b = b;
2040+
}
2041+
module(function($compileProvider) {
2042+
$compileProvider.directive('test', function() {
2043+
return {
2044+
restrict: 'E',
2045+
controller: TestController,
2046+
controllerAs: '$ctrl'
2047+
};
2048+
});
2049+
$compileProvider.component('test', {
2050+
controller: TestController
2051+
});
2052+
});
2053+
inject(function($componentController, $rootScope) {
2054+
expect(function() {
2055+
var $scope = {};
2056+
$componentController('test', { $scope: $scope, a: 'A', b: 'B' }, { x: 'X', y: 'Y' });
2057+
}).toThrow('Too many components found');
2058+
});
2059+
});
19412060
});
19422061
});
19432062

0 commit comments

Comments
 (0)