mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 21:40:07 +00:00
Update language_2/nested_generic_closure_test.dart.
No longer depends on the unspecified `Type.toString`. Bug: http://dartbug.com/37452 Change-Id: Ie7eeeecdc8970831082e763edc46f195a8bfc7e7 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108275 Commit-Queue: Lasse R.H. Nielsen <lrn@google.com> Reviewed-by: Stephen Adams <sra@google.com> Reviewed-by: Erik Ernst <eernst@google.com>
This commit is contained in:
parent
52858391e6
commit
ac41a20081
134
tests/corelib_2/type_tostring_test.dart
Normal file
134
tests/corelib_2/type_tostring_test.dart
Normal file
|
@ -0,0 +1,134 @@
|
|||
// Copyright (c) 2019, 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.
|
||||
|
||||
// Testing the behavior of `Type.toString`.
|
||||
//
|
||||
// The behavior is *unspecified*, but users may depend on it.
|
||||
// This test ensures that we do not change the format inadvertently.
|
||||
// If we decide to change the format, it should be deliberate and consistent.
|
||||
|
||||
import "dart:async" show FutureOr;
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
void expectType(Type type, Pattern text) {
|
||||
var typeString = "$type";
|
||||
if (typeString.contains("minimized:")) {
|
||||
return; // No checks for minimized types.
|
||||
}
|
||||
if (text is String) {
|
||||
Expect.equals(text, typeString);
|
||||
return;
|
||||
}
|
||||
var match = text.matchAsPrefix(typeString);
|
||||
if (match != null && match.end == typeString.length) return;
|
||||
Expect.fail(
|
||||
"$typeString was not matched by $text${match == null ? "" : ", match: ${match[0]}"}");
|
||||
}
|
||||
|
||||
void expect<T>(Pattern text) {
|
||||
expectType(T, text);
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Simple interface types.
|
||||
expect<int>("int");
|
||||
expect<Object>("Object");
|
||||
expect<Null>("Null");
|
||||
expect<Base>("Base");
|
||||
expect<Mixin>("Mixin");
|
||||
// Named mixin applications use their name.
|
||||
expect<MixinApplication>("MixinApplication");
|
||||
|
||||
// Non-class, non-function types.
|
||||
expect<void>("void");
|
||||
expect<dynamic>("dynamic");
|
||||
expect<Function>("Function");
|
||||
// TODO: Add Never with NNBD.
|
||||
|
||||
// Generic interface types.
|
||||
expect<List<int>>("List<int>");
|
||||
expect<Iterable<Object>>("Iterable<Object>");
|
||||
expect<Map<List<String>, Future<void>>>("Map<List<String>, Future<void>>");
|
||||
expect<GenericMixin<String>>("GenericMixin<String>");
|
||||
|
||||
// Generic non-class, non-function type.
|
||||
expect<FutureOr<int>>("FutureOr<int>");
|
||||
expect<FutureOr<Object>>("FutureOr<Object>");
|
||||
expect<FutureOr<FutureOr<Future<Object>>>>(
|
||||
"FutureOr<FutureOr<Future<Object>>>");
|
||||
expect<FutureOr<Null>>("FutureOr<Null>");
|
||||
// TODO: Add nullable types with NNBD.
|
||||
|
||||
// Private names may be mangled.
|
||||
expect<_Private>(re(r'_Private\b.*$'));
|
||||
|
||||
// Function types.
|
||||
expect<void Function()>("() => void");
|
||||
expect<String Function()>("() => String");
|
||||
expect<String Function(String)>("(String) => String");
|
||||
expect<String Function(int, [String])>("(int, [String]) => String");
|
||||
expect<String Function(int, {String z})>("(int, {String z}) => String");
|
||||
expect<int Function(void Function(String))>("((String) => void) => int");
|
||||
expect<int Function(void) Function(String)>("(String) => (void) => int");
|
||||
|
||||
// A type alias is expanded to its type.
|
||||
expect<Typedef>("(dynamic) => dynamic");
|
||||
expect<Typedef<int>>("(int) => int");
|
||||
expectType(Typedef, "(dynamic) => dynamic");
|
||||
|
||||
// Generic functions do not promise to preserve type variable names,
|
||||
// but do keep the structure of `<typevars>(params) => result`.
|
||||
|
||||
// Cannot pass a generic type as type argument, so passing the Type object
|
||||
// derived from evaluating the typedef name.
|
||||
|
||||
// Format: <T>() => void
|
||||
expectType(G0, re(r"<\w+>\(\) => void$"));
|
||||
// Format: <T>() => T
|
||||
expectType(G1, re(r"<(\w+)>\(\) => \1$"));
|
||||
// Format: <T>(T) => T
|
||||
expectType(G2, re(r"<(\w+)>\(\1\) => \1$"));
|
||||
// Format: <T>(<S>(S, T) => S) => T
|
||||
expectType(G3, re(r"<(\w+)>\(<(\w+)>\(\2, \1\) => \2\) => \1$"));
|
||||
// Format: <S>(S) => <T>(S, T) => S
|
||||
expectType(G4, re(r"<(\w+)>\(\1\) => <(\w+)>\(\1, \2\) => \1$"));
|
||||
// Format: <S, T>(S, T) => S
|
||||
expectType(G5, re(r"<(\w+), (\w+)>\(\1, \2\) => \1$"));
|
||||
|
||||
// Format: <T>(<S>(S) => S) => T
|
||||
expectType(Weird, re(r"<(\w+)>\(<(\w+)>\(\2\) => \2\) => \1$"));
|
||||
|
||||
// One with everything.
|
||||
expect<FutureOr<void Function([T Function<S, T>(Map<dynamic, Typedef<S>>)])>>(
|
||||
// Format: FutureOr<([<S, T>(Map<dynamic, (S) => S>) => T]) => void>
|
||||
re(r"FutureOr<\(\[<(\w+), (\w+)>\(Map<dynamic, "
|
||||
r"\(\1\) => \1>\) => \2\]\) => void>$"));
|
||||
}
|
||||
|
||||
// Types to test against.
|
||||
class _Private {}
|
||||
|
||||
class Base {}
|
||||
|
||||
mixin Mixin {}
|
||||
|
||||
class MixinApplication = Base with Mixin;
|
||||
|
||||
mixin GenericMixin<T> implements List<T> {}
|
||||
|
||||
typedef Typedef<T> = T Function(T);
|
||||
|
||||
// Generic function types.
|
||||
typedef G0 = void Function<T>();
|
||||
typedef G1 = T Function<T>();
|
||||
typedef G2 = T Function<T>(T);
|
||||
typedef G3 = T Function<T>(S Function<S>(S, T));
|
||||
typedef G4 = S Function<T>(S, T) Function<S>(S);
|
||||
typedef G5 = S Function<S, T>(S, T);
|
||||
|
||||
typedef Weird = Function Function<Function>(
|
||||
Function Function<Function>(Function));
|
||||
|
||||
RegExp re(String source) => RegExp(source);
|
|
@ -2,8 +2,6 @@
|
|||
// 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.
|
||||
|
||||
// TODO(37452): Avoid using unspecified 'toString' behaviour in language test.
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
void foo(F f<F>(F f)) {}
|
||||
|
@ -11,7 +9,7 @@ void foo(F f<F>(F f)) {}
|
|||
B bar<B>(B g<F>(F f)) => null;
|
||||
|
||||
Function baz<B>() {
|
||||
B foo<F>(F f) => null;
|
||||
B foo<F>(B b, F f) => null;
|
||||
return foo;
|
||||
}
|
||||
|
||||
|
@ -25,34 +23,27 @@ class C<T> {
|
|||
}
|
||||
|
||||
main() {
|
||||
expectOne(
|
||||
foo.runtimeType.toString(),
|
||||
["(<F>(F) => F) => void", "(<T1>(T1) => T1) => void"],
|
||||
);
|
||||
expectOne(
|
||||
bar.runtimeType.toString(),
|
||||
["<B>(<F>(F) => B) => B", "<T1>(<T2>(T2) => T1) => T1"],
|
||||
);
|
||||
expectOne(
|
||||
baz<int>().runtimeType.toString(),
|
||||
["<F>(F) => int", "<T1>(T1) => int"],
|
||||
);
|
||||
// Check the run-time type of the functions with generic parameters.
|
||||
|
||||
var c = new C<bool>();
|
||||
expectOne(
|
||||
c.foo.runtimeType.toString(),
|
||||
["(<F>(bool, F) => F) => void", "(<T1>(bool, T1) => T1) => void"],
|
||||
);
|
||||
expectOne(
|
||||
c.bar.runtimeType.toString(),
|
||||
["<B>(<F>(bool, F) => B) => B", "<T1>(<T2>(bool, T2) => T1) => T1"],
|
||||
);
|
||||
expectOne(
|
||||
c.baz<int>().runtimeType.toString(),
|
||||
["<F>(bool, F) => int", "<T1>(bool, T1) => int"],
|
||||
);
|
||||
Expect.type<void Function(X Function<X>(X))>(foo);
|
||||
|
||||
Expect.isTrue(bar is X1 Function<X1>(X1 Function<X2>(X2)));
|
||||
|
||||
Expect.isTrue(baz<int>() is int Function<X1>(int, X1));
|
||||
Expect.isTrue(baz<Object>() is Object Function<X1>(Object, X1));
|
||||
Expect.isTrue(baz<Null>() is Null Function<X1>(Null, X1));
|
||||
|
||||
void testC<T>() {
|
||||
var c = new C<T>();
|
||||
|
||||
Expect.type<void Function(F Function<F>(T, F))>(c.foo);
|
||||
|
||||
Expect.isTrue(c.bar is X1 Function<X1>(X1 Function<X2>(T, X2)));
|
||||
|
||||
Expect.isTrue(c.baz<int>() is int Function<X1>(T, X1));
|
||||
}
|
||||
|
||||
expectOne(String name, Iterable<String> names) {
|
||||
Expect.isTrue(names.contains(name), '"$name" should be one of: ${names}');
|
||||
testC<bool>();
|
||||
testC<Object>();
|
||||
testC<Null>();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue