'use strict'; describe('ngBind*', function() { var element; afterEach(function() { dealoc(element); }); describe('ngBind', function() { it('should set text', inject(function($rootScope, $compile) { element = $compile('
')($rootScope); expect(element.text()).toEqual(''); $rootScope.a = 'misko'; $rootScope.$digest(); expect(element.hasClass('ng-binding')).toEqual(true); expect(element.text()).toEqual('misko'); })); it('should set text to blank if undefined', inject(function($rootScope, $compile) { element = $compile('
')($rootScope); $rootScope.a = 'misko'; $rootScope.$digest(); expect(element.text()).toEqual('misko'); $rootScope.a = undefined; $rootScope.$digest(); expect(element.text()).toEqual(''); $rootScope.a = null; $rootScope.$digest(); expect(element.text()).toEqual(''); })); it('should suppress rendering of falsy values', inject(function($rootScope, $compile) { element = $compile('
' + '' + '-' + '' + '' + '
')($rootScope); $rootScope.$digest(); expect(element.text()).toEqual('-0false'); })); they('should jsonify $prop', [[{a: 1}, '{"a":1}'], [true, 'true'], [false, 'false']], function(prop) { inject(function($rootScope, $compile) { $rootScope.value = prop[0]; element = $compile('
')($rootScope); $rootScope.$digest(); expect(element.text()).toEqual(prop[1]); }); }); it('should use custom toString when present', inject(function($rootScope, $compile) { $rootScope.value = { toString: function() { return 'foo'; } }; element = $compile('
')($rootScope); $rootScope.$digest(); expect(element.text()).toEqual('foo'); })); it('should NOT use toString on array objects', inject(function($rootScope, $compile) { $rootScope.value = []; element = $compile('
')($rootScope); $rootScope.$digest(); expect(element.text()).toEqual('[]'); })); it('should NOT use toString on Date objects', inject(function($rootScope, $compile) { $rootScope.value = new Date(2014, 10, 10, 0, 0, 0); element = $compile('
')($rootScope); $rootScope.$digest(); expect(element.text()).toBe(JSON.stringify($rootScope.value)); expect(element.text()).not.toEqual($rootScope.value.toString()); })); it('should one-time bind if the expression starts with two colons', inject(function($rootScope, $compile) { element = $compile('
')($rootScope); $rootScope.a = 'lucas'; expect($rootScope.$$watchers.length).toEqual(1); $rootScope.$digest(); expect(element.text()).toEqual('lucas'); expect($rootScope.$$watchers.length).toEqual(0); $rootScope.a = undefined; $rootScope.$digest(); expect(element.text()).toEqual('lucas'); })); it('should be possible to bind to a new value within the same $digest', inject(function($rootScope, $compile) { element = $compile('
')($rootScope); $rootScope.$watch('a', function(newVal) { if (newVal === 'foo') { $rootScope.a = 'bar'; } }); $rootScope.a = 'foo'; $rootScope.$digest(); expect(element.text()).toEqual('bar'); $rootScope.a = undefined; $rootScope.$digest(); expect(element.text()).toEqual('bar'); })); it('should remove the binding if the value is defined at the end of a $digest loop', inject(function($rootScope, $compile) { element = $compile('
')($rootScope); $rootScope.$watch('a', function(newVal) { if (newVal === 'foo') { $rootScope.a = undefined; } }); $rootScope.a = 'foo'; $rootScope.$digest(); expect(element.text()).toEqual(''); $rootScope.a = 'bar'; $rootScope.$digest(); expect(element.text()).toEqual('bar'); $rootScope.a = 'man'; $rootScope.$digest(); expect(element.text()).toEqual('bar'); })); }); describe('ngBindTemplate', function() { it('should ngBindTemplate', inject(function($rootScope, $compile) { element = $compile('
')($rootScope); $rootScope.name = 'Misko'; $rootScope.$digest(); expect(element.hasClass('ng-binding')).toEqual(true); expect(element.text()).toEqual('Hello Misko!'); })); it('should one-time bind the expressions that start with ::', inject(function($rootScope, $compile) { element = $compile('
')($rootScope); $rootScope.name = 'Misko'; expect($rootScope.$$watchers.length).toEqual(2); $rootScope.$digest(); expect(element.hasClass('ng-binding')).toEqual(true); expect(element.text()).toEqual(' Misko!'); expect($rootScope.$$watchers.length).toEqual(1); $rootScope.hello = 'Hello'; $rootScope.name = 'Lucas'; $rootScope.$digest(); expect(element.text()).toEqual('Hello Misko!'); expect($rootScope.$$watchers.length).toEqual(0); })); it('should render object as JSON ignore $$', inject(function($rootScope, $compile) { element = $compile('
{{ {key:"value", $$key:"hide"}  }}
')($rootScope); $rootScope.$digest(); expect(fromJson(element.text())).toEqual({key:'value'}); })); }); describe('ngBindHtml', function() { it('should complain about accidental use of interpolation', inject(function($compile) { expect(function() { $compile('
'); }).toThrowMinErr('$parse', 'syntax', 'Syntax Error: Token \'{\' invalid key at column 2 of the expression [{{myHtml}}] starting at [{myHtml}}]'); })); describe('SCE disabled', function() { beforeEach(function() { module(function($sceProvider) { $sceProvider.enabled(false); }); }); it('should set html', inject(function($rootScope, $compile) { element = $compile('
')($rootScope); $rootScope.html = '
hello
'; $rootScope.$digest(); expect(lowercase(element.html())).toEqual('
hello
'); })); it('should update html', inject(function($rootScope, $compile, $sce) { element = $compile('
')($rootScope); $rootScope.html = 'hello'; $rootScope.$digest(); expect(lowercase(element.html())).toEqual('hello'); $rootScope.html = 'goodbye'; $rootScope.$digest(); expect(lowercase(element.html())).toEqual('goodbye'); })); it('should one-time bind if the expression starts with two colons', inject(function($rootScope, $compile) { element = $compile('
')($rootScope); $rootScope.html = '
hello
'; expect($rootScope.$$watchers.length).toEqual(1); $rootScope.$digest(); expect(element.text()).toEqual('hello'); expect($rootScope.$$watchers.length).toEqual(0); $rootScope.html = '
hello
'; $rootScope.$digest(); expect(element.text()).toEqual('hello'); })); }); describe('SCE enabled', function() { it('should NOT set html for untrusted values', inject(function($rootScope, $compile) { element = $compile('
')($rootScope); $rootScope.html = '
hello
'; expect(function() { $rootScope.$digest(); }).toThrow(); })); it('should NOT set html for wrongly typed values', inject(function($rootScope, $compile, $sce) { element = $compile('
')($rootScope); $rootScope.html = $sce.trustAsCss('
hello
'); expect(function() { $rootScope.$digest(); }).toThrow(); })); it('should set html for trusted values', inject(function($rootScope, $compile, $sce) { element = $compile('
')($rootScope); $rootScope.html = $sce.trustAsHtml('
hello
'); $rootScope.$digest(); expect(lowercase(element.html())).toEqual('
hello
'); })); it('should update html', inject(function($rootScope, $compile, $sce) { element = $compile('
')($rootScope); $rootScope.html = $sce.trustAsHtml('hello'); $rootScope.$digest(); expect(lowercase(element.html())).toEqual('hello'); $rootScope.html = $sce.trustAsHtml('goodbye'); $rootScope.$digest(); expect(lowercase(element.html())).toEqual('goodbye'); })); it('should not cause infinite recursion for trustAsHtml object watches', inject(function($rootScope, $compile, $sce) { // Ref: https://github.com/angular/angular.js/issues/3932 // If the binding is a function that creates a new value on every call via trustAs, we'll // trigger an infinite digest if we don't take care of it. element = $compile('
')($rootScope); $rootScope.getHtml = function() { return $sce.trustAsHtml('
hello
'); }; $rootScope.$digest(); expect(lowercase(element.html())).toEqual('
hello
'); })); it('should handle custom $sce objects', function() { function MySafeHtml(val) { this.val = val; } module(function($provide) { $provide.decorator('$sce', function($delegate) { $delegate.trustAsHtml = function(html) { return new MySafeHtml(html); }; $delegate.getTrustedHtml = function(mySafeHtml) { return mySafeHtml.val; }; $delegate.valueOf = function(v) { return v instanceof MySafeHtml ? v.val : v; }; return $delegate; }); }); inject(function($rootScope, $compile, $sce) { // Ref: https://github.com/angular/angular.js/issues/14526 // Previous code used toString for change detection, which fails for custom objects // that don't override toString. element = $compile('
')($rootScope); var html = 'hello'; $rootScope.getHtml = function() { return $sce.trustAsHtml(html); }; $rootScope.$digest(); expect(lowercase(element.html())).toEqual('hello'); html = 'goodbye'; $rootScope.$digest(); expect(lowercase(element.html())).toEqual('goodbye'); }); }); describe('when $sanitize is available', function() { beforeEach(function() { module('ngSanitize'); }); it('should sanitize untrusted html', inject(function($rootScope, $compile) { element = $compile('
')($rootScope); $rootScope.html = '
hello
'; $rootScope.$digest(); expect(lowercase(element.html())).toEqual('
hello
'); })); }); }); }); });