diff options
| author | Igor Minar | 2013-10-10 21:35:54 -0700 | 
|---|---|---|
| committer | Igor Minar | 2013-10-11 17:12:24 -0700 | 
| commit | 63c5334c84b7269428c710226764d1f08a36e0d4 (patch) | |
| tree | 4924c3e942b6d94d7dcc9bfb6ab629fd52491a0f /test/ng/compileSpec.js | |
| parent | b7af76b4c5aa77648cc1bfd49935b48583419023 (diff) | |
| download | angular.js-63c5334c84b7269428c710226764d1f08a36e0d4.tar.bz2 | |
fix($compile): abort compilation when duplicate element transclusion
Issue an error and abort compilation when two directives that ask for transclusion are found
on a single element. This configuration is not supported and we previously failed to issue
the error because in the case of element transclusion the compilation is re-started and this
caused the compilation context to be lost.
The ngRepeat directive has been special-cased to bypass this warning because it knows how to
handle this scenario internally.
This is not an ideal solution to the problem of multiple transclusions per element, we are
hoping to have this configuration supported by the compiler in the future. See #4357.
Closes #3893
Closes #4217
Closes #3307
Diffstat (limited to 'test/ng/compileSpec.js')
| -rwxr-xr-x | test/ng/compileSpec.js | 84 | 
1 files changed, 72 insertions, 12 deletions
| diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js index 1e6f6e26..9a69824a 100755 --- a/test/ng/compileSpec.js +++ b/test/ng/compileSpec.js @@ -1042,10 +1042,12 @@ describe('$compile', function() {                templateUrl: 'template.html'              }));            }); -          inject(function($compile){ +          inject(function($compile, $httpBackend){ +            $httpBackend.whenGET('template.html').respond('<p>template.html</p>');              expect(function() {                $compile('<div><div class="sync async"></div></div>'); -            }).toThrowMinErr('$compile', 'multidir', 'Multiple directives [sync, async] asking for template on: '+ +              $httpBackend.flush(); +            }).toThrowMinErr('$compile', 'multidir', 'Multiple directives [async, sync] asking for template on: '+                  '<div class="sync async">');            });          }); @@ -1205,7 +1207,7 @@ describe('$compile', function() {          )); -        it('should work when directive is a repeater', inject( +        it('should work when directive is in a repeater', inject(            function($compile, $httpBackend, $rootScope) {              $httpBackend.expect('GET', 'hello.html').                  respond('<span>i=<span ng-transclude></span>;</span>'); @@ -1317,7 +1319,7 @@ describe('$compile', function() {        }); -      describe('template as function', function() { +      describe('templateUrl as function', function() {          beforeEach(module(function() {            directive('myDirective', valueFn({ @@ -2745,23 +2747,81 @@ describe('$compile', function() {      }); -    it('should only allow one transclude per element', function() { +    it('should only allow one content transclusion per element', function() {        module(function() {          directive('first', valueFn({ -          scope: {}, -          restrict: 'CA', -          transclude: 'content' +          transclude: true          }));          directive('second', valueFn({ -          restrict: 'CA', -          transclude: 'content' +          transclude: true          }));        });        inject(function($compile) {          expect(function() { -          $compile('<div class="first second"></div>'); +          $compile('<div first="" second=""></div>'); +        }).toThrowMinErr('$compile', 'multidir', /Multiple directives \[first, second\] asking for transclusion on: <div .+/); +      }); +    }); + + +    it('should only allow one element transclusion per element', function() { +      module(function() { +        directive('first', valueFn({ +          transclude: 'element' +        })); +        directive('second', valueFn({ +          transclude: 'element' +        })); +      }); +      inject(function($compile) { +        expect(function() { +          $compile('<div first second></div>');          }).toThrowMinErr('$compile', 'multidir', 'Multiple directives [first, second] asking for transclusion on: ' + -            '<div class="first second ng-isolate-scope ng-scope">'); +                '<!-- first:  -->'); +      }); +    }); + + +    it('should only allow one element transclusion per element when directives have different priorities', function() { +      // we restart compilation in this case and we need to remember the duplicates during the second compile +      // regression #3893 +      module(function() { +        directive('first', valueFn({ +          transclude: 'element', +          priority: 100 +        })); +        directive('second', valueFn({ +          transclude: 'element' +        })); +      }); +      inject(function($compile) { +        expect(function() { +          $compile('<div first second></div>'); +        }).toThrowMinErr('$compile', 'multidir', /Multiple directives \[first, second\] asking for transclusion on: <div .+/); +      }); +    }); + + +    it('should only allow one element transclusion per element when async replace directive is in the mix', function() { +      module(function() { +        directive('template', valueFn({ +          templateUrl: 'template.html', +          replace: true +        })); +        directive('first', valueFn({ +          transclude: 'element', +          priority: 100 +        })); +        directive('second', valueFn({ +          transclude: 'element' +        })); +      }); +      inject(function($compile, $httpBackend) { +        $httpBackend.expectGET('template.html').respond('<p second>template.html</p>'); +        $compile('<div template first></div>'); +        expect(function() { +          $httpBackend.flush(); +        }).toThrowMinErr('$compile', 'multidir', /Multiple directives \[first, second\] asking for transclusion on: <p .+/);        });      }); | 
