// 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. import 'dart:math'; import 'package:expect/expect.dart'; void testInstantiateToBounds() { f() => [T, U]; g, U extends int>() => [T, U]; h(T x, U y) => h.runtimeType.toString(); Expect.listEquals([num, num], (f as dynamic)()); Expect.equals('List|int', (g as dynamic)().join('|')); Expect.equals('(T, U) => String', (h as dynamic)(null, null)); i>() => null; j, S extends T>() => null; Expect.throws( () => (i as dynamic)(), (e) => '$e'.contains('Instantiate to bounds')); Expect.throws( () => (j as dynamic)(), (e) => '$e'.contains('Instantiate to bounds')); } void testChecksBound() { f(T x) => x; Expect.equals((f as dynamic)(42), 42); Expect.throws(() => (f as dynamic)('42')); msg(t1, t2, tf) => Expect.throws(() => (f as dynamic)(42), (e) => '$e' == 'type `Object` does not extend `num` of `T'); g(T x, U y) => x; Expect.equals((g as dynamic)(42.0, 100), 42.0); Expect.throws(() => (g as dynamic)('hi', 100)); Expect.throws(() => (g as dynamic)(42.0, 100), (e) => '$e' == 'type `double` does not extend `int` of `T`.'); Expect.throws(() => (g as dynamic)(42.0, 100), (e) => '$e' == 'type `Object` does not extend `num` of `U`.'); } typedef G = T Function(T x); void testSubtype() { f(T x) => x + 2; dynamic d = f; Expect.equals(d(40.0), 42.0); Expect.equals((f as G)(40), 42); Expect.equals((d as G)(40), 42); Expect.equals((f as G)(40.0), 42.0); Expect.equals((d as G)(40.0), 42.0); d as G; Expect.throws(() => d as G); Expect.throws(() => d as G); Expect.throws(() => d as G); } void testToString() { // TODO(jmesserly): I don't think the cast on `y` should be required. num f(T x, U y) => min(x, y as num); num g(T x, U y) => max(x as num, y as num); String h(T x, U y) => h.runtimeType.toString(); Expect.equals( f.runtimeType.toString(), '(T, U) => num'); Expect.equals(g.runtimeType.toString(), '(T, U) => num'); Expect.equals(h(42, 123.0), '(T, U) => String'); } main() { testInstantiateToBounds(); testToString(); testChecksBound(); testSubtype(); }