Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(827)

Side by Side Diff: pkg/mdv/test/binding_syntax_test.dart

Issue 19771010: implement dirty checking for @observable objects (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: logging for loops in dirty checking Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library binding_syntax_test; 5 library binding_syntax_test;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 import 'dart:html'; 9 import 'dart:html';
10 import 'package:mdv/mdv.dart' as mdv; 10 import 'package:mdv/mdv.dart' as mdv;
11 import 'package:observe/observe.dart'; 11 import 'package:observe/observe.dart';
12 import 'package:unittest/html_config.dart'; 12 import 'package:unittest/html_config.dart';
13 import 'package:unittest/unittest.dart'; 13 import 'package:unittest/unittest.dart';
14 import 'observe_utils.dart'; 14 import 'mdv_test_utils.dart';
15 15
16 // Note: this file ported from 16 // Note: this file ported from
17 // https://github.com/toolkitchen/mdv/blob/master/tests/syntax.js 17 // https://github.com/toolkitchen/mdv/blob/master/tests/syntax.js
18 18
19 main() { 19 main() {
20 mdv.initialize(); 20 mdv.initialize();
21 useHtmlConfiguration(); 21 useHtmlConfiguration();
22 group('Syntax', syntaxTests); 22
23 group('Syntax FooBarModel', () {
24 syntaxTests(([f, b]) => new FooBarModel(f, b));
25 });
26 group('Syntax FooBarNotifyModel', () {
27 syntaxTests(([f, b]) => new FooBarNotifyModel(f, b));
28 });
23 } 29 }
24 30
25 syntaxTests() { 31 syntaxTests(FooBarModel fooModel([foo, bar])) {
26 var testDiv; 32 var testDiv;
27 33
28 setUp(() { 34 setUp(() {
29 document.body.append(testDiv = new DivElement()); 35 document.body.append(testDiv = new DivElement());
30 }); 36 });
31 37
32 tearDown(() { 38 tearDown(() {
33 testDiv.remove(); 39 testDiv.remove();
34 testDiv = null; 40 testDiv = null;
35 }); 41 });
36 42
37 createTestHtml(s) { 43 createTestHtml(s) {
38 var div = new DivElement(); 44 var div = new DivElement();
39 div.innerHtml = s; 45 div.innerHtml = s;
40 testDiv.append(div); 46 testDiv.append(div);
41 47
42 for (var node in div.queryAll('*')) { 48 for (var node in div.queryAll('*')) {
43 if (node.isTemplate) TemplateElement.decorate(node); 49 if (node.isTemplate) TemplateElement.decorate(node);
44 } 50 }
45 51
46 return div; 52 return div;
47 } 53 }
48 54
49 recursivelySetTemplateModel(element, model) { 55 recursivelySetTemplateModel(element, model) {
50 for (var node in element.queryAll('*')) { 56 for (var node in element.queryAll('*')) {
51 if (node.isTemplate) node.model = model; 57 if (node.isTemplate) node.model = model;
52 } 58 }
53 } 59 }
54 60
55 test('Registration', () { 61 observeTest('Registration', () {
56 var model = toSymbolMap({'foo': 'bar'}); 62 var model = fooModel('bar');
57 63
58 var testSyntax = new TestBindingSyntax(); 64 var testSyntax = new TestBindingSyntax();
59 TemplateElement.syntax['Test'] = testSyntax; 65 TemplateElement.syntax['Test'] = testSyntax;
60 try { 66 try {
61 var div = createTestHtml( 67 var div = createTestHtml(
62 '<template bind syntax="Test">{{ foo }}' + 68 '<template bind syntax="Test">{{ foo }}' +
63 '<template bind>{{ foo }}</template></template>'); 69 '<template bind>{{ foo }}</template></template>');
64 recursivelySetTemplateModel(div, model); 70 recursivelySetTemplateModel(div, model);
65 deliverChangeRecords(); 71 performMicrotaskCheckpoint();
66 expect(div.nodes.length, 4); 72 expect(div.nodes.length, 4);
67 expect(div.nodes.last.text, 'bar'); 73 expect(div.nodes.last.text, 'bar');
68 expect(div.nodes[2].tagName, 'TEMPLATE'); 74 expect(div.nodes[2].tagName, 'TEMPLATE');
69 expect(div.nodes[2].attributes['syntax'], 'Test'); 75 expect(div.nodes[2].attributes['syntax'], 'Test');
70 76
71 expect(testSyntax.log, [ 77 expect(testSyntax.log, [
72 [model, '', 'bind', 'TEMPLATE'], 78 [model, '', 'bind', 'TEMPLATE'],
73 [model, 'foo', 'text', null], 79 [model, 'foo', 'text', null],
74 [model, '', 'bind', 'TEMPLATE'], 80 [model, '', 'bind', 'TEMPLATE'],
75 [model, 'foo', 'text', null], 81 [model, 'foo', 'text', null],
76 ]); 82 ]);
77 } finally { 83 } finally {
78 TemplateElement.syntax.remove('Test'); 84 TemplateElement.syntax.remove('Test');
79 } 85 }
80 }); 86 });
81 87
82 test('getInstanceModel', () { 88 observeTest('getInstanceModel', () {
83 var model = toObservable([{'foo': 1}, {'foo': 2}, {'foo': 3}] 89 var model = toObservable([fooModel(1), fooModel(2), fooModel(3)]);
84 .map(toSymbolMap));
85 90
86 var testSyntax = new TestModelSyntax(); 91 var testSyntax = new TestModelSyntax();
87 testSyntax.altModels.addAll([{'foo': 'a'}, {'foo': 'b'}, {'foo': 'c'}] 92 testSyntax.altModels.addAll([fooModel('a'), fooModel('b'), fooModel('c')]);
88 .map(toSymbolMap));
89 93
90 TemplateElement.syntax['Test'] = testSyntax; 94 TemplateElement.syntax['Test'] = testSyntax;
91 try { 95 try {
92 96
93 var div = createTestHtml( 97 var div = createTestHtml(
94 '<template repeat syntax="Test">' + 98 '<template repeat syntax="Test">' +
95 '{{ foo }}</template>'); 99 '{{ foo }}</template>');
96 100
97 var template = div.nodes[0]; 101 var template = div.nodes[0];
98 recursivelySetTemplateModel(div, model); 102 recursivelySetTemplateModel(div, model);
99 deliverChangeRecords(); 103 performMicrotaskCheckpoint();
100 104
101 expect(div.nodes.length, 4); 105 expect(div.nodes.length, 4);
102 expect(div.nodes[0].tagName, 'TEMPLATE'); 106 expect(div.nodes[0].tagName, 'TEMPLATE');
103 expect(div.nodes[1].text, 'a'); 107 expect(div.nodes[1].text, 'a');
104 expect(div.nodes[2].text, 'b'); 108 expect(div.nodes[2].text, 'b');
105 expect(div.nodes[3].text, 'c'); 109 expect(div.nodes[3].text, 'c');
106 110
107 expect(testSyntax.log, [ 111 expect(testSyntax.log, [
108 [template, model[0]], 112 [template, model[0]],
109 [template, model[1]], 113 [template, model[1]],
110 [template, model[2]], 114 [template, model[2]],
111 ]); 115 ]);
112 116
113 } finally { 117 } finally {
114 TemplateElement.syntax.remove('Test'); 118 TemplateElement.syntax.remove('Test');
115 } 119 }
116 }); 120 });
117 121
118 test('Basic', () { 122 observeTest('Basic', () {
119 var model = toSymbolMap({'foo': 2, 'bar': 4}); 123 var model = fooModel(2, 4);
120 124
121 TemplateElement.syntax['2x'] = new TimesTwoSyntax(); 125 TemplateElement.syntax['2x'] = new TimesTwoSyntax();
122 126
123 var div = createTestHtml( 127 var div = createTestHtml(
124 '<template bind syntax="2x">' 128 '<template bind syntax="2x">'
125 '{{ foo }} + {{ 2x: bar }} + {{ 4x: bar }}</template>'); 129 '{{ foo }} + {{ 2x: bar }} + {{ 4x: bar }}</template>');
126 recursivelySetTemplateModel(div, model); 130 recursivelySetTemplateModel(div, model);
127 deliverChangeRecords(); 131 performMicrotaskCheckpoint();
128 expect(div.nodes.length, 2); 132 expect(div.nodes.length, 2);
129 expect(div.nodes.last.text, '2 + 8 + '); 133 expect(div.nodes.last.text, '2 + 8 + ');
130 134
131 model[const Symbol('foo')] = 4; 135 model.foo = 4;
132 model[const Symbol('bar')] = 8; 136 model.bar = 8;
133 deliverChangeRecords(); 137 performMicrotaskCheckpoint();
134 expect(div.nodes.last.text, '4 + 16 + '); 138 expect(div.nodes.last.text, '4 + 16 + ');
135 139
136 TemplateElement.syntax.remove('2x'); 140 TemplateElement.syntax.remove('2x');
137 }); 141 });
138 142
139 test('Different Sub-Template Syntax', () { 143 observeTest('Different Sub-Template Syntax', () {
140 var model = toSymbolMap({'foo': 'bar'}); 144 var model = fooModel('bar');
141 145
142 TemplateElement.syntax['Test'] = new TestBindingSyntax(); 146 TemplateElement.syntax['Test'] = new TestBindingSyntax();
143 TemplateElement.syntax['Test2'] = new TestBindingSyntax(); 147 TemplateElement.syntax['Test2'] = new TestBindingSyntax();
144 148
145 var div = createTestHtml( 149 var div = createTestHtml(
146 '<template bind syntax="Test">{{ foo }}' 150 '<template bind syntax="Test">{{ foo }}'
147 '<template bind syntax="Test2">{{ foo }}</template></template>'); 151 '<template bind syntax="Test2">{{ foo }}</template></template>');
148 recursivelySetTemplateModel(div, model); 152 recursivelySetTemplateModel(div, model);
149 deliverChangeRecords(); 153 performMicrotaskCheckpoint();
150 expect(div.nodes.length, 4); 154 expect(div.nodes.length, 4);
151 expect(div.nodes.last.text, 'bar'); 155 expect(div.nodes.last.text, 'bar');
152 expect(div.nodes[2].tagName, 'TEMPLATE'); 156 expect(div.nodes[2].tagName, 'TEMPLATE');
153 expect(div.nodes[2].attributes['syntax'], 'Test2'); 157 expect(div.nodes[2].attributes['syntax'], 'Test2');
154 158
155 var testLog = TemplateElement.syntax['Test'].log; 159 var testLog = TemplateElement.syntax['Test'].log;
156 var test2Log = TemplateElement.syntax['Test2'].log; 160 var test2Log = TemplateElement.syntax['Test2'].log;
157 161
158 expect(testLog, [ 162 expect(testLog, [
159 [model, '', 'bind', 'TEMPLATE'], 163 [model, '', 'bind', 'TEMPLATE'],
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 } 217 }
214 } 218 }
215 219
216 for (var node in toRemove) node.remove(); 220 for (var node in toRemove) node.remove();
217 removed += toRemove.length; 221 removed += toRemove.length;
218 222
219 return instance; 223 return instance;
220 } 224 }
221 } 225 }
222 226
223
224 class TimesTwoSyntax extends CustomBindingSyntax { 227 class TimesTwoSyntax extends CustomBindingSyntax {
225 getBinding(model, path, name, node) { 228 getBinding(model, path, name, node) {
226 path = path.trim(); 229 path = path.trim();
227 if (!path.startsWith('2x:')) return null; 230 if (!path.startsWith('2x:')) return null;
228 231
229 path = path.substring(3); 232 path = path.substring(3);
230 return new CompoundBinding((values) => values['value'] * 2) 233 return new CompoundBinding((values) => values['value'] * 2)
231 ..bind('value', model, path); 234 ..bind('value', model, path);
232 } 235 }
233 } 236 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698