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

Side by Side Diff: pkg/polymer_expressions/test/bindings_test.dart

Issue 304223004: Remove Comprehension type in polymer expressions (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 6 months 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 bindings_test; 5 library bindings_test;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:html'; 8 import 'dart:html';
9 9
10 import 'package:observe/observe.dart'; 10 import 'package:observe/observe.dart';
11 import 'package:observe/mirrors_used.dart'; // make test smaller. 11 import 'package:observe/mirrors_used.dart'; // make test smaller.
12 import 'package:observe/src/dirty_check.dart' show dirtyCheckZone; 12 import 'package:observe/src/dirty_check.dart' show dirtyCheckZone;
13 import 'package:polymer_expressions/polymer_expressions.dart'; 13 import 'package:polymer_expressions/polymer_expressions.dart';
14 import 'package:template_binding/template_binding.dart' show templateBind; 14 import 'package:template_binding/template_binding.dart' show templateBind;
15 import 'package:unittest/html_config.dart'; 15 import 'package:unittest/html_config.dart';
16 import 'package:unittest/unittest.dart'; 16 import 'package:unittest/unittest.dart';
17 17
18 var testDiv;
19
18 main() => dirtyCheckZone().run(() { 20 main() => dirtyCheckZone().run(() {
19 useHtmlConfiguration(); 21 useHtmlConfiguration();
20 22
21 group('bindings', () { 23 group('bindings', () {
22 var stop = null; 24 var stop = null;
23 var testDiv;
24 setUp(() { 25 setUp(() {
25 document.body.append(testDiv = new DivElement()); 26 document.body.append(testDiv = new DivElement());
26 }); 27 });
27 28
28 tearDown(() { 29 tearDown(() {
29 testDiv.remove(); 30 testDiv.remove();
30 testDiv = null; 31 testDiv = null;
31 }); 32 });
32 33
33 test('should update binding when data changes', () { 34 test('should update binding when data changes', () {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 new PolymerExpressions())); 70 new PolymerExpressions()));
70 71
71 return _nextMicrotask(null); 72 return _nextMicrotask(null);
72 }, onError: (e) { 73 }, onError: (e) {
73 expect('$e', startsWith("Error evaluating expression 'foo':")); 74 expect('$e', startsWith("Error evaluating expression 'foo':"));
74 completer.complete(true); 75 completer.complete(true);
75 }); 76 });
76 return completer.future; 77 return completer.future;
77 }); 78 });
78 79
79 test('should preserve the cursor position', () {
80 var model = new NotifyModel('abcde');
81 var template = templateBind(new Element.html(
82 '<template><input id="i1" value={{x}}></template>'));
83 testDiv.append(template.createInstance(model, new PolymerExpressions()));
84
85 var el;
86 return new Future(() {
87 el = testDiv.query("#i1");
88 var subscription = el.onInput.listen(expectAsync((_) {}, count: 1));
89 el.focus();
90
91 expect(el.value, 'abcde');
92 expect(model.x, 'abcde');
93
94 el.selectionStart = 3;
95 el.selectionEnd = 3;
96 expect(el.selectionStart, 3);
97 expect(el.selectionEnd, 3);
98
99 el.value = 'abc de';
100 // Updating the input value programatically (even to the same value in
101 // Chrome) loses the selection position.
102 expect(el.selectionStart, 6);
103 expect(el.selectionEnd, 6);
104
105 el.selectionStart = 4;
106 el.selectionEnd = 4;
107
108 expect(model.x, 'abcde');
109 el.dispatchEvent(new Event('input'));
110 expect(model.x, 'abc de');
111 expect(el.value, 'abc de');
112
113 // But propagating observable values through reassign the value and
114 // selection will be preserved.
115 expect(el.selectionStart, 4);
116 expect(el.selectionEnd, 4);
117 subscription.cancel();
118 }).then(_nextMicrotask).then((_) {
119 // Nothing changes on the next micro task.
120 expect(el.selectionStart, 4);
121 expect(el.selectionEnd, 4);
122 }).then((_) => window.animationFrame).then((_) {
123 // ... or on the next animation frame.
124 expect(el.selectionStart, 4);
125 expect(el.selectionEnd, 4);
126 }).then(_afterTimeout).then((_) {
127 // ... or later.
128 expect(el.selectionStart, 4);
129 expect(el.selectionEnd, 4);
130 });
131 });
132
133 test('detects changes to ObservableList', () { 80 test('detects changes to ObservableList', () {
134 var list = new ObservableList.from([1, 2, 3]); 81 var list = new ObservableList.from([1, 2, 3]);
135 var template = templateBind(new Element.html( 82 var template = templateBind(new Element.html(
136 '<template>{{x[1]}}</template>')); 83 '<template>{{x[1]}}</template>'));
137 var model = new NotifyModel(list); 84 var model = new NotifyModel(list);
138 testDiv.append(template.createInstance(model, new PolymerExpressions())); 85 testDiv.append(template.createInstance(model, new PolymerExpressions()));
139 86
140 return new Future(() { 87 return new Future(() {
141 expect(testDiv.text, '2'); 88 expect(testDiv.text, '2');
142 list[1] = 10; 89 list[1] = 10;
(...skipping 27 matching lines...) Expand all
170 expect(testDiv.text, 'a:1,b:2,'); 117 expect(testDiv.text, 'a:1,b:2,');
171 map.remove('b'); 118 map.remove('b');
172 map['c'] = 3; 119 map['c'] = 3;
173 }).then(_nextMicrotask).then((_) { 120 }).then(_nextMicrotask).then((_) {
174 expect(testDiv.text, 'a:1,c:3,'); 121 expect(testDiv.text, 'a:1,c:3,');
175 map['a'] = 4; 122 map['a'] = 4;
176 }).then(_nextMicrotask).then((_) { 123 }).then(_nextMicrotask).then((_) {
177 expect(testDiv.text, 'a:4,c:3,'); 124 expect(testDiv.text, 'a:4,c:3,');
178 }); 125 });
179 }); 126 });
127
128 // TODO(sigmund): enable this test (issue 19105)
129 // _cursorPositionTest(false);
130 _cursorPositionTest(true);
131
132 // Regression tests for issue 18792.
133 for (var usePolymer in [true, false]) {
134 // We run these tests both with PolymerExpressions and with the default
135 // delegate to ensure the results are consistent. The expressions on these
136 // tests use syntax common to both delegates.
137 var name = usePolymer ? 'polymer-expressions' : 'default';
138 group('$name delegate', () {
139 // Use <option template repeat="{{y}}" value="{{}}">item {{}}
140 _initialSelectTest('{{y}}', '{{}}', usePolymer);
141 _updateSelectTest('{{y}}', '{{}}', usePolymer);
142 });
143 }
144
145 group('polymer-expressions delegate, polymer syntax', () {
146 // Use <option template repeat="{{i in y}}" value="{{i}}">item {{i}}
147 _initialSelectTest('{{i in y}}', '{{i}}', true);
148 _updateSelectTest('{{i in y}}', '{{i}}', true);
149 });
180 }); 150 });
181 }); 151 });
182 152
153
154 _cursorPositionTest(bool usePolymer) {
155 test('should preserve the cursor position', () {
Siggi Cherem (dart-lang) 2014/05/30 21:36:03 this test is unchanged, just moved down and change
156 var model = new NotifyModel('abcde');
157 var template = templateBind(new Element.html(
158 '<template><input id="i1" value={{x}}></template>'));
159 var delegate = usePolymer ? new PolymerExpressions() : null;
160 testDiv.append(template.createInstance(model, delegate));
161
162 var el;
163 return new Future(() {
164 el = testDiv.query("#i1");
165 var subscription = el.onInput.listen(expectAsync((_) {}, count: 1));
166 el.focus();
167
168 expect(el.value, 'abcde');
169 expect(model.x, 'abcde');
170
171 el.selectionStart = 3;
172 el.selectionEnd = 3;
173 expect(el.selectionStart, 3);
174 expect(el.selectionEnd, 3);
175
176 el.value = 'abc de';
177 // Updating the input value programatically (even to the same value in
178 // Chrome) loses the selection position.
179 expect(el.selectionStart, 6);
180 expect(el.selectionEnd, 6);
181
182 el.selectionStart = 4;
183 el.selectionEnd = 4;
184
185 expect(model.x, 'abcde');
186 el.dispatchEvent(new Event('input'));
187 expect(model.x, 'abc de');
188 expect(el.value, 'abc de');
189
190 // But propagating observable values through reassign the value and
191 // selection will be preserved.
192 expect(el.selectionStart, 4);
193 expect(el.selectionEnd, 4);
194 subscription.cancel();
195 }).then(_nextMicrotask).then((_) {
196 // Nothing changes on the next micro task.
197 expect(el.selectionStart, 4);
198 expect(el.selectionEnd, 4);
199 }).then((_) => window.animationFrame).then((_) {
200 // ... or on the next animation frame.
201 expect(el.selectionStart, 4);
202 expect(el.selectionEnd, 4);
203 }).then(_afterTimeout).then((_) {
204 // ... or later.
205 expect(el.selectionStart, 4);
206 expect(el.selectionEnd, 4);
207 });
208 });
209 }
210
211 _initialSelectTest(String repeatExp, String valueExp, bool usePolymer) {
212 test('initial select value is set correctly', () {
213 var list = const ['a', 'b'];
214 var template = templateBind(new Element.html('<template>'
215 '<select value="{{x}}">'
216 '<option template repeat="$repeatExp" value="$valueExp">item $valueExp'
217 '</option></select></template>',
218 treeSanitizer: _nullTreeSanitizer));
219 var model = new NotifyModel('b', list);
220 var delegate = usePolymer ? new PolymerExpressions() : null;
221 testDiv.append(template.createInstance(model, delegate));
222
223 expect(testDiv.querySelector('select').value, 'b');
224 return new Future(() {
225 expect(model.x, 'b');
226 expect(testDiv.querySelector('select').value, 'b');
227 });
228 });
229 }
230
231 _updateSelectTest(String repeatExp, String valueExp, bool usePolymer) {
232 test('updates to select value propagate correctly', () {
233 var list = const ['a', 'b'];
234 var template = templateBind(new Element.html('<template>'
235 '<select value="{{x}}">'
236 '<option template repeat="$repeatExp" value="$valueExp">item $valueExp'
237 '</option></select></template>',
238 treeSanitizer: _nullTreeSanitizer));
239 var model = new NotifyModel('a', list);
240 var delegate = usePolymer ? new PolymerExpressions() : null;
241 testDiv.append(template.createInstance(model, delegate));
242
243 expect(testDiv.querySelector('select').value, 'a');
244 return new Future(() {
245 expect(testDiv.querySelector('select').value, 'a');
246 model.x = 'b';
247 }).then(_nextMicrotask).then((_) {
248 expect(testDiv.querySelector('select').value, 'b');
249 });
250 });
251 }
252
183 _nextMicrotask(_) => new Future(() {}); 253 _nextMicrotask(_) => new Future(() {});
184 _afterTimeout(_) => new Future.delayed(new Duration(milliseconds: 30), () {}); 254 _afterTimeout(_) => new Future.delayed(new Duration(milliseconds: 30), () {});
185 255
186 @reflectable 256 @reflectable
187 class NotifyModel extends ChangeNotifier { 257 class NotifyModel extends ChangeNotifier {
188 var _x; 258 var _x;
189 NotifyModel([this._x]); 259 var _y;
260 NotifyModel([this._x, this._y]);
190 261
191 get x => _x; 262 get x => _x;
192 set x(value) { 263 set x(value) {
193 _x = notifyPropertyChange(#x, _x, value); 264 _x = notifyPropertyChange(#x, _x, value);
194 } 265 }
266
267 get y => _y;
268 set y(value) {
269 _y = notifyPropertyChange(#y, _y, value);
270 }
195 } 271 }
272
273 class _NullTreeSanitizer implements NodeTreeSanitizer {
274 void sanitizeTree(Node node) {}
275 }
276 final _nullTreeSanitizer = new _NullTreeSanitizer();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698