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 'package:expect/expect.dart'; |
| 6 import 'package:async_helper/async_helper.dart'; |
| 7 import 'dart:async'; |
| 8 |
| 9 main() { |
| 10 asyncStart(); |
| 11 testNoChange(); |
| 12 testWithReplacement(); |
| 13 asyncEnd(); |
| 14 } |
| 15 |
| 16 class MockStack implements StackTrace { |
| 17 final int id; |
| 18 const MockStack(this.id); |
| 19 String toString() => "MocKStack($id)"; |
| 20 } |
| 21 const stack1 = const MockStack(1); |
| 22 const stack2 = const MockStack(2); |
| 23 |
| 24 class SomeError implements Error { |
| 25 final int id; |
| 26 const SomeError(this.id); |
| 27 StackTrace get stackTrace => stack2; |
| 28 String toString() => "SomeError($id)"; |
| 29 } |
| 30 |
| 31 const error1 = const SomeError(1); |
| 32 const error2 = const SomeError(2); |
| 33 |
| 34 void expectError(e, s) { |
| 35 // Remember one asyncStart per use of this callback. |
| 36 Expect.identical(error1, e); |
| 37 Expect.identical(stack1, s); |
| 38 asyncEnd(); |
| 39 } |
| 40 |
| 41 void expectErrorOnly(e, s) { |
| 42 // Remember one asyncStart per use of this callback. |
| 43 Expect.identical(error1, e); |
| 44 asyncEnd(); |
| 45 } |
| 46 |
| 47 AsyncError replace(self, parent, zone, e, s) { |
| 48 if (e == "ignore") return null; // For testing handleError throwing. |
| 49 Expect.identical(error1, e); // Ensure replacement only called once |
| 50 return new AsyncError(error2, stack2); |
| 51 } |
| 52 |
| 53 var replaceZoneSpec = new ZoneSpecification(errorCallback: replace); |
| 54 |
| 55 // Expectation after replacing. |
| 56 void expectReplaced(e, s) { |
| 57 Expect.identical(error2, e); |
| 58 Expect.identical(stack2, s); |
| 59 asyncEnd(); |
| 60 } |
| 61 |
| 62 |
| 63 void testProgrammaticErrors(expectError) { |
| 64 { |
| 65 asyncStart(); |
| 66 Completer c = new Completer(); |
| 67 c.future.catchError(expectError); |
| 68 c.completeError(error1, stack1); |
| 69 } |
| 70 |
| 71 { |
| 72 asyncStart(); |
| 73 StreamController controller = new StreamController(); |
| 74 controller.stream.listen(null, onError: expectError, cancelOnError: true); |
| 75 controller.addError(error1, stack1); |
| 76 } |
| 77 |
| 78 { |
| 79 asyncStart(); |
| 80 StreamController controller = new StreamController(sync: true); |
| 81 controller.stream.listen(null, onError: expectError, cancelOnError: true); |
| 82 controller.addError(error1, stack1); |
| 83 } |
| 84 |
| 85 { |
| 86 asyncStart(); |
| 87 StreamController controller = new StreamController.broadcast(); |
| 88 controller.stream.listen(null, onError: expectError, cancelOnError: true); |
| 89 controller.addError(error1, stack1); |
| 90 } |
| 91 |
| 92 { |
| 93 asyncStart(); |
| 94 StreamController controller = new StreamController.broadcast(sync: true); |
| 95 controller.stream.listen(null, onError: expectError, cancelOnError: true); |
| 96 controller.addError(error1, stack1); |
| 97 } |
| 98 |
| 99 { |
| 100 asyncStart(); |
| 101 StreamController controller = new StreamController(); |
| 102 controller.stream.asBroadcastStream().listen( |
| 103 null, onError: expectError, cancelOnError: true); |
| 104 controller.addError(error1, stack1); |
| 105 } |
| 106 |
| 107 { |
| 108 asyncStart(); |
| 109 StreamController controller = new StreamController(sync: true); |
| 110 controller.stream.asBroadcastStream().listen( |
| 111 null, onError: expectError, cancelOnError: true); |
| 112 controller.addError(error1, stack1); |
| 113 } |
| 114 |
| 115 { |
| 116 asyncStart(); |
| 117 Future f = new Future.error(error1, stack1); |
| 118 f.catchError(expectError); |
| 119 } |
| 120 } |
| 121 |
| 122 void testThrownErrors(expectErrorOnly) { |
| 123 // Throw error in non-registered callback. |
| 124 { |
| 125 asyncStart(); |
| 126 Future f = new Future(() => throw error1); |
| 127 f.catchError(expectErrorOnly); |
| 128 } |
| 129 |
| 130 { |
| 131 asyncStart(); |
| 132 Future f = new Future.microtask(() => throw error1); |
| 133 f.catchError(expectErrorOnly); |
| 134 } |
| 135 |
| 136 { |
| 137 asyncStart(); |
| 138 Future f = new Future.sync(() => throw error1); |
| 139 f.catchError(expectErrorOnly); |
| 140 } |
| 141 |
| 142 { |
| 143 asyncStart(); |
| 144 StreamController controller = new StreamController(); |
| 145 controller.stream.map((x) => throw error1).listen( |
| 146 null, onError: expectErrorOnly, cancelOnError: true); |
| 147 controller.add(null); |
| 148 } |
| 149 |
| 150 { |
| 151 asyncStart(); |
| 152 StreamController controller = new StreamController(); |
| 153 controller.stream.where((x) => throw error1).listen( |
| 154 null, onError: expectErrorOnly, cancelOnError: true); |
| 155 controller.add(null); |
| 156 } |
| 157 |
| 158 { |
| 159 asyncStart(); |
| 160 StreamController controller = new StreamController(); |
| 161 controller.stream.forEach((x) => throw error1).catchError(expectErrorOnly); |
| 162 controller.add(null); |
| 163 } |
| 164 |
| 165 { |
| 166 asyncStart(); |
| 167 StreamController controller = new StreamController(); |
| 168 controller.stream.expand((x) => throw error1).listen( |
| 169 null, onError: expectErrorOnly, cancelOnError: true); |
| 170 controller.add(null); |
| 171 } |
| 172 |
| 173 { |
| 174 asyncStart(); |
| 175 StreamController controller = new StreamController(); |
| 176 controller.stream.asyncMap((x) => throw error1).listen( |
| 177 null, onError: expectErrorOnly, cancelOnError: true); |
| 178 controller.add(null); |
| 179 } |
| 180 |
| 181 { |
| 182 asyncStart(); |
| 183 StreamController controller = new StreamController(); |
| 184 controller.stream.asyncExpand((x) => throw error1).listen( |
| 185 null, onError: expectErrorOnly, cancelOnError: true); |
| 186 controller.add(null); |
| 187 } |
| 188 |
| 189 { |
| 190 asyncStart(); |
| 191 StreamController controller = new StreamController(); |
| 192 controller.stream.handleError((e, s) => throw error1).listen( |
| 193 null, onError: expectErrorOnly, cancelOnError: true); |
| 194 controller.addError("ignore", null); |
| 195 } |
| 196 |
| 197 { |
| 198 asyncStart(); |
| 199 StreamController controller = new StreamController(); |
| 200 controller.stream.skipWhile((x) => throw error1).listen( |
| 201 null, onError: expectErrorOnly, cancelOnError: true); |
| 202 controller.add(null); |
| 203 } |
| 204 |
| 205 { |
| 206 asyncStart(); |
| 207 StreamController controller = new StreamController(); |
| 208 controller.stream.takeWhile((x) => throw error1).listen( |
| 209 null, onError: expectErrorOnly, cancelOnError: true); |
| 210 controller.add(null); |
| 211 } |
| 212 |
| 213 { |
| 214 asyncStart(); |
| 215 StreamController controller = new StreamController(); |
| 216 controller.stream.every((x) => throw error1).catchError(expectErrorOnly); |
| 217 controller.add(null); |
| 218 } |
| 219 |
| 220 { |
| 221 asyncStart(); |
| 222 StreamController controller = new StreamController(); |
| 223 controller.stream.any((x) => throw error1).catchError(expectErrorOnly); |
| 224 controller.add(null); |
| 225 } |
| 226 |
| 227 { |
| 228 asyncStart(); |
| 229 StreamController controller = new StreamController(); |
| 230 controller.stream.firstWhere((x) => throw error1) |
| 231 .catchError(expectErrorOnly); |
| 232 controller.add(null); |
| 233 } |
| 234 |
| 235 { |
| 236 asyncStart(); |
| 237 StreamController controller = new StreamController(); |
| 238 controller.stream.lastWhere((x) => throw error1) |
| 239 .catchError(expectErrorOnly); |
| 240 controller.add(null); |
| 241 } |
| 242 |
| 243 { |
| 244 asyncStart(); |
| 245 StreamController controller = new StreamController(); |
| 246 controller.stream.singleWhere((x) => throw error1) |
| 247 .catchError(expectErrorOnly); |
| 248 controller.add(null); |
| 249 } |
| 250 |
| 251 { |
| 252 asyncStart(); |
| 253 StreamController controller = new StreamController(); |
| 254 controller.stream.reduce((x, y) => throw error1) |
| 255 .catchError(expectErrorOnly); |
| 256 controller.add(null); |
| 257 controller.add(null); |
| 258 } |
| 259 |
| 260 { |
| 261 asyncStart(); |
| 262 StreamController controller = new StreamController(); |
| 263 controller.stream.fold(null, (x, y) => throw error1) |
| 264 .catchError(expectErrorOnly); |
| 265 controller.add(null); |
| 266 } |
| 267 } |
| 268 |
| 269 |
| 270 testNoChange() { |
| 271 void testTransparent() { |
| 272 testProgrammaticErrors(expectError); |
| 273 testThrownErrors(expectErrorOnly); |
| 274 } |
| 275 |
| 276 // Run directly. |
| 277 testTransparent(); |
| 278 |
| 279 // Run in a zone that doesn't change callback. |
| 280 runZoned(testTransparent, |
| 281 zoneSpecification: |
| 282 new ZoneSpecification(handleUncaughtError: (s,p,z,e,t){})); |
| 283 |
| 284 // Run in zone that delegates to root zone |
| 285 runZoned(testTransparent, |
| 286 zoneSpecification: new ZoneSpecification( |
| 287 errorCallback: (s,p,z,e,t) => p.errorCallback(z, e, t))); |
| 288 |
| 289 // Run in a zone that returns null from the callback. |
| 290 runZoned(testTransparent, |
| 291 zoneSpecification: |
| 292 new ZoneSpecification(errorCallback: (s,p,z,e,t) => null)); |
| 293 |
| 294 // Run in zone that returns same values. |
| 295 runZoned(testTransparent, |
| 296 zoneSpecification: new ZoneSpecification( |
| 297 errorCallback: (s,p,z,e,t) => new AsyncError(e, t))); |
| 298 |
| 299 // Run in zone that returns null, inside zone that does replacement. |
| 300 runZoned(() { |
| 301 runZoned(testTransparent, |
| 302 zoneSpecification: |
| 303 new ZoneSpecification(errorCallback: (s,p,z,e,t)=>null)); |
| 304 }, zoneSpecification: replaceZoneSpec); |
| 305 } |
| 306 |
| 307 |
| 308 void testWithReplacement() { |
| 309 void testReplaced() { |
| 310 testProgrammaticErrors(expectReplaced); |
| 311 testThrownErrors(expectReplaced); |
| 312 } |
| 313 // Zone which replaces errors. |
| 314 runZoned(testReplaced, zoneSpecification: replaceZoneSpec); |
| 315 |
| 316 // Nested zone, only innermost gets to act. |
| 317 runZoned(() { |
| 318 runZoned(testReplaced, zoneSpecification: replaceZoneSpec); |
| 319 }, zoneSpecification: replaceZoneSpec); |
| 320 |
| 321 // Use delegation to parent which replaces. |
| 322 runZoned(() { |
| 323 runZoned(testReplaced, |
| 324 zoneSpecification: new ZoneSpecification( |
| 325 errorCallback: (s,p,z,e,t) => p.errorCallback(z,e,t))); |
| 326 }, zoneSpecification: replaceZoneSpec); |
| 327 } |
OLD | NEW |