161 lines
4.7 KiB
Dart
161 lines
4.7 KiB
Dart
|
import 'dart:async';
|
||
|
|
||
|
import 'package:angel3_reactivex/angel3_reactivex.dart';
|
||
|
import 'package:test/test.dart';
|
||
|
|
||
|
import '../../utils.dart';
|
||
|
|
||
|
Stream<int> _stream() =>
|
||
|
Stream.periodic(const Duration(milliseconds: 100), (i) => i + 1).take(10);
|
||
|
|
||
|
void main() {
|
||
|
test('Rx.throttle', () async {
|
||
|
await expectLater(
|
||
|
_stream()
|
||
|
.throttle(
|
||
|
(_) => Stream<void>.periodic(const Duration(milliseconds: 250)))
|
||
|
.take(3),
|
||
|
emitsInOrder(<dynamic>[1, 4, 7, emitsDone]));
|
||
|
});
|
||
|
|
||
|
test('Rx.throttle.trailing', () async {
|
||
|
await expectLater(
|
||
|
_stream()
|
||
|
.throttle(
|
||
|
(_) => Stream<void>.periodic(const Duration(milliseconds: 250)),
|
||
|
trailing: true,
|
||
|
leading: false)
|
||
|
.take(3),
|
||
|
emitsInOrder(<dynamic>[3, 6, 9, emitsDone]));
|
||
|
});
|
||
|
|
||
|
test('Rx.throttle.dynamic.window', () async {
|
||
|
await expectLater(
|
||
|
_stream()
|
||
|
.throttle((value) => value == 1
|
||
|
? Stream<void>.periodic(const Duration(milliseconds: 10))
|
||
|
: Stream<void>.periodic(const Duration(milliseconds: 250)))
|
||
|
.take(3),
|
||
|
emitsInOrder(<dynamic>[1, 2, 5, emitsDone]));
|
||
|
});
|
||
|
|
||
|
test('Rx.throttle.dynamic.window.trailing', () async {
|
||
|
await expectLater(
|
||
|
_stream()
|
||
|
.throttle(
|
||
|
(value) => value == 1
|
||
|
? Stream<void>.periodic(const Duration(milliseconds: 10))
|
||
|
: Stream<void>.periodic(const Duration(milliseconds: 250)),
|
||
|
trailing: true,
|
||
|
leading: false)
|
||
|
.take(3),
|
||
|
emitsInOrder(<dynamic>[1, 4, 7, emitsDone]));
|
||
|
});
|
||
|
|
||
|
test('Rx.throttle.leading.trailing.1', () async {
|
||
|
// --1--2--3--4--5--6--7--8--9--10--11|
|
||
|
// --1-----3--4-----6--7-----9--10-----11|
|
||
|
// --^--------^--------^---------^-----
|
||
|
|
||
|
final values = <int>[];
|
||
|
|
||
|
final stream = _stream()
|
||
|
.concatWith([Rx.timer(11, const Duration(milliseconds: 100))]).throttle(
|
||
|
(v) {
|
||
|
values.add(v);
|
||
|
return Stream<void>.periodic(const Duration(milliseconds: 250));
|
||
|
},
|
||
|
leading: true,
|
||
|
trailing: true,
|
||
|
);
|
||
|
await expectLater(
|
||
|
stream,
|
||
|
emitsInOrder(<dynamic>[1, 3, 4, 6, 7, 9, 10, 11, emitsDone]),
|
||
|
);
|
||
|
expect(values, [1, 4, 7, 10]);
|
||
|
});
|
||
|
|
||
|
test('Rx.throttle.leading.trailing.2', () async {
|
||
|
// --1--2--3--4--5--6--7--8--9--10--11|
|
||
|
// --1-----3--4-----6--7-----9--10-----11|
|
||
|
// --^--------^--------^---------^-----
|
||
|
|
||
|
final values = <int>[];
|
||
|
|
||
|
final stream = _stream().throttle(
|
||
|
(v) {
|
||
|
values.add(v);
|
||
|
return Stream<void>.periodic(const Duration(milliseconds: 250));
|
||
|
},
|
||
|
leading: true,
|
||
|
trailing: true,
|
||
|
);
|
||
|
await expectLater(
|
||
|
stream,
|
||
|
emitsInOrder(<dynamic>[1, 3, 4, 6, 7, 9, 10, emitsDone]),
|
||
|
);
|
||
|
expect(values, [1, 4, 7, 10]);
|
||
|
});
|
||
|
|
||
|
test('Rx.throttle.reusable', () async {
|
||
|
final transformer = ThrottleStreamTransformer<int>(
|
||
|
(_) => Stream<void>.periodic(const Duration(milliseconds: 250)));
|
||
|
|
||
|
await expectLater(_stream().transform(transformer).take(2),
|
||
|
emitsInOrder(<dynamic>[1, 4, emitsDone]));
|
||
|
|
||
|
await expectLater(_stream().transform(transformer).take(2),
|
||
|
emitsInOrder(<dynamic>[1, 4, emitsDone]));
|
||
|
});
|
||
|
|
||
|
test('Rx.throttle.asBroadcastStream', () async {
|
||
|
final future = _stream()
|
||
|
.asBroadcastStream()
|
||
|
.throttle(
|
||
|
(_) => Stream<void>.periodic(const Duration(milliseconds: 250)))
|
||
|
.drain<void>();
|
||
|
|
||
|
// listen twice on same stream
|
||
|
await expectLater(future, completes);
|
||
|
await expectLater(future, completes);
|
||
|
});
|
||
|
|
||
|
test('Rx.throttle.error.shouldThrowA', () async {
|
||
|
final streamWithError = Stream<void>.error(Exception()).throttle(
|
||
|
(_) => Stream<void>.periodic(const Duration(milliseconds: 250)));
|
||
|
|
||
|
streamWithError.listen(null,
|
||
|
onError: expectAsync2((Exception e, StackTrace s) {
|
||
|
expect(e, isException);
|
||
|
}));
|
||
|
});
|
||
|
|
||
|
test('Rx.throttle.pause.resume', () async {
|
||
|
late StreamSubscription<int> subscription;
|
||
|
|
||
|
final controller = StreamController<int>();
|
||
|
|
||
|
subscription = _stream()
|
||
|
.throttle(
|
||
|
(_) => Stream<void>.periodic(const Duration(milliseconds: 250)))
|
||
|
.take(2)
|
||
|
.listen(controller.add, onDone: () {
|
||
|
controller.close();
|
||
|
subscription.cancel();
|
||
|
});
|
||
|
|
||
|
await expectLater(
|
||
|
controller.stream, emitsInOrder(<dynamic>[1, 4, emitsDone]));
|
||
|
|
||
|
await Future<void>.delayed(const Duration(milliseconds: 150)).whenComplete(
|
||
|
() => subscription
|
||
|
.pause(Future<void>.delayed(const Duration(milliseconds: 150))));
|
||
|
});
|
||
|
|
||
|
test('Rx.throttle.nullable', () {
|
||
|
nullableTest<String?>(
|
||
|
(s) => s.throttle((_) => Stream<void>.empty()),
|
||
|
);
|
||
|
});
|
||
|
}
|