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