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

Side by Side Diff: pkg/template_binding/test/node_bindings_test.dart

Issue 42433002: port Node.bind to bd0a0591920da9091b326627a46a104a92c7efe7 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 1 month 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 template_binding.test.node_bindings_test; 5 library template_binding.test.node_bindings_test;
6 6
7 import 'dart:html'; 7 import 'dart:html';
8 import 'package:observe/observe.dart' show toObservable; 8
9 import 'package:template_binding/template_binding.dart'; 9 @MirrorsUsed(targets: const [NodeBinding], override:
10 'template_binding.test.node_bindings_test')
11 import 'dart:mirrors';
12
13 import 'package:observe/observe.dart' show toObservable, PathObserver;
14 import 'package:template_binding/template_binding.dart'
15 show nodeBind, NodeBinding;
10 import 'package:unittest/html_config.dart'; 16 import 'package:unittest/html_config.dart';
11 import 'package:unittest/unittest.dart'; 17 import 'package:unittest/unittest.dart';
12 import 'utils.dart'; 18 import 'utils.dart';
13 19
14 // Note: this file ported from 20 // Note: this file ported from
15 // https://github.com/toolkitchen/mdv/blob/master/tests/node_bindings.js 21 // https://github.com/toolkitchen/mdv/blob/master/tests/node_bindings.js
16 22
17 main() { 23 main() {
18 useHtmlConfiguration(); 24 useHtmlConfiguration();
19 group('Node Bindings', nodeBindingTests);
20 }
21 25
22 nodeBindingTests() {
23 setUp(() { 26 setUp(() {
24 document.body.append(testDiv = new DivElement()); 27 document.body.append(testDiv = new DivElement());
25 }); 28 });
26 29
27 tearDown(() { 30 tearDown(() {
28 testDiv.remove(); 31 testDiv.remove();
29 testDiv = null; 32 testDiv = null;
30 }); 33 });
31 34
32 observeTest('Text', () { 35
36 group('Text bindings', testBindings);
37 group('Element attribute bindings', elementBindings);
38 group('Form Element bindings', formBindings);
39 }
40
41 testBindings() {
42 observeTest('Basic', () {
33 var text = new Text('hi'); 43 var text = new Text('hi');
34 var model = toObservable({'a': 1}); 44 var model = toObservable({'a': 1});
35 nodeBind(text).bind('text', model, 'a'); 45 nodeBind(text).bind('text', model, 'a');
36 expect(text.text, '1'); 46 expect(text.text, '1');
37 47
38 model['a'] = 2; 48 model['a'] = 2;
39 performMicrotaskCheckpoint(); 49 performMicrotaskCheckpoint();
40 expect(text.text, '2'); 50 expect(text.text, '2');
41 51
42 nodeBind(text).unbind('text'); 52 nodeBind(text).unbind('text');
43 model['a'] = 3; 53 model['a'] = 3;
44 performMicrotaskCheckpoint(); 54 performMicrotaskCheckpoint();
45 expect(text.text, '2'); 55 expect(text.text, '2');
46 56
47 // TODO(rafaelw): Throw on binding to unavailable property? 57 // TODO(rafaelw): Throw on binding to unavailable property?
48 }); 58 });
49 59
50 observeTest('Element', () { 60 observeTest('No Path', () {
61 var text = new Text('hi');
62 var model = 1;
63 nodeBind(text).bind('text', model);
64 expect(text.text, '1');
65 });
66
67 observeTest('Path unreachable', () {
68 var text = testDiv.append(new Text('hi'));
69 var model = 1;
70 nodeBind(text).bind('text', model, 'a');
71 expect(text.text, '');
72 });
73
74 observeTest('Observer is Model', () {
75 _observer(x) => reflect(x).getField(
76 privateSymbol(NodeBinding, '_observer')).reflectee;
77
78 var text = new Text('');
79 var model = toObservable({'a': {'b': {'c': 1}}});
80 var observer = new PathObserver(model, 'a.b.c');
81 nodeBind(text).bind('text', observer, 'value');
82 expect(text.text, '1');
83
84 var binding = nodeBind(text).bindings['text'];
85 expect(binding, isNotNull);
86 expect(privateField(binding, '_observer'), observer,
87 reason: 'should reuse observer');
88
89 model['a']['b']['c'] = 2;
90 performMicrotaskCheckpoint();
91 expect(text.text, '2');
92 nodeBind(text).unbind('text');
93 });
94 }
95
96 elementBindings() {
97 observeTest('Basic', () {
98 var el = new DivElement();
99 var model = toObservable({'a': '1'});
100 nodeBind(el).bind('foo', model, 'a');
101 performMicrotaskCheckpoint();
102 expect(el.attributes['foo'], '1');
103
104 model['a'] = '2';
105 performMicrotaskCheckpoint();
106 expect(el.attributes['foo'], '2');
107
108 model['a'] = 232.2;
109 performMicrotaskCheckpoint();
110 expect(el.attributes['foo'], '232.2');
111
112 model['a'] = 232;
113 performMicrotaskCheckpoint();
114 expect(el.attributes['foo'], '232');
115
116 model['a'] = null;
117 performMicrotaskCheckpoint();
118 expect(el.attributes['foo'], '');
119 });
120
121 observeTest('No Path', () {
122 var el = testDiv.append(new DivElement());
123 var model = 1;
124 nodeBind(el).bind('foo', model);
125 expect(el.attributes['foo'], '1');
126 });
127
128 observeTest('Path unreachable', () {
129 var el = testDiv.append(new DivElement());
130 var model = toObservable({});
131 nodeBind(el).bind('foo', model, 'bar');
132 expect(el.attributes['foo'], '');
133 });
134
135 observeTest('Dashes', () {
136 var el = testDiv.append(new DivElement());
137 var model = toObservable({'a': '1'});
138 nodeBind(el).bind('foo-bar', model, 'a');
139 performMicrotaskCheckpoint();
140 expect(el.attributes['foo-bar'], '1');
141
142 model['a'] = '2';
143 performMicrotaskCheckpoint();
144 expect(el.attributes['foo-bar'], '2');
145 });
146
147 observeTest('Element.id, Element.hidden?', () {
51 var element = new DivElement(); 148 var element = new DivElement();
52 var model = toObservable({'a': 1, 'b': 2}); 149 var model = toObservable({'a': 1, 'b': 2});
53 nodeBind(element).bind('hidden?', model, 'a'); 150 nodeBind(element).bind('hidden?', model, 'a');
54 nodeBind(element).bind('id', model, 'b'); 151 nodeBind(element).bind('id', model, 'b');
55 152
56 expect(element.attributes, contains('hidden')); 153 expect(element.attributes, contains('hidden'));
57 expect(element.attributes['hidden'], ''); 154 expect(element.attributes['hidden'], '');
58 expect(element.id, '2'); 155 expect(element.id, '2');
59 156
60 model['a'] = null; 157 model['a'] = null;
61 performMicrotaskCheckpoint(); 158 performMicrotaskCheckpoint();
62 expect(element.attributes, isNot(contains('hidden')), 159 expect(element.attributes, isNot(contains('hidden')),
63 reason: 'null is false-y'); 160 reason: 'null is false-y');
64 161
65 model['a'] = false; 162 model['a'] = false;
66 performMicrotaskCheckpoint(); 163 performMicrotaskCheckpoint();
67 expect(element.attributes, isNot(contains('hidden'))); 164 expect(element.attributes, isNot(contains('hidden')));
68 165
69 model['a'] = 'foo'; 166 model['a'] = 'foo';
70 model['b'] = 'x'; 167 model['b'] = 'x';
71 performMicrotaskCheckpoint(); 168 performMicrotaskCheckpoint();
72 expect(element.attributes, contains('hidden')); 169 expect(element.attributes, contains('hidden'));
73 expect(element.attributes['hidden'], ''); 170 expect(element.attributes['hidden'], '');
74 expect(element.id, 'x'); 171 expect(element.id, 'x');
75 }); 172 });
76 173
174 observeTest('Element.id - path unreachable', () {
175 var element = testDiv.append(new DivElement());
176 var model = toObservable({});
177 nodeBind(element).bind('id', model, 'a');
178 expect(element.id, '');
179 });
180 }
181
182 formBindings() {
77 inputTextAreaValueTest(String tagName) { 183 inputTextAreaValueTest(String tagName) {
78 var el = new Element.tag(tagName); 184 var el = new Element.tag(tagName);
79 testDiv.nodes.add(el); 185 testDiv.nodes.add(el);
80 var model = toObservable({'x': 42}); 186 var model = toObservable({'x': 42});
81 nodeBind(el).bind('value', model, 'x'); 187 nodeBind(el).bind('value', model, 'x');
82 expect(el.value, '42'); 188 expect(el.value, '42');
83 189
84 model['x'] = 'Hi'; 190 model['x'] = 'Hi';
85 expect(el.value, '42', reason: 'changes delivered async'); 191 expect(el.value, '42', reason: 'changes delivered async');
86 performMicrotaskCheckpoint(); 192 performMicrotaskCheckpoint();
87 expect(el.value, 'Hi'); 193 expect(el.value, 'Hi');
88 194
89 el.value = 'changed'; 195 el.value = 'changed';
90 dispatchEvent('input', el); 196 dispatchEvent('input', el);
91 expect(model['x'], 'changed'); 197 expect(model['x'], 'changed');
92 198
93 nodeBind(el).unbind('value'); 199 nodeBind(el).unbind('value');
94 200
95 el.value = 'changed again'; 201 el.value = 'changed again';
96 dispatchEvent('input', el); 202 dispatchEvent('input', el);
97 expect(model['x'], 'changed'); 203 expect(model['x'], 'changed');
98 204
99 nodeBind(el).bind('value', model, 'x'); 205 nodeBind(el).bind('value', model, 'x');
100 model['x'] = null; 206 model['x'] = null;
101 performMicrotaskCheckpoint(); 207 performMicrotaskCheckpoint();
102 expect(el.value, ''); 208 expect(el.value, '');
103 } 209 }
104 210
105 observeTest('Input.value', () => inputTextAreaValueTest('input')); 211 inputTextAreaNoPath(String tagName) {
106 observeTest('TextArea.value', () => inputTextAreaValueTest('textarea')); 212 var el = testDiv.append(new Element.tag(tagName));
213 var model = 42;
214 nodeBind(el).bind('value', model);
215 expect(el.value, '42');
216 }
217
218 inputTextAreaPathUnreachable(String tagName) {
219 var el = testDiv.append(new Element.tag(tagName));
220 var model = toObservable({});
221 nodeBind(el).bind('value', model, 'a');
222 expect(el.value, '');
223 }
224
225 observeTest('Input.value',
226 () => inputTextAreaValueTest('input'));
227 observeTest('Input.value - no path',
228 () => inputTextAreaNoPath('input'));
229 observeTest('Input.value - path unreachable',
230 () => inputTextAreaPathUnreachable('input'));
231 observeTest('TextArea.value',
232 () => inputTextAreaValueTest('textarea'));
233 observeTest('TextArea.value - no path',
234 () => inputTextAreaNoPath('textarea'));
235 observeTest('TextArea.value - path unreachable',
236 () => inputTextAreaPathUnreachable('textarea'));
107 237
108 observeTest('Radio Input', () { 238 observeTest('Radio Input', () {
109 var input = new InputElement(); 239 var input = new InputElement();
110 input.type = 'radio'; 240 input.type = 'radio';
111 var model = toObservable({'x': true}); 241 var model = toObservable({'x': true});
112 nodeBind(input).bind('checked', model, 'x'); 242 nodeBind(input).bind('checked', model, 'x');
113 expect(input.checked, true); 243 expect(input.checked, true);
114 244
115 model['x'] = false; 245 model['x'] = false;
116 expect(input.checked, true); 246 expect(input.checked, true);
117 performMicrotaskCheckpoint(); 247 performMicrotaskCheckpoint();
118 expect(input.checked, false,reason: 'model change should update checked'); 248 expect(input.checked, false,reason: 'model change should update checked');
119 249
120 input.checked = true; 250 input.checked = true;
121 dispatchEvent('change', input); 251 dispatchEvent('change', input);
122 expect(model['x'], true, reason: 'input.checked should set model'); 252 expect(model['x'], true, reason: 'input.checked should set model');
123 253
124 nodeBind(input).unbind('checked'); 254 nodeBind(input).unbind('checked');
125 255
126 input.checked = false; 256 input.checked = false;
127 dispatchEvent('change', input); 257 dispatchEvent('change', input);
128 expect(model['x'], true, 258 expect(model['x'], true,
129 reason: 'disconnected binding should not fire'); 259 reason: 'disconnected binding should not fire');
130 }); 260 });
131 261
132 observeTest('Checkbox Input', () { 262 observeTest('Input.value - user value rejected', () {
133 var input = new InputElement(); 263 var model = toObservable({'val': 'ping'});
134 testDiv.append(input); 264
265 var el = new InputElement();
266 nodeBind(el).bind('value', model, 'val');
267 performMicrotaskCheckpoint();
268 expect(el.value, 'ping');
269
270 el.value = 'pong';
271 dispatchEvent('input', el);
272 expect(model['val'], 'pong');
273
274 // Try a deep path.
275 model = toObservable({'a': {'b': {'c': 'ping'}}});
276
277 nodeBind(el).bind('value', model, 'a.b.c');
278 performMicrotaskCheckpoint();
279 expect(el.value, 'ping');
280
281 el.value = 'pong';
282 dispatchEvent('input', el);
283 expect(new PathObserver(model, 'a.b.c').value, 'pong');
284
285 // Start with the model property being absent.
286 model['a']['b'].remove('c');
287 performMicrotaskCheckpoint();
288 expect(el.value, '');
289
290 el.value = 'pong';
291 dispatchEvent('input', el);
292 expect(new PathObserver(model, 'a.b.c').value, 'pong');
293 performMicrotaskCheckpoint();
294
295 // Model property unreachable (and unsettable).
296 model['a'].remove('b');
297 performMicrotaskCheckpoint();
298 expect(el.value, '');
299
300 el.value = 'pong';
301 dispatchEvent('input', el);
302 expect(new PathObserver(model, 'a.b.c').value, null);
303 });
304
305 observeTest('(Checkbox)Input.checked', () {
306 var el = testDiv.append(new InputElement());
307 el.type = 'checkbox';
308
309 var model = toObservable({'x': true});
310 nodeBind(el).bind('checked', model, 'x');
311 expect(el.checked, true);
312
313 model['x'] = false;
314 expect(el.checked, true, reason: 'changes delivered async');
315 performMicrotaskCheckpoint();
316 expect(el.checked, false);
317
318 el.click();
319 expect(model['x'], true);
320 performMicrotaskCheckpoint();
321
322 el.click();
323 expect(model['x'], false);
324 });
325
326 observeTest('(Checkbox)Input.checked - path unreachable', () {
327 var input = testDiv.append(new InputElement());
135 input.type = 'checkbox'; 328 input.type = 'checkbox';
329 var model = toObservable({});
330 nodeBind(input).bind('checked', model, 'x');
331 expect(input.checked, false);
332 });
333
334 observeTest('(Checkbox)Input.checked 2', () {
335 var model = toObservable({'val': true});
336
337 var el = testDiv.append(new InputElement());
338 el.type = 'checkbox';
339 nodeBind(el).bind('checked', model, 'val');
340 performMicrotaskCheckpoint();
341 expect(el.checked, true);
342
343 model['val'] = false;
344 performMicrotaskCheckpoint();
345 expect(el.checked, false);
346
347 el.click();
348 expect(model['val'], true);
349
350 el.click();
351 expect(model['val'], false);
352
353 el.onClick.listen((_) {
354 expect(model['val'], true);
355 });
356 el.onChange.listen((_) {
357 expect(model['val'], true);
358 });
359
360 el.dispatchEvent(new MouseEvent('click', view: window));
361 });
362
363 observeTest('(Checkbox)Input.checked - binding updated on click', () {
364 var model = toObservable({'val': true});
365
366 var el = new InputElement();
367 testDiv.append(el);
368 el.type = 'checkbox';
369 nodeBind(el).bind('checked', model, 'val');
370 performMicrotaskCheckpoint();
371 expect(el.checked, true);
372
373 el.onClick.listen((_) {
374 expect(model['val'], false);
375 });
376
377 el.dispatchEvent(new MouseEvent('click', view: window));
378 });
379
380 observeTest('(Checkbox)Input.checked - binding updated on change', () {
381 var model = toObservable({'val': true});
382
383 var el = new InputElement();
384 testDiv.append(el);
385 el.type = 'checkbox';
386 nodeBind(el).bind('checked', model, 'val');
387 performMicrotaskCheckpoint();
388 expect(el.checked, true);
389
390 el.onChange.listen((_) {
391 expect(model['val'], false);
392 });
393
394 el.dispatchEvent(new MouseEvent('click', view: window));
395 });
396
397 observeTest('(Radio)Input.checked', () {
398 var input = testDiv.append(new InputElement());
399 input.type = 'radio';
136 var model = toObservable({'x': true}); 400 var model = toObservable({'x': true});
137 nodeBind(input).bind('checked', model, 'x'); 401 nodeBind(input).bind('checked', model, 'x');
138 expect(input.checked, true); 402 expect(input.checked, true);
139 403
140 model['x'] = false; 404 model['x'] = false;
141 expect(input.checked, true, reason: 'changes delivered async'); 405 expect(input.checked, true);
142 performMicrotaskCheckpoint(); 406 performMicrotaskCheckpoint();
143 expect(input.checked, false); 407 expect(input.checked, false);
144 408
145 input.click(); 409 input.checked = true;
410 dispatchEvent('change', input);
146 expect(model['x'], true); 411 expect(model['x'], true);
147 performMicrotaskCheckpoint(); 412
148 413 nodeBind(input).unbind('checked');
149 input.click(); 414
150 expect(model['x'], false); 415 input.checked = false;
416 dispatchEvent('change', input);
417 expect(model['x'], true);
418 });
419
420 radioInputChecked2(host) {
421 var model = toObservable({'val1': true, 'val2': false, 'val3': false,
422 'val4': true});
423 var RADIO_GROUP_NAME = 'test';
424
425 var container = host.append(new DivElement());
426
427 var el1 = container.append(new InputElement());
428 el1.type = 'radio';
429 el1.name = RADIO_GROUP_NAME;
430 nodeBind(el1).bind('checked', model, 'val1');
431
432 var el2 = container.append(new InputElement());
433 el2.type = 'radio';
434 el2.name = RADIO_GROUP_NAME;
435 nodeBind(el2).bind('checked', model, 'val2');
436
437 var el3 = container.append(new InputElement());
438 el3.type = 'radio';
439 el3.name = RADIO_GROUP_NAME;
440 nodeBind(el3).bind('checked', model, 'val3');
441
442 var el4 = container.append(new InputElement());
443 el4.type = 'radio';
444 el4.name = 'othergroup';
445 nodeBind(el4).bind('checked', model, 'val4');
446
447 performMicrotaskCheckpoint();
448 expect(el1.checked, true);
449 expect(el2.checked, false);
450 expect(el3.checked, false);
451 expect(el4.checked, true);
452
453 model['val1'] = false;
454 model['val2'] = true;
455 performMicrotaskCheckpoint();
456 expect(el1.checked, false);
457 expect(el2.checked, true);
458 expect(el3.checked, false);
459 expect(el4.checked, true);
460
461 el1.checked = true;
462 dispatchEvent('change', el1);
463 expect(model['val1'], true);
464 expect(model['val2'], false);
465 expect(model['val3'], false);
466 expect(model['val4'], true);
467
468 el3.checked = true;
469 dispatchEvent('change', el3);
470 expect(model['val1'], false);
471 expect(model['val2'], false);
472 expect(model['val3'], true);
473 expect(model['val4'], true);
474 }
475
476 observeTest('(Radio)Input.checked 2', () {
477 radioInputChecked2(testDiv);
478 });
479
480 observeTest('(Radio)Input.checked 2 - ShadowRoot', () {
481 if (!ShadowRoot.supported) return;
482
483 var div = new DivElement();
484 var shadowRoot = div.createShadowRoot();
485 radioInputChecked2(shadowRoot);
486 unbindAll(shadowRoot);
487 });
488
489 radioInputCheckedMultipleForms(host) {
490 var model = toObservable({'val1': true, 'val2': false, 'val3': false,
491 'val4': true});
492 var RADIO_GROUP_NAME = 'observeTest';
493
494 var container = testDiv.append(new DivElement());
495 var form1 = new FormElement();
496 container.append(form1);
497 var form2 = new FormElement();
498 container.append(form2);
499
500 var el1 = new InputElement();
501 form1.append(el1);
502 el1.type = 'radio';
503 el1.name = RADIO_GROUP_NAME;
504 nodeBind(el1).bind('checked', model, 'val1');
505
506 var el2 = new InputElement();
507 form1.append(el2);
508 el2.type = 'radio';
509 el2.name = RADIO_GROUP_NAME;
510 nodeBind(el2).bind('checked', model, 'val2');
511
512 var el3 = new InputElement();
513 form2.append(el3);
514 el3.type = 'radio';
515 el3.name = RADIO_GROUP_NAME;
516 nodeBind(el3).bind('checked', model, 'val3');
517
518 var el4 = new InputElement();
519 form2.append(el4);
520 el4.type = 'radio';
521 el4.name = RADIO_GROUP_NAME;
522 nodeBind(el4).bind('checked', model, 'val4');
523
524 performMicrotaskCheckpoint();
525 expect(el1.checked, true);
526 expect(el2.checked, false);
527 expect(el3.checked, false);
528 expect(el4.checked, true);
529
530 el2.checked = true;
531 dispatchEvent('change', el2);
532 expect(model['val1'], false);
533 expect(model['val2'], true);
534
535 // Radio buttons in form2 should be unaffected
536 expect(model['val3'], false);
537 expect(model['val4'], true);
538
539 el3.checked = true;
540 dispatchEvent('change', el3);
541 expect(model['val3'], true);
542 expect(model['val4'], false);
543
544 // Radio buttons in form1 should be unaffected
545 expect(model['val1'], false);
546 expect(model['val2'], true);
547 }
548
549 observeTest('(Radio)Input.checked - multiple forms', () {
550 radioInputCheckedMultipleForms(testDiv);
551 });
552
553 observeTest('(Radio)Input.checked 2 - ShadowRoot', () {
554 if (!ShadowRoot.supported) return;
555
556 var shadowRoot = new DivElement().createShadowRoot();
557 radioInputChecked2(shadowRoot);
558 unbindAll(shadowRoot);
559 });
560
561 observeTest('Select.selectedIndex', () {
562 var select = new SelectElement();
563 testDiv.append(select);
564 var option0 = select.append(new OptionElement());
565 var option1 = select.append(new OptionElement());
566 var option2 = select.append(new OptionElement());
567
568 var model = toObservable({'val': 2});
569
570 nodeBind(select).bind('selectedIndex', model, 'val');
571 performMicrotaskCheckpoint();
572 expect(select.selectedIndex, 2);
573
574 select.selectedIndex = 1;
575 dispatchEvent('change', select);
576 expect(model['val'], 1);
577 });
578
579 observeTest('Select.selectedIndex - path NaN', () {
580 var select = new SelectElement();
581 testDiv.append(select);
582 var option0 = select.append(new OptionElement());
583 var option1 = select.append(new OptionElement());
584 option1.selected = true;
585 var option2 = select.append(new OptionElement());
586
587 var model = toObservable({'val': 'foo'});
588
589 nodeBind(select).bind('selectedIndex', model, 'val');
590 performMicrotaskCheckpoint();
591 expect(select.selectedIndex, 0);
592 });
593
594 observeTest('Select.selectedIndex - path unreachable', () {
595 var select = new SelectElement();
596 testDiv.append(select);
597 var option0 = select.append(new OptionElement());
598 var option1 = select.append(new OptionElement());
599 option1.selected = true;
600 var option2 = select.append(new OptionElement());
601
602 var model = toObservable({});
603
604 nodeBind(select).bind('selectedIndex', model, 'val');
605 performMicrotaskCheckpoint();
606 expect(select.selectedIndex, 0);
607 });
608
609 observeTest('Option.value', () {
610 var option = testDiv.append(new OptionElement());
611 var model = toObservable({'x': 42});
612 nodeBind(option).bind('value', model, 'x');
613 expect(option.value, '42');
614
615 model['x'] = 'Hi';
616 expect(option.value, '42');
617 performMicrotaskCheckpoint();
618 expect(option.value, 'Hi');
619 });
620
621 observeTest('Select.value', () {
622 var select = testDiv.append(new SelectElement());
623 testDiv.append(select);
624 var option0 = select.append(new OptionElement());
625 var option1 = select.append(new OptionElement());
626 var option2 = select.append(new OptionElement());
627
628 var model = toObservable({
629 'opt0': 'a',
630 'opt1': 'b',
631 'opt2': 'c',
632 'selected': 'b'
633 });
634
635 nodeBind(option0).bind('value', model, 'opt0');
636 nodeBind(option1).bind('value', model, 'opt1');
637 nodeBind(option2).bind('value', model, 'opt2');
638
639 nodeBind(select).bind('value', model, 'selected');
640 performMicrotaskCheckpoint();
641 expect(select.value, 'b');
642
643 select.value = 'c';
644 dispatchEvent('change', select);
645 expect(model['selected'], 'c');
646
647 model['opt2'] = 'X';
648 performMicrotaskCheckpoint();
649 expect(select.value, 'X');
650 expect(model['selected'], 'X');
651
652 model['selected'] = 'a';
653 performMicrotaskCheckpoint();
654 expect(select.value, 'a');
151 }); 655 });
152 } 656 }
657
658 privateField(x, name) => reflect(x).getField(
659 privateSymbol(reflect(x).type, name)).reflectee;
660
661 // TODO(jmesserly): fix this when it's easier to get a private symbol.
662 privateSymbol(TypeMirror type, String name) {
663 while (type != null) {
664 var symbol = type.variables.keys.firstWhere(
665 (s) => MirrorSystem.getName(s) == name, orElse: () => null);
666 if (symbol != null) return symbol;
667 type = type.superclass;
668 }
669 return null;
670 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698