OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2014, 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 import 'dart:async'; |
| 6 import 'dart:html'; |
| 7 import 'package:unittest/unittest.dart'; |
| 8 import 'package:unittest/html_config.dart'; |
| 9 import 'package:polymer/polymer.dart'; |
| 10 |
| 11 class XAttrPublish extends PolymerElement { |
| 12 XAttrPublish.created() : super.created(); |
| 13 |
| 14 @PublishedProperty(reflect: false) |
| 15 String nog = ''; |
| 16 } |
| 17 |
| 18 class XFoo extends PolymerElement { |
| 19 XFoo.created() : super.created(); |
| 20 |
| 21 @PublishedProperty(reflect: true) var foo = ''; |
| 22 @PublishedProperty(reflect: true) String baz = ''; |
| 23 |
| 24 @PublishedProperty(reflect: true) var def1, def2; |
| 25 } |
| 26 |
| 27 class XBar extends XFoo { |
| 28 XBar.created() : super.created(); |
| 29 |
| 30 @PublishedProperty(reflect: true) int zot = 3; |
| 31 @PublishedProperty(reflect: true) bool zim = false; |
| 32 @PublishedProperty(reflect: true) String str = 'str'; |
| 33 @PublishedProperty(reflect: true) Object obj; |
| 34 } |
| 35 |
| 36 class XZot extends XBar { |
| 37 // Dart note: trying to make this roughly equivalent to the JS |
| 38 @PublishedProperty(reflect: false) int get zot => super.zot; |
| 39 @PublishedProperty(reflect: false) set zot(int x) { |
| 40 super.zot = x; |
| 41 } |
| 42 |
| 43 XZot.created() : super.created() { |
| 44 zot = 2; |
| 45 str = 'str2'; |
| 46 } |
| 47 } |
| 48 |
| 49 class XCompose extends PolymerElement { |
| 50 XCompose.created() : super.created(); |
| 51 |
| 52 @observable bool zim = false; |
| 53 } |
| 54 |
| 55 Future onAttributeChange(Element node) { |
| 56 var completer = new Completer(); |
| 57 new MutationObserver((records, observer) { |
| 58 observer.disconnect(); |
| 59 completer.complete(); |
| 60 })..observe(node, attributes: true); |
| 61 scheduleMicrotask(Observable.dirtyCheck); |
| 62 return completer.future; |
| 63 } |
| 64 |
| 65 main() => initPolymer().then((zone) => zone.run(() { |
| 66 useHtmlConfiguration(); |
| 67 |
| 68 // Most tests use @CustomTag, here we test out the impertive register: |
| 69 Polymer.register('x-foo', XFoo); |
| 70 Polymer.register('x-bar', XBar); |
| 71 Polymer.register('x-zot', XZot); |
| 72 Polymer.register('x-compose', XCompose); |
| 73 Polymer.register('x-attr-publish', XAttrPublish); |
| 74 |
| 75 setUp(() => Polymer.onReady); |
| 76 |
| 77 test('property to attribute reflection', () { |
| 78 var xbasic = querySelector('x-basic'); |
| 79 expect(xbasic.getAttribute('nog'), null, |
| 80 reason: 'property published with `attributes` has correct initial ' |
| 81 'value'); |
| 82 xbasic.setAttribute('nog', 'hi'); |
| 83 expect(xbasic.getAttribute('nog'), 'hi', |
| 84 reason: 'deserialization of property published via `attributes`'); |
| 85 |
| 86 var xattrpublish = querySelector('x-attr-publish'); |
| 87 expect(xattrpublish.nog, '', |
| 88 reason: 'property published with `attributes` has correct initial ' |
| 89 'value'); |
| 90 xattrpublish.setAttribute('nog', 'hi'); |
| 91 expect(xattrpublish.nog, 'hi', |
| 92 reason: 'deserialization of property published via `attributes`'); |
| 93 |
| 94 var xcompose = querySelector('x-compose'); |
| 95 var xfoo = querySelector('x-foo'); |
| 96 expect(xfoo.foo, '', |
| 97 reason: 'property published with info object has correct initial ' |
| 98 'value'); |
| 99 var xbar = querySelector('x-bar'); |
| 100 expect(xbar.zim, false, |
| 101 reason: 'property published with info object has correct initial ' |
| 102 'value'); |
| 103 expect(xbar.foo, '', |
| 104 reason: 'property published with info object has correct initial ' |
| 105 'value'); |
| 106 var xzot = querySelector('x-zot'); |
| 107 xfoo.foo = 5; |
| 108 xfoo.attributes['def1'] = '15'; |
| 109 xfoo.def2 = 15; |
| 110 |
| 111 // Dart note: our test here is more async than JS until we change |
| 112 // Polymer.dart bindings to work like observe.js "bindToInstance". |
| 113 return onAttributeChange(xfoo).then((_) { |
| 114 expect(xcompose.$['bar'].attributes.containsKey('zim'), false, |
| 115 reason: 'attribute bound to property updates when binding is made'); |
| 116 |
| 117 expect(xfoo.attributes['def2'], '15', |
| 118 reason: 'default valued published property reflects to attr'); |
| 119 |
| 120 expect(xfoo.def1, 15, |
| 121 reason: 'attr updates default valued published property'); |
| 122 |
| 123 expect('${xfoo.foo}', xfoo.attributes['foo'], |
| 124 reason: 'attribute reflects property as string'); |
| 125 xfoo.attributes['foo'] = '27'; |
| 126 // TODO(jmesserly): why is JS leaving this as a String? From the code it |
| 127 // looks like it should use the type of 5 and parse it as a number. |
| 128 expect('${xfoo.foo}', xfoo.attributes['foo'], |
| 129 reason: 'property reflects attribute'); |
| 130 // |
| 131 xfoo.baz = 'Hello'; |
| 132 }).then((_) => onAttributeChange(xfoo)).then((_) { |
| 133 expect(xfoo.baz, xfoo.attributes['baz'], |
| 134 reason: 'attribute reflects property'); |
| 135 // |
| 136 xbar.foo = 'foo!'; |
| 137 xbar.zot = 27; |
| 138 xbar.zim = true; |
| 139 xbar.str = 'str!'; |
| 140 xbar.obj = {'hello': 'world'}; |
| 141 }).then((_) => onAttributeChange(xbar)).then((_) { |
| 142 expect(xbar.foo, xbar.attributes['foo'], |
| 143 reason: 'inherited published property is reflected'); |
| 144 expect('${xbar.zot}', xbar.attributes['zot'], |
| 145 reason: 'attribute reflects property as number'); |
| 146 expect(xbar.attributes['zim'], '', |
| 147 reason: 'attribute reflects true valued boolean property as ' |
| 148 'having attribute'); |
| 149 expect(xbar.str, xbar.attributes['str'], |
| 150 reason: 'attribute reflects property as published string'); |
| 151 expect(xbar.attributes.containsKey('obj'), false, |
| 152 reason: 'attribute does not reflect object property'); |
| 153 xbar.attributes['zim'] = 'false'; |
| 154 xbar.attributes['foo'] = 'foo!!'; |
| 155 xbar.attributes['zot'] = '54'; |
| 156 xbar.attributes['str'] = 'str!!'; |
| 157 xbar.attributes['obj'] = "{'hello': 'world'}"; |
| 158 expect(xbar.foo, xbar.attributes['foo'], |
| 159 reason: 'property reflects attribute as string'); |
| 160 expect(xbar.zot, 54, reason: 'property reflects attribute as number'); |
| 161 expect(xbar.zim, false, reason: 'property reflects attribute as boolean'); |
| 162 expect(xbar.str, 'str!!', |
| 163 reason: 'property reflects attribute as published string'); |
| 164 expect(xbar.obj, {'hello': 'world'}, |
| 165 reason: 'property reflects attribute as object'); |
| 166 xbar.zim = false; |
| 167 }).then((_) => onAttributeChange(xbar)).then((_) { |
| 168 expect(xbar.attributes.containsKey('zim'), false, |
| 169 reason: 'attribute reflects false valued boolean property as NOT ' |
| 170 'having attribute'); |
| 171 xbar.obj = 'hi'; |
| 172 }).then((_) => onAttributeChange(xbar)).then((_) { |
| 173 expect(xbar.attributes['obj'], 'hi', |
| 174 reason: 'reflect property based on current type'); |
| 175 |
| 176 expect(xzot.str, 'str2'); |
| 177 expect(xzot.zot, 2); |
| 178 xzot.str = 'hello'; |
| 179 xzot.zot = 5; |
| 180 }).then((_) => onAttributeChange(xzot)).then((_) { |
| 181 expect(xzot.attributes['str'], xzot.str); |
| 182 // TODO(jmesserly): the JS test seems backwards of the description text. |
| 183 // Is it because it doesn't do "WebComponents.flush()"? |
| 184 expect(xzot.attributes['zot'], '5', |
| 185 reason: 'extendee reflect false not honored'); |
| 186 }); |
| 187 }); |
| 188 })); |
OLD | NEW |