// 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. typedef R Fun(A argument); class C { const C(); T returns() => null; void accepts(T x) {} } class NullBound {} class ListBound> {} main() { testClassTypes(); testFunctionTypes(); } void testClassTypes() { var cn = new C(); Expect.isTrue(cn is C, "C is C"); Expect.isTrue(cn is C, "C is C"); Expect.isTrue(cn is C, "C is C"); Expect.isNotNull(cn as C, "C as C"); Expect.isNotNull(cn as C, "C as C"); Expect.isNotNull(cn as C, "C as C"); var ccn = new C>(); Expect.isTrue(ccn is C>); Expect.isTrue(ccn is C>); Expect.isTrue(ccn is C>); Expect.isNotNull(ccn as C>); Expect.isNotNull(ccn as C>); Expect.isNotNull(ccn as C>); var ci = new C(); Expect.isFalse(ci is C); var co = new C(); Expect.isFalse(co is C); if (!typeAssertionsEnabled) return; List li1 = const []; C x1 = cn; C x2 = cn; Expect.identical(x1, cn); Expect.identical(x2, cn); const C cocn = const C(); const C coco = cocn; const C 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 nb = new NullBound(); // Should not fail. use(nb); // Avoid "nb unused" warning. ListBound> lb = new ListBound(); // Should not fails use(lb); // Avoid "nb unused" warning. } void testFunctionTypes() { T1 t1 = new T1(); T2 t2 = new T2(); T1 t = t2; Fun f1 = t1.foo; Fun f2 = t.bar; f1 = t1.baz; f2 = t.qux; use(f1); use(f2); var l = new List>(); Expect.isTrue(l is List>); l = new List>(); Expect.isTrue(l is List>); Expect.isTrue(((int _) => null) is Fun); Null fun(int x) => null; Fun fun2 = fun; // Safe assignment. if (fun2 is Fun) { // 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: 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; Null bar(Null x) => null; int baz(int x) => x; int qux(int x) => x; } // Avoid "variable not used" warnings. use(x) { return identical(x, x); }