317 lines
9.3 KiB
Dart
317 lines
9.3 KiB
Dart
|
import 'dart:async';
|
||
|
|
||
|
import 'package:angel3_reactivex/angel3_reactivex.dart';
|
||
|
import 'package:test/test.dart';
|
||
|
|
||
|
void main() {
|
||
|
group('CompositeSubscription', () {
|
||
|
test('cast to StreamSubscription of any type', () {
|
||
|
final cs = CompositeSubscription();
|
||
|
|
||
|
expect(cs, isA<StreamSubscription<void>>());
|
||
|
// ignore: prefer_void_to_null
|
||
|
expect(cs, isA<StreamSubscription<Null>>());
|
||
|
expect(cs, isA<StreamSubscription<int>>());
|
||
|
expect(cs, isA<StreamSubscription<int?>>());
|
||
|
expect(cs, isA<StreamSubscription<Object>>());
|
||
|
expect(cs, isA<StreamSubscription<Object?>>());
|
||
|
|
||
|
cs as StreamSubscription<void>; // ignore: unnecessary_cast
|
||
|
// ignore: unnecessary_cast, prefer_void_to_null
|
||
|
cs as StreamSubscription<Null>;
|
||
|
cs as StreamSubscription<int>; // ignore: unnecessary_cast
|
||
|
cs as StreamSubscription<int?>; // ignore: unnecessary_cast
|
||
|
cs as StreamSubscription<Object>; // ignore: unnecessary_cast
|
||
|
cs as StreamSubscription<Object?>; // ignore: unnecessary_cast
|
||
|
|
||
|
expect(true, true);
|
||
|
});
|
||
|
|
||
|
group('throws UnsupportedError', () {
|
||
|
test('when calling asFuture()', () {
|
||
|
expect(
|
||
|
() => CompositeSubscription().asFuture(0), throwsUnsupportedError);
|
||
|
});
|
||
|
|
||
|
test('when calling onData()', () {
|
||
|
expect(() => CompositeSubscription().onData((_) {}),
|
||
|
throwsUnsupportedError);
|
||
|
});
|
||
|
|
||
|
test('when calling onError()', () {
|
||
|
expect(() => CompositeSubscription().onError((Object _) {}),
|
||
|
throwsUnsupportedError);
|
||
|
});
|
||
|
|
||
|
test('when calling onDone()', () {
|
||
|
expect(() => CompositeSubscription().onDone(() {}),
|
||
|
throwsUnsupportedError);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
group('Rx.compositeSubscription.clear', () {
|
||
|
test('should cancel all subscriptions', () {
|
||
|
final stream = Stream.fromIterable(const [1, 2, 3]).shareValue();
|
||
|
final composite = CompositeSubscription();
|
||
|
|
||
|
composite
|
||
|
..add(stream.listen(null))
|
||
|
..add(stream.listen(null))
|
||
|
..add(stream.listen(null));
|
||
|
|
||
|
final done = composite.clear();
|
||
|
|
||
|
expect(stream, neverEmits(anything));
|
||
|
expect(done, isA<Future<void>>());
|
||
|
});
|
||
|
|
||
|
test(
|
||
|
'should return null since no subscription has been canceled clear()',
|
||
|
() {
|
||
|
final composite = CompositeSubscription();
|
||
|
final done = composite.clear();
|
||
|
expect(done, null);
|
||
|
},
|
||
|
);
|
||
|
});
|
||
|
|
||
|
group('Rx.compositeSubscription.onDispose', () {
|
||
|
test('should cancel all subscriptions when calling dispose()', () {
|
||
|
final stream = Stream.fromIterable(const [1, 2, 3]).shareValue();
|
||
|
final composite = CompositeSubscription();
|
||
|
|
||
|
composite
|
||
|
..add(stream.listen(null))
|
||
|
..add(stream.listen(null))
|
||
|
..add(stream.listen(null));
|
||
|
|
||
|
final done = composite.dispose();
|
||
|
|
||
|
expect(stream, neverEmits(anything));
|
||
|
expect(done, isA<Future<void>>());
|
||
|
});
|
||
|
|
||
|
test('should cancel all subscriptions when calling cancel()', () {
|
||
|
final stream = Stream.fromIterable(const [1, 2, 3]).shareValue();
|
||
|
final composite = CompositeSubscription();
|
||
|
|
||
|
composite
|
||
|
..add(stream.listen(null))
|
||
|
..add(stream.listen(null))
|
||
|
..add(stream.listen(null));
|
||
|
|
||
|
final done = composite.cancel();
|
||
|
|
||
|
expect(stream, neverEmits(anything));
|
||
|
expect(done, isA<Future<void>>());
|
||
|
});
|
||
|
|
||
|
test(
|
||
|
'should return null since no subscription has been canceled on dispose()',
|
||
|
() {
|
||
|
final composite = CompositeSubscription();
|
||
|
final done = composite.dispose();
|
||
|
expect(done, null);
|
||
|
},
|
||
|
);
|
||
|
|
||
|
test(
|
||
|
'should return Future completed with null since no subscription has been canceled on cancel()',
|
||
|
() {
|
||
|
final composite = CompositeSubscription();
|
||
|
final done = composite.cancel();
|
||
|
expect(done, completion(null));
|
||
|
},
|
||
|
);
|
||
|
|
||
|
test(
|
||
|
'should throw exception if trying to add subscription to disposed composite, after calling dispose()',
|
||
|
() {
|
||
|
final stream = Stream.fromIterable(const [1, 2, 3]).shareValue();
|
||
|
final composite = CompositeSubscription();
|
||
|
|
||
|
composite.dispose();
|
||
|
|
||
|
expect(() => composite.add(stream.listen(null)), throwsA(anything));
|
||
|
},
|
||
|
);
|
||
|
|
||
|
test(
|
||
|
'should throw exception if trying to add subscription to disposed composite, after calling cancel()',
|
||
|
() {
|
||
|
final stream = Stream.fromIterable(const [1, 2, 3]).shareValue();
|
||
|
final composite = CompositeSubscription();
|
||
|
|
||
|
composite.cancel();
|
||
|
|
||
|
expect(() => composite.add(stream.listen(null)), throwsA(anything));
|
||
|
},
|
||
|
);
|
||
|
});
|
||
|
|
||
|
group('Rx.compositeSubscription.remove', () {
|
||
|
test('should cancel subscription on if it is removed from composite', () {
|
||
|
const value = 1;
|
||
|
final stream = Stream.fromIterable([value]).shareValue();
|
||
|
final composite = CompositeSubscription();
|
||
|
final subscription = stream.listen(null);
|
||
|
|
||
|
composite.add(subscription);
|
||
|
final done = composite.remove(subscription);
|
||
|
|
||
|
expect(stream, neverEmits(anything));
|
||
|
expect(done, isA<Future<void>>());
|
||
|
});
|
||
|
|
||
|
test(
|
||
|
'should not cancel the subscription since it is not present in the composite',
|
||
|
() {
|
||
|
const value = 1;
|
||
|
final stream = Stream.fromIterable([value]).shareValue();
|
||
|
final composite = CompositeSubscription();
|
||
|
final subscription = stream.listen(null);
|
||
|
|
||
|
final done = composite.remove(subscription);
|
||
|
|
||
|
expect(stream, emits(anything));
|
||
|
expect(done, null);
|
||
|
},
|
||
|
);
|
||
|
});
|
||
|
|
||
|
test('Rx.compositeSubscription.pauseAndResume()', () {
|
||
|
final composite = CompositeSubscription();
|
||
|
final s1 = Stream.fromIterable(const [1, 2, 3]).listen(null),
|
||
|
s2 = Stream.fromIterable(const [4, 5, 6]).listen(null);
|
||
|
|
||
|
composite.add(s1);
|
||
|
composite.add(s2);
|
||
|
|
||
|
void expectPaused() {
|
||
|
expect(composite.allPaused, isTrue);
|
||
|
expect(composite.isPaused, isTrue);
|
||
|
|
||
|
expect(s1.isPaused, isTrue);
|
||
|
expect(s2.isPaused, isTrue);
|
||
|
}
|
||
|
|
||
|
void expectResumed() {
|
||
|
expect(composite.allPaused, isFalse);
|
||
|
expect(composite.isPaused, isFalse);
|
||
|
|
||
|
expect(s1.isPaused, isFalse);
|
||
|
expect(s2.isPaused, isFalse);
|
||
|
}
|
||
|
|
||
|
composite.pauseAll();
|
||
|
|
||
|
expectPaused();
|
||
|
|
||
|
composite.resumeAll();
|
||
|
|
||
|
expectResumed();
|
||
|
|
||
|
composite.pause();
|
||
|
|
||
|
expectPaused();
|
||
|
|
||
|
composite.resume();
|
||
|
|
||
|
expectResumed();
|
||
|
});
|
||
|
|
||
|
test('Rx.compositeSubscription.resumeWithFuture', () async {
|
||
|
final composite = CompositeSubscription();
|
||
|
final s1 = Stream.fromIterable(const [1, 2, 3]).listen(null),
|
||
|
s2 = Stream.fromIterable(const [4, 5, 6]).listen(null);
|
||
|
final completer = Completer<void>();
|
||
|
|
||
|
composite.add(s1);
|
||
|
composite.add(s2);
|
||
|
composite.pauseAll(completer.future);
|
||
|
|
||
|
expect(composite.allPaused, isTrue);
|
||
|
expect(composite.isPaused, isTrue);
|
||
|
|
||
|
completer.complete();
|
||
|
|
||
|
await expectLater(completer.future.then((_) => composite.allPaused),
|
||
|
completion(isFalse));
|
||
|
await expectLater(completer.future.then((_) => composite.isPaused),
|
||
|
completion(isFalse));
|
||
|
});
|
||
|
|
||
|
test('Rx.compositeSubscription.allPaused', () {
|
||
|
final composite = CompositeSubscription();
|
||
|
final s1 = Stream.fromIterable(const [1, 2, 3]).listen(null),
|
||
|
s2 = Stream.fromIterable(const [4, 5, 6]).listen(null);
|
||
|
|
||
|
expect(composite.allPaused, isFalse);
|
||
|
expect(composite.isPaused, isFalse);
|
||
|
|
||
|
composite.add(s1);
|
||
|
composite.add(s2);
|
||
|
|
||
|
expect(composite.allPaused, isFalse);
|
||
|
expect(composite.isPaused, isFalse);
|
||
|
|
||
|
composite.pauseAll();
|
||
|
|
||
|
expect(composite.allPaused, isTrue);
|
||
|
expect(composite.isPaused, isTrue);
|
||
|
|
||
|
composite.remove(s1);
|
||
|
composite.remove(s2);
|
||
|
|
||
|
/// all subscriptions are removed, allPaused should yield false
|
||
|
expect(composite.allPaused, isFalse);
|
||
|
expect(composite.isPaused, isFalse);
|
||
|
});
|
||
|
|
||
|
test('Rx.compositeSubscription.allPaused.indirectly', () {
|
||
|
final composite = CompositeSubscription();
|
||
|
final s1 = Stream.fromIterable(const [1, 2, 3]).listen(null),
|
||
|
s2 = Stream.fromIterable(const [4, 5, 6]).listen(null);
|
||
|
|
||
|
s1.pause();
|
||
|
s2.pause();
|
||
|
|
||
|
composite.add(s1);
|
||
|
composite.add(s2);
|
||
|
|
||
|
expect(composite.allPaused, isTrue);
|
||
|
expect(composite.isPaused, isTrue);
|
||
|
|
||
|
s1.resume();
|
||
|
s2.resume();
|
||
|
|
||
|
expect(composite.allPaused, isFalse);
|
||
|
expect(composite.isPaused, isFalse);
|
||
|
});
|
||
|
|
||
|
test('Rx.compositeSubscription.size', () {
|
||
|
final composite = CompositeSubscription();
|
||
|
final s1 = Stream.fromIterable(const [1, 2, 3]).listen(null),
|
||
|
s2 = Stream.fromIterable(const [4, 5, 6]).listen(null);
|
||
|
|
||
|
expect(composite.isEmpty, isTrue);
|
||
|
expect(composite.isNotEmpty, isFalse);
|
||
|
expect(composite.length, 0);
|
||
|
|
||
|
composite.add(s1);
|
||
|
composite.add(s2);
|
||
|
|
||
|
expect(composite.isEmpty, isFalse);
|
||
|
expect(composite.isNotEmpty, isTrue);
|
||
|
expect(composite.length, 2);
|
||
|
|
||
|
composite.remove(s1);
|
||
|
composite.remove(s2);
|
||
|
|
||
|
expect(composite.isEmpty, isTrue);
|
||
|
expect(composite.isNotEmpty, isFalse);
|
||
|
expect(composite.length, 0);
|
||
|
});
|
||
|
});
|
||
|
}
|