Skip to content

Commit e1712b3

Browse files
authored
#1401. [Patterns] cast, null-assert and null-check patterns tests added (#1537)
Cast, null-assert and null-check patterns tests added
1 parent 0eeafc7 commit e1712b3

14 files changed

+622
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion castPattern ::= primaryPattern 'as' type
6+
///
7+
/// A cast pattern is similar to an extractor pattern in that it checks the
8+
/// matched value against a given type. But where an extractor pattern is
9+
/// refuted if the value doesn't have that type, a cast pattern throws. Like the
10+
/// null-assert pattern, this lets you forcibly assert the expected type of some
11+
/// destructured value.
12+
///
13+
/// @description Check some valid cast patterns
14+
/// @author [email protected]
15+
16+
// SharedOptions=--enable-experiment=patterns,records
17+
18+
import "../../Utils/static_type_helper.dart";
19+
20+
main() {
21+
(num, Object) r1 = (1, "s");
22+
var (i as int, s as String) = r1;
23+
i.expectStaticType<Exactly<int>>();
24+
s.expectStaticType<Exactly<String>>();
25+
26+
(Record,) r2 = ((),);
27+
var (rec1 as (),) = r2;
28+
rec1.expectStaticType<Exactly<()>>();
29+
30+
({num n, Object o}) r3 = (n: 1, o: "s");
31+
var (n: n as int, o: o as String) = r3;
32+
n.expectStaticType<Exactly<int>>();
33+
o.expectStaticType<Exactly<String>>();
34+
35+
({Record r}) r4 = (r: ());
36+
var (r: rec2 as ()) = r4;
37+
rec2.expectStaticType<Exactly<()>>();
38+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion castPattern ::= primaryPattern 'as' type
6+
///
7+
/// A cast pattern is similar to an extractor pattern in that it checks the
8+
/// matched value against a given type. But where an extractor pattern is
9+
/// refuted if the value doesn't have that type, a cast pattern throws. Like the
10+
/// null-assert pattern, this lets you forcibly assert the expected type of some
11+
/// destructured value.
12+
///
13+
/// @description Check some valid cast patterns in a switch expressions and
14+
/// statements
15+
/// @author [email protected]
16+
17+
// SharedOptions=--enable-experiment=patterns
18+
19+
import "../../Utils/expect.dart";
20+
21+
const Object zero = 0;
22+
23+
bool isZero(num i) {
24+
return switch (i) {
25+
zero as int => true,
26+
_ => false
27+
};
28+
}
29+
30+
bool isInt(Object o) =>
31+
switch (o) {
32+
_ as int => true,
33+
_ => false
34+
};
35+
36+
main() {
37+
Expect.isTrue(isZero(0));
38+
Expect.isFalse(isZero(1));
39+
Expect.isFalse(isZero(-1));
40+
Expect.isTrue(isInt(42));
41+
Expect.throws(() {
42+
isInt("42");
43+
});
44+
45+
int i = 0;
46+
switch (i) {
47+
case zero as int:
48+
Expect.equals(0, i);
49+
break;
50+
default:
51+
Expect.fail("Shouldn't be here");
52+
}
53+
Object j = 2;
54+
switch (j) {
55+
case var v as int:
56+
Expect.equals(2, v);
57+
break;
58+
default:
59+
Expect.fail("Shouldn't be here");
60+
}
61+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion castPattern ::= primaryPattern 'as' type
6+
///
7+
/// A cast pattern is similar to an extractor pattern in that it checks the
8+
/// matched value against a given type. But where an extractor pattern is
9+
/// refuted if the value doesn't have that type, a cast pattern throws. Like the
10+
/// null-assert pattern, this lets you forcibly assert the expected type of some
11+
/// destructured value.
12+
///
13+
/// @description Check some valid cast patterns in an if-case statements
14+
/// @author [email protected]
15+
16+
// SharedOptions=--enable-experiment=patterns
17+
18+
import "../../Utils/expect.dart";
19+
20+
const Object zero = 0;
21+
22+
main() {
23+
int i = 0;
24+
if (i case zero as int) {
25+
Expect.equals(0, i);
26+
} else {
27+
Expect.fail("Shouldn't be here");
28+
}
29+
bool visited = false;
30+
if (i case _ as int) {
31+
visited = true;
32+
} else {
33+
Expect.fail("Shouldn't be here");
34+
}
35+
Expect.isTrue(visited);
36+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion castPattern ::= primaryPattern 'as' type
6+
///
7+
/// A cast pattern is similar to an extractor pattern in that it checks the
8+
/// matched value against a given type. But where an extractor pattern is
9+
/// refuted if the value doesn't have that type, a cast pattern throws. Like the
10+
/// null-assert pattern, this lets you forcibly assert the expected type of some
11+
/// destructured value.
12+
///
13+
/// @description Check that cast pattern throws if the value doesn't have an
14+
/// expected type
15+
/// @author [email protected]
16+
17+
// SharedOptions=--enable-experiment=patterns,records
18+
19+
import "../../Utils/expect.dart";
20+
21+
main() {
22+
(num, Object) r1 = (1, 2);
23+
Expect.throws(() {
24+
var (i as int, s as String) = r1;
25+
});
26+
27+
(Record,) r2 = ((3.14, name: "pi"),);
28+
Expect.throws(() {
29+
var (rec1 as (),) = r2;
30+
});
31+
32+
({num n, Object o}) r3 = (n: 1, o: 2);
33+
Expect.throws(() {
34+
var (n: n as int, o: o as String) = r3;
35+
});
36+
37+
({Record r}) r4 = (r: (1, 2));
38+
Expect.throws(() {
39+
var (r: rec1 as ()) = r4;
40+
});
41+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion castPattern ::= primaryPattern 'as' type
6+
///
7+
/// A cast pattern is similar to an extractor pattern in that it checks the
8+
/// matched value against a given type. But where an extractor pattern is
9+
/// refuted if the value doesn't have that type, a cast pattern throws. Like the
10+
/// null-assert pattern, this lets you forcibly assert the expected type of some
11+
/// destructured value.
12+
///
13+
/// @description Check that cast pattern throws if the value doesn't have an
14+
/// expected type
15+
/// @author [email protected]
16+
17+
// SharedOptions=--enable-experiment=patterns
18+
19+
import "../../Utils/expect.dart";
20+
21+
bool isOdd1(Object o) =>
22+
switch (o) {
23+
var v as int => v.isOdd,
24+
_ => false
25+
};
26+
27+
bool isOdd2(Object o) {
28+
switch (o) {
29+
case var v as int:
30+
return v.isOdd;
31+
default:
32+
return false;
33+
}
34+
}
35+
36+
bool isOdd3(Object o) {
37+
if (o case var v as int) {
38+
return v.isOdd;
39+
}
40+
return false;
41+
}
42+
43+
main() {
44+
Expect.isTrue(isOdd1(1));
45+
Expect.isFalse(isOdd1(2));
46+
Expect.throws(() {
47+
isOdd1("1");
48+
});
49+
50+
Expect.isTrue(isOdd2(1));
51+
Expect.isFalse(isOdd2(2));
52+
Expect.throws(() {
53+
isOdd2("1");
54+
});
55+
56+
Expect.isTrue(isOdd3(1));
57+
Expect.isFalse(isOdd3(2));
58+
Expect.throws(() {
59+
isOdd3("1");
60+
});
61+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion nullAssertPattern ::= primaryPattern '!'
6+
///
7+
/// A null-assert pattern is similar to a null-check pattern in that it permits
8+
/// non-null values to flow through. But a null-assert throws if the matched
9+
/// value is null. It lets you forcibly assert that you know a value shouldn't
10+
/// be null, much like the corresponding ! null-assert expression.
11+
///
12+
/// @description Check null-assert in a variable pattern
13+
/// @author [email protected]
14+
15+
// SharedOptions=--enable-experiment=patterns,records
16+
17+
import "../../Utils/static_type_helper.dart";
18+
import "../../Utils/expect.dart";
19+
20+
test1((int?, int?) position) {
21+
var (x!, _!) = position;
22+
x.expectStaticType<Exactly<int>>();
23+
x.isOdd;
24+
Expect.equals(1, x);
25+
}
26+
27+
test2(({int? x, int? y}) position) {
28+
var (x: x!, y: _!) = position;
29+
x.expectStaticType<Exactly<int>>();
30+
x.isOdd;
31+
Expect.equals(1, x);
32+
}
33+
34+
main() {
35+
test1((1, 1));
36+
test2((x: 1, y: 1));
37+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion nullAssertPattern ::= primaryPattern '!'
6+
///
7+
/// A null-assert pattern is similar to a null-check pattern in that it permits
8+
/// non-null values to flow through. But a null-assert throws if the matched
9+
/// value is null. It lets you forcibly assert that you know a value shouldn't
10+
/// be null, much like the corresponding ! null-assert expression.
11+
///
12+
/// @description Check null-assert pattern in a switch statement
13+
/// @author [email protected]
14+
15+
// SharedOptions=--enable-experiment=patterns
16+
17+
import "../../Utils/static_type_helper.dart";
18+
import "../../Utils/expect.dart";
19+
20+
test(List<String?> list, [bool testVisited = false]) {
21+
bool visited = false;
22+
switch (list) {
23+
case ['name', var name!]:
24+
name.expectStaticType<Exactly<String>>();
25+
name.substring(0);
26+
break;
27+
case ['answer', _!]:
28+
visited = true;
29+
break;
30+
default:
31+
Expect.fail("Wrong branch of code");
32+
}
33+
if (testVisited) {
34+
Expect.isTrue(visited);
35+
}
36+
}
37+
38+
main() {
39+
test(['name', 'Lily']);
40+
test(['answer', '42'], true);
41+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion nullAssertPattern ::= primaryPattern '!'
6+
///
7+
/// A null-assert pattern is similar to a null-check pattern in that it permits
8+
/// non-null values to flow through. But a null-assert throws if the matched
9+
/// value is null. It lets you forcibly assert that you know a value shouldn't
10+
/// be null, much like the corresponding ! null-assert expression.
11+
///
12+
/// @description Check null-assert pattern in an if-case statement
13+
/// @author [email protected]
14+
15+
// SharedOptions=--enable-experiment=patterns
16+
17+
import "../../Utils/static_type_helper.dart";
18+
import "../../Utils/expect.dart";
19+
20+
test(List<String?> list, [bool testVisited = false]) {
21+
bool visited = false;
22+
if (list case ['name', var name!]) {
23+
name.expectStaticType<Exactly<String>>();
24+
name.substring(0);
25+
visited = true;
26+
} else if (list case ['answer', _!]) {
27+
visited = true;
28+
} else {
29+
Expect.fail("Wrong branch of code");
30+
}
31+
if (testVisited) {
32+
Expect.isTrue(visited);
33+
}
34+
}
35+
36+
main() {
37+
test(['name', 'Lily']);
38+
test(['answer', '42'], true);
39+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion nullAssertPattern ::= primaryPattern '!'
6+
///
7+
/// A null-assert pattern is similar to a null-check pattern in that it permits
8+
/// non-null values to flow through. But a null-assert throws if the matched
9+
/// value is null. It lets you forcibly assert that you know a value shouldn't
10+
/// be null, much like the corresponding ! null-assert expression.
11+
///
12+
/// @description Check null-assert pattern in a switch expression
13+
/// @author [email protected]
14+
15+
// SharedOptions=--enable-experiment=patterns
16+
17+
import "../../Utils/expect.dart";
18+
19+
String test(List<String?> list) {
20+
return switch (list) {
21+
['name', var name!] => name.substring(0),
22+
['answer', _!] => "answer",
23+
_ => "default"
24+
};
25+
}
26+
27+
main() {
28+
Expect.equals("Lily", test(['name', 'Lily']));
29+
Expect.equals("answer", test(['answer', '42']));
30+
}

0 commit comments

Comments
 (0)