blob: b0724ed0cee73c0c0b596680f982139b82d37e5a [file] [log] [blame]
// Copyright 2014 The Flutter Authors. 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 'dart:typed_data';
import 'package:fake_async/fake_async.dart';
import 'package:flutter_tools/src/proxied_devices/debounce_data_stream.dart';
import '../../src/common.dart';
void main() {
group('debounceDataStreams', () {
late FakeAsync fakeAsync;
late StreamController<Uint8List> source;
late Stream<Uint8List> output;
const Duration debounceDuration = Duration(seconds: 10);
const Duration smallDuration = Duration(milliseconds: 10);
void addToSource(int value) {
source.add(Uint8List.fromList(<int>[value]));
}
setUp(() {
fakeAsync = FakeAsync();
fakeAsync.run((FakeAsync time) {
source = StreamController<Uint8List>();
output = debounceDataStream(source.stream, debounceDuration);
});
});
testWithoutContext('does not listen if returned stream is not listened to', () {
expect(source.hasListener, false);
output.listen(dummy);
expect(source.hasListener, true);
});
testWithoutContext('forwards data normally is all data if longer than duration apart', () {
fakeAsync.run((FakeAsync time) {
final List<Uint8List> outputItems = <Uint8List>[];
output.listen(outputItems.add);
addToSource(1);
time.elapse(debounceDuration + smallDuration);
addToSource(2);
time.elapse(debounceDuration + smallDuration);
addToSource(3);
time.elapse(debounceDuration + smallDuration);
expect(outputItems, <List<int>>[
<int>[1],
<int>[2],
<int>[3],
]);
});
});
testWithoutContext('merge data after the first if sent within duration', () {
fakeAsync.run((FakeAsync time) {
final List<Uint8List> outputItems = <Uint8List>[];
output.listen(outputItems.add);
addToSource(1);
time.elapse(smallDuration);
addToSource(2);
time.elapse(smallDuration);
addToSource(3);
time.elapse(debounceDuration + smallDuration);
expect(outputItems, <List<int>>[
<int>[1],
<int>[2, 3],
]);
});
});
testWithoutContext('output data in separate chunks if time between them is longer than duration', () {
fakeAsync.run((FakeAsync time) {
final List<Uint8List> outputItems = <Uint8List>[];
output.listen(outputItems.add);
addToSource(1);
time.elapse(smallDuration);
addToSource(2);
time.elapse(smallDuration);
addToSource(3);
time.elapse(debounceDuration + smallDuration);
addToSource(4);
time.elapse(smallDuration);
addToSource(5);
time.elapse(debounceDuration + smallDuration);
expect(outputItems, <List<int>>[
<int>[1],
<int>[2, 3],
<int>[4, 5],
]);
});
});
testWithoutContext('sends the last chunk after debounce duration', () {
fakeAsync.run((FakeAsync time) {
final List<Uint8List> outputItems = <Uint8List>[];
output.listen(outputItems.add);
addToSource(1);
time.flushMicrotasks();
expect(outputItems, <List<int>>[<int>[1]]);
time.elapse(smallDuration);
addToSource(2);
time.elapse(smallDuration);
addToSource(3);
expect(outputItems, <List<int>>[<int>[1]]);
time.elapse(debounceDuration + smallDuration);
expect(outputItems, <List<int>>[
<int>[1],
<int>[2, 3],
]);
});
});
testWithoutContext('close if source stream is closed', () {
fakeAsync.run((FakeAsync time) {
bool isDone = false;
output.listen(dummy, onDone: () => isDone = true);
expect(isDone, false);
source.close();
time.flushMicrotasks();
expect(isDone, true);
});
});
testWithoutContext('delay close until after last chunk is sent', () {
fakeAsync.run((FakeAsync time) {
final List<Uint8List> outputItems = <Uint8List>[];
bool isDone = false;
output.listen(outputItems.add, onDone: () => isDone = true);
addToSource(1);
time.flushMicrotasks();
expect(outputItems, <List<int>>[<int>[1]]);
addToSource(2);
source.close();
time.elapse(smallDuration);
expect(isDone, false);
expect(outputItems, <List<int>>[<int>[1]]);
time.elapse(debounceDuration + smallDuration);
expect(outputItems, <List<int>>[
<int>[1],
<int>[2],
]);
expect(isDone, true);
});
});
testWithoutContext('close if returned stream is closed', () {
fakeAsync.run((FakeAsync time) {
bool isCancelled = false;
source.onCancel = () => isCancelled = true;
final StreamSubscription<Uint8List> subscription = output.listen(dummy);
expect(isCancelled, false);
subscription.cancel();
expect(isCancelled, true);
});
});
});
}
Uint8List dummy(Uint8List data) => data;