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

Side by Side Diff: packages/template_binding/test/binding_syntax.dart

Issue 2989763002: Update charted to 0.4.8 and roll (Closed)
Patch Set: Removed Cutch from list of reviewers Created 3 years, 4 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
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library template_binding.test.binding_syntax;
6
7 import 'dart:async';
8 import 'dart:collection';
9 import 'dart:html';
10 import 'package:template_binding/template_binding.dart';
11 import 'package:observe/observe.dart';
12 import 'package:unittest/unittest.dart';
13 import 'utils.dart';
14
15 // Note: this test is executed by template_element_test.dart
16
17 syntaxTests(FooBarModel fooModel([foo, bar])) {
18 test('prepareBinding', () {
19 var model = fooModel('bar');
20 var testSyntax = new TestBindingSyntax();
21 var div = createTestHtml(
22 '<template bind>{{ foo }}'
23 '<template bind>{{ foo }}</template>'
24 '</template>');
25 var template = templateBind(div.firstChild);
26 template
27 ..model = model
28 ..bindingDelegate = testSyntax;
29 return new Future(() {
30 expect(div.nodes.length, 4);
31 expect(div.nodes.last.text, 'bar');
32 expect(div.nodes[2].tagName, 'TEMPLATE');
33 expect(testSyntax.log, [
34 ['prepare', '', 'bind', 'TEMPLATE'],
35 ['bindFn', model, 'TEMPLATE', 0],
36 ['prepare', 'foo', 'text', 'TEXT'],
37 ['prepare', '', 'bind', 'TEMPLATE'],
38 ['bindFn', model, 'TEXT', 2],
39 ['bindFn', model, 'TEMPLATE', 3],
40 ['prepare', 'foo', 'text', 'TEXT'],
41 ['bindFn', model, 'TEXT', 6],
42 ]);
43 });
44 });
45
46 test('prepareInstanceModel', () {
47 var model = toObservable([fooModel(1), fooModel(2), fooModel(3)]);
48
49 var testSyntax = new TestModelSyntax();
50 testSyntax.altModels.addAll([fooModel('a'), fooModel('b'), fooModel('c')]);
51
52 var div = createTestHtml('<template repeat>{{ foo }}</template>');
53
54 var template = div.nodes[0];
55 templateBind(template)
56 ..model = model
57 ..bindingDelegate = testSyntax;
58 return new Future(() {
59
60 expect(div.nodes.length, 4);
61 expect(div.nodes[0].tagName, 'TEMPLATE');
62 expect(div.nodes[1].text, 'a');
63 expect(div.nodes[2].text, 'b');
64 expect(div.nodes[3].text, 'c');
65
66 expect(testSyntax.log, [
67 ['prepare', template],
68 ['bindFn', model[0]],
69 ['bindFn', model[1]],
70 ['bindFn', model[2]],
71 ]);
72 });
73 });
74
75 test('prepareInstanceModel - reorder instances', () {
76 var model = toObservable([0, 1, 2]);
77
78 var div = createTestHtml('<template repeat>{{}}</template>');
79 var template = div.firstChild;
80 var delegate = new TestInstanceModelSyntax();
81
82 templateBind(template)
83 ..model = model
84 ..bindingDelegate = delegate;
85 return new Future(() {
86 expect(delegate.prepareCount, 1);
87 expect(delegate.callCount, 3);
88
89 // Note: intentionally mutate in place.
90 model.replaceRange(0, model.length, model.reversed.toList());
91 }).then(endOfMicrotask).then((_) {
92 expect(delegate.prepareCount, 1);
93 expect(delegate.callCount, 3);
94 });
95 });
96
97 test('prepareInstancePositionChanged', () {
98 var model = toObservable(['a', 'b', 'c']);
99
100 var div = createTestHtml('<template repeat>{{}}</template>');
101 var delegate = new TestPositionChangedSyntax();
102
103 var template = div.nodes[0];
104 templateBind(template)
105 ..model = model
106 ..bindingDelegate = delegate;
107 return new Future(() {
108
109 expect(div.nodes.length, 4);
110 expect(div.nodes[0].tagName, 'TEMPLATE');
111 expect(div.nodes[1].text, 'a');
112 expect(div.nodes[2].text, 'b');
113 expect(div.nodes[3].text, 'c');
114
115 expect(delegate.log, [
116 ['prepare', template],
117 ['bindFn', model[0], 0],
118 ['bindFn', model[1], 1],
119 ['bindFn', model[2], 2],
120 ]);
121
122 delegate.log.clear();
123
124 model.removeAt(1);
125 }).then(endOfMicrotask).then((_) {
126
127 expect(delegate.log, [['bindFn', 'c', 1]], reason: 'removed item');
128
129 expect(div.nodes.skip(1).map((n) => n.text), ['a', 'c']);
130 });
131 });
132
133
134 test('Update bindingDelegate with active template', () {
135 var model = toObservable([1, 2]);
136
137 var div = createTestHtml(
138 '<template repeat>{{ \$index }} - {{ \$ident }}</template>');
139 var template = templateBind(div.firstChild)
140 ..bindingDelegate = new UpdateBindingDelegateA()
141 ..model = model;
142
143 return new Future(() {
144 expect(div.nodes.length, 3);
145 expect(div.nodes[1].text, 'i:0 - a:1');
146 expect(div.nodes[2].text, 'i:1 - a:2');
147
148 expect(() {
149 template.bindingDelegate = new UpdateBindingDelegateB();
150 }, throws);
151
152 template.clear();
153 expect(div.nodes.length, 1);
154
155 template
156 ..bindingDelegate = new UpdateBindingDelegateB()
157 ..model = model;
158
159 model.add(3);
160 }).then(nextMicrotask).then((_) {
161 // All instances should reflect delegateB
162 expect(4, div.nodes.length);
163 expect(div.nodes[1].text, 'I:0 - A:1-narg');
164 expect(div.nodes[2].text, 'I:2 - A:2-narg');
165 expect(div.nodes[3].text, 'I:4 - A:3-narg');
166 });
167 });
168
169 test('Basic', () {
170 var model = fooModel(2, 4);
171 var div = createTestHtml(
172 '<template bind>'
173 '{{ foo }} + {{ 2x: bar }} + {{ 4x: bar }}</template>');
174 var template = templateBind(div.firstChild);
175 template
176 ..model = model
177 ..bindingDelegate = new TimesTwoSyntax();
178 return new Future(() {
179 expect(div.nodes.length, 2);
180 expect(div.nodes.last.text, '2 + 8 + ');
181
182 model.foo = 4;
183 model.bar = 8;
184 }).then(endOfMicrotask).then((_) {
185 expect(div.nodes.last.text, '4 + 16 + ');
186 });
187 });
188
189 test('CreateInstance', () {
190 var delegateFoo = new SimpleTextDelegate('foo');
191 var delegateBar = new SimpleTextDelegate('bar');
192
193 var div = createTestHtml('<template bind>[[ 2x: bar ]]</template>');
194 var template = templateBind(div.firstChild);
195 template..bindingDelegate = delegateFoo..model = {};
196
197 return new Future(() {
198 expect(div.nodes.length, 2);
199 expect(div.lastChild.text, 'foo');
200
201 var fragment = template.createInstance({});
202 expect(fragment.nodes.length, 1);
203 expect(fragment.lastChild.text, 'foo');
204
205 fragment = template.createInstance({}, delegateBar);
206 expect(fragment.nodes.length, 1);
207 expect(fragment.lastChild.text, 'bar');
208 });
209 });
210
211 // Note: issue-141 test not included here as it's not related to the
212 // BindingDelegate
213 }
214
215 // TODO(jmesserly): mocks would be cleaner here.
216
217 class TestBindingSyntax extends BindingDelegate {
218 var log = [];
219
220 prepareBinding(String path, String name, Node node) {
221 var tagName = node is Element ? node.tagName : 'TEXT';
222 int id = log.length;
223 log.add(['prepare', path, name, tagName]);
224 final outerNode = node;
225 return (model, node, oneTime) {
226 var tagName = node is Element ? node.tagName : 'TEXT';
227 log.add(['bindFn', model, tagName, id]);
228 return oneTime ? new PropertyPath(path).getValueFrom(model) :
229 new PathObserver(model, path);
230 };
231 }
232 }
233
234 class SimpleTextDelegate extends BindingDelegate {
235 final String text;
236 SimpleTextDelegate(this.text);
237
238 prepareBinding(path, name, node) =>
239 name != 'text' ? null : (_, __, ___) => text;
240 }
241
242 class TestModelSyntax extends BindingDelegate {
243 var log = [];
244 var altModels = new ListQueue();
245
246 prepareInstanceModel(template) {
247 log.add(['prepare', template]);
248 return (model) {
249 log.add(['bindFn', model]);
250 return altModels.removeFirst();
251 };
252 }
253 }
254
255 class TestInstanceModelSyntax extends BindingDelegate {
256 int prepareCount = 0;
257 int callCount = 0;
258 prepareInstanceModel(template) {
259 prepareCount++;
260 return (model) {
261 callCount++;
262 return model;
263 };
264 }
265 }
266
267
268 class TestPositionChangedSyntax extends BindingDelegate {
269 var log = [];
270
271 prepareInstancePositionChanged(template) {
272 int id = log.length;
273 log.add(['prepare', template]);
274 return (templateInstance, index) {
275 log.add(['bindFn', templateInstance.model, index]);
276 };
277 }
278 }
279
280
281 class TimesTwoSyntax extends BindingDelegate {
282 prepareBinding(path, name, node) {
283 path = path.trim();
284 if (!path.startsWith('2x:')) return null;
285
286 path = path.substring(3);
287 return (model, _, oneTime) {
288 return new ObserverTransform(new PathObserver(model, path), (x) => 2 * x);
289 };
290 }
291 }
292
293 class UpdateBindingDelegateBase extends BindingDelegate {
294 bindingHandler(prefix, path) => (model, _, oneTime) =>
295 new ObserverTransform(new PathObserver(model, path), (x) => '$prefix:$x');
296 }
297
298 class UpdateBindingDelegateA extends UpdateBindingDelegateBase {
299 prepareBinding(path, name, node) {
300 if (path == '\$ident') return bindingHandler('a', 'id');
301 if (path == '\$index') return bindingHandler('i', 'index');
302 }
303
304 prepareInstanceModel(template) => (model) => toObservable({ 'id': model });
305
306 prepareInstancePositionChanged(template) => (templateInstance, index) {
307 templateInstance.model['index'] = index;
308 };
309 }
310
311 class UpdateBindingDelegateB extends UpdateBindingDelegateBase {
312 prepareBinding(path, name, node) {
313 if (path == '\$ident') return bindingHandler('A', 'id');
314 if (path == '\$index') return bindingHandler('I', 'index');
315 }
316
317 prepareInstanceModel(template) =>
318 (model) => toObservable({ 'id': '${model}-narg' });
319
320
321 prepareInstancePositionChanged(template) => (templateInstance, index) {
322 templateInstance.model['index'] = 2 * index;
323 };
324 }
325
OLDNEW
« no previous file with comments | « packages/template_binding/pubspec.yaml ('k') | packages/template_binding/test/custom_element_bindings_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698