')
+ ($rootScope);
+ var div = element.find('div');
+ expect(div.hasClass('medium-log')).toBe(true);
+ expect(div.hasClass('log')).toBe(true);
+ expect(div.css('width')).toBe('10px');
+ expect(div.css('height')).toBe('20px');
+ expect(div.attr('replace')).toEqual('');
+ expect(div.attr('high-log')).toEqual('');
+ }));
+
+ it('should prevent multiple templates per element', inject(function($compile) {
+ try {
+ $compile('
')
+ fail();
+ } catch(e) {
+ expect(e.message).toMatch(/Multiple directives .* asking for template/);
+ }
+ }));
+
+ it('should play nice with repeater when inline', inject(function($compile, $rootScope) {
+ element = $compile(
+ '
')($rootScope);
+ $rootScope.$digest();
+ expect(element.text()).toEqual('Hello: 1; Hello: 2; ');
+ }));
+
+
+ it('should play nice with repeater when append', inject(function($compile, $rootScope) {
+ element = $compile(
+ '
')($rootScope);
+ $rootScope.$digest();
+ expect(element.text()).toEqual('Hello: 1; Hello: 2; ');
+ }));
+ });
+
+
+ describe('async templates', function() {
+
+ beforeEach(module(
+ function($compileProvider) {
+ $compileProvider.directive('hello', valueFn({ templateUrl: 'hello.html' }));
+ $compileProvider.directive('cau', valueFn({ templateUrl:'cau.html' }));
+
+ $compileProvider.directive('cError', valueFn({
+ templateUrl:'error.html',
+ compile: function() {
+ throw Error('cError');
+ }
+ }));
+ $compileProvider.directive('lError', valueFn({
+ templateUrl: 'error.html',
+ compile: function() {
+ throw Error('lError');
+ }
+ }));
+
+
+ $compileProvider.directive('iHello', valueFn({
+ replace: true,
+ templateUrl: 'hello.html'
+ }));
+ $compileProvider.directive('iCau', valueFn({
+ replace: true,
+ templateUrl:'cau.html'
+ }));
+
+ $compileProvider.directive('iCError', valueFn({
+ replace: true,
+ templateUrl:'error.html',
+ compile: function() {
+ throw Error('cError');
+ }
+ }));
+ $compileProvider.directive('iLError', valueFn({
+ replace: true,
+ templateUrl: 'error.html',
+ compile: function() {
+ throw Error('lError');
+ }
+ }));
+
+ }
+ ));
+
+
+ it('should append template via $http and cache it in $templateCache', inject(
+ function($compile, $httpBackend, $templateCache, $rootScope, $browser) {
+ $httpBackend.expect('GET', 'hello.html').respond('
Hello! World!');
+ $templateCache.put('cau.html', '
Cau!');
+ element = $compile('
ignoreignore
')($rootScope);
+ expect(sortedHtml(element)).
+ toEqual('
');
+
+ $rootScope.$digest();
+
+
+ expect(sortedHtml(element)).
+ toEqual('
Cau!
');
+
+ $httpBackend.flush();
+ expect(sortedHtml(element)).toEqual(
+ '
' +
+ 'Hello! World!' +
+ 'Cau!' +
+ '
');
+ }
+ ));
+
+
+ it('should inline template via $http and cache it in $templateCache', inject(
+ function($compile, $httpBackend, $templateCache, $rootScope) {
+ $httpBackend.expect('GET', 'hello.html').respond('
Hello!');
+ $templateCache.put('cau.html', '
Cau!');
+ element = $compile('
ignoreignore
')($rootScope);
+ expect(sortedHtml(element)).
+ toEqual('
');
+
+ $rootScope.$digest();
+
+
+ expect(sortedHtml(element)).
+ toEqual('
Cau!
');
+
+ $httpBackend.flush();
+ expect(sortedHtml(element)).
+ toEqual('
Hello!Cau!
');
+ }
+ ));
+
+
+ it('should compile, link and flush the template append', inject(
+ function($compile, $templateCache, $rootScope, $browser) {
+ $templateCache.put('hello.html', '
Hello, {{name}}!');
+ $rootScope.name = 'Elvis';
+ element = $compile('
')($rootScope);
+
+ $rootScope.$digest();
+
+ expect(sortedHtml(element)).
+ toEqual('
Hello, Elvis!
');
+ }
+ ));
+
+
+ it('should compile, link and flush the template inline', inject(
+ function($compile, $templateCache, $rootScope) {
+ $templateCache.put('hello.html', '
Hello, {{name}}!');
+ $rootScope.name = 'Elvis';
+ element = $compile('
')($rootScope);
+
+ $rootScope.$digest();
+
+ expect(sortedHtml(element)).
+ toEqual('
Hello, Elvis!
');
+ }
+ ));
+
+
+ it('should compile, flush and link the template append', inject(
+ function($compile, $templateCache, $rootScope) {
+ $templateCache.put('hello.html', '
Hello, {{name}}!');
+ $rootScope.name = 'Elvis';
+ var template = $compile('
');
+
+ element = template($rootScope);
+ $rootScope.$digest();
+
+ expect(sortedHtml(element)).
+ toEqual('
Hello, Elvis!
');
+ }
+ ));
+
+
+ it('should compile, flush and link the template inline', inject(
+ function($compile, $templateCache, $rootScope) {
+ $templateCache.put('hello.html', '
Hello, {{name}}!');
+ $rootScope.name = 'Elvis';
+ var template = $compile('
');
+
+ element = template($rootScope);
+ $rootScope.$digest();
+
+ expect(sortedHtml(element)).
+ toEqual('
Hello, Elvis!
');
+ }
+ ));
+
+
+ it('should resolve widgets after cloning in append mode', function() {
+ module(function($exceptionHandlerProvider) {
+ $exceptionHandlerProvider.mode('log');
+ });
+ inject(function($compile, $templateCache, $rootScope, $httpBackend, $browser,
+ $exceptionHandler) {
+ $httpBackend.expect('GET', 'hello.html').respond('
{{greeting}} ');
+ $httpBackend.expect('GET', 'error.html').respond('
');
+ $templateCache.put('cau.html', '
{{name}}');
+ $rootScope.greeting = 'Hello';
+ $rootScope.name = 'Elvis';
+ var template = $compile(
+ '
' +
+ '' +
+ '' +
+ '' +
+ '' +
'
');
- $rootScope.value = 1;
- $rootScope.$digest();
- expect(sortedHtml($rootScope.$element)).
- toEqual('
' +
- 'before<#comment>#comment>' +
- 'x' +
- 'after' +
- '
');
- $rootScope.value = 2;
- $rootScope.$digest();
- expect(sortedHtml($rootScope.$element)).
- toEqual('
' +
- 'before<#comment>#comment>' +
- 'x' +
- 'x' +
- 'after' +
- '
');
- $rootScope.value = 3;
- $rootScope.$digest();
- expect(sortedHtml($rootScope.$element)).
- toEqual('
' +
- 'before<#comment>#comment>' +
- 'x' +
- 'x' +
- 'x' +
- 'after' +
- '
');
- }));
+ var e1;
+ var e2;
+
+ e1 = template($rootScope.$new(), noop); // clone
+ expect(e1.text()).toEqual('');
+
+ $httpBackend.flush();
+
+ e2 = template($rootScope.$new(), noop); // clone
+ $rootScope.$digest();
+ expect(e1.text()).toEqual('Hello Elvis');
+ expect(e2.text()).toEqual('Hello Elvis');
+
+ expect($exceptionHandler.errors.length).toEqual(2);
+ expect($exceptionHandler.errors[0][0].message).toEqual('cError');
+ expect($exceptionHandler.errors[1][0].message).toEqual('lError');
+
+ dealoc(e1);
+ dealoc(e2);
+ });
+ });
+
+
+ it('should resolve widgets after cloning in inline mode', function() {
+ module(function($exceptionHandlerProvider) {
+ $exceptionHandlerProvider.mode('log');
+ });
+ inject(function($compile, $templateCache, $rootScope, $httpBackend, $browser,
+ $exceptionHandler) {
+ $httpBackend.expect('GET', 'hello.html').respond('
{{greeting}} ');
+ $httpBackend.expect('GET', 'error.html').respond('
');
+ $templateCache.put('cau.html', '
{{name}}');
+ $rootScope.greeting = 'Hello';
+ $rootScope.name = 'Elvis';
+ var template = $compile(
+ '
' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '
');
+ var e1;
+ var e2;
+
+ e1 = template($rootScope.$new(), noop); // clone
+ expect(e1.text()).toEqual('');
+
+ $httpBackend.flush();
+
+ e2 = template($rootScope.$new(), noop); // clone
+ $rootScope.$digest();
+ expect(e1.text()).toEqual('Hello Elvis');
+ expect(e2.text()).toEqual('Hello Elvis');
+
+ expect($exceptionHandler.errors.length).toEqual(2);
+ expect($exceptionHandler.errors[0][0].message).toEqual('cError');
+ expect($exceptionHandler.errors[1][0].message).toEqual('lError');
+
+ dealoc(e1);
+ dealoc(e2);
+ });
+ });
+
+
+ it('should be implicitly terminal and not compile placeholder content in append', inject(
+ function($compile, $templateCache, $rootScope, log) {
+ // we can't compile the contents because that would result in a memory leak
+
+ $templateCache.put('hello.html', 'Hello!');
+ element = $compile('
')($rootScope);
+
+ expect(log).toEqual('');
+ }
+ ));
+
+
+ it('should be implicitly terminal and not compile placeholder content in inline', inject(
+ function($compile, $templateCache, $rootScope, log) {
+ // we can't compile the contents because that would result in a memory leak
+
+ $templateCache.put('hello.html', 'Hello!');
+ element = $compile('
')($rootScope);
+
+ expect(log).toEqual('');
+ }
+ ));
+
+
+ it('should throw an error and clear element content if the template fails to load', inject(
+ function($compile, $httpBackend, $rootScope) {
+ $httpBackend.expect('GET', 'hello.html').respond(404, 'Not Found!');
+ element = $compile('
content
')($rootScope);
+
+ expect(function() {
+ $httpBackend.flush();
+ }).toThrow('Failed to load template: hello.html');
+ expect(sortedHtml(element)).toBe('
');
+ }
+ ));
+
+
+ it('should prevent multiple templates per element', function() {
+ module(function($compileProvider) {
+ $compileProvider.directive('sync', valueFn({
+ template: '
'
+ }));
+ $compileProvider.directive('async', valueFn({
+ templateUrl: 'template.html'
+ }));
+ });
+ inject(function($compile){
+ expect(function() {
+ $compile('
');
+ }).toThrow('Multiple directives [sync, async] asking for template on: <'+
+ (msie <= 8 ? 'DIV' : 'div') + ' class="sync async">');
+ });
+ });
+
+
+ describe('delay compile / linking functions until after template is resolved', function(){
+ var template;
+ beforeEach(module(function($compileProvider) {
+ function directive (name, priority, options) {
+ $compileProvider.directive(name, function(log) {
+ return (extend({
+ priority: priority,
+ compile: function() {
+ log(name + '-C');
+ return function() { log(name + '-L'); }
+ }
+ }, options || {}));
+ });
+ }
+
+ directive('first', 10);
+ directive('second', 5, { templateUrl: 'second.html' });
+ directive('third', 3);
+ directive('last', 0);
+
+ directive('iFirst', 10, {replace: true});
+ directive('iSecond', 5, {replace: true, templateUrl: 'second.html' });
+ directive('iThird', 3, {replace: true});
+ directive('iLast', 0, {replace: true});
+ }));
+
+ it('should flush after link append', inject(
+ function($compile, $rootScope, $httpBackend, log) {
+ $httpBackend.expect('GET', 'second.html').respond('
{{1+2}}
');
+ template = $compile('
');
+ element = template($rootScope);
+ expect(log).toEqual('first-C');
+
+ log('FLUSH');
+ $httpBackend.flush();
+ $rootScope.$digest();
+ expect(log).toEqual(
+ 'first-C; FLUSH; second-C; last-C; third-C; ' +
+ 'third-L; first-L; second-L; last-L');
+
+ var span = element.find('span');
+ expect(span.attr('first')).toEqual('');
+ expect(span.attr('second')).toEqual('');
+ expect(span.find('div').attr('third')).toEqual('');
+ expect(span.attr('last')).toEqual('');
+
+ expect(span.text()).toEqual('3');
+ }));
+
+
+ it('should flush after link inline', inject(
+ function($compile, $rootScope, $httpBackend, log) {
+ $httpBackend.expect('GET', 'second.html').respond('
{{1+2}}
');
+ template = $compile('
');
+ element = template($rootScope);
+ expect(log).toEqual('iFirst-C');
+
+ log('FLUSH');
+ $httpBackend.flush();
+ $rootScope.$digest();
+ expect(log).toEqual(
+ 'iFirst-C; FLUSH; iSecond-C; iThird-C; iLast-C; ' +
+ 'iFirst-L; iSecond-L; iThird-L; iLast-L');
+
+ var div = element.find('div');
+ expect(div.attr('i-first')).toEqual('');
+ expect(div.attr('i-second')).toEqual('');
+ expect(div.attr('i-third')).toEqual('');
+ expect(div.attr('i-last')).toEqual('');
+
+ expect(div.text()).toEqual('3');
+ }));
+
+
+ it('should flush before link append', inject(
+ function($compile, $rootScope, $httpBackend, log) {
+ $httpBackend.expect('GET', 'second.html').respond('
{{1+2}}
');
+ template = $compile('
');
+ expect(log).toEqual('first-C');
+ log('FLUSH');
+ $httpBackend.flush();
+ expect(log).toEqual('first-C; FLUSH; second-C; last-C; third-C');
+
+ element = template($rootScope);
+ $rootScope.$digest();
+ expect(log).toEqual(
+ 'first-C; FLUSH; second-C; last-C; third-C; ' +
+ 'third-L; first-L; second-L; last-L');
+
+ var span = element.find('span');
+ expect(span.attr('first')).toEqual('');
+ expect(span.attr('second')).toEqual('');
+ expect(span.find('div').attr('third')).toEqual('');
+ expect(span.attr('last')).toEqual('');
+
+ expect(span.text()).toEqual('3');
+ }));
+
+
+ it('should flush before link inline', inject(
+ function($compile, $rootScope, $httpBackend, log) {
+ $httpBackend.expect('GET', 'second.html').respond('
{{1+2}}
');
+ template = $compile('
');
+ expect(log).toEqual('iFirst-C');
+ log('FLUSH');
+ $httpBackend.flush();
+ expect(log).toEqual('iFirst-C; FLUSH; iSecond-C; iThird-C; iLast-C');
+
+ element = template($rootScope);
+ $rootScope.$digest();
+ expect(log).toEqual(
+ 'iFirst-C; FLUSH; iSecond-C; iThird-C; iLast-C; ' +
+ 'iFirst-L; iSecond-L; iThird-L; iLast-L');
+
+ var div = element.find('div');
+ expect(div.attr('i-first')).toEqual('');
+ expect(div.attr('i-second')).toEqual('');
+ expect(div.attr('i-third')).toEqual('');
+ expect(div.attr('i-last')).toEqual('');
+
+ expect(div.text()).toEqual('3');
+ }));
+ });
+
+
+ it('should check that template has root element', inject(function($compile, $httpBackend) {
+ $httpBackend.expect('GET', 'hello.html').respond('before
mid after');
+ $compile('
');
+ expect(function(){
+ $httpBackend.flush();
+ }).toThrow('Template must have exactly one root element: before
mid after');
+ }));
+
+
+ it('should allow multiple elements in template', inject(function($compile, $httpBackend) {
+ $httpBackend.expect('GET', 'hello.html').respond('before
mid after');
+ element = jqLite('
');
+ $compile(element);
+ $httpBackend.flush();
+ expect(element.text()).toEqual('before mid after');
+ }));
+
+
+ it('should work when widget is in root element', inject(
+ function($compile, $httpBackend, $rootScope) {
+ $httpBackend.expect('GET', 'hello.html').respond('
3==<>');
+ element = jqLite('
{{1+2}}');
+ $compile(element)($rootScope);
+
+ $httpBackend.flush();
+ expect(element.text()).toEqual('3==3');
+ }
+ ));
+
+
+ it('should work when widget is a repeater', inject(
+ function($compile, $httpBackend, $rootScope) {
+ $httpBackend.expect('GET', 'hello.html').respond('
i=<>;');
+ element = jqLite('
{{i}}
');
+ $compile(element)($rootScope);
+
+ $httpBackend.flush();
+ expect(element.text()).toEqual('i=1;i=2;');
+ }
+ ));
+ });
+
+
+ describe('scope', function() {
+
+ beforeEach(module(function($compileProvider) {
+ forEach(['', 'a', 'b'], function(name) {
+ $compileProvider.directive('scope' + uppercase(name), function(log) {
+ return {
+ scope: true,
+ compile: function() {
+ return function (scope, element) {
+ log(scope.$id);
+ expect(element.data('$scope')).toBe(scope);
+ };
+ }
+ };
+ });
+ });
+ $compileProvider.directive('log', function(log) {
+ return function(scope) {
+ log('log-' + scope.$id + '-' + scope.$parent.$id);
+ };
+ });
+ }));
+
+
+ it('should allow creation of new scopes', inject(function($rootScope, $compile, log) {
+ element = $compile('
')($rootScope);
+ expect(log).toEqual('LOG; log-002-001; 002');
+ }));
+
+ it('should correctly create the scope hierachy properly', inject(
+ function($rootScope, $compile, log) {
+ element = $compile(
+ '
' + //1
+ '' + //2
+ '' + //3
+ '' +
+ '' +
+ '' + //4
+ '' +
+ '' +
+ '
'
+ )($rootScope);
+ expect(log).toEqual('LOG; log-003-002; 003; LOG; log-002-001; 002; LOG; log-004-001; 004');
+ }));
- it('should process markup before directives', inject(function($rootScope, $compile) {
- textMarkup.push(function(text, textNode, parentNode) {
- if (text == 'middle') {
- expect(textNode.text()).toEqual(text);
- parentNode.attr('hello', text);
- textNode[0].nodeValue = 'replaced';
- }
+
+ it('should not allow more then one scope creation per element', inject(
+ function($rootScope, $compile) {
+ expect(function(){
+ $compile('
');
+ }).toThrow('Multiple directives [scopeA, scopeB] asking for new scope on: ' +
+ '<' + (msie < 9 ? 'DIV' : 'div') + ' class="scope-a; scope-b">');
+ }));
+
+
+ it('should treat new scope on new template as noop', inject(
+ function($rootScope, $compile, log) {
+ element = $compile('
')($rootScope);
+ expect(log).toEqual('001');
+ }));
+ });
});
- $compile('
beforemiddleafter
')($rootScope);
- expect(sortedHtml($rootScope.$element[0], true)).
- toEqual('
beforereplacedafter
');
- expect(log).toEqual("hello middle");
- }));
+ });
- it('should replace widgets', inject(function($rootScope, $compile) {
- widgets['NG:BUTTON'] = function(element) {
- expect(element.hasClass('ng-widget')).toEqual(true);
- element.replaceWith('
button
');
- return function(element) {
- log += 'init';
- };
- };
- $compile('
push me
')($rootScope);
- expect(lowercase($rootScope.$element[0].innerHTML)).toEqual('
button
');
- expect(log).toEqual('init');
- }));
+ describe('interpolation', function() {
+ it('should compile and link both attribute and text bindings', inject(
+ function($rootScope, $compile) {
+ $rootScope.name = 'angular';
+ element = $compile('
text: {{name}}
')($rootScope);
+ $rootScope.$digest();
+ expect(element.text()).toEqual('text: angular');
+ expect(element.attr('name')).toEqual('attr: angular');
+ }));
- it('should use the replaced element after calling widget', inject(function($rootScope, $compile) {
- widgets['H1'] = function(element) {
- // HTML elements which are augmented by acting as widgets, should not be marked as so
- expect(element.hasClass('ng-widget')).toEqual(false);
- var span = angular.element('
{{1+2}}');
- element.replaceWith(span);
- this.descend(true);
- this.directives(true);
- return noop;
- };
- textMarkup.push(function(text, textNode, parent){
- if (text == '{{1+2}}')
- parent.text('3');
- });
- $compile('
ignore me
')($rootScope);
- expect($rootScope.$element.text()).toEqual('3');
- }));
+ it('should decorate the binding with ng-binding and interpolation function', inject(
+ function($compile, $rootScope) {
+ element = $compile('
{{1+2}}
')($rootScope);
+ expect(element.hasClass('ng-binding')).toBe(true);
+ expect(element.data('$binding')[0].exp).toEqual('{{1+2}}');
+ }));
+ });
- it('should allow multiple markups per text element', inject(function($rootScope, $compile) {
- textMarkup.push(function(text, textNode, parent){
- var index = text.indexOf('---');
- if (index > -1) {
- textNode.after(text.substring(index + 3));
- textNode.after("
");
- textNode.after(text.substring(0, index));
- textNode.remove();
- }
- });
- textMarkup.push(function(text, textNode, parent){
- var index = text.indexOf('===');
- if (index > -1) {
- textNode.after(text.substring(index + 3));
- textNode.after("
");
- textNode.after(text.substring(0, index));
- textNode.remove();
- }
- });
- $compile('
A---B---C===D
')($rootScope);
- expect(sortedHtml($rootScope.$element)).toEqual('
');
- }));
+ describe('link phase', function() {
- it('should add class for namespace elements', inject(function($rootScope, $compile) {
- var element = $compile('
abc')($rootScope);
- expect(element.hasClass('ng-space')).toEqual(true);
- }));
+ beforeEach(module(function($compileProvider) {
+
+ forEach(['a', 'b', 'c'], function(name) {
+ $compileProvider.directive(name, function(log) {
+ return {
+ compile: function() {
+ log('t' + uppercase(name))
+ return {
+ pre: function() {
+ log('pre' + uppercase(name));
+ },
+ post: function linkFn() {
+ log('post' + uppercase(name));
+ }
+ };
+ }
+ };
+ });
+ });
+ }));
+
+
+ it('should not store linkingFns for noop branches', inject(function ($rootScope, $compile) {
+ element = jqLite('
ignore
');
+ var linkingFn = $compile(element);
+ // Now prune the branches with no directives
+ element.find('span').remove();
+ expect(element.find('span').length).toBe(0);
+ // and we should still be able to compile without errors
+ linkingFn($rootScope);
+ }));
+
+
+ it('should compile from top to bottom but link from bottom up', inject(
+ function($compile, $rootScope, log) {
+ element = $compile('
')($rootScope);
+ expect(log).toEqual('tA; tB; tC; preA; preB; preC; postC; postA; postB');
+ }
+ ));
+
+
+ it('should support link function on directive object', function() {
+ module(function($compileProvider) {
+ $compileProvider.directive('abc', valueFn({
+ link: function(scope, element, attrs) {
+ element.text(attrs.abc);
+ }
+ }));
+ });
+ inject(function($compile, $rootScope) {
+ element = $compile('
FAIL
')($rootScope);
+ expect(element.text()).toEqual('WORKS');
+ });
+ });
+ });
+
+
+ describe('attrs', function() {
+
+ it('should allow setting of attributes', function() {
+ module(function($compileProvider) {
+ $compileProvider.directive({
+ setter: valueFn(function(scope, element, attr) {
+ attr.$set('name', 'abc');
+ attr.$set('disabled', true);
+ expect(attr.name).toBe('abc');
+ expect(attr.disabled).toBe(true);
+ })
+ });
+ });
+ inject(function($rootScope, $compile) {
+ element = $compile('
')($rootScope);
+ expect(element.attr('name')).toEqual('abc');
+ expect(element.attr('disabled')).toEqual('disabled');
+ });
+ });
+
+
+ it('should read boolean attributes as boolean', function() {
+ module(function($compileProvider) {
+ $compileProvider.directive({
+ div: valueFn(function(scope, element, attr) {
+ element.text(attr.required);
+ })
+ });
+ });
+ inject(function($rootScope, $compile) {
+ element = $compile('
')($rootScope);
+ expect(element.text()).toEqual('true');
+ });
+ });
+
+ it('should allow setting of attributes', function() {
+ module(function($compileProvider) {
+ $compileProvider.directive({
+ setter: valueFn(function(scope, element, attr) {
+ attr.$set('name', 'abc');
+ attr.$set('disabled', true);
+ expect(attr.name).toBe('abc');
+ expect(attr.disabled).toBe(true);
+ })
+ });
+ });
+ inject(function($rootScope, $compile) {
+ element = $compile('
')($rootScope);
+ expect(element.attr('name')).toEqual('abc');
+ expect(element.attr('disabled')).toEqual('disabled');
+ });
+ });
+
+
+ it('should read boolean attributes as boolean', function() {
+ module(function($compileProvider) {
+ $compileProvider.directive({
+ div: valueFn(function(scope, element, attr) {
+ element.text(attr.required);
+ })
+ });
+ });
+ inject(function($rootScope, $compile) {
+ element = $compile('
')($rootScope);
+ expect(element.text()).toEqual('true');
+ });
+ });
+
+
+ it('should create new instance of attr for each template stamping', function() {
+ module(function($compileProvider, $provide) {
+ var state = { first: [], second: [] };
+ $provide.value('state', state);
+ $compileProvider.directive({
+ first: valueFn({
+ priority: 1,
+ compile: function(templateElement, templateAttr) {
+ return function(scope, element, attr) {
+ state.first.push({
+ template: {element: templateElement, attr:templateAttr},
+ link: {element: element, attr: attr}
+ });
+ }
+ }
+ }),
+ second: valueFn({
+ priority: 2,
+ compile: function(templateElement, templateAttr) {
+ return function(scope, element, attr) {
+ state.second.push({
+ template: {element: templateElement, attr:templateAttr},
+ link: {element: element, attr: attr}
+ });
+ }
+ }
+ })
+ });
+ });
+ inject(function($rootScope, $compile, state) {
+ var template = $compile('
');
+ dealoc(template($rootScope.$new(), noop));
+ dealoc(template($rootScope.$new(), noop));
+
+ // instance between directives should be shared
+ expect(state.first[0].template.element).toBe(state.second[0].template.element);
+ expect(state.first[0].template.attr).toBe(state.second[0].template.attr);
+
+ // the template and the link can not be the same instance
+ expect(state.first[0].template.element).not.toBe(state.first[0].link.element);
+ expect(state.first[0].template.attr).not.toBe(state.first[0].link.attr);
+
+ // each new template needs to be new instance
+ expect(state.first[0].link.element).not.toBe(state.first[1].link.element);
+ expect(state.first[0].link.attr).not.toBe(state.first[1].link.attr);
+ expect(state.second[0].link.element).not.toBe(state.second[1].link.element);
+ expect(state.second[0].link.attr).not.toBe(state.second[1].link.attr);
+ });
+ });
+
+
+ describe('$set', function() {
+ var attr;
+ beforeEach(function(){
+ module(function($compileProvider) {
+ $compileProvider.directive('div', valueFn(function(scope, element, attr){
+ scope.attr = attr;
+ }));
+ });
+ inject(function($compile, $rootScope) {
+ element = $compile('
')($rootScope);
+ attr = $rootScope.attr;
+ expect(attr).toBeDefined();
+ });
+ });
+
+
+ it('should set attributes', function() {
+ attr.$set('ngMyAttr', 'value');
+ expect(element.attr('ng-my-attr')).toEqual('value');
+ expect(attr.ngMyAttr).toEqual('value');
+ });
+
+
+ it('should allow overriding of attribute name and remember the name', function() {
+ attr.$set('ngOther', '123', 'other');
+ expect(element.attr('other')).toEqual('123');
+ expect(attr.ngOther).toEqual('123');
+
+ attr.$set('ngOther', '246');
+ expect(element.attr('other')).toEqual('246');
+ expect(attr.ngOther).toEqual('246');
+ });
+
+
+ it('should set boolean attributes', function() {
+ attr.$set('disabled', 'true');
+ attr.$set('readOnly', 'true');
+ expect(element.attr('disabled')).toEqual('disabled');
+ expect(element.attr('readonly')).toEqual('readonly');
+
+ attr.$set('disabled', 'false');
+ expect(element.attr('disabled')).toEqual(undefined);
+
+ attr.$set('disabled', false);
+ attr.$set('readOnly', false);
+ expect(element.attr('disabled')).toEqual(undefined);
+ expect(element.attr('readonly')).toEqual(undefined);
+ });
+
+
+ it('should remove attribute', function() {
+ attr.$set('ngMyAttr', 'value');
+ expect(element.attr('ng-my-attr')).toEqual('value');
+
+ attr.$set('ngMyAttr', undefined);
+ expect(element.attr('ng-my-attr')).toBe(undefined);
+
+ attr.$set('ngMyAttr', 'value');
+ attr.$set('ngMyAttr', null);
+ expect(element.attr('ng-my-attr')).toBe(undefined);
+ })
+ });
+ });
});
diff --git a/test/testabilityPatch.js b/test/testabilityPatch.js
index 13e726bb..85c844cb 100644
--- a/test/testabilityPatch.js
+++ b/test/testabilityPatch.js
@@ -67,7 +67,10 @@ function dealoc(obj) {
}
}
-
+/**
+ * @param {DOMElement} element
+ * @param {boolean=} showNgClass
+ */
function sortedHtml(element, showNgClass) {
var html = "";
forEach(jqLite(element), function toString(node) {
--
cgit v1.2.3