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

Commit

Permalink
refact(ngMock.$componentController): use $injector instead of adding …
Browse files Browse the repository at this point in the history
…new code to angular.min.js

Closes #13742
  • Loading branch information
drpicox authored and petebacondarwin committed Jan 12, 2016
1 parent 90975db commit 72b96ef
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 7 deletions.
5 changes: 1 addition & 4 deletions src/ng/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -928,7 +928,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
return this;
};

this.$$componentControllers = createMap();
/**
* @ngdoc method
* @name $compileProvider#component
Expand Down Expand Up @@ -1052,8 +1051,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
*/
this.component = function registerComponent(name, options) {
var controller = options.controller || function() {};
var ident = identifierForController(options.controller) || options.controllerAs || '$ctrl';
this.$$componentControllers[name] = { controller: controller, ident: ident};

function factory($injector) {
function makeInjectable(fn) {
Expand All @@ -1069,7 +1066,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
var template = (!options.template && !options.templateUrl ? '' : options.template);
return {
controller: controller,
controllerAs: ident,
controllerAs: identifierForController(options.controller) || options.controllerAs || '$ctrl',
template: makeInjectable(template),
templateUrl: makeInjectable(options.templateUrl),
transclude: options.transclude,
Expand Down
21 changes: 18 additions & 3 deletions src/ngMock/angular-mocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -2183,10 +2183,25 @@ angular.mock.$ControllerDecorator = ['$delegate', function($delegate) {
*/
angular.mock.$ComponentControllerProvider = ['$compileProvider', function($compileProvider) {
return {
$get: ['$controller', function($controller) {
$get: ['$controller','$injector', function($controller,$injector) {
return function $componentController(componentName, locals, bindings, ident) {
var controllerInfo = $compileProvider.$$componentControllers[componentName];
return $controller(controllerInfo.controller, locals, bindings, ident || controllerInfo.ident);
// get all directives associated to the component name
var directives = $injector.get(componentName + 'Directive');
// look for those directives that are components
var candidateDirectives = directives.filter(function(directiveInfo) {
// components have controller, controllerAs and restrict:'E'
return directiveInfo.controller && directiveInfo.controllerAs && directiveInfo.restrict === 'E';
});
// check if valid directives found
if (candidateDirectives.length === 0) {
throw new Error('No component found');
}
if (candidateDirectives.length > 1) {
throw new Error('Too many components found');
}
// get the info of the component
var directiveInfo = candidateDirectives[0];
return $controller(directiveInfo.controller, locals, bindings, ident || directiveInfo.controllerAs);
};
}]
};
Expand Down
119 changes: 119 additions & 0 deletions test/ngMock/angular-mocksSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1938,6 +1938,125 @@ describe('ngMock', function() {
expect($scope.testCtrl).toBe(ctrl);
});
});

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() {
function TestController() {
this.r = 6779;
}
module(function($compileProvider) {
$compileProvider.directive('test', function() {
return { restrict: 'A' };
});
$compileProvider.component('test', {
controller: TestController
});
});
inject(function($componentController, $rootScope) {
var ctrl = $componentController('test', { $scope: {} });
expect(ctrl).toEqual({ r: 6779 });
});
});

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() {
function TestController() {
this.r = 22926;
}
module(function($compileProvider) {
$compileProvider.directive('test', function() {
return { restrict: 'E' };
});
$compileProvider.component('test', {
controller: TestController
});
});
inject(function($componentController, $rootScope) {
var ctrl = $componentController('test', { $scope: {} });
expect(ctrl).toEqual({ r: 22926 });
});
});

it('should instantiate the controller of the directive with controller, controllerAs and restrict:\'E\' if there are more directives', function() {
function TestController() {
this.r = 18842;
}
module(function($compileProvider) {
$compileProvider.directive('test', function() {
return { };
});
$compileProvider.directive('test', function() {
return {
restrict: 'E',
controller: TestController,
controllerAs: '$ctrl'
};
});
});
inject(function($componentController, $rootScope) {
var ctrl = $componentController('test', { $scope: {} });
expect(ctrl).toEqual({ r: 18842 });
});
});

it('should fail if there is no directive with restrict:\'E\' and controller', function() {
function TestController() {
this.r = 31145;
}
module(function($compileProvider) {
$compileProvider.directive('test', function() {
return {
restrict: 'AC',
controller: TestController
};
});
$compileProvider.directive('test', function() {
return {
restrict: 'E',
controller: TestController
};
});
$compileProvider.directive('test', function() {
return {
restrict: 'EA',
controller: TestController,
controllerAs: '$ctrl'
};
});
$compileProvider.directive('test', function() {
return { restrict: 'E' };
});
});
inject(function($componentController, $rootScope) {
expect(function() {
$componentController('test', { $scope: {} });
}).toThrow('No component found');
});
});

it('should fail if there more than two components with same name', function() {
function TestController($scope, a, b) {
this.$scope = $scope;
this.a = a;
this.b = b;
}
module(function($compileProvider) {
$compileProvider.directive('test', function() {
return {
restrict: 'E',
controller: TestController,
controllerAs: '$ctrl'
};
});
$compileProvider.component('test', {
controller: TestController
});
});
inject(function($componentController, $rootScope) {
expect(function() {
var $scope = {};
$componentController('test', { $scope: $scope, a: 'A', b: 'B' }, { x: 'X', y: 'Y' });
}).toThrow('Too many components found');
});
});
});
});

Expand Down

0 comments on commit 72b96ef

Please sign in to comment.