OLD | NEW |
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.template_binding_test; | 5 library template_binding.test.template_binding_test; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:html'; | 8 import 'dart:html'; |
9 import 'dart:js' show JsObject; | 9 import 'dart:js' show JsObject; |
10 import 'dart:math' as math; | 10 import 'dart:math' as math; |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 }).then(endOfMicrotask).then((_) { | 390 }).then(endOfMicrotask).then((_) { |
391 expect(div.nodes.length, 2); | 391 expect(div.nodes.length, 2); |
392 expect(div.lastChild.text, 'foo'); | 392 expect(div.lastChild.text, 'foo'); |
393 | 393 |
394 templateBind(template).model = null; | 394 templateBind(template).model = null; |
395 }).then(endOfMicrotask).then((_) { | 395 }).then(endOfMicrotask).then((_) { |
396 expect(div.nodes.length, 1); | 396 expect(div.nodes.length, 1); |
397 }); | 397 }); |
398 }); | 398 }); |
399 | 399 |
| 400 test('Bind If minimal discardChanges', () { |
| 401 var div = createTestHtml( |
| 402 '<template bind="{{bound}}" if="{{predicate}}">value:{{ value }}' |
| 403 '</template>'); |
| 404 // Dart Note: bound changed from null->{}. |
| 405 var m = toObservable({ 'bound': {}, 'predicate': null }); |
| 406 var template = div.firstChild; |
| 407 |
| 408 var discardChangesCalled = { 'bound': 0, 'predicate': 0 }; |
| 409 templateBind(template) |
| 410 ..model = m |
| 411 ..bindingDelegate = |
| 412 new BindIfMinimalDiscardChanges(discardChangesCalled); |
| 413 |
| 414 return new Future(() { |
| 415 expect(discardChangesCalled['bound'], 0); |
| 416 expect(discardChangesCalled['predicate'], 0); |
| 417 expect(div.childNodes.length, 1); |
| 418 m['predicate'] = 1; |
| 419 }).then(endOfMicrotask).then((_) { |
| 420 expect(discardChangesCalled['bound'], 1); |
| 421 expect(discardChangesCalled['predicate'], 0); |
| 422 |
| 423 expect(div.nodes.length, 2); |
| 424 expect(div.lastChild.text, 'value:'); |
| 425 |
| 426 m['bound'] = toObservable({'value': 2}); |
| 427 }).then(endOfMicrotask).then((_) { |
| 428 expect(discardChangesCalled['bound'], 1); |
| 429 expect(discardChangesCalled['predicate'], 1); |
| 430 |
| 431 expect(div.nodes.length, 2); |
| 432 expect(div.lastChild.text, 'value:2'); |
| 433 |
| 434 m['bound']['value'] = 3; |
| 435 |
| 436 }).then(endOfMicrotask).then((_) { |
| 437 expect(discardChangesCalled['bound'], 1); |
| 438 expect(discardChangesCalled['predicate'], 1); |
| 439 |
| 440 expect(div.nodes.length, 2); |
| 441 expect(div.lastChild.text, 'value:3'); |
| 442 |
| 443 templateBind(template).model = null; |
| 444 }).then(endOfMicrotask).then((_) { |
| 445 expect(discardChangesCalled['bound'], 1); |
| 446 expect(discardChangesCalled['predicate'], 1); |
| 447 |
| 448 expect(div.nodes.length, 1); |
| 449 }); |
| 450 }); |
| 451 |
| 452 |
400 test('Empty-If', () { | 453 test('Empty-If', () { |
401 var div = createTestHtml('<template if>{{ value }}</template>'); | 454 var div = createTestHtml('<template if>{{ value }}</template>'); |
402 var template = div.firstChild; | 455 var template = div.firstChild; |
403 var m = toObservable({ 'value': 'foo' }); | 456 var m = toObservable({ 'value': 'foo' }); |
404 templateBind(template).model = null; | 457 templateBind(template).model = null; |
405 return new Future(() { | 458 return new Future(() { |
406 expect(div.nodes.length, 1); | 459 expect(div.nodes.length, 1); |
407 | 460 |
408 templateBind(template).model = m; | 461 templateBind(template).model = m; |
409 }).then(endOfMicrotask).then((_) { | 462 }).then(endOfMicrotask).then((_) { |
(...skipping 2226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2636 } | 2689 } |
2637 | 2690 |
2638 class Issue18Syntax extends BindingDelegate { | 2691 class Issue18Syntax extends BindingDelegate { |
2639 prepareBinding(path, name, node) { | 2692 prepareBinding(path, name, node) { |
2640 if (name != 'class') return null; | 2693 if (name != 'class') return null; |
2641 | 2694 |
2642 return (model, _, oneTime) => new PathObserver(model, path); | 2695 return (model, _, oneTime) => new PathObserver(model, path); |
2643 } | 2696 } |
2644 } | 2697 } |
2645 | 2698 |
| 2699 class BindIfMinimalDiscardChanges extends BindingDelegate { |
| 2700 Map<String, int> discardChangesCalled; |
| 2701 |
| 2702 BindIfMinimalDiscardChanges(this.discardChangesCalled) : super() {} |
| 2703 |
| 2704 prepareBinding(path, name, node) { |
| 2705 return (model, node, oneTime) => |
| 2706 new DiscardCountingPathObserver(discardChangesCalled, model, path); |
| 2707 } |
| 2708 } |
| 2709 |
| 2710 class DiscardCountingPathObserver extends PathObserver { |
| 2711 Map<String, int> discardChangesCalled; |
| 2712 |
| 2713 DiscardCountingPathObserver(this.discardChangesCalled, model, path) |
| 2714 : super(model, path) {} |
| 2715 |
| 2716 get value { |
| 2717 discardChangesCalled[path.toString()]++; |
| 2718 return super.value; |
| 2719 } |
| 2720 } |
| 2721 |
2646 class TestAccessorModel extends Observable { | 2722 class TestAccessorModel extends Observable { |
2647 @observable var value = 1; | 2723 @observable var value = 1; |
2648 var count = 0; | 2724 var count = 0; |
2649 | 2725 |
2650 @reflectable | 2726 @reflectable |
2651 get prop { | 2727 get prop { |
2652 count++; | 2728 count++; |
2653 return value; | 2729 return value; |
2654 } | 2730 } |
2655 } | 2731 } |
OLD | NEW |