From 4915363602c4bbe5028053767700f33c3f7723a3 Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Thu, 2 Oct 2014 10:30:23 -0600 Subject: [PATCH 1/2] test($compile): add test for optional `require` in directives with `^` operator The directive property `require` allows optional requirement via the `?` before or after the `^` operator. Add tests to ensure this functionality is not lost inadvertently. Closes #9391 --- test/ng/compileSpec.js | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 6b425cca4c1e..e3d88182eb8f 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -4095,6 +4095,42 @@ describe('$compile', function() { }); + it("should not throw an error if required controller can't be found and is optional",function() { + module(function() { + directive('dep', function(log) { + return { + require: '?^main', + link: function(scope, element, attrs, controller) { + log('dep:' + !!controller); + } + }; + }); + }); + inject(function(log, $compile, $rootScope) { + $compile('
')($rootScope); + expect(log).toEqual('dep:false'); + }); + }); + + + it("should not throw an error if required controller can't be found and is optional with the question mark on the right",function() { + module(function() { + directive('dep', function(log) { + return { + require: '^?main', + link: function(scope, element, attrs, controller) { + log('dep:' + !!controller); + } + }; + }); + }); + inject(function(log, $compile, $rootScope) { + $compile('
')($rootScope); + expect(log).toEqual('dep:false'); + }); + }); + + it('should have optional controller on current element', function() { module(function() { directive('dep', function(log) { From fe45f497c8bd06733b5965699400bd44ee3a5375 Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Thu, 2 Oct 2014 16:42:53 -0600 Subject: [PATCH 2/2] fix($compile): returning null when an optional controller is not found Currently, `undefined` is returned. However, the desired behavior is to return `null` when the controller is optional and not found. Closes #9404 --- src/ng/compile.js | 2 +- test/ng/compileSpec.js | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ng/compile.js b/src/ng/compile.js index 9cb0a75e9ef4..002e24497877 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -1764,7 +1764,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { "Controller '{0}', required by directive '{1}', can't be found!", require, directiveName); } - return value; + return value || null; } else if (isArray(require)) { value = []; forEach(require, function(require) { diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index e3d88182eb8f..2056faaba44d 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -4095,38 +4095,38 @@ describe('$compile', function() { }); - it("should not throw an error if required controller can't be found and is optional",function() { + it("should pass null if required controller can't be found and is optional",function() { module(function() { directive('dep', function(log) { return { require: '?^main', link: function(scope, element, attrs, controller) { - log('dep:' + !!controller); + log('dep:' + controller); } }; }); }); inject(function(log, $compile, $rootScope) { $compile('
')($rootScope); - expect(log).toEqual('dep:false'); + expect(log).toEqual('dep:null'); }); }); - it("should not throw an error if required controller can't be found and is optional with the question mark on the right",function() { + it("should pass null if required controller can't be found and is optional with the question mark on the right",function() { module(function() { directive('dep', function(log) { return { require: '^?main', link: function(scope, element, attrs, controller) { - log('dep:' + !!controller); + log('dep:' + controller); } }; }); }); inject(function(log, $compile, $rootScope) { $compile('
')($rootScope); - expect(log).toEqual('dep:false'); + expect(log).toEqual('dep:null'); }); });