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

Commit 7a5ddb4

Browse files
feat(ngMock.$componentController): add helper to instantiate controllers for components
Closes #13683
1 parent d91cf16 commit 7a5ddb4

File tree

3 files changed

+87
-1
lines changed

3 files changed

+87
-1
lines changed

src/ng/compile.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
928928
return this;
929929
};
930930

931+
this.$$componentControllers = createMap();
931932
/**
932933
* @ngdoc method
933934
* @name $compileProvider#component
@@ -1052,6 +1053,9 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
10521053
* See also {@link ng.$compileProvider#directive $compileProvider.directive()}.
10531054
*/
10541055
this.component = function registerComponent(name, options) {
1056+
var controller = options.controller || function() {};
1057+
this.$$componentControllers[name] = controller;
1058+
10551059
function factory($injector) {
10561060
function makeInjectable(fn) {
10571061
if (isFunction(fn) || isArray(fn)) {

src/ngMock/angular-mocks.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2161,6 +2161,28 @@ angular.mock.$ControllerDecorator = ['$delegate', function($delegate) {
21612161
};
21622162
}];
21632163

2164+
/**
2165+
* @ngdoc service
2166+
* @name $componentController
2167+
* @description
2168+
* A service that can be used to create instances of component controllers.
2169+
* @param {string} componentName the name of the component whose controller we want to instantiate
2170+
* @param {Object} locals Injection locals for Controller.
2171+
* @param {Object=} bindings Properties to add to the controller before invoking the constructor. This is used
2172+
* to simulate the `bindToController` feature and simplify certain kinds of tests.
2173+
* @return {Object} Instance of requested controller.
2174+
*/
2175+
angular.mock.$ComponentControllerProvider = ['$compileProvider', function($compileProvider) {
2176+
return {
2177+
$get: ['$controller', function($controller) {
2178+
return function $directiveController(componentName, locals, bindings, ident) {
2179+
var controller = $compileProvider.$$componentControllers[componentName];
2180+
return $controller(controller, locals, bindings, ident);
2181+
};
2182+
}]
2183+
};
2184+
}];
2185+
21642186

21652187
/**
21662188
* @ngdoc module
@@ -2184,7 +2206,8 @@ angular.module('ngMock', ['ng']).provider({
21842206
$log: angular.mock.$LogProvider,
21852207
$interval: angular.mock.$IntervalProvider,
21862208
$httpBackend: angular.mock.$HttpBackendProvider,
2187-
$rootElement: angular.mock.$RootElementProvider
2209+
$rootElement: angular.mock.$RootElementProvider,
2210+
$componentController: angular.mock.$ComponentControllerProvider
21882211
}).config(['$provide', function($provide) {
21892212
$provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
21902213
$provide.decorator('$$rAF', angular.mock.$RAFDecorator);

test/ngMock/angular-mocksSpec.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1857,6 +1857,65 @@ describe('ngMock', function() {
18571857
});
18581858
});
18591859
});
1860+
1861+
1862+
describe('$componentController', function() {
1863+
it('should instantiate a simple controller defined inline in a component', function() {
1864+
function TestController($scope, a, b) {
1865+
this.$scope = $scope;
1866+
this.a = a;
1867+
this.b = b;
1868+
}
1869+
module(function($compileProvider) {
1870+
$compileProvider.component('test', {
1871+
controller: TestController
1872+
});
1873+
});
1874+
inject(function($componentController, $rootScope) {
1875+
var $scope = {};
1876+
var ctrl = $componentController('test', {$scope: $scope, a: 'A', b: 'B'}, { x: 'X', y: 'Y' });
1877+
expect(ctrl).toEqual({$scope: $scope, a: 'A', b: 'B', x: 'X', y: 'Y' });
1878+
});
1879+
});
1880+
1881+
it('should instantiate a controller with $$inject annotation defined inline in a component', function() {
1882+
function TestController(x, y, z) {
1883+
this.$scope = x;
1884+
this.a = y;
1885+
this.b = z;
1886+
}
1887+
TestController.$inject = ['$scope', 'a', 'b'];
1888+
module(function($compileProvider) {
1889+
$compileProvider.component('test', {
1890+
controller: TestController
1891+
});
1892+
});
1893+
inject(function($componentController, $rootScope) {
1894+
var $scope = {};
1895+
var ctrl = $componentController('test', {$scope: $scope, a: 'A', b: 'B'}, { x: 'X', y: 'Y' });
1896+
expect(ctrl).toEqual({$scope: $scope, a: 'A', b: 'B', x: 'X', y: 'Y' });
1897+
});
1898+
});
1899+
1900+
it('should instantiate a named controller defined in a component', function() {
1901+
function TestController($scope, a, b) {
1902+
this.$scope = $scope;
1903+
this.a = a;
1904+
this.b = b;
1905+
}
1906+
module(function($controllerProvider, $compileProvider) {
1907+
$controllerProvider.register('TestController', TestController);
1908+
$compileProvider.component('test', {
1909+
controller: 'TestController'
1910+
});
1911+
});
1912+
inject(function($componentController, $rootScope) {
1913+
var $scope = {};
1914+
var ctrl = $componentController('test', {$scope: $scope, a: 'A', b: 'B'}, { x: 'X', y: 'Y' });
1915+
expect(ctrl).toEqual({$scope: $scope, a: 'A', b: 'B', x: 'X', y: 'Y' });
1916+
});
1917+
});
1918+
});
18601919
});
18611920

18621921

0 commit comments

Comments
 (0)