mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:19:48 +00:00
a4d3ee054d
In order for asynchronous tests to work on the web, they have to tell the test runner that * the test is async * when the async test has finished running This is done via calling asyncStart/asyncEnd. Issue https://github.com/dart-lang/sdk/issues/52631 Issue https://github.com/dart-lang/sdk/issues/55865 Change-Id: I790960d7da708de4e36be9197ceb3e89f316a84e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/368581 Reviewed-by: Ömer Ağacan <omersa@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
151 lines
3.7 KiB
Dart
151 lines
3.7 KiB
Dart
// Copyright (c) 2015, 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.
|
|
|
|
// Check that the `flatten` function is implemented and applied correctly
|
|
// when applied to interfaces that have `Future` as a superinterface.
|
|
|
|
import 'dart:async';
|
|
|
|
import 'package:async_helper/async_helper.dart';
|
|
import 'package:expect/expect.dart';
|
|
|
|
import '../static_type_helper.dart';
|
|
|
|
mixin Base {
|
|
noSuchMethod(Invocation invocation) {
|
|
if (const {
|
|
#then,
|
|
#catchError,
|
|
#whenComplete,
|
|
}.contains(invocation.memberName)) {
|
|
// Throw a sentinel value (using the receiver since it's available)
|
|
// when one of the `Future` callback methods is called.
|
|
throw this;
|
|
}
|
|
return super.noSuchMethod(invocation);
|
|
}
|
|
}
|
|
|
|
extension on Future<void> {
|
|
Future<void> ignoreError<T>() => then((_) => null, onError: (e) {
|
|
if (e is! T) throw e;
|
|
});
|
|
}
|
|
|
|
class Derived<T> = Object with Base implements Future<T>;
|
|
|
|
class FixedPoint<T> = Object with Base implements Future<FixedPoint<T>>;
|
|
|
|
class Divergent<T> = Object
|
|
with Base
|
|
implements Future<Divergent<Divergent<T>>>;
|
|
|
|
void main() async {
|
|
asyncStart();
|
|
// ----- Test the static types of await on the non-standard futures.
|
|
|
|
bool obscureFalse = DateTime.now().millisecondsSinceEpoch < 0;
|
|
|
|
if (obscureFalse) {
|
|
var x1 = await Derived<int>();
|
|
x1.expectStaticType<Exactly<int>>();
|
|
|
|
var x2 = await FixedPoint<int>();
|
|
x2.expectStaticType<Exactly<FixedPoint<int>>>();
|
|
|
|
var x3 = await Divergent<int>();
|
|
x3.expectStaticType<Exactly<Divergent<Divergent<int>>>>();
|
|
}
|
|
|
|
// ----- flatten(Derived<int>) == int.
|
|
|
|
try {
|
|
int x = await Derived<int>();
|
|
Expect.fail("Derived did not throw");
|
|
} on Derived {
|
|
// Expected throw.
|
|
}
|
|
|
|
Future<int> f1() async => Derived<int>();
|
|
|
|
// A non-standard future which implements `Future<int>` can be returned
|
|
// in an async function with return type `Future<int>`. It does not
|
|
// implement any members, so we need to ignore the dynamic error that
|
|
// occurs when any of its future callback methods is called.
|
|
f1().ignoreError<Derived>();
|
|
|
|
Future<int> f2() async {
|
|
return Derived<int>();
|
|
}
|
|
|
|
// Like the `f1` case, using a `{}` function.
|
|
f2().ignoreError<Derived>();
|
|
|
|
Future<int> x1 = (() async => Derived<int>())();
|
|
|
|
try {
|
|
await x1;
|
|
Expect.fail("Derived did not throw");
|
|
} on Derived {
|
|
// Expected throw.
|
|
}
|
|
|
|
// ----- flatten(FixedPoint<int>) == FixedPoint<int>.
|
|
|
|
try {
|
|
FixedPoint<int> x = await FixedPoint<int>();
|
|
Expect.fail("FixedPoint did not throw");
|
|
} on FixedPoint {
|
|
// Expected throw.
|
|
}
|
|
|
|
Future<FixedPoint<int>> f3() async => FixedPoint<int>();
|
|
|
|
f3().ignoreError<FixedPoint>();
|
|
|
|
Future<FixedPoint<int>> f4() async {
|
|
return FixedPoint<int>();
|
|
}
|
|
|
|
f4().ignoreError<FixedPoint>();
|
|
|
|
Future<FixedPoint<int>> x2 = (() async => FixedPoint<int>())();
|
|
|
|
try {
|
|
await x2;
|
|
Expect.fail("FixedPoint did not throw");
|
|
} on FixedPoint {
|
|
// Expected throw.
|
|
}
|
|
|
|
// ----- flatten(Divergent<int>) == Divergent<Divergent<int>>.
|
|
|
|
try {
|
|
Divergent<Divergent<int>> x = await Divergent<int>();
|
|
Expect.fail("Divergent did not throw");
|
|
} on Divergent {
|
|
// Expected throw.
|
|
}
|
|
|
|
Future<Divergent<Divergent<int>>> f5() async => Divergent<int>();
|
|
f5().ignoreError<Divergent>();
|
|
|
|
Future<Divergent<Divergent<int>>> f6() async {
|
|
return Divergent<int>();
|
|
}
|
|
|
|
f6().ignoreError<Divergent>();
|
|
|
|
Future<Divergent<Divergent<int>>> f7() async => Divergent<int>();
|
|
Future<Divergent<Divergent<int>>> x3 = f7();
|
|
|
|
try {
|
|
await x3;
|
|
Expect.fail("Divergent did not throw");
|
|
} on Divergent {
|
|
// Expected throw.
|
|
}
|
|
asyncEnd();
|
|
}
|