aboutsummaryrefslogtreecommitdiffstats
path: root/test/JsonSpec.js
blob: f0019befd1b3385a1ec4b5121fa885544d12eee0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
describe('json', function(){
  it('should serialize primitives', function() {
    expect(toJson(0/0)).toEqual('null');
    expect(toJson(null)).toEqual('null');
    expect(toJson(true)).toEqual('true');
    expect(toJson(false)).toEqual('false');
    expect(toJson(123.45)).toEqual("123.45");
    expect(toJson("abc")).toEqual('"abc"');
    expect(toJson("a \t \n \r b \\")).toEqual('"a \\t \\n \\r b \\\\"');
  });

  it('should serialize strings with escaped characters', function() {
    expect(toJson("7\\\"7")).toEqual("\"7\\\\\\\"7\"");
  });

  it('should serialize objects', function() {
    expect(toJson({a:1,b:2})).toEqual('{"a":1,"b":2}');
    expect(toJson({a:{b:2}})).toEqual('{"a":{"b":2}}');
    expect(toJson({a:{b:{c:0}}})).toEqual('{"a":{"b":{"c":0}}}');
    expect(toJson({a:{b:0/0}})).toEqual('{"a":{"b":null}}');
  });

  it('should format objects pretty', function() {
    expect(toJson({a:1,b:2}, true)).toEqual('{\n  "a":1,\n  "b":2}');
    expect(toJson({a:{b:2}}, true)).toEqual('{\n  "a":{\n    "b":2}}');
  });

  it('should serialize array', function() {
    expect(toJson([])).toEqual('[]');
    expect(toJson([1,"b"])).toEqual('[1,"b"]');
  });

  it('should serialize RegExp', function() {
    expect(toJson(/foo/)).toEqual('"/foo/"');
    expect(toJson([1,new RegExp("foo")])).toEqual('[1,"/foo/"]');
  });

  it('should ignore functions', function() {
    expect(toJson([function(){},1])).toEqual('[null,1]');
    expect(toJson({a:function(){}})).toEqual('{}');
  });

  it('should parse null', function() {
    expect(fromJson("null")).toBeNull();
  });

  it('should parse boolean', function() {
    expect(fromJson("true")).toBeTruthy();
    expect(fromJson("false")).toBeFalsy();
  });

  it('should serialize array with empty items', function() {
    var a = [];
    a[1] = "X";
    expect(toJson(a)).toEqual('[null,"X"]');
  });

  it('should escape unicode', function() {
    expect("\u00a0".length).toEqual(1);
    expect(toJson("\u00a0").length).toEqual(8);
    expect(fromJson(toJson("\u00a0")).length).toEqual(1);
  });

  it('should serialize UTC dates', function() {
    var date = angular.String.toDate("2009-10-09T01:02:03.027Z");
    expect(toJson(date)).toEqual('"2009-10-09T01:02:03.027Z"');
    expect(fromJson('"2009-10-09T01:02:03.027Z"').getTime()).toEqual(date.getTime());
  });

  it('should prevent recursion', function() {
    var obj = {a:'b'};
    obj.recursion = obj;
    expect(angular.toJson(obj)).toEqual('{"a":"b","recursion":RECURSION}');
  });

  it('should serialize $ properties', function() {
    var obj = {$a: 'a'};
    expect(angular.toJson(obj)).toEqual('{"$a":"a"}');
  });

  it('should serialize inherited properties', function() {
    var obj = inherit({p:'p'});
    obj.a = 'a';
    expect(angular.toJson(obj)).toEqual('{"a":"a","p":"p"}');
  });

  it('should serialize same objects multiple times', function() {
    var obj = {a:'b'};
    expect(angular.toJson({A:obj, B:BinderTest = TestCase('BinderTest');

BinderTest.prototype.setUp = function(){
  var self = this;

  this.compile = function(html, initialScope, parent) {
    var compiler = new Compiler(angularTextMarkup, angularAttrMarkup, angularDirective, angularWidget);
    if (self.element) dealoc(self.element);
    var element = self.element = jqLite(html);
    var scope = compiler.compile(element)(element);

    if (parent) parent.append(element);

    extend(scope, initialScope);
    scope.$init();
    return {node:element, scope:scope};
  };
  this.compileToHtml = function (content) {
    return sortedHtml(this.compile(content).node);
  };
};

BinderTest.prototype.tearDown = function(){
  if (this.element && this.element.dealoc) {
    this.element.dealoc();
  }
};


BinderTest.prototype.testChangingTextfieldUpdatesModel = function(){
  var state = this.compile('<input type="text" name="model.price" value="abc">', {model:{}});
  state.scope.$eval();
  assertEquals('abc', state.scope.model.price);
};

BinderTest.prototype.testChangingTextareaUpdatesModel = function(){
  var c = this.compile('<textarea name="model.note">abc</textarea>');
  c.scope.$eval();
  assertEquals(c.scope.model.note, 'abc');
};

BinderTest.prototype.testChangingRadioUpdatesModel = function(){
  var c = this.compile('<input type="radio" name="model.price" value="A" checked>' +
        '<input type="radio" name="model.price" value="B">');
  c.scope.$eval();
  assertEquals(c.scope.model.price, 'A');
};

BinderTest.prototype.testChangingCheckboxUpdatesModel = function(){
  var form = this.compile('<input type="checkbox" name="model.price" value="true" checked ng:format="boolean"/>');
  assertEquals(true, form.scope.model.price);
};

BinderTest.prototype.testBindUpdate = function() {
  var c = this.compile('<div ng:eval="a=123"/>');
  assertEquals(123, c.scope.$get('a'));
};

BinderTest.prototype.testChangingSelectNonSelectedUpdatesModel = function(){
  var form = this.compile('<select name="model.price"><option value="A">A</option><option value="B">B</option></select>');
  assertEquals('A', form.scope.model.price);
};

BinderTest.prototype.testChangingMultiselectUpdatesModel = function(){
  var form = this.compile('<select name="Invoice.options" multiple="multiple">' +
          
class="s1">'<option value="C">Expedite</option>' + '</select>'); assertJsonEquals(["A", "B"], form.scope.$get('Invoice').options); }; BinderTest.prototype.testChangingSelectSelectedUpdatesModel = function(){ var form = this.compile('<select name="model.price"><option>A</option><option selected value="b">B</option></select>'); assertEquals(form.scope.model.price, 'b'); }; BinderTest.prototype.testExecuteInitialization = function() { var c = this.compile('<div ng:init="a=123">'); assertEquals(c.scope.$get('a'), 123); }; BinderTest.prototype.testExecuteInitializationStatements = function() { var c = this.compile('<div ng:init="a=123;b=345">'); assertEquals(c.scope.$get('a'), 123); assertEquals(c.scope.$get('b'), 345); }; BinderTest.prototype.testApplyTextBindings = function(){ var form = this.compile('<div ng:bind="model.a">x</div>'); form.scope.$set('model', {a:123}); form.scope.$eval(); assertEquals('123', form.node.text()); }; BinderTest.prototype.testReplaceBindingInTextWithSpan = function() { assertEquals(this.compileToHtml("<b>a{{b}}c</b>"), '<b>a<span ng:bind="b"></span>c</b>'); assertEquals(this.compileToHtml("<b>{{b}}</b>"), '<b><span ng:bind="b"></span></b>'); }; BinderTest.prototype.testBindingSpaceConfusesIE = function() { if (!msie) return; var span = document.createElement("span"); span.innerHTML = '&nbsp;'; var nbsp = span.firstChild.nodeValue; assertEquals( '<b><span ng:bind="a"></span><span>'+nbsp+'</span><span ng:bind="b"></span></b>', this.compileToHtml("<b>{{a}} {{b}}</b>")); assertEquals( '<b><span ng:bind="A"></span><span>'+nbsp+'x </span><span ng:bind="B"></span><span>'+nbsp+'(</span><span ng:bind="C"></span>)</b>', this.compileToHtml("<b>{{A}} x {{B}} ({{C}})</b>")); }; BinderTest.prototype.testBindingOfAttributes = function() { var c = this.compile("<a href='http://s/a{{b}}c' foo='x'></a>"); var attrbinding = c.node.attr("ng:bind-attr"); var bindings = fromJson(attrbinding); assertEquals("http://s/a{{b}}c", decodeURI(bindings.href)); assertTrue(!bindings.foo); }; BinderTest.prototype.testMarkMultipleAttributes = function() { var c = this.compile('<a href="http://s/a{{b}}c" foo="{{d}}"></a>'); var attrbinding = c.node.attr("ng:bind-attr"); var bindings = fromJson(attrbinding); assertEquals(bindings.foo, "{{d}}"); assertEquals(decodeURI(bindings.href), "http://s/a{{b}}c"); }; BinderTest.prototype.testAttributesNoneBound = function() { var c = this.compile("<a href='abc' foo='def'></a>"); var a = c.node; assertEquals(a[0].nodeName, "A"); assertTrue(!a.attr("ng:bind-attr")); }; BinderTest.prototype.testExistingAttrbindingIsAppended = function() { var c = this.compile("<a href='http://s/{{abc}}' ng:bind-attr='{\"b\":\"{{def}}\"}'></a>"); var a = c.node; assertEquals('{"b":"{{def}}","href":"http://s/{{abc}}"}', a.attr('ng:bind-attr')); }; BinderTest.prototype.testAttributesAreEvaluated = function(){ var c = this.compile('<a ng:bind-attr=\'{"a":"a", "b":"a+b={{a+b}}"}\'></a>'); var binder = c.binder, form = c.node; c.scope.$eval('a=1;b=2'); c.scope.$eval(); var a = c.node; assertEquals(a.attr('a'), 'a'); assertEquals(a.attr('b'), 'a+b=3'); }; BinderTest.prototype.testInputTypeButtonActionExecutesInScope = function(){ var savedCalled = false; var c = this.compile('<input type="button" ng:click="person.save()" value="Apply">'); c.scope.$set("person.save", function(){ savedCalled = true; }); browserTrigger(c.node, 'click'); assertTrue(savedCalled); }; BinderTest.prototype.testInputTypeButtonActionExecutesInScope2 = function(){ var log = ""; var c = this.compile('<input type="image" ng:click="action()">'); c.scope.$set("action", function(){ log += 'click;'; }); expect(log).toEqual(''); browserTrigger(c.node, 'click'); expect(log).toEqual('click;'); }; BinderTest.prototype.testButtonElementActionExecutesInScope = function(){ var savedCalled = false; var c = this.compile('<button ng:click="person.save()">Apply</button>'); c.scope.$set("person.save", function(){ savedCalled = true; }); browserTrigger(c.node, 'click'); assertTrue(savedCalled); }; BinderTest.prototype.testRepeaterUpdateBindings = function(){ var a = this.compile('<ul><LI ng:repeat="item in model.items" ng:bind="item.a"/></ul>'); var form = a.node; var items = [{a:"A"}, {a:"B"}]; a.scope.$set('model', {items:items}); a.scope.$eval(); assertEquals('<ul>' + '<#comment></#comment>' + '<li ng:bind="item.a" ng:repeat-index="0">A</li>' + '<li ng:bind="item.a" ng:repeat-index="1">B</li>' + '</ul>', sortedHtml(form)); items.unshift({a:'C'}); a.scope.$eval(); assertEquals('<ul>' + '<#comment></#comment>' + '<li ng:bind="item.a" ng:repeat-index="0">C</li>' + '<li ng:bind="item.a" ng:repeat-index="1">A</li>' + '<li ng:bind="item.a" ng:repeat-index="2">B</li>' + '</ul>', sortedHtml(form)); items.shift(); a.scope.$eval(); assertEquals('<ul>' + '<#comment></#comment>' + '<li ng:bind="item.a" ng:repeat-index="0">A</li>' + '<li ng:bind="item.a" ng:repeat-index="1">B</li>' + '</ul>', sortedHtml(form)); items.shift(); items.shift(); a.scope.$eval(); }; BinderTest.prototype.testRepeaterContentDoesNotBind = function(){ var a = this.compile('<ul><LI ng:repeat="item in model.items"><span ng:bind="item.a"></span></li></ul>'); a.scope.$set('model', {items:[{a:"A"}]}); a.scope.$eval(); assertEquals('<ul>' + '<#comment></#comment>' + '<li ng:repeat-index="0"><span ng:bind="item.a">A</span></li>' + '</ul>', sortedHtml(a.node)); }; BinderTest.prototype.testExpandEntityTag = function(){ assertEquals( '<div ng-entity="Person" ng:watch="$anchor.a:1"></div>', this.compileToHtml('<div ng-entity="Person" ng:watch="$anchor.a:1"/>')); }; BinderTest.prototype.testDoNotOverwriteCustomAction = function(){ var html = this.compileToHtml('<input type="submit" value="Save" action="foo();">'); assertTrue(html.indexOf('action="foo();"') > 0 ); }; BinderTest.prototype.testRepeaterAdd = function(){ var c = this.compile('<div><input type="text" name="item.x" ng:repeat="item in items"></div>'); var doc = c.node; c.scope.$set('items', [{x:'a'}, {x:'b'}]); c.scope.$eval(); var first = childNode(c.node, 1); var second = childNode(c.node, 2); assertEquals('a', first.val()); assertEquals('b', second.val()); first.val('ABC'); browserTrigger(first, 'keyup'); assertEquals(c.scope.items[0].x, 'ABC'); }; BinderTest.prototype.testItShouldRemoveExtraChildrenWhenIteratingOverHash = function(){ var c = this.compile('<div><div ng:repeat="i in items">{{i}}</div></div>'); var items = {}; c.scope.$set("items", items); c.scope.$eval(); expect(c.node[0].childNodes.length - 1).toEqual(0); items.name = "misko"; c.scope.$eval(); expect(c.node[0].childNodes.length - 1).toEqual(1); delete items.name; c.scope.$eval(); expect(c.node[0].childNodes.length - 1).toEqual(0); }; BinderTest.prototype.testIfTextBindingThrowsErrorDecorateTheSpan = function(){ var a = this