| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 import "dart:async"; | |
| 6 import "dart:collection"; | |
| 7 | |
| 8 import "package:async/async.dart"; | |
| 9 import "package:stack_trace/stack_trace.dart"; | |
| 10 import "package:test/test.dart"; | |
| 11 | |
| 12 void main() { | |
| 13 var stack = new Trace.current(); | |
| 14 | |
| 15 test("create result value", () { | |
| 16 Result<int> result = new Result<int>.value(42); | |
| 17 expect(result.isValue, isTrue); | |
| 18 expect(result.isError, isFalse); | |
| 19 ValueResult value = result.asValue; | |
| 20 expect(value.value, equals(42)); | |
| 21 }); | |
| 22 | |
| 23 test("create result value 2", () { | |
| 24 Result<int> result = new ValueResult<int>(42); | |
| 25 expect(result.isValue, isTrue); | |
| 26 expect(result.isError, isFalse); | |
| 27 ValueResult<int> value = result.asValue; | |
| 28 expect(value.value, equals(42)); | |
| 29 }); | |
| 30 | |
| 31 test("create result error", () { | |
| 32 Result<bool> result = new Result<bool>.error("BAD", stack); | |
| 33 expect(result.isValue, isFalse); | |
| 34 expect(result.isError, isTrue); | |
| 35 ErrorResult error = result.asError; | |
| 36 expect(error.error, equals("BAD")); | |
| 37 expect(error.stackTrace, same(stack)); | |
| 38 }); | |
| 39 | |
| 40 test("create result error 2", () { | |
| 41 Result<bool> result = new ErrorResult("BAD", stack); | |
| 42 expect(result.isValue, isFalse); | |
| 43 expect(result.isError, isTrue); | |
| 44 ErrorResult error = result.asError; | |
| 45 expect(error.error, equals("BAD")); | |
| 46 expect(error.stackTrace, same(stack)); | |
| 47 }); | |
| 48 | |
| 49 test("create result error no stack", () { | |
| 50 Result<bool> result = new Result<bool>.error("BAD"); | |
| 51 expect(result.isValue, isFalse); | |
| 52 expect(result.isError, isTrue); | |
| 53 ErrorResult error = result.asError; | |
| 54 expect(error.error, equals("BAD")); | |
| 55 expect(error.stackTrace, isNull); | |
| 56 }); | |
| 57 | |
| 58 test("complete with value", () { | |
| 59 Result<int> result = new ValueResult<int>(42); | |
| 60 var c = new Completer<int>(); | |
| 61 c.future.then(expectAsync1((int v) { | |
| 62 expect(v, equals(42)); | |
| 63 }), onError: (e, s) { | |
| 64 fail("Unexpected error"); | |
| 65 }); | |
| 66 result.complete(c); | |
| 67 }); | |
| 68 | |
| 69 test("complete with error", () { | |
| 70 Result<bool> result = new ErrorResult("BAD", stack); | |
| 71 var c = new Completer<bool>(); | |
| 72 c.future.then((bool v) { | |
| 73 fail("Unexpected value $v"); | |
| 74 }, onError: expectAsync2((e, s) { | |
| 75 expect(e, equals("BAD")); | |
| 76 expect(s, same(stack)); | |
| 77 })); | |
| 78 result.complete(c); | |
| 79 }); | |
| 80 | |
| 81 test("add sink value", () { | |
| 82 var result = new ValueResult<int>(42); | |
| 83 EventSink<int> sink = new TestSink(onData: expectAsync1((v) { | |
| 84 expect(v, equals(42)); | |
| 85 })); | |
| 86 result.addTo(sink); | |
| 87 }); | |
| 88 | |
| 89 test("add sink error", () { | |
| 90 Result<bool> result = new ErrorResult("BAD", stack); | |
| 91 EventSink<bool> sink = new TestSink(onError: expectAsync2((e, s) { | |
| 92 expect(e, equals("BAD")); | |
| 93 expect(s, same(stack)); | |
| 94 })); | |
| 95 result.addTo(sink); | |
| 96 }); | |
| 97 | |
| 98 test("value as future", () { | |
| 99 Result<int> result = new ValueResult<int>(42); | |
| 100 result.asFuture.then(expectAsync1((int v) { | |
| 101 expect(v, equals(42)); | |
| 102 }), onError: (e, s) { | |
| 103 fail("Unexpected error"); | |
| 104 }); | |
| 105 }); | |
| 106 | |
| 107 test("error as future", () { | |
| 108 Result<bool> result = new ErrorResult("BAD", stack); | |
| 109 result.asFuture.then((bool v) { | |
| 110 fail("Unexpected value $v"); | |
| 111 }, onError: expectAsync2((e, s) { | |
| 112 expect(e, equals("BAD")); | |
| 113 expect(s, same(stack)); | |
| 114 })); | |
| 115 }); | |
| 116 | |
| 117 test("capture future value", () { | |
| 118 Future<int> value = new Future<int>.value(42); | |
| 119 Result.capture(value).then(expectAsync1((Result result) { | |
| 120 expect(result.isValue, isTrue); | |
| 121 expect(result.isError, isFalse); | |
| 122 ValueResult value = result.asValue; | |
| 123 expect(value.value, equals(42)); | |
| 124 }), onError: (e, s) { | |
| 125 fail("Unexpected error: $e"); | |
| 126 }); | |
| 127 }); | |
| 128 | |
| 129 test("capture future error", () { | |
| 130 Future<bool> value = new Future<bool>.error("BAD", stack); | |
| 131 Result.capture(value).then(expectAsync1((Result result) { | |
| 132 expect(result.isValue, isFalse); | |
| 133 expect(result.isError, isTrue); | |
| 134 ErrorResult error = result.asError; | |
| 135 expect(error.error, equals("BAD")); | |
| 136 expect(error.stackTrace, same(stack)); | |
| 137 }), onError: (e, s) { | |
| 138 fail("Unexpected error: $e"); | |
| 139 }); | |
| 140 }); | |
| 141 | |
| 142 test("release future value", () { | |
| 143 Future<Result<int>> future = | |
| 144 new Future<Result<int>>.value(new Result<int>.value(42)); | |
| 145 Result.release(future).then(expectAsync1((v) { | |
| 146 expect(v, equals(42)); | |
| 147 }), onError: (e, s) { | |
| 148 fail("Unexpected error: $e"); | |
| 149 }); | |
| 150 }); | |
| 151 | |
| 152 test("release future error", () { | |
| 153 // An error in the result is unwrapped and reified by release. | |
| 154 Future<Result<bool>> future = | |
| 155 new Future<Result<bool>>.value(new Result<bool>.error("BAD", stack)); | |
| 156 Result.release(future).then((v) { | |
| 157 fail("Unexpected value: $v"); | |
| 158 }, onError: expectAsync2((e, s) { | |
| 159 expect(e, equals("BAD")); | |
| 160 expect(s, same(stack)); | |
| 161 })); | |
| 162 }); | |
| 163 | |
| 164 test("release future real error", () { | |
| 165 // An error in the error lane is passed through by release. | |
| 166 Future<Result<bool>> future = new Future<Result<bool>>.error("BAD", stack); | |
| 167 Result.release(future).then((v) { | |
| 168 fail("Unexpected value: $v"); | |
| 169 }, onError: expectAsync2((e, s) { | |
| 170 expect(e, equals("BAD")); | |
| 171 expect(s, same(stack)); | |
| 172 })); | |
| 173 }); | |
| 174 | |
| 175 test("capture stream", () { | |
| 176 StreamController<int> c = new StreamController<int>(); | |
| 177 Stream<Result> stream = Result.captureStream(c.stream); | |
| 178 var expectedList = new Queue.from([ | |
| 179 new Result.value(42), | |
| 180 new Result.error("BAD", stack), | |
| 181 new Result.value(37) | |
| 182 ]); | |
| 183 void listener(Result actual) { | |
| 184 expect(expectedList.isEmpty, isFalse); | |
| 185 expectResult(actual, expectedList.removeFirst()); | |
| 186 } | |
| 187 | |
| 188 stream.listen(expectAsync1(listener, count: 3), onError: (e, s) { | |
| 189 fail("Unexpected error: $e"); | |
| 190 }, onDone: expectAsync0(() {}), cancelOnError: true); | |
| 191 c.add(42); | |
| 192 c.addError("BAD", stack); | |
| 193 c.add(37); | |
| 194 c.close(); | |
| 195 }); | |
| 196 | |
| 197 test("release stream", () { | |
| 198 StreamController<Result<int>> c = new StreamController<Result<int>>(); | |
| 199 Stream<int> stream = Result.releaseStream(c.stream); | |
| 200 var events = [ | |
| 201 new Result<int>.value(42), | |
| 202 new Result<int>.error("BAD", stack), | |
| 203 new Result<int>.value(37) | |
| 204 ]; | |
| 205 // Expect the data events, and an extra error event. | |
| 206 var expectedList = new Queue.from(events) | |
| 207 ..add(new Result.error("BAD2", stack)); | |
| 208 | |
| 209 void dataListener(int v) { | |
| 210 expect(expectedList.isEmpty, isFalse); | |
| 211 Result expected = expectedList.removeFirst(); | |
| 212 expect(expected.isValue, isTrue); | |
| 213 expect(v, equals(expected.asValue.value)); | |
| 214 } | |
| 215 | |
| 216 void errorListener(error, StackTrace stackTrace) { | |
| 217 expect(expectedList.isEmpty, isFalse); | |
| 218 Result expected = expectedList.removeFirst(); | |
| 219 expect(expected.isError, isTrue); | |
| 220 expect(error, equals(expected.asError.error)); | |
| 221 expect(stackTrace, same(expected.asError.stackTrace)); | |
| 222 } | |
| 223 | |
| 224 stream.listen(expectAsync1(dataListener, count: 2), | |
| 225 onError: expectAsync2(errorListener, count: 2), | |
| 226 onDone: expectAsync0(() {})); | |
| 227 for (Result<int> result in events) { | |
| 228 c.add(result); // Result value or error in data line. | |
| 229 } | |
| 230 c.addError("BAD2", stack); // Error in error line. | |
| 231 c.close(); | |
| 232 }); | |
| 233 | |
| 234 test("release stream cancel on error", () { | |
| 235 StreamController<Result<int>> c = new StreamController<Result<int>>(); | |
| 236 Stream<int> stream = Result.releaseStream(c.stream); | |
| 237 stream.listen(expectAsync1((v) { | |
| 238 expect(v, equals(42)); | |
| 239 }), onError: expectAsync2((e, s) { | |
| 240 expect(e, equals("BAD")); | |
| 241 expect(s, same(stack)); | |
| 242 }), onDone: () { | |
| 243 fail("Unexpected done event"); | |
| 244 }, cancelOnError: true); | |
| 245 c.add(new Result.value(42)); | |
| 246 c.add(new Result.error("BAD", stack)); | |
| 247 c.add(new Result.value(37)); | |
| 248 c.close(); | |
| 249 }); | |
| 250 | |
| 251 test("flatten error 1", () { | |
| 252 Result<int> error = new Result<int>.error("BAD", stack); | |
| 253 Result<int> flattened = | |
| 254 Result.flatten(new Result<Result<int>>.error("BAD", stack)); | |
| 255 expectResult(flattened, error); | |
| 256 }); | |
| 257 | |
| 258 test("flatten error 2", () { | |
| 259 Result<int> error = new Result<int>.error("BAD", stack); | |
| 260 Result<Result<int>> result = new Result<Result<int>>.value(error); | |
| 261 Result<int> flattened = Result.flatten(result); | |
| 262 expectResult(flattened, error); | |
| 263 }); | |
| 264 | |
| 265 test("flatten value", () { | |
| 266 Result<Result<int>> result = | |
| 267 new Result<Result<int>>.value(new Result<int>.value(42)); | |
| 268 expectResult(Result.flatten(result), new Result<int>.value(42)); | |
| 269 }); | |
| 270 | |
| 271 test("handle unary", () { | |
| 272 ErrorResult result = new Result.error("error", stack); | |
| 273 bool called = false; | |
| 274 result.handle((error) { | |
| 275 called = true; | |
| 276 expect(error, "error"); | |
| 277 }); | |
| 278 expect(called, isTrue); | |
| 279 }); | |
| 280 | |
| 281 test("handle binary", () { | |
| 282 ErrorResult result = new Result.error("error", stack); | |
| 283 bool called = false; | |
| 284 result.handle((error, stackTrace) { | |
| 285 called = true; | |
| 286 expect(error, "error"); | |
| 287 expect(stackTrace, same(stack)); | |
| 288 }); | |
| 289 expect(called, isTrue); | |
| 290 }); | |
| 291 | |
| 292 test("handle unary and binary", () { | |
| 293 ErrorResult result = new Result.error("error", stack); | |
| 294 bool called = false; | |
| 295 result.handle((error, [stackTrace]) { | |
| 296 called = true; | |
| 297 expect(error, "error"); | |
| 298 expect(stackTrace, same(stack)); | |
| 299 }); | |
| 300 expect(called, isTrue); | |
| 301 }); | |
| 302 | |
| 303 test("handle neither unary nor binary", () { | |
| 304 ErrorResult result = new Result.error("error", stack); | |
| 305 expect(() => result.handle(() => fail("unreachable")), throws); | |
| 306 expect(() => result.handle((a, b, c) => fail("unreachable")), throws); | |
| 307 expect(() => result.handle((a, b, {c}) => fail("unreachable")), throws); | |
| 308 expect(() => result.handle((a, {b}) => fail("unreachable")), throws); | |
| 309 expect(() => result.handle(({a, b}) => fail("unreachable")), throws); | |
| 310 expect(() => result.handle(({a}) => fail("unreachable")), throws); | |
| 311 }); | |
| 312 } | |
| 313 | |
| 314 void expectResult(Result actual, Result expected) { | |
| 315 expect(actual.isValue, equals(expected.isValue)); | |
| 316 expect(actual.isError, equals(expected.isError)); | |
| 317 if (actual.isValue) { | |
| 318 expect(actual.asValue.value, equals(expected.asValue.value)); | |
| 319 } else { | |
| 320 expect(actual.asError.error, equals(expected.asError.error)); | |
| 321 expect(actual.asError.stackTrace, same(expected.asError.stackTrace)); | |
| 322 } | |
| 323 } | |
| 324 | |
| 325 class TestSink<T> implements EventSink<T> { | |
| 326 final Function onData; | |
| 327 final Function onError; | |
| 328 final Function onDone; | |
| 329 | |
| 330 TestSink( | |
| 331 {void this.onData(T data): _nullData, | |
| 332 void this.onError(e, StackTrace s): _nullError, | |
| 333 void this.onDone(): _nullDone}); | |
| 334 | |
| 335 void add(T value) { | |
| 336 onData(value); | |
| 337 } | |
| 338 | |
| 339 void addError(error, [StackTrace stack]) { | |
| 340 onError(error, stack); | |
| 341 } | |
| 342 | |
| 343 void close() { | |
| 344 onDone(); | |
| 345 } | |
| 346 | |
| 347 static void _nullData(value) { | |
| 348 fail("Unexpected sink add: $value"); | |
| 349 } | |
| 350 | |
| 351 static void _nullError(e, StackTrace s) { | |
| 352 fail("Unexpected sink addError: $e"); | |
| 353 } | |
| 354 | |
| 355 static void _nullDone() { | |
| 356 fail("Unepxected sink close"); | |
| 357 } | |
| 358 } | |
| OLD | NEW |