82b78916fd
Change-Id: If31c487e3ebe2c1ae847aff7c8994580b8b6f2f6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/309660 Reviewed-by: Alexander Thomas <athom@google.com> Commit-Queue: Alexander Thomas <athom@google.com>
222 lines
5.5 KiB
Dart
222 lines
5.5 KiB
Dart
// Copyright (c) 2023, 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.
|
|
|
|
/// Test various places that implicit casts from dynamic can be inserted in
|
|
/// patterns and what happens when those casts succeed and fail.
|
|
|
|
import "package:expect/expect.dart";
|
|
|
|
main() {
|
|
testRelational();
|
|
testTypedVariable();
|
|
testListPattern();
|
|
testMapPattern();
|
|
testObjectPattern();
|
|
testListDestructure();
|
|
testMapDestructure();
|
|
testObjectDestructure();
|
|
}
|
|
|
|
class C {
|
|
int get knownInt => 123;
|
|
dynamic get dynamicInt => 123;
|
|
dynamic get dynamicString => 'wrong type';
|
|
}
|
|
|
|
void testRelational() {
|
|
// Test casts from dynamic on the right operand to a relational operator.
|
|
const dynamic big = 234;
|
|
|
|
// Matches in refutable context if type matches and operation is true.
|
|
if (123 case < big) {
|
|
// OK.
|
|
} else {
|
|
Expect.fail('Should have matched.');
|
|
}
|
|
}
|
|
|
|
void testTypedVariable() {
|
|
// Succeeds if cast succeeds.
|
|
var (int x) = 123 as dynamic;
|
|
Expect.equals(123, x);
|
|
|
|
// Throws in irrefutable context if cast fails.
|
|
Expect.throws(() {
|
|
var (int x) = 'wrong type' as dynamic;
|
|
});
|
|
|
|
// Matches in refutable context if type matches.
|
|
if (123 as dynamic case int x) {
|
|
Expect.equals(123, x);
|
|
} else {
|
|
Expect.fail('Should have matched.');
|
|
}
|
|
|
|
// Refuted in refutable context if type doesn't match.
|
|
if ('wrong type' as dynamic case int x) {
|
|
Expect.fail('Should not have matched.');
|
|
} else {
|
|
// OK.
|
|
}
|
|
}
|
|
|
|
void testListPattern() {
|
|
// Succeeds if cast to List succeeds.
|
|
var [x] = [123] as dynamic;
|
|
Expect.equals(123, x);
|
|
|
|
// Throws in irrefutable context if cast fails.
|
|
Expect.throws(() {
|
|
var [x] = 'wrong type' as dynamic;
|
|
});
|
|
|
|
// Matches in refutable context if type matches.
|
|
if ([123] as dynamic case [var x]) {
|
|
Expect.equals(123, x);
|
|
} else {
|
|
Expect.fail('Should have matched.');
|
|
}
|
|
|
|
// Refuted in refutable context if type doesn't match.
|
|
if ('wrong type' as dynamic case [var x]) {
|
|
Expect.fail('Should not have matched.');
|
|
} else {
|
|
// OK.
|
|
}
|
|
}
|
|
|
|
void testMapPattern() {
|
|
// Succeeds if cast to Map succeeds.
|
|
var {'x': x} = {'x': 123} as dynamic;
|
|
Expect.equals(123, x);
|
|
|
|
// Throws in irrefutable context if cast fails.
|
|
Expect.throws(() {
|
|
var {'x': x} = 'wrong type' as dynamic;
|
|
});
|
|
|
|
// Matches in refutable context if type matches.
|
|
if ({'x': 123} as dynamic case {'x': var x}) {
|
|
Expect.equals(123, x);
|
|
} else {
|
|
Expect.fail('Should have matched.');
|
|
}
|
|
|
|
// Refuted in refutable context if type doesn't match.
|
|
if ('wrong type' as dynamic case {'x': var x}) {
|
|
Expect.fail('Should not have matched.');
|
|
} else {
|
|
// OK.
|
|
}
|
|
}
|
|
|
|
void testObjectPattern() {
|
|
// Succeeds if cast to C succeeds.
|
|
var C(knownInt: x) = C() as dynamic;
|
|
Expect.equals(123, x);
|
|
|
|
// Throws in irrefutable context if cast fails.
|
|
Expect.throws(() {
|
|
var C(knownInt: x) = 'wrong type' as dynamic;
|
|
});
|
|
|
|
// Matches in refutable context if type matches.
|
|
if (C() as dynamic case C(knownInt: var x)) {
|
|
Expect.equals(123, x);
|
|
} else {
|
|
Expect.fail('Should have matched.');
|
|
}
|
|
|
|
// Refuted in refutable context if type doesn't match.
|
|
if ('wrong type' as dynamic case C(knownInt: var x)) {
|
|
Expect.fail('Should not have matched.');
|
|
} else {
|
|
// OK.
|
|
}
|
|
}
|
|
|
|
void testListDestructure() {
|
|
// Test when a destructured list element of type dynamic is matched by a
|
|
// subpattern that expects a type.
|
|
|
|
// Succeeds if cast succeeds.
|
|
var [int x] = <dynamic>[123];
|
|
Expect.equals(123, x);
|
|
|
|
// Throws in irrefutable context if cast fails.
|
|
Expect.throws(() {
|
|
var [int x] = <dynamic>['wrong type'];
|
|
});
|
|
|
|
// Matches in refutable context if type matches.
|
|
if (<dynamic>[123] case [int x]) {
|
|
Expect.equals(123, x);
|
|
} else {
|
|
Expect.fail('Should have matched.');
|
|
}
|
|
|
|
// Refuted in refutable context if type doesn't match.
|
|
if (<dynamic>['wrong type'] case [int x]) {
|
|
Expect.fail('Should not have matched.');
|
|
} else {
|
|
// OK.
|
|
}
|
|
}
|
|
|
|
void testMapDestructure() {
|
|
// Test when a destructured map value of type dynamic is matched by a
|
|
// subpattern that expects a type.
|
|
|
|
// Succeeds if cast succeeds.
|
|
var {'x': int x} = <String, dynamic>{'x': 123};
|
|
Expect.equals(123, x);
|
|
|
|
// Throws in irrefutable context if cast fails.
|
|
Expect.throws(() {
|
|
var {'x': int x} = <String, dynamic>{'x': 'wrong type'};
|
|
});
|
|
|
|
// Matches in refutable context if type matches.
|
|
if (<String, dynamic>{'x': 123} case {'x': int x}) {
|
|
Expect.equals(123, x);
|
|
} else {
|
|
Expect.fail('Should have matched.');
|
|
}
|
|
|
|
// Refuted in refutable context if type doesn't match.
|
|
if (<String, dynamic>{'x': 'wrong type'} case {'x': int x}) {
|
|
Expect.fail('Should not have matched.');
|
|
} else {
|
|
// OK.
|
|
}
|
|
}
|
|
|
|
void testObjectDestructure() {
|
|
// Test when a destructured object getter of type dynamic is matched by a
|
|
// subpattern that expects a type.
|
|
|
|
// Succeeds if cast succeeds.
|
|
var C(dynamicInt: int x) = C();
|
|
Expect.equals(123, x);
|
|
|
|
// Throws in irrefutable context if cast fails.
|
|
Expect.throws(() {
|
|
var C(dynamicString: int x) = C();
|
|
});
|
|
|
|
// Matches in refutable context if type matches.
|
|
if (C() case C(dynamicInt: int x)) {
|
|
Expect.equals(123, x);
|
|
} else {
|
|
Expect.fail('Should have matched.');
|
|
}
|
|
|
|
// Refuted in refutable context if type doesn't match.
|
|
if (C() case C(dynamicString: int x)) {
|
|
Expect.fail('Should not have matched.');
|
|
} else {
|
|
// OK.
|
|
}
|
|
}
|