OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 /** Tests for the watcher library. */ | 5 /** Tests for the watcher library. */ |
6 library watcher_test; | 6 library watcher_test; |
7 | 7 |
8 import 'dart:collection'; | 8 import 'dart:collection'; |
9 import 'package:unittest/compact_vm_config.dart'; | 9 import 'package:unittest/compact_vm_config.dart'; |
10 import 'package:unittest/unittest.dart'; | 10 import 'package:unittest/unittest.dart'; |
11 import 'package:web_ui/watcher.dart'; | 11 import 'package:web_ui/watcher.dart'; |
| 12 import 'package:logging/logging.dart'; |
| 13 import 'package:stack_trace/stack_trace.dart'; |
12 | 14 |
13 main() { | 15 main() { |
14 useCompactVMConfiguration(); | 16 useCompactVMConfiguration(); |
15 | 17 |
16 group('core', () { | 18 group('core', () { |
17 test('simple watcher ', () { | 19 test('simple watcher ', () { |
18 int x = 0; | 20 int x = 0; |
19 int valueSeen = null; | 21 int valueSeen = null; |
20 var stop = watch(() => x, expectAsync1((_) { valueSeen = x; })); | 22 var stop = watch(() => x, expectAsync1((_) { valueSeen = x; })); |
21 x = 22; | 23 x = 22; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 x = 12; | 99 x = 12; |
98 dispatch(); | 100 dispatch(); |
99 expect(oldValue, 1); | 101 expect(oldValue, 1); |
100 expect(newValue, 12); | 102 expect(newValue, 12); |
101 x = 14; | 103 x = 14; |
102 dispatch(); | 104 dispatch(); |
103 expect(oldValue, 12); | 105 expect(oldValue, 12); |
104 expect(newValue, 14); | 106 expect(newValue, 14); |
105 stop(); | 107 stop(); |
106 }); | 108 }); |
| 109 |
| 110 test('loop is detected', () { |
| 111 int x = 0; |
| 112 var oldValue; |
| 113 var newValue; |
| 114 var stop = watch(() => x, expectAsync1((e) { |
| 115 x++; |
| 116 oldValue = e.oldValue; |
| 117 newValue = e.newValue; |
| 118 }, count: maxNumIterations)); |
| 119 var subscription = Logger.root.onRecord.listen(expectAsync1((record) { |
| 120 expect(record.message, startsWith('Possible loop in watchers')); |
| 121 })); |
| 122 x = 1; |
| 123 dispatch(); |
| 124 expect(oldValue, maxNumIterations - 1); |
| 125 expect(newValue, maxNumIterations); |
| 126 stop(); |
| 127 subscription.cancel(); |
| 128 }); |
| 129 |
| 130 group('loops can be debugged', () { |
| 131 var messages; |
| 132 var subscription; |
| 133 setUp(() { |
| 134 verboseDebugMessages = true; |
| 135 messages = []; |
| 136 subscription = Logger.root.onRecord.listen((record) { |
| 137 messages.add(record.message); |
| 138 }); |
| 139 }); |
| 140 |
| 141 tearDown(() { |
| 142 subscription.cancel(); |
| 143 verboseDebugMessages = false; |
| 144 }); |
| 145 |
| 146 test('no debug name', () { |
| 147 int x = 0; |
| 148 var oldValue; |
| 149 var newValue; |
| 150 // Note: the next line number (151) is recorded in the debug messages |
| 151 var stop = watch(() => x, expectAsync1((e) { |
| 152 x++; |
| 153 oldValue = e.oldValue; |
| 154 newValue = e.newValue; |
| 155 }, count: maxNumIterations)); |
| 156 x = 1; |
| 157 dispatch(); |
| 158 expect(oldValue, maxNumIterations - 1); |
| 159 expect(newValue, maxNumIterations); |
| 160 expect(messages.length, maxNumIterations + 1); |
| 161 |
| 162 // First message contains details of the definition of a callback: |
| 163 var first = messages.first; |
| 164 expect(first, contains('defined at')); |
| 165 expect(first, contains('watcher_test.dart:151:25')); |
| 166 |
| 167 // The id is based on some global numbering, read the id, and see that |
| 168 // it is mentioned on every other message: |
| 169 var regExp = new RegExp('(\\(id: #[0-9]*\\))'); |
| 170 var match = regExp.firstMatch(first); |
| 171 expect(match, isNotNull); |
| 172 var id = match.group(1); |
| 173 for (int i = 1; i < maxNumIterations - 1; i++) { |
| 174 expect(messages[i], 'watcher updated: <unnamed> $id'); |
| 175 } |
| 176 expect(messages.last, startsWith('Possible loop in watchers')); |
| 177 stop(); |
| 178 }); |
| 179 |
| 180 test('debug name provided', () { |
| 181 readCurrentStackTrace = () { |
| 182 try { throw "" ; } catch (e, trace) { |
| 183 return new Trace.from(trace).terse.toString(); |
| 184 } |
| 185 }; |
| 186 var messages = []; |
| 187 var subscription = Logger.root.onRecord.listen((record) { |
| 188 messages.add(record.message); |
| 189 }); |
| 190 int x = 0; |
| 191 var oldValue; |
| 192 var newValue; |
| 193 // Note: the next line number (194) is recorded in the debug messages |
| 194 var stop = watch(() => x, expectAsync1((e) { |
| 195 x++; |
| 196 oldValue = e.oldValue; |
| 197 newValue = e.newValue; |
| 198 }, count: maxNumIterations), 'my-debug-name'); |
| 199 x = 1; |
| 200 dispatch(); |
| 201 expect(oldValue, maxNumIterations - 1); |
| 202 expect(newValue, maxNumIterations); |
| 203 expect(messages.length, maxNumIterations + 1); |
| 204 |
| 205 // First message contains details of the definition of a callback: |
| 206 var first = messages.first; |
| 207 expect(first, contains('defined at')); |
| 208 expect(first, contains('watcher_test.dart 194:25')); |
| 209 |
| 210 // The id is based on some global numbering, read the id, and see that |
| 211 // it is mentioned on every other message: |
| 212 var regExp = new RegExp('my-debug-name (\\(id: #[0-9]*\\))'); |
| 213 var match = regExp.firstMatch(first); |
| 214 expect(match, isNotNull); |
| 215 var id = match.group(1); |
| 216 for (int i = 1; i < maxNumIterations - 1; i++) { |
| 217 expect(messages[i], 'watcher updated: my-debug-name $id'); |
| 218 } |
| 219 expect(messages.last, startsWith('Possible loop in watchers')); |
| 220 stop(); |
| 221 }); |
| 222 }); |
107 }); | 223 }); |
108 | 224 |
109 group('fields', () { | 225 group('fields', () { |
110 test('watch changes to shallow fields', () { | 226 test('watch changes to shallow fields', () { |
111 B b = new B(3); | 227 B b = new B(3); |
112 int value = null; | 228 int value = null; |
113 var stop = watch(() => b.c, | 229 var stop = watch(() => b.c, |
114 expectAsync1((_) { value = b.c; }, count: 2)); | 230 expectAsync1((_) { value = b.c; }, count: 2)); |
115 b.c = 5; | 231 b.c = 5; |
116 dispatch(); | 232 dispatch(); |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 } | 473 } |
358 | 474 |
359 class A { | 475 class A { |
360 B b = new B(3); | 476 B b = new B(3); |
361 } | 477 } |
362 | 478 |
363 class B { | 479 class B { |
364 int c; | 480 int c; |
365 B(this.c); | 481 B(this.c); |
366 } | 482 } |
OLD | NEW |