mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:27:17 +00:00
df4f53adc1
The following tests began passing: dartk-strong-linux-release-x64:lib/async/zone_error_callback_test was fixed (RuntimeError -> Pass) Change-Id: I67118d4023cf60737c2434b005007121dd182aff Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/142402 Reviewed-by: Liam Appelbe <liama@google.com> Reviewed-by: Bob Nystrom <rnystrom@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
347 lines
9 KiB
Dart
347 lines
9 KiB
Dart
// Copyright (c) 2014, 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.
|
|
|
|
import 'package:expect/expect.dart';
|
|
import 'package:async_helper/async_helper.dart';
|
|
import 'dart:async';
|
|
|
|
main() {
|
|
asyncStart();
|
|
testNoChange();
|
|
testWithReplacement();
|
|
asyncEnd();
|
|
}
|
|
|
|
class MockStack implements StackTrace {
|
|
final int id;
|
|
const MockStack(this.id);
|
|
String toString() => "MocKStack($id)";
|
|
}
|
|
|
|
const stack1 = const MockStack(1);
|
|
const stack2 = const MockStack(2);
|
|
|
|
class SomeError implements Error {
|
|
final int id;
|
|
const SomeError(this.id);
|
|
StackTrace get stackTrace => stack2;
|
|
String toString() => "SomeError($id)";
|
|
}
|
|
|
|
const error1 = const SomeError(1);
|
|
const error2 = const SomeError(2);
|
|
|
|
Null expectError(e, s) {
|
|
// Remember one asyncStart per use of this callback.
|
|
Expect.identical(error1, e);
|
|
Expect.identical(stack1, s);
|
|
asyncEnd();
|
|
return null;
|
|
}
|
|
|
|
Null expectErrorOnly(e, s) {
|
|
// Remember one asyncStart per use of this callback.
|
|
Expect.identical(error1, e);
|
|
asyncEnd();
|
|
return null;
|
|
}
|
|
|
|
AsyncError? replace(self, parent, zone, e, s) {
|
|
if (e == "ignore") return null; // For testing handleError throwing.
|
|
Expect.identical(error1, e); // Ensure replacement only called once
|
|
return new AsyncError(error2, stack2);
|
|
}
|
|
|
|
var replaceZoneSpec = new ZoneSpecification(errorCallback: replace);
|
|
|
|
// Expectation after replacing.
|
|
Null expectReplaced(e, s) {
|
|
Expect.identical(error2, e);
|
|
Expect.identical(stack2, s);
|
|
asyncEnd();
|
|
return null;
|
|
}
|
|
|
|
void testProgrammaticErrors(expectError) {
|
|
{
|
|
asyncStart();
|
|
Completer c = new Completer();
|
|
c.future.catchError(expectError);
|
|
c.completeError(error1, stack1);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
controller.stream.listen(null, onError: expectError, cancelOnError: true);
|
|
controller.addError(error1, stack1);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController(sync: true);
|
|
controller.stream.listen(null, onError: expectError, cancelOnError: true);
|
|
controller.addError(error1, stack1);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController.broadcast();
|
|
controller.stream.listen(null, onError: expectError, cancelOnError: true);
|
|
controller.addError(error1, stack1);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController.broadcast(sync: true);
|
|
controller.stream.listen(null, onError: expectError, cancelOnError: true);
|
|
controller.addError(error1, stack1);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
controller.stream
|
|
.asBroadcastStream()
|
|
.listen(null, onError: expectError, cancelOnError: true);
|
|
controller.addError(error1, stack1);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController(sync: true);
|
|
controller.stream
|
|
.asBroadcastStream()
|
|
.listen(null, onError: expectError, cancelOnError: true);
|
|
controller.addError(error1, stack1);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
Future f = new Future.error(error1, stack1);
|
|
f.catchError(expectError);
|
|
}
|
|
}
|
|
|
|
void testThrownErrors(expectErrorOnly) {
|
|
// Throw error in non-registered callback.
|
|
{
|
|
asyncStart();
|
|
Future f = new Future(() => throw error1);
|
|
f.catchError(expectErrorOnly);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
Future f = new Future.microtask(() => throw error1);
|
|
f.catchError(expectErrorOnly);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
Future f = new Future.sync(() => throw error1);
|
|
f.catchError(expectErrorOnly);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
controller.stream
|
|
.map((x) => throw error1)
|
|
.listen(null, onError: expectErrorOnly, cancelOnError: true);
|
|
controller.add(null);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
controller.stream
|
|
.where((x) => throw error1)
|
|
.listen(null, onError: expectErrorOnly, cancelOnError: true);
|
|
controller.add(null);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
controller.stream.forEach((x) => throw error1).catchError(expectErrorOnly);
|
|
controller.add(null);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
controller.stream
|
|
.expand((x) => throw error1)
|
|
.listen(null, onError: expectErrorOnly, cancelOnError: true);
|
|
controller.add(null);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
controller.stream
|
|
.asyncMap((x) => throw error1)
|
|
.listen(null, onError: expectErrorOnly, cancelOnError: true);
|
|
controller.add(null);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
controller.stream
|
|
.asyncExpand((x) => throw error1)
|
|
.listen(null, onError: expectErrorOnly, cancelOnError: true);
|
|
controller.add(null);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
controller.stream
|
|
.handleError((e, s) => throw error1)
|
|
.listen(null, onError: expectErrorOnly, cancelOnError: true);
|
|
controller.addError("ignore", null);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
controller.stream
|
|
.skipWhile((x) => throw error1)
|
|
.listen(null, onError: expectErrorOnly, cancelOnError: true);
|
|
controller.add(null);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
controller.stream
|
|
.takeWhile((x) => throw error1)
|
|
.listen(null, onError: expectErrorOnly, cancelOnError: true);
|
|
controller.add(null);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
Future<bool?>.value(controller.stream.every((x) => throw error1))
|
|
.catchError(expectErrorOnly);
|
|
controller.add(null);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
Future<bool?>.value(controller.stream.any((x) => throw error1))
|
|
.catchError(expectErrorOnly);
|
|
controller.add(null);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
controller.stream
|
|
.firstWhere((x) => throw error1)
|
|
.catchError(expectErrorOnly);
|
|
controller.add(null);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
controller.stream
|
|
.lastWhere((x) => throw error1)
|
|
.catchError(expectErrorOnly);
|
|
controller.add(null);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
controller.stream
|
|
.singleWhere((x) => throw error1)
|
|
.catchError(expectErrorOnly);
|
|
controller.add(null);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
controller.stream
|
|
.reduce((x, y) => throw error1)
|
|
.catchError(expectErrorOnly);
|
|
controller.add(null);
|
|
controller.add(null);
|
|
}
|
|
|
|
{
|
|
asyncStart();
|
|
StreamController controller = new StreamController();
|
|
controller.stream
|
|
.fold(null, (x, y) => throw error1)
|
|
.catchError(expectErrorOnly);
|
|
controller.add(null);
|
|
}
|
|
}
|
|
|
|
testNoChange() {
|
|
void testTransparent() {
|
|
testProgrammaticErrors(expectError);
|
|
testThrownErrors(expectErrorOnly);
|
|
}
|
|
|
|
// Run directly.
|
|
testTransparent();
|
|
|
|
// Run in a zone that doesn't change callback.
|
|
runZoned(testTransparent,
|
|
zoneSpecification:
|
|
new ZoneSpecification(handleUncaughtError: (s, p, z, e, t) {}));
|
|
|
|
// Run in zone that delegates to root zone
|
|
runZoned(testTransparent,
|
|
zoneSpecification: new ZoneSpecification(
|
|
errorCallback: (s, p, z, e, t) => p.errorCallback(z, e, t)));
|
|
|
|
// Run in a zone that returns null from the callback.
|
|
runZoned(testTransparent,
|
|
zoneSpecification:
|
|
new ZoneSpecification(errorCallback: (s, p, z, e, t) => null));
|
|
|
|
// Run in zone that returns same values.
|
|
runZoned(testTransparent,
|
|
zoneSpecification: new ZoneSpecification(
|
|
errorCallback: (s, p, z, e, t) => new AsyncError(e, t)));
|
|
|
|
// Run in zone that returns null, inside zone that does replacement.
|
|
runZoned(() {
|
|
runZoned(testTransparent,
|
|
zoneSpecification:
|
|
new ZoneSpecification(errorCallback: (s, p, z, e, t) => null));
|
|
}, zoneSpecification: replaceZoneSpec);
|
|
}
|
|
|
|
void testWithReplacement() {
|
|
void testReplaced() {
|
|
testProgrammaticErrors(expectReplaced);
|
|
testThrownErrors(expectReplaced);
|
|
}
|
|
|
|
// Zone which replaces errors.
|
|
runZoned(testReplaced, zoneSpecification: replaceZoneSpec);
|
|
|
|
// Nested zone, only innermost gets to act.
|
|
runZoned(() {
|
|
runZoned(testReplaced, zoneSpecification: replaceZoneSpec);
|
|
}, zoneSpecification: replaceZoneSpec);
|
|
|
|
// Use delegation to parent which replaces.
|
|
runZoned(() {
|
|
runZoned(testReplaced,
|
|
zoneSpecification: new ZoneSpecification(
|
|
errorCallback: (s, p, z, e, t) => p.errorCallback(z, e, t)));
|
|
}, zoneSpecification: replaceZoneSpec);
|
|
}
|