mirror of
https://github.com/dart-lang/sdk
synced 2024-09-19 23:31:42 +00:00
fa1d2c896d
Expect.equals (and Expect.listEquals) takes expected first and actual second. When these are flipped in tests, the failure message can be super hard to understand. Bug: Change-Id: I1d3c5a31365fa41ee7bcc7781474d76de9184cd5 Reviewed-on: https://dart-review.googlesource.com/23420 Reviewed-by: Jonas Termansen <sortie@google.com> Commit-Queue: Kevin Millikin <kmillikin@google.com>
79 lines
2.6 KiB
Dart
79 lines
2.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.
|
|
|
|
import 'dart:math';
|
|
import 'package:expect/expect.dart';
|
|
|
|
void testInstantiateToBounds() {
|
|
f<T extends num, U extends T>() => [T, U];
|
|
g<T extends List<U>, U extends int>() => [T, U];
|
|
h<T extends num, U extends T>(T x, U y) => h.runtimeType.toString();
|
|
|
|
Expect.listEquals([num, num], (f as dynamic)());
|
|
Expect.equals('List<int>|int', (g as dynamic)().join('|'));
|
|
Expect.equals('<T extends num, U extends T>(T, U) => String',
|
|
(h as dynamic)(null, null));
|
|
|
|
i<T extends Iterable<T>>() => null;
|
|
j<T extends Iterable<S>, 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 extends num>(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)<Object>(42),
|
|
(e) => '$e' == 'type `Object` does not extend `num` of `T');
|
|
|
|
g<T extends U, U extends num>(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)<double, int>(42.0, 100),
|
|
(e) => '$e' == 'type `double` does not extend `int` of `T`.');
|
|
|
|
Expect.throws(() => (g as dynamic)<num, Object>(42.0, 100),
|
|
(e) => '$e' == 'type `Object` does not extend `num` of `U`.');
|
|
}
|
|
|
|
typedef G<U> = T Function<T extends U>(T x);
|
|
|
|
void testSubtype() {
|
|
f<T extends num>(T x) => x + 2;
|
|
|
|
dynamic d = f;
|
|
Expect.equals(d(40.0), 42.0);
|
|
Expect.equals((f as G<int>)(40), 42);
|
|
Expect.equals((d as G<int>)(40), 42);
|
|
Expect.equals((f as G<double>)(40.0), 42.0);
|
|
Expect.equals((d as G<double>)(40.0), 42.0);
|
|
|
|
d as G<Null>;
|
|
Expect.throws(() => d as G);
|
|
Expect.throws(() => d as G<Object>);
|
|
Expect.throws(() => d as G<String>);
|
|
}
|
|
|
|
void testToString() {
|
|
// TODO(jmesserly): I don't think the cast on `y` should be required.
|
|
num f<T extends num, U extends T>(T x, U y) => min(x, y as num);
|
|
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();
|
|
Expect.equals(
|
|
f.runtimeType.toString(), '<T extends num, U extends T>(T, U) => num');
|
|
Expect.equals(g.runtimeType.toString(), '<T, U>(T, U) => num');
|
|
Expect.equals(h(42, 123.0), '<T, U>(T, U) => String');
|
|
}
|
|
|
|
main() {
|
|
testInstantiateToBounds();
|
|
testToString();
|
|
testChecksBound();
|
|
testSubtype();
|
|
}
|