aboutsummaryrefslogtreecommitdiffstats
path: root/test/directivesSpec.js
diff options
context:
space:
mode:
authorMisko Hevery2011-03-23 09:33:29 -0700
committerVojta Jina2011-08-02 01:00:03 +0200
commit8f0dcbab804180828d6859b1340c86cf161209fb (patch)
treed13d47d47a1889cb7c96a87cecacd2e25307d51c /test/directivesSpec.js
parent1f4b417184ce53af15474de065400f8a686430c5 (diff)
downloadangular.js-8f0dcbab804180828d6859b1340c86cf161209fb.tar.bz2
feat(scope): new and improved scope implementation
- Speed improvements (about 4x on flush phase) - Memory improvements (uses no function closures) - Break $eval into $apply, $dispatch, $flush - Introduced $watch and $observe Breaks angular.equals() use === instead of == Breaks angular.scope() does not take parent as first argument Breaks scope.$watch() takes scope as first argument Breaks scope.$set(), scope.$get are removed Breaks scope.$config is removed Breaks $route.onChange callback has not "this" bounded
Diffstat (limited to 'test/directivesSpec.js')
-rw-r--r--test/directivesSpec.js69
1 files changed, 39 insertions, 30 deletions
diff --git a/test/directivesSpec.js b/test/directivesSpec.js
index 22d3c84b..a05861ae 100644
--- a/test/directivesSpec.js
+++ b/test/directivesSpec.js
@@ -22,8 +22,9 @@ describe("directive", function(){
it("should ng:eval", function() {
var scope = compile('<div ng:init="a=0" ng:eval="a = a + 1"></div>');
+ scope.$flush();
expect(scope.a).toEqual(1);
- scope.$eval();
+ scope.$flush();
expect(scope.a).toEqual(2);
});
@@ -32,7 +33,7 @@ describe("directive", function(){
var scope = compile('<div ng:bind="a"></div>');
expect(element.text()).toEqual('');
scope.a = 'misko';
- scope.$eval();
+ scope.$flush();
expect(element.hasClass('ng-binding')).toEqual(true);
expect(element.text()).toEqual('misko');
});
@@ -40,24 +41,24 @@ describe("directive", function(){
it('should set text to blank if undefined', function() {
var scope = compile('<div ng:bind="a"></div>');
scope.a = 'misko';
- scope.$eval();
+ scope.$flush();
expect(element.text()).toEqual('misko');
scope.a = undefined;
- scope.$eval();
+ scope.$flush();
expect(element.text()).toEqual('');
});
it('should set html', function() {
var scope = compile('<div ng:bind="html|html"></div>');
scope.html = '<div unknown>hello</div>';
- scope.$eval();
+ scope.$flush();
expect(lowercase(element.html())).toEqual('<div>hello</div>');
});
it('should set unsafe html', function() {
var scope = compile('<div ng:bind="html|html:\'unsafe\'"></div>');
scope.html = '<div onclick="">hello</div>';
- scope.$eval();
+ scope.$flush();
expect(lowercase(element.html())).toEqual('<div onclick="">hello</div>');
});
@@ -66,7 +67,7 @@ describe("directive", function(){
return jqLite('<a>hello</a>');
};
var scope = compile('<div ng:bind="0|myElement"></div>');
- scope.$eval();
+ scope.$flush();
expect(lowercase(element.html())).toEqual('<a>hello</a>');
});
@@ -76,12 +77,14 @@ describe("directive", function(){
return 'HELLO';
};
var scope = compile('<div>before<div ng:bind="0|myFilter"></div>after</div>');
+ scope.$flush();
expect(sortedHtml(scope.$element)).toEqual('<div>before<div class="filter" ng:bind="0|myFilter">HELLO</div>after</div>');
});
it('should suppress rendering of falsy values', function(){
var scope = compile('<div>{{ null }}{{ undefined }}{{ "" }}-{{ 0 }}{{ false }}</div>');
+ scope.$flush();
expect(scope.$element.text()).toEqual('-0false');
});
@@ -90,8 +93,8 @@ describe("directive", function(){
describe('ng:bind-template', function(){
it('should ng:bind-template', function() {
var scope = compile('<div ng:bind-template="Hello {{name}}!"></div>');
- scope.$set('name', 'Misko');
- scope.$eval();
+ scope.name = 'Misko';
+ scope.$flush();
expect(element.hasClass('ng-binding')).toEqual(true);
expect(element.text()).toEqual('Hello Misko!');
});
@@ -103,6 +106,7 @@ describe("directive", function(){
return text;
};
var scope = compile('<div>before<span ng:bind-template="{{\'HELLO\'|myFilter}}">INNER</span>after</div>');
+ scope.$flush();
expect(scope.$element.text()).toEqual("beforeHELLOafter");
expect(innerText).toEqual('INNER');
});
@@ -112,12 +116,14 @@ describe("directive", function(){
describe('ng:bind-attr', function(){
it('should bind attributes', function(){
var scope = compile('<div ng:bind-attr="{src:\'http://localhost/mysrc\', alt:\'myalt\'}"/>');
+ scope.$flush();
expect(element.attr('src')).toEqual('http://localhost/mysrc');
expect(element.attr('alt')).toEqual('myalt');
});
it('should not pretty print JSON in attributes', function(){
var scope = compile('<img alt="{{ {a:1} }}"/>');
+ scope.$flush();
expect(element.attr('alt')).toEqual('{"a":1}');
});
});
@@ -132,7 +138,7 @@ describe("directive", function(){
scope.disabled = true;
scope.readonly = true;
scope.checked = true;
- scope.$eval();
+ scope.$flush();
expect(input.disabled).toEqual(true);
expect(input.readOnly).toEqual(true);
@@ -142,16 +148,16 @@ describe("directive", function(){
describe('ng:click', function(){
it('should get called on a click', function(){
var scope = compile('<div ng:click="clicked = true"></div>');
- scope.$eval();
- expect(scope.$get('clicked')).toBeFalsy();
+ scope.$flush();
+ expect(scope.clicked).toBeFalsy();
browserTrigger(element, 'click');
- expect(scope.$get('clicked')).toEqual(true);
+ expect(scope.clicked).toEqual(true);
});
it('should stop event propagation', function() {
var scope = compile('<div ng:click="outer = true"><div ng:click="inner = true"></div></div>');
- scope.$eval();
+ scope.$flush();
expect(scope.outer).not.toBeDefined();
expect(scope.inner).not.toBeDefined();
@@ -169,7 +175,7 @@ describe("directive", function(){
var scope = compile('<form action="" ng:submit="submitted = true">' +
'<input type="submit"/>' +
'</form>');
- scope.$eval();
+ scope.$flush();
expect(scope.submitted).not.toBeDefined();
browserTrigger(element.children()[0]);
@@ -177,23 +183,22 @@ describe("directive", function(){
});
});
-
describe('ng:class', function() {
it('should add new and remove old classes dynamically', function() {
var scope = compile('<div class="existing" ng:class="dynClass"></div>');
scope.dynClass = 'A';
- scope.$eval();
+ scope.$flush();
expect(element.hasClass('existing')).toBe(true);
expect(element.hasClass('A')).toBe(true);
scope.dynClass = 'B';
- scope.$eval();
+ scope.$flush();
expect(element.hasClass('existing')).toBe(true);
expect(element.hasClass('A')).toBe(false);
expect(element.hasClass('B')).toBe(true);
delete scope.dynClass;
- scope.$eval();
+ scope.$flush();
expect(element.hasClass('existing')).toBe(true);
expect(element.hasClass('A')).toBe(false);
expect(element.hasClass('B')).toBe(false);
@@ -201,7 +206,7 @@ describe("directive", function(){
it('should support adding multiple classes', function(){
var scope = compile('<div class="existing" ng:class="[\'A\', \'B\']"></div>');
- scope.$eval();
+ scope.$flush();
expect(element.hasClass('existing')).toBeTruthy();
expect(element.hasClass('A')).toBeTruthy();
expect(element.hasClass('B')).toBeTruthy();
@@ -211,7 +216,7 @@ describe("directive", function(){
it('should ng:class odd/even', function(){
var scope = compile('<ul><li ng:repeat="i in [0,1]" class="existing" ng:class-odd="\'odd\'" ng:class-even="\'even\'"></li><ul>');
- scope.$eval();
+ scope.$flush();
var e1 = jqLite(element[0].childNodes[1]);
var e2 = jqLite(element[0].childNodes[2]);
expect(e1.hasClass('existing')).toBeTruthy();
@@ -223,32 +228,32 @@ describe("directive", function(){
describe('ng:style', function(){
it('should set', function(){
var scope = compile('<div ng:style="{height: \'40px\'}"></div>');
- scope.$eval();
+ scope.$flush();
expect(element.css('height')).toEqual('40px');
});
it('should silently ignore undefined style', function() {
var scope = compile('<div ng:style="myStyle"></div>');
- scope.$eval();
+ scope.$flush();
expect(element.hasClass('ng-exception')).toBeFalsy();
});
it('should preserve and remove previous style', function(){
var scope = compile('<div style="height: 10px;" ng:style="myStyle"></div>');
- scope.$eval();
+ scope.$flush();
expect(getStyle(element)).toEqual({height: '10px'});
scope.myStyle = {height: '20px', width: '10px'};
- scope.$eval();
+ scope.$flush();
expect(getStyle(element)).toEqual({height: '20px', width: '10px'});
scope.myStyle = {};
- scope.$eval();
+ scope.$flush();
expect(getStyle(element)).toEqual({height: '10px'});
});
});
it('should silently ignore undefined ng:style', function() {
var scope = compile('<div ng:style="myStyle"></div>');
- scope.$eval();
+ scope.$flush();
expect(element.hasClass('ng-exception')).toBeFalsy();
});
@@ -258,9 +263,10 @@ describe("directive", function(){
var element = jqLite('<div ng:show="exp"></div>'),
scope = compile(element);
+ scope.$flush();
expect(isCssVisible(element)).toEqual(false);
scope.exp = true;
- scope.$eval();
+ scope.$flush();
expect(isCssVisible(element)).toEqual(true);
});
@@ -271,7 +277,7 @@ describe("directive", function(){
expect(isCssVisible(element)).toBe(false);
scope.exp = true;
- scope.$eval();
+ scope.$flush();
expect(isCssVisible(element)).toBe(true);
});
});
@@ -283,7 +289,7 @@ describe("directive", function(){
expect(isCssVisible(element)).toBe(true);
scope.exp = true;
- scope.$eval();
+ scope.$flush();
expect(isCssVisible(element)).toBe(false);
});
});
@@ -333,11 +339,13 @@ describe("directive", function(){
expect(scope.greeter.greeting).toEqual('hello');
expect(scope.childGreeter.greeting).toEqual('hey');
expect(scope.childGreeter.$parent.greeting).toEqual('hello');
+ scope.$flush();
expect(scope.$element.text()).toEqual('hey dude!');
});
});
+ //TODO(misko): this needs to be deleted when ng:eval-order is gone
it('should eval things according to ng:eval-order', function(){
var scope = compile(
'<div ng:init="log=\'\'">' +
@@ -348,6 +356,7 @@ describe("directive", function(){
'<span bind-template="{{log = log + \'d\'}}"></span>' +
'</span>' +
'</div>');
+ scope.$flush();
expect(scope.log).toEqual('abcde');
});