// Copyright (c) 2020, 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. // Requirements=nnbd import 'dart:_rti' as rti; import 'dart:_foreign_helper' show JS; import "package:expect/expect.dart"; const typeRulesJson = r''' { "B": {"A": []}, "C": {"B": []} } '''; final typeRules = JS('=Object', 'JSON.parse(#)', typeRulesJson); main() { var universe = rti.testingCreateUniverse(); rti.testingAddRules(universe, typeRules); // Recipe is properly parsed var rti1 = rti.testingUniverseEval(universe, "@(B,{a!B,b:B,c!B})"); // Subtype must be contravariant in its named parameter types var rti2 = rti.testingUniverseEval(universe, "@(B,{a!A,b:B,c!B})"); Expect.isTrue(rti.testingIsSubtype(universe, rti2, rti1)); rti2 = rti.testingUniverseEval(universe, "@(B,{a!B,b:A,c!B})"); Expect.isTrue(rti.testingIsSubtype(universe, rti2, rti1)); rti2 = rti.testingUniverseEval(universe, "@(B,{a!C,b:B,c!B})"); Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1)); rti2 = rti.testingUniverseEval(universe, "@(B,{a!B,b:C,c!B})"); Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1)); // Subtype may not omit optional named parameters rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,c!A})"); Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1)); // Subtype may not omit required named parameters rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b:A})"); Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1)); // Subtype may contain additional named optional parameters rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b:A,c!A,d:A})"); Expect.isTrue(rti.testingIsSubtype(universe, rti2, rti1)); // Subtype may redeclare required parameters as optional. rti2 = rti.testingUniverseEval(universe, "@(A,{a:A,b:A,c:A})"); Expect.isTrue(rti.testingIsSubtype(universe, rti2, rti1)); // Subtype may not redeclare optional parameters as required rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b!A,c!A})"); Expect.equals( hasUnsoundNullSafety, rti.testingIsSubtype(universe, rti2, rti1)); // Subtype may not declare new required named parameters rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b:A,c!A,d!A})"); Expect.equals( hasUnsoundNullSafety, rti.testingIsSubtype(universe, rti2, rti1)); // Rti.toString() appears as expected Expect.equals('(B, {required B a, B b, required B c}) => dynamic', rti.testingRtiToString(rti1)); // Rti debug string properly annotates all required parameters Expect.equals( 2, 'required'.allMatches(rti.testingRtiToDebugString(rti1)).length); }