blob: 1c01a34c33c011948b09e6f830325108ca4d1cc2 [file] [log] [blame]
// Copyright (c) 2020, 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.
// @dart = 2.9
import 'dart:async';
import 'package:async_helper/async_minitest.dart';
import 'utils.dart';
main() {
// Stream.take(n) automatically cancels after seeing the n'th value.
test('cancels at yield', () {
Completer exits = Completer();
var list = [];
f() async* {
try {
list.add(0);
list.add(1);
yield null;
list.add(2);
} finally {
exits.complete(3);
}
}
// No events must be fired synchronously in response to a listen.
var subscription = f().listen((v) {
fail('Received event $v');
}, onDone: () {
fail('Received done');
});
// No events must be delivered after a cancel.
subscription.cancel();
return exits.future.then((v) {
expect(v, equals(3));
expect(list, equals([0, 1]));
});
});
test('does cancel eventually', () {
var exits = Completer();
var list = [];
f() async* {
int i = 0;
try {
while (true) yield i++;
} finally {
list.add('a');
exits.complete(i);
}
}
return expectList(f().take(5), [0, 1, 2, 3, 4])
.then((_) => exits.future)
.then((v) {
expect(v, greaterThan(4));
expect(list, ['a']);
});
});
group('at index', () {
f() async* {
try {
yield await Future.microtask(() => 1);
} finally {
try {
yield await Future.microtask(() => 2);
} finally {
yield await Future.microtask(() => 3);
}
}
}
test('- all, sanity check', () {
return expectList(f(), [1, 2, 3]);
});
test('after end', () {
return expectList(f().take(4), [1, 2, 3]);
});
test('at end', () {
return expectList(f().take(3), [1, 2, 3]);
});
test('before end', () {
return expectList(f().take(2), [1, 2]);
});
test('early', () {
return expectList(f().take(1), [1]);
});
test('at start', () {
return expectList(f().take(0), []);
});
});
test('regression-fugl/fisk', () {
var res = [];
fisk() async* {
res.add('+fisk');
try {
for (int i = 0; i < 2; i++) {
yield await Future.microtask(() => i);
}
} finally {
res.add('-fisk');
}
}
fugl(int count) async {
res.add('fisk $count');
try {
await for (int i in fisk().take(count)) res.add(i);
} finally {
res.add('done');
}
}
return fugl(3)
.whenComplete(() => fugl(2))
.whenComplete(() => fugl(1))
.whenComplete(() {
expect(res, [
'fisk 3',
'+fisk',
0,
1,
'-fisk',
'done',
'fisk 2',
'+fisk',
0,
1,
'-fisk',
'done',
'fisk 1',
'+fisk',
0,
'-fisk',
'done',
]);
});
});
}