| // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| import 'dart:async'; | |
| import 'package:expect/legacy/async_minitest.dart'; // ignore: deprecated_member_use | |
| main() { | |
| const ms5 = const Duration(milliseconds: 5); | |
| const twoSecs = const Duration(seconds: 2); | |
| test("stream timeout", () { | |
| StreamController c = new StreamController(); | |
| Stream tos = c.stream.timeout(ms5); | |
| expect(tos.isBroadcast, false); | |
| tos | |
| .handleError( | |
| expectAsync((e, s) { | |
| expect(e, new isInstanceOf<TimeoutException>()); | |
| expect(s, StackTrace.empty); | |
| }), | |
| ) | |
| .listen((v) { | |
| fail("Unexpected event"); | |
| }); | |
| }); | |
| test("stream timeout add events", () { | |
| StreamController c = new StreamController(); | |
| Stream tos = c.stream.timeout( | |
| ms5, | |
| onTimeout: (sink) { | |
| sink.add(42); | |
| sink.addError("ERROR"); | |
| sink.close(); | |
| }, | |
| ); | |
| expect(tos.isBroadcast, false); | |
| tos.listen( | |
| expectAsync((v) { | |
| expect(v, 42); | |
| }), | |
| onError: expectAsync((e, s) { | |
| expect(e, "ERROR"); | |
| }), | |
| onDone: expectAsync(() {}), | |
| ); | |
| }); | |
| test("stream no timeout", () { | |
| StreamController c = new StreamController(); | |
| Stream tos = c.stream.timeout(twoSecs); | |
| int ctr = 0; | |
| tos.listen( | |
| (v) { | |
| expect(v, 42); | |
| ctr++; | |
| }, | |
| onError: (e, s) { | |
| fail("No error expected"); | |
| }, | |
| onDone: expectAsync(() { | |
| expect(ctr, 2); | |
| }), | |
| ); | |
| expect(tos.isBroadcast, false); | |
| c | |
| ..add(42) | |
| ..add(42) | |
| ..close(); // Faster than a timeout! | |
| }); | |
| test("stream timeout after events", () { | |
| StreamController c = new StreamController(); | |
| Stream tos = c.stream.timeout(twoSecs); | |
| expect(tos.isBroadcast, false); | |
| int ctr = 0; | |
| tos.listen( | |
| (v) { | |
| expect(v, 42); | |
| ctr++; | |
| }, | |
| onError: expectAsync((e, s) { | |
| expect(ctr, 2); | |
| expect(e, new isInstanceOf<TimeoutException>()); | |
| }), | |
| ); | |
| c | |
| ..add(42) | |
| ..add(42); // No close, timeout after two events. | |
| }); | |
| test("broadcast stream timeout", () { | |
| StreamController c = new StreamController.broadcast(); | |
| Stream tos = c.stream.timeout(ms5); | |
| expect(tos.isBroadcast, true); | |
| tos | |
| .handleError( | |
| expectAsync((e, s) { | |
| expect(e, new isInstanceOf<TimeoutException>()); | |
| expect(s, StackTrace.empty); | |
| }), | |
| ) | |
| .listen((v) { | |
| fail("Unexpected event"); | |
| }); | |
| }); | |
| test("asBroadcast stream timeout", () { | |
| StreamController c = new StreamController.broadcast(); | |
| Stream tos = c.stream.asBroadcastStream().timeout(ms5); | |
| expect(tos.isBroadcast, true); | |
| tos | |
| .handleError( | |
| expectAsync((e, s) { | |
| expect(e, new isInstanceOf<TimeoutException>()); | |
| expect(s, StackTrace.empty); | |
| }), | |
| ) | |
| .listen((v) { | |
| fail("Unexpected event"); | |
| }); | |
| }); | |
| test("mapped stream timeout", () { | |
| StreamController c = new StreamController(); | |
| Stream tos = c.stream.map((x) => 2 * x).timeout(ms5); | |
| expect(tos.isBroadcast, false); | |
| tos | |
| .handleError( | |
| expectAsync((e, s) { | |
| expect(e, new isInstanceOf<TimeoutException>()); | |
| expect(s, StackTrace.empty); | |
| }), | |
| ) | |
| .listen((v) { | |
| fail("Unexpected event"); | |
| }); | |
| }); | |
| test("events prevent timeout", () { | |
| Stopwatch sw = new Stopwatch(); | |
| StreamController c = new StreamController(); | |
| Stream tos = c.stream.timeout( | |
| twoSecs, | |
| onTimeout: (_) { | |
| int elapsed = sw.elapsedMilliseconds; | |
| if (elapsed > 250) { | |
| // This should not happen, but it does occasionally. | |
| // Starving the periodic timer has made the test useless. | |
| print("Periodic timer of 5 ms delayed $elapsed ms."); | |
| return; | |
| } | |
| fail("Timeout not prevented by events"); | |
| throw "ERROR"; | |
| }, | |
| ); | |
| // Start the periodic timer before we start listening to the stream. | |
| // This should reduce the flakiness of the test. | |
| int ctr = 200; // send this many events at 5ms intervals. Then close. | |
| new Timer.periodic(ms5, (timer) { | |
| sw.reset(); | |
| c.add(42); | |
| if (--ctr == 0) { | |
| timer.cancel(); | |
| c.close(); | |
| } | |
| }); | |
| sw.start(); | |
| tos.listen((v) { | |
| expect(v, 42); | |
| }, onDone: expectAsync(() {})); | |
| }); | |
| test("errors prevent timeout", () { | |
| Stopwatch sw = new Stopwatch(); | |
| StreamController c = new StreamController(); | |
| Stream tos = c.stream.timeout( | |
| twoSecs, | |
| onTimeout: (_) { | |
| int elapsed = sw.elapsedMilliseconds; | |
| if (elapsed > 250) { | |
| // This should not happen, but it does occasionally. | |
| // Starving the periodic timer has made the test useless. | |
| print("Periodic timer of 5 ms delayed $elapsed ms."); | |
| return; | |
| } | |
| fail("Timeout not prevented by errors"); | |
| }, | |
| ); | |
| // Start the periodic timer before we start listening to the stream. | |
| // This should reduce the flakiness of the test. | |
| int ctr = 200; // send this many error events at 5ms intervals. Then close. | |
| new Timer.periodic(ms5, (timer) { | |
| sw.reset(); | |
| c.addError("ERROR"); | |
| if (--ctr == 0) { | |
| timer.cancel(); | |
| c.close(); | |
| } | |
| }); | |
| sw.start(); | |
| tos.listen( | |
| (_) {}, | |
| onError: (e, s) { | |
| expect(e, "ERROR"); | |
| }, | |
| onDone: expectAsync(() {}), | |
| ); | |
| }); | |
| test("closing prevents timeout", () { | |
| StreamController c = new StreamController(); | |
| Stream tos = c.stream.timeout( | |
| twoSecs, | |
| onTimeout: (_) { | |
| fail("Timeout not prevented by close"); | |
| }, | |
| ); | |
| tos.listen((_) {}, onDone: expectAsync(() {})); | |
| c.close(); | |
| }); | |
| test("pausing prevents timeout", () { | |
| StreamController c = new StreamController(); | |
| Stream tos = c.stream.timeout( | |
| ms5, | |
| onTimeout: (_) { | |
| fail("Timeout not prevented by close"); | |
| }, | |
| ); | |
| var subscription = tos.listen((_) {}, onDone: expectAsync(() {})); | |
| subscription.pause(); | |
| new Timer(twoSecs, () { | |
| c.close(); | |
| subscription.resume(); | |
| }); | |
| }); | |
| } |