| 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 custom_element_bindings_test; | 5 library custom_element_bindings_test; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:html'; | 8 import 'dart:html'; |
| 9 import 'package:mdv/mdv.dart' as mdv; | 9 import 'package:mdv/mdv.dart' as mdv; |
| 10 import 'package:observe/observe.dart'; | 10 import 'package:observe/observe.dart'; |
| 11 import 'package:unittest/html_config.dart'; | 11 import 'package:unittest/html_config.dart'; |
| 12 import 'package:unittest/unittest.dart'; | 12 import 'package:unittest/unittest.dart'; |
| 13 import 'observe_utils.dart'; | 13 import 'mdv_test_utils.dart'; |
| 14 | 14 |
| 15 main() { | 15 main() { |
| 16 mdv.initialize(); | 16 mdv.initialize(); |
| 17 useHtmlConfiguration(); | 17 useHtmlConfiguration(); |
| 18 group('Custom Element Bindings', customElementBindingsTest); | 18 group('Custom Element Bindings', customElementBindingsTest); |
| 19 } | 19 } |
| 20 | 20 |
| 21 sym(x) => new Symbol(x); | 21 sym(x) => new Symbol(x); |
| 22 | 22 |
| 23 customElementBindingsTest() { | 23 customElementBindingsTest() { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 38 testDiv.append(div); | 38 testDiv.append(div); |
| 39 | 39 |
| 40 for (var node in div.queryAll('*')) { | 40 for (var node in div.queryAll('*')) { |
| 41 if (node.isTemplate) TemplateElement.decorate(node); | 41 if (node.isTemplate) TemplateElement.decorate(node); |
| 42 } | 42 } |
| 43 | 43 |
| 44 return div; | 44 return div; |
| 45 } | 45 } |
| 46 | 46 |
| 47 | 47 |
| 48 test('override bind/unbind/unbindAll', () { | 48 observeTest('override bind/unbind/unbindAll', () { |
| 49 var element = new MyCustomElement(); | 49 var element = new MyCustomElement(); |
| 50 var model = toSymbolMap({'a': new Point(123, 444), 'b': new Monster(100)}); | 50 var model = toSymbolMap({'a': new Point(123, 444), 'b': new Monster(100)}); |
| 51 | 51 |
| 52 element.bind('my-point', model, 'a'); | 52 element.bind('my-point', model, 'a'); |
| 53 element.bind('scary-monster', model, 'b'); | 53 element.bind('scary-monster', model, 'b'); |
| 54 | 54 |
| 55 expect(element.attributes, isNot(contains('my-point'))); | 55 expect(element.attributes, isNot(contains('my-point'))); |
| 56 expect(element.attributes, isNot(contains('scary-monster'))); | 56 expect(element.attributes, isNot(contains('scary-monster'))); |
| 57 | 57 |
| 58 expect(element.myPoint, model[sym('a')]); | 58 expect(element.myPoint, model[sym('a')]); |
| 59 expect(element.scaryMonster, model[sym('b')]); | 59 expect(element.scaryMonster, model[sym('b')]); |
| 60 | 60 |
| 61 model[sym('a')] = null; | 61 model[sym('a')] = null; |
| 62 deliverChangeRecords(); | 62 performMicrotaskCheckpoint(); |
| 63 expect(element.myPoint, null); | 63 expect(element.myPoint, null); |
| 64 element.unbind('my-point'); | 64 element.unbind('my-point'); |
| 65 | 65 |
| 66 model[sym('a')] = new Point(1, 2); | 66 model[sym('a')] = new Point(1, 2); |
| 67 model[sym('b')] = new Monster(200); | 67 model[sym('b')] = new Monster(200); |
| 68 deliverChangeRecords(); | 68 performMicrotaskCheckpoint(); |
| 69 expect(element.scaryMonster, model[sym('b')]); | 69 expect(element.scaryMonster, model[sym('b')]); |
| 70 expect(element.myPoint, null, reason: 'a was unbound'); | 70 expect(element.myPoint, null, reason: 'a was unbound'); |
| 71 | 71 |
| 72 element.unbindAll(); | 72 element.unbindAll(); |
| 73 model[sym('b')] = null; | 73 model[sym('b')] = null; |
| 74 deliverChangeRecords(); | 74 performMicrotaskCheckpoint(); |
| 75 expect(element.scaryMonster.health, 200); | 75 expect(element.scaryMonster.health, 200); |
| 76 }); | 76 }); |
| 77 | 77 |
| 78 test('override attribute setter', () { | 78 observeTest('override attribute setter', () { |
| 79 var element = new WithAttrsCustomElement().real; | 79 var element = new WithAttrsCustomElement().real; |
| 80 var model = toSymbolMap({'a': 1, 'b': 2}); | 80 var model = toSymbolMap({'a': 1, 'b': 2}); |
| 81 element.bind('hidden?', model, 'a'); | 81 element.bind('hidden?', model, 'a'); |
| 82 element.bind('id', model, 'b'); | 82 element.bind('id', model, 'b'); |
| 83 | 83 |
| 84 expect(element.attributes, contains('hidden')); | 84 expect(element.attributes, contains('hidden')); |
| 85 expect(element.attributes['hidden'], ''); | 85 expect(element.attributes['hidden'], ''); |
| 86 expect(element.id, '2'); | 86 expect(element.id, '2'); |
| 87 | 87 |
| 88 model[sym('a')] = null; | 88 model[sym('a')] = null; |
| 89 deliverChangeRecords(); | 89 performMicrotaskCheckpoint(); |
| 90 expect(element.attributes, isNot(contains('hidden')), | 90 expect(element.attributes, isNot(contains('hidden')), |
| 91 reason: 'null is false-y'); | 91 reason: 'null is false-y'); |
| 92 | 92 |
| 93 model[sym('a')] = false; | 93 model[sym('a')] = false; |
| 94 deliverChangeRecords(); | 94 performMicrotaskCheckpoint(); |
| 95 expect(element.attributes, isNot(contains('hidden'))); | 95 expect(element.attributes, isNot(contains('hidden'))); |
| 96 | 96 |
| 97 model[sym('a')] = 'foo'; | 97 model[sym('a')] = 'foo'; |
| 98 // TODO(jmesserly): this is here to force an ordering between the two |
| 99 // changes. Otherwise the order depends on what order StreamController |
| 100 // chooses to fire the two listeners in. |
| 101 performMicrotaskCheckpoint(); |
| 102 |
| 98 model[sym('b')] = 'x'; | 103 model[sym('b')] = 'x'; |
| 99 deliverChangeRecords(); | 104 performMicrotaskCheckpoint(); |
| 100 expect(element.attributes, contains('hidden')); | 105 expect(element.attributes, contains('hidden')); |
| 101 expect(element.attributes['hidden'], ''); | 106 expect(element.attributes['hidden'], ''); |
| 102 expect(element.id, 'x'); | 107 expect(element.id, 'x'); |
| 103 | 108 |
| 104 expect(element.xtag.attributes.log, [ | 109 expect(element.xtag.attributes.log, [ |
| 105 ['remove', 'hidden?'], | 110 ['remove', 'hidden?'], |
| 106 ['[]=', 'hidden', ''], | 111 ['[]=', 'hidden', ''], |
| 107 ['remove', 'id'], | 112 ['remove', 'id'], |
| 108 ['[]=', 'id', '2'], | 113 ['[]=', 'id', '2'], |
| 109 ['remove', 'hidden'], | 114 ['remove', 'hidden'], |
| 110 ['remove', 'hidden'], | 115 ['remove', 'hidden'], |
| 111 ['[]=', 'hidden', ''], | 116 ['[]=', 'hidden', ''], |
| 112 ['[]=', 'id', 'x'], | 117 ['[]=', 'id', 'x'], |
| 113 ]); | 118 ]); |
| 114 }); | 119 }); |
| 115 | 120 |
| 116 test('template bind uses overridden custom element bind', () { | 121 observeTest('template bind uses overridden custom element bind', () { |
| 117 | 122 |
| 118 var model = toSymbolMap({'a': new Point(123, 444), 'b': new Monster(100)}); | 123 var model = toSymbolMap({'a': new Point(123, 444), 'b': new Monster(100)}); |
| 119 | 124 |
| 120 var div = createTestHtml('<template bind>' | 125 var div = createTestHtml('<template bind>' |
| 121 '<my-custom-element my-point="{{a}}" scary-monster="{{b}}">' | 126 '<my-custom-element my-point="{{a}}" scary-monster="{{b}}">' |
| 122 '</my-custom-element>' | 127 '</my-custom-element>' |
| 123 '</template>'); | 128 '</template>'); |
| 124 | 129 |
| 125 mdv.instanceCreated.listen((fragment) { | 130 mdv.instanceCreated.listen((fragment) { |
| 126 for (var e in fragment.queryAll('my-custom-element')) { | 131 for (var e in fragment.queryAll('my-custom-element')) { |
| 127 new MyCustomElement.attach(e); | 132 new MyCustomElement.attach(e); |
| 128 } | 133 } |
| 129 }); | 134 }); |
| 130 | 135 |
| 131 div.query('template').model = model; | 136 div.query('template').model = model; |
| 132 deliverChangeRecords(); | 137 performMicrotaskCheckpoint(); |
| 133 | 138 |
| 134 var element = div.nodes[1]; | 139 var element = div.nodes[1]; |
| 135 | 140 |
| 136 expect(element.xtag is MyCustomElement, true, | 141 expect(element.xtag is MyCustomElement, true, |
| 137 reason: '${element.xtag} should be a MyCustomElement'); | 142 reason: '${element.xtag} should be a MyCustomElement'); |
| 138 | 143 |
| 139 expect(element.xtag.myPoint, model[sym('a')]); | 144 expect(element.xtag.myPoint, model[sym('a')]); |
| 140 expect(element.xtag.scaryMonster, model[sym('b')]); | 145 expect(element.xtag.scaryMonster, model[sym('b')]); |
| 141 | 146 |
| 142 expect(element.attributes, isNot(contains('my-point'))); | 147 expect(element.attributes, isNot(contains('my-point'))); |
| 143 expect(element.attributes, isNot(contains('scary-monster'))); | 148 expect(element.attributes, isNot(contains('scary-monster'))); |
| 144 | 149 |
| 145 model[sym('a')] = null; | 150 model[sym('a')] = null; |
| 146 deliverChangeRecords(); | 151 performMicrotaskCheckpoint(); |
| 147 expect(element.xtag.myPoint, null); | 152 expect(element.xtag.myPoint, null); |
| 148 | 153 |
| 149 div.query('template').model = null; | 154 div.query('template').model = null; |
| 150 deliverChangeRecords(); | 155 performMicrotaskCheckpoint(); |
| 151 | 156 |
| 152 expect(element.parentNode, null, reason: 'element was detached'); | 157 expect(element.parentNode, null, reason: 'element was detached'); |
| 153 | 158 |
| 154 model[sym('a')] = new Point(1, 2); | 159 model[sym('a')] = new Point(1, 2); |
| 155 model[sym('b')] = new Monster(200); | 160 model[sym('b')] = new Monster(200); |
| 156 deliverChangeRecords(); | 161 performMicrotaskCheckpoint(); |
| 157 | 162 |
| 158 expect(element.xtag.myPoint, null, reason: 'model was unbound'); | 163 expect(element.xtag.myPoint, null, reason: 'model was unbound'); |
| 159 expect(element.xtag.scaryMonster.health, 100, reason: 'model was unbound'); | 164 expect(element.xtag.scaryMonster.health, 100, reason: 'model was unbound'); |
| 160 }); | 165 }); |
| 161 | 166 |
| 162 } | 167 } |
| 163 | 168 |
| 164 class Monster { | 169 class Monster { |
| 165 int health; | 170 int health; |
| 166 Monster(this.health); | 171 Monster(this.health); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 } | 283 } |
| 279 | 284 |
| 280 void clear() => _map.clear(); | 285 void clear() => _map.clear(); |
| 281 void forEach(void f(K key, V value)) => _map.forEach(f); | 286 void forEach(void f(K key, V value)) => _map.forEach(f); |
| 282 Iterable<K> get keys => _map.keys; | 287 Iterable<K> get keys => _map.keys; |
| 283 Iterable<V> get values => _map.values; | 288 Iterable<V> get values => _map.values; |
| 284 int get length => _map.length; | 289 int get length => _map.length; |
| 285 bool get isEmpty => _map.isEmpty; | 290 bool get isEmpty => _map.isEmpty; |
| 286 bool get isNotEmpty => _map.isNotEmpty; | 291 bool get isNotEmpty => _map.isNotEmpty; |
| 287 } | 292 } |
| OLD | NEW |