76548a7ab9
In dart2wasm applications are by default deployed in `-O2` mode which implies `--minify`. Given this is the default configuration for customers, we want good testing of this configuration and not large numbers of approved failures. => Rewrite various tests to not depend on `<obj>.runtimeType.toString()` Change-Id: I1108b28c63b8bec6ad94df0d7b878b3339776df9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/436281 Reviewed-by: Lasse Nielsen <lrn@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
125 lines
4.6 KiB
Dart
125 lines
4.6 KiB
Dart
// Copyright (c) 2017, 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.
|
|
|
|
// Formatting can break multitests, so don't format them.
|
|
// dart format off
|
|
|
|
import 'dart:math';
|
|
import 'package:expect/expect.dart';
|
|
|
|
Type getType<T>() => T;
|
|
|
|
void testInstantiateToBounds() {
|
|
f<T extends num, U extends T>() => [T, U];
|
|
g<T extends List<U>, U extends int>() => [T, U];
|
|
h<T extends U, U extends num>(T x, U y) => [T, U];
|
|
|
|
// Check that instantiate to bounds creates the correct type arguments
|
|
// during dynamic calls.
|
|
Expect.listEquals([num, num], (f as dynamic)());
|
|
Expect.listEquals([getType<List<int>>(), int], (g as dynamic)());
|
|
Expect.listEquals([num, num], (h as dynamic)(-1, -1));
|
|
|
|
// Check that when instantiate to bounds creates a super-bounded type argument
|
|
// during a dynamic call, an error is thrown.
|
|
i<T extends Iterable<T>>() => null;
|
|
j<T extends Iterable<S>, S extends T>() => null;
|
|
Expect.throwsTypeError(() => (i as dynamic)(), "Super bounded type argument");
|
|
Expect.throwsTypeError(() => (j as dynamic)(), "Super bounded type argument");
|
|
}
|
|
|
|
void testChecksBound() {
|
|
f<T extends num>(T x) => x;
|
|
g<T extends U, U extends num>(T x, U y) => x;
|
|
|
|
// Check that arguments are checked against the correct types when instantiate
|
|
// to bounds produces a type argument during a dynamic call.
|
|
Expect.equals((f as dynamic)(42), 42);
|
|
Expect.equals((g as dynamic)(42.0, 100), 42.0);
|
|
Expect.throwsTypeError(() => (f as dynamic)('42'), "Argument check");
|
|
Expect.throwsTypeError(() => (g as dynamic)('hi', 100), "Argument check");
|
|
|
|
// Check that an actual type argument is checked against the bound during a
|
|
// dynamic call.
|
|
Expect.equals((f as dynamic)<int>(42), 42);
|
|
Expect.equals((g as dynamic)<double, num>(42.0, 100), 42.0);
|
|
Expect.throwsTypeError(() => (g as dynamic)<double, int>(42.0, 100),
|
|
"Type argument bounds check");
|
|
Expect.throwsTypeError(
|
|
() => (f as dynamic)<Object>(42), "Type argument bounds check");
|
|
Expect.throwsTypeError(() => (g as dynamic)<double, int>(42.0, 100),
|
|
"Type argument bounds check");
|
|
Expect.throwsTypeError(() => (g as dynamic)<num, Object>(42.0, 100),
|
|
"Type argument bounds check");
|
|
}
|
|
|
|
typedef G<U> = num Function<T extends U>(T x);
|
|
|
|
typedef F<U> = Object Function<T extends U>(T x);
|
|
|
|
void testSubtype() {
|
|
num f<T extends num>(T x) => x + 2;
|
|
dynamic d = f;
|
|
|
|
// Check that casting to an equal generic function type works
|
|
Expect.equals((f as G<num>)(40), 42);
|
|
Expect.equals((d as G<num>)(40), 42);
|
|
|
|
// Check that casting to a more general generic function type works
|
|
Expect.equals((f as F<num>)(40), 42);
|
|
Expect.equals((d as F<num>)(40), 42);
|
|
|
|
// Check that casting to a generic function with more specific bounds fails
|
|
Expect.throwsTypeError(
|
|
() => (f as G<int>), "Generic functions are invariant");
|
|
Expect.throwsTypeError(
|
|
() => (d as G<int>), "Generic functions are invariant");
|
|
Expect.throwsTypeError(
|
|
() => (f as G<double>), "Generic functions are invariant");
|
|
Expect.throwsTypeError(
|
|
() => (d as G<double>), "Generic functions are invariant");
|
|
Expect.throwsTypeError(
|
|
() => (f as G<Null>), "Generic functions are invariant");
|
|
Expect.throwsTypeError(
|
|
() => (d as G<Null>), "Generic functions are invariant");
|
|
|
|
// Check that casting to a generic function with a more general bound fails
|
|
Expect.throwsTypeError(
|
|
() => (f as G<Object>), "Generic functions are invariant");
|
|
Expect.throwsTypeError(
|
|
() => (d as G<Object>), "Generic functions are invariant");
|
|
|
|
// Check that casting to a generic function with an unrelated bound fails
|
|
Expect.throwsTypeError(
|
|
() => (f as G<String>), "Generic functions are invariant");
|
|
Expect.throwsTypeError(
|
|
() => (d as G<String>), "Generic functions are invariant");
|
|
}
|
|
|
|
void testToString() {
|
|
num f<T extends num, U extends T>(T x, U y) => min(x, y);
|
|
num g<T, U>(T x, U y) => max(x as num, y as num);
|
|
String h<T, U>(T x, U y) => h.runtimeType.toString();
|
|
|
|
// Check that generic method types are printed in a reasonable way
|
|
void checkMatches(String pattern, Type type) {
|
|
Expect.isTrue(RegExp(pattern).hasMatch(type.toString()));
|
|
}
|
|
|
|
checkMatches(
|
|
'<(\\w+) extends $num, (\\w+) extends \\1>\\(\\1, \\2\\) => $num',
|
|
f.runtimeType);
|
|
checkMatches('<(\\w+), (\\w+)>\\(\\1, \\2\\) => $num',
|
|
g.runtimeType);
|
|
checkMatches(
|
|
'<(\\w+), (\\w+)>\\(\\1, \\2\\) => $String', h.runtimeType);
|
|
}
|
|
|
|
main() {
|
|
testInstantiateToBounds(); //# 01: ok
|
|
testToString(); //# 02: ok
|
|
testChecksBound(); //# 03: ok
|
|
testSubtype(); //# 04: ok
|
|
}
|