Skip to content

Commit 44a5e90

Browse files
committed
feat(ngMock.$componentController): handle multiple directives with the same name angular#13683
1 parent 437f9ac commit 44a5e90

File tree

2 files changed

+126
-1
lines changed

2 files changed

+126
-1
lines changed

src/ngMock/angular-mocks.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2185,7 +2185,22 @@ angular.mock.$ComponentControllerProvider = ['$compileProvider', function($compi
21852185
return {
21862186
$get: ['$controller','$injector', function($controller,$injector) {
21872187
return function $componentController(componentName, locals, bindings, ident) {
2188-
var directiveInfo = $injector.get(componentName + 'Directive')[0];
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];
21892204
return $controller(directiveInfo.controller, locals, bindings, ident || directiveInfo.controllerAs);
21902205
};
21912206
}]

test/ngMock/angular-mocksSpec.js

Lines changed: 110 additions & 0 deletions
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)