[tests] Adding and extending tests for required named parameters.

Some of these are currently disabled in the CFE. See: https://github.com/dart-lang/sdk/blob/master/pkg/front_end/lib/src/fasta/source/source_library_builder.dart#L403

Change-Id: If5aeff4e3743ea589e8c2572ada869aeced5c826
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/144671
Reviewed-by: Mayank Patke <fishythefish@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
This commit is contained in:
Mark Zhou 2020-05-04 21:17:47 +00:00 committed by commit-bot@chromium.org
parent 14dfa1b9ee
commit 3391be2d16
5 changed files with 81 additions and 0 deletions

View file

@ -0,0 +1,67 @@
// 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.isFalse(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.isFalse(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);
}

View file

@ -15,13 +15,17 @@ main() {
// Valid: Invocation with all arguments provided.
f("", p1: 100, p2: "", p3: true);
Function.apply(f, [""], {#p1: 100, #p2: "", #p3: true});
// Valid: Invocation that omits non-required named arguments.
f("", p1: 100, p2: "");
Function.apply(f, [""], {#p1: 100, #p2: ""});
// Valid: Invocation may pass null as a required named argument.
f("", p1: null, p2: null);
Function.apply(f, [""], {#p1: null, #p2: null});
// Valid: Invocation may omit a required named argument.
f("", p1: 100);
Function.apply(f, [""], {#p1: 100});
}

View file

@ -32,9 +32,15 @@ main() {
Expect.throws(() {
f("", p1: null, p2: null);
});
Expect.throws(() {
Function.apply(f, [""], {#p1: null, #p2: null});
});
// Invalid: Invocation that omits a required named argument.
Expect.throws(() {
f("", p1: 100);
});
Expect.throws(() {
Function.apply(f, [""], {#p1: 100});
});
}

View file

@ -19,7 +19,9 @@ main() {
// Valid: Invocation with all arguments provided.
f("", p1: 100, p2: "", p3: true);
Function.apply(f, [""], {#p1: 100, #p2: "", #p3: true});
// Valid: Invocation that omits non-required named arguments.
f("", p1: 100, p2: "");
Function.apply(f, [""], {#p1: 100, #p2: ""});
}

View file

@ -26,7 +26,9 @@ main() {
// Valid: Invocation may pass null as a required named argument in weak mode.
f("", p1: null, p2: null);
Function.apply(f, [""], {#p1: null, #p2: null});
// Valid: Invocation may omit a required named argument in weak mode.
f("", p1: 100);
Function.apply(f, [""], {#p1: 100});
}