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