Chromium Code Reviews| Index: tests/language/null_bottom_test.dart |
| diff --git a/tests/language/null_bottom_test.dart b/tests/language/null_bottom_test.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..efc13c900cf02393042945dc3f745ec290a44cc5 |
| --- /dev/null |
| +++ b/tests/language/null_bottom_test.dart |
| @@ -0,0 +1,133 @@ |
| +// 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. |
| +// Dart test for testing the ternary operator. |
| + |
| +import "package:expect/expect.dart"; |
| + |
| +// Test that `Null` acts like the bottom type - less than any other type. |
| + |
| +bool checkedMode = () { bool c = false; assert(c = true); return c; } (); |
|
floitsch
2016/12/20 10:52:58
isCheckedMode
Lasse Reichstein Nielsen
2017/01/02 12:48:50
Done.
|
| + |
| +typedef R Fun<A, R>(A argument); |
| + |
| +class C<T> { |
| + const C(); |
| + T returns() => null; |
| + void accepts(T x) {} |
| +} |
| + |
| +class NullBound<T extends num> {} |
| + |
| +main() { |
| + testClassTypes(); |
| + testFunctionTypes(); |
| +} |
| + |
| +void testClassTypes() { |
| + var cn = new C<Null>(); |
| + |
| + Expect.isTrue(cn is C<Null>); |
| + Expect.isTrue(cn is C<Object>); |
| + Expect.isTrue(cn is C<int>); |
| + |
| + Expect.isNotNull(cn as C<Null>); |
| + Expect.isNotNull(cn as C<Object>); |
| + Expect.isNotNull(cn as C<int>); |
| + |
| + var ccn = new C<C<Null>>(); |
| + |
| + Expect.isTrue(ccn is C<C<Null>>); |
| + Expect.isTrue(ccn is C<C<Object>>); |
| + Expect.isTrue(ccn is C<C<int>>); |
| + |
| + Expect.isNotNull(ccn as C<C<Null>>); |
| + Expect.isNotNull(ccn as C<C<Object>>); |
| + Expect.isNotNull(ccn as C<C<int>>); |
| + |
| + var ci = new C<int>(); |
| + Expect.isFalse(ci is C<Null>); |
| + |
| + var co = new C<Object>(); |
| + Expect.isFalse(co is C<Null>); |
| + |
| + if (!checkedMode) return; |
| + |
| + List<int> = const <Null>[]; |
| + |
| + C<Null> x1 = cn; |
| + C<Object> x2 = cn; |
| + |
| + Expect.identical(x1 , cn); |
| + Expect.identical(x2 , cn); |
| + |
| + const C<Null> cocn = const C<Null>(); |
| + const C<Object> coco = cocn; |
| + const C<int> coci = cocn; |
| + |
| + Expect.identical(cocn, coco); |
| + Expect.identical(cocn, coci); |
| + |
| + Expect.throws(() { |
| + Null x = "string" as dynamic; |
| + use(x); // Avoid "x unused" warning. |
| + }); |
| + |
| + Expect.throws(() { |
| + Null x = new Object(); |
| + use(x); // Avoid "x unused" warning. |
| + }); |
| + |
| + NullBound<int> nb = new NullBound<Null>(); // Should not fail. |
| + use(nb); // Avoid "nb unused" warning. |
| +} |
| + |
| +void testFunctionTypes() { |
| + T1 t1 = new T1(); |
| + T2 t2 = new T2(); |
| + T1 t = t2; |
| + |
| + Fun<int, Null> f1 = t1.foo; |
| + Fun<Null, int> f2 = t.bar; |
| + f1 = t1.baz; |
| + f2 = t.qux; |
| + use(f1); |
| + use(f2); |
| + |
| + var l = new List<Fun<Null, Null>>(); |
| + Expect.isTrue(l is List<Fun<int, Null>>); |
|
floitsch
2016/12/20 10:52:58
Why is that?
a List of Null->Null should not be a
Lasse Reichstein Nielsen
2017/01/02 12:48:50
Done.
|
| + l = new List<Fun<int, int>>; |
| + Expect.isTrue(l is List<Fun<Null, num>>); |
| + |
| + Expect.isTrue(((int _) => null) is Fun<int, Null>); |
| + |
| + Null fun(int x) => null; |
| + Fun<Null, int> fun2 = fun; // Safe assignment. |
| + if (fun2 is Fun<int, Null>) { |
| + // If int->Null is *subtype* of Null->int (which it should be), |
| + // then type promotion succeeds. |
| + // If type promotion succeeds, the static type is int->Null, otherwise |
| + // it's Null->int. |
| + fun2(42); // Should not give a warning after type promotion. |
| + fun2(null).abs(); /// 03: static type warning, runtime error |
| + } |
| +} |
| + |
| +class T1 { |
| + Null foo(int x) => null; |
| + int bar(Null x) => null; |
| + Null baz(int x) => null; |
| + int qux(Null x) => null; |
| +} |
| + |
| +class T2 extends T1 { |
| + Null foo(Null x) => null; /// 01: static type warning |
| + Null bar(Null x) => null; |
| + int baz(int x) => x; /// 02: static type warning |
| + int qux(int x) => x; |
| +} |
| + |
| +// Avoid "variable not used" warnings. |
| +use(x) { |
| + return identical(x, x); |
| +} |