| Index: tests/lib/mirrors/reflected_type_generics_test.dart
|
| diff --git a/tests/lib/mirrors/reflected_type_generics_test.dart b/tests/lib/mirrors/reflected_type_generics_test.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f10425c4337037b1bf114ebaf0520ec0586fd537
|
| --- /dev/null
|
| +++ b/tests/lib/mirrors/reflected_type_generics_test.dart
|
| @@ -0,0 +1,99 @@
|
| +// Copyright (c) 2016, 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.
|
| +
|
| +library test.reflected_type_generics_test;
|
| +
|
| +@MirrorsUsed(targets: "test.reflected_type_generics_test")
|
| +import 'dart:mirrors';
|
| +
|
| +import 'package:expect/expect.dart';
|
| +
|
| +import 'reflected_type_helper.dart';
|
| +
|
| +class A<T> {}
|
| +
|
| +class P {}
|
| +
|
| +class B extends A<P> {}
|
| +
|
| +class C<K, V> {}
|
| +
|
| +class D<T> extends A<T> {}
|
| +
|
| +class E<K> extends C<K, int> {}
|
| +
|
| +class F<G> {}
|
| +
|
| +typedef bool Predicate<T>(T arg);
|
| +
|
| +class FBounded<S extends FBounded> {}
|
| +
|
| +class Helper<T> {
|
| + Type get param => T;
|
| +}
|
| +
|
| +class Mixin<T extends P> {}
|
| +
|
| +class Composite<K extends P, V> extends Object with Mixin<K> {}
|
| +
|
| +main() {
|
| + // "Happy" paths:
|
| + expectReflectedType(reflectType(A, [P]), new A<P>().runtimeType);
|
| + expectReflectedType(reflectType(C, [B, P]), new C<B, P>().runtimeType);
|
| + expectReflectedType(reflectType(D, [P]), new D<P>().runtimeType);
|
| + expectReflectedType(reflectType(E, [P]), new E<P>().runtimeType);
|
| + expectReflectedType(
|
| + reflectType(FBounded, [FBounded]), new FBounded<FBounded>().runtimeType);
|
| +
|
| + var predicateHelper = new Helper<Predicate<P>>();
|
| + expectReflectedType(reflectType(Predicate, [P]), predicateHelper.param); /// 01: ok
|
| + var composite = new Composite<P, int>();
|
| + expectReflectedType(reflectType(Composite, [P, int]), composite.runtimeType);
|
| +
|
| + // Edge cases:
|
| + Expect.throws(
|
| + () => reflectType(P, []),
|
| + (e) => e is ArgumentError && e.invalidValue is List,
|
| + "Should throw an ArgumentError if reflecting not a generic class with "
|
| + "empty list of type arguments");
|
| + Expect.throws( /// 03: ok
|
| + () => reflectType(P, [B]), /// 03: continued
|
| + (e) => e is Error, /// 03: continued
|
| + "Should throw an ArgumentError if reflecting not a generic class with " /// 03: continued
|
| + "some type arguments"); /// 03: continued
|
| + Expect.throws(
|
| + () => reflectType(A, []),
|
| + (e) => e is ArgumentError && e.invalidValue is List,
|
| + "Should throw an ArgumentError if type argument list is empty for a "
|
| + "generic class");
|
| + Expect.throws( /// 04: ok
|
| + () => reflectType(A, [P, B]), /// 04: continued
|
| + (e) => e is ArgumentError && e.invalidValue is List, /// 04: continued
|
| + "Should throw an ArgumentError if number of type arguments is not " /// 04: continued
|
| + "correct"); /// 04: continued
|
| + Expect.throws(() => reflectType(B, [P]), (e) => e is Error, /// 05: ok
|
| + "Should throw an ArgumentError for non-generic class extending " /// 05: continued
|
| + "generic one"); /// 05: continued
|
| + Expect.throws(
|
| + () => reflectType(A, ["non-type"]),
|
| + (e) => e is ArgumentError && e.invalidValue is List,
|
| + "Should throw an ArgumentError when any of type arguments is not a Type");
|
| + Expect.throws( /// 06: ok
|
| + () => reflectType(A, [P, B]), /// 06: continued
|
| + (e) => e is ArgumentError && e.invalidValue is List, /// 06: continued
|
| + "Should throw an ArgumentError if number of type arguments is not correct " /// 06: continued
|
| + "for generic extending another generic"); /// 06: continued
|
| + Expect.throws(
|
| + () => reflectType(reflectType(F).typeVariables[0].reflectedType, [int]));
|
| + Expect.throws(() => reflectType(FBounded, [int])); /// 02: ok
|
| + var boundedType =
|
| + reflectType(FBounded).typeVariables[0].upperBound.reflectedType;
|
| + Expect.throws(() => reflectType(boundedType, [int])); /// 02: ok
|
| + Expect.throws(() => reflectType(Composite, [int, int])); /// 02: ok
|
| +
|
| + // Instantiation of a generic class preserves type information:
|
| + ClassMirror m = reflectType(A, [P]) as ClassMirror;
|
| + var instance = m.newInstance(const Symbol(""), []).reflectee;
|
| + Expect.equals(new A<P>().runtimeType, instance.runtimeType);
|
| +}
|
|
|