Skip to content

Commit 44e3ea3

Browse files
committed
dart-lang#1401. Exhaustiveness algorithm tests
1 parent cd2670b commit 44e3ea3

33 files changed

+1545
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright (c) 2023, 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 Switch statements and expressions with enum as a matched type are
6+
/// always exhaustive
7+
///
8+
/// @description Check that it is no compile-time error if a matched type of a
9+
/// switch expression is an enum and all cases are exhaustive
10+
/// @author [email protected]
11+
12+
// SharedOptions=--enable-experiment=patterns
13+
14+
import "../../../Utils/expect.dart";
15+
16+
enum E<T> {
17+
a<int>(),
18+
b<String>(),
19+
c<double>(),
20+
}
21+
22+
String test1(E<num> e) {
23+
switch (e) {
24+
case E.a:
25+
case E.c:
26+
return "ok";
27+
}
28+
}
29+
30+
String test2(E<num> e) =>
31+
switch (e) {
32+
E.a => "a",
33+
E.c => "c"
34+
};
35+
36+
main() {
37+
Expect.equals("ok", test1(E.a));
38+
Expect.equals("ok", test1(E.c));
39+
Expect.equals("a", test2(E.a));
40+
Expect.equals("c", test2(E.c));
41+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (c) 2023, 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 Switch statements and expressions with enum as a matched type are
6+
/// always exhaustive
7+
///
8+
/// @description Check that it is no compile-time error if a matched type of a
9+
/// switch expression is an enum and all cases are exhaustive
10+
/// @author [email protected]
11+
12+
// SharedOptions=--enable-experiment=patterns
13+
14+
import "../../../Utils/expect.dart";
15+
16+
enum E<T> {
17+
a<int>(),
18+
b<String>(),
19+
c<double>(),
20+
}
21+
22+
String test1<T extends num>(E<T> e) {
23+
switch (e) {
24+
case E.a:
25+
case E.c:
26+
return "ok";
27+
}
28+
}
29+
30+
String test2<T extends num>(E<T> e) =>
31+
switch (e) {
32+
E.a => "a",
33+
E.c => "c"
34+
};
35+
36+
main() {
37+
Expect.equals("ok", test1(E.a));
38+
Expect.equals("ok", test1(E.c));
39+
Expect.equals("ok", test1<int>(E.a));
40+
Expect.equals("ok", test1<double>(E.c));
41+
Expect.equals("a", test2(E.a));
42+
Expect.equals("c", test2(E.c));
43+
Expect.equals("a", test2<int>(E.a));
44+
Expect.equals("c", test2<double>(E.c));
45+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (c) 2023, 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 Switch statements and expressions with enum as a matched type are
6+
/// always exhaustive
7+
///
8+
/// @description Check that it is no compile-time error if a matched type of a
9+
/// switch expression is an enum and all cases are exhaustive
10+
/// @author [email protected]
11+
12+
// SharedOptions=--enable-experiment=patterns
13+
14+
import "../../../Utils/expect.dart";
15+
16+
enum E<T> {
17+
a<int>(),
18+
b<String>(),
19+
c<double>(),
20+
}
21+
22+
String test1<T extends num>(E<T> e) {
23+
switch (e) {
24+
case E.a || E.c:
25+
return "ok";
26+
}
27+
}
28+
29+
String test2<T extends num>(E<T> e) =>
30+
switch (e) {
31+
E.a || E.c => "ok"
32+
};
33+
34+
main() {
35+
Expect.equals("ok", test1(E.a));
36+
Expect.equals("ok", test1(E.c));
37+
Expect.equals("ok", test1<int>(E.a));
38+
Expect.equals("ok", test1<double>(E.c));
39+
Expect.equals("ok", test2(E.a));
40+
Expect.equals("ok", test2(E.c));
41+
Expect.equals("ok", test2<int>(E.a));
42+
Expect.equals("ok", test2<double>(E.c));
43+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright (c) 2023, 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 Switch statements and expressions with enum as a matched type are
6+
/// always exhaustive
7+
///
8+
/// @description Check that it is a compile-time error if a matched type of a
9+
/// switch expression is an enum and not all cases are exhaustive
10+
/// @author [email protected]
11+
12+
// SharedOptions=--enable-experiment=patterns
13+
14+
enum E<T> {
15+
a<int>(),
16+
b<String>(),
17+
c<double>(),
18+
}
19+
20+
String test1<T extends num>(E<T> e) {
21+
switch (e) {
22+
//^^^^^^
23+
// [analyzer] unspecified
24+
// [cfe] unspecified
25+
case E.a:
26+
return "a";
27+
case E.b:
28+
return "b";
29+
}
30+
}
31+
32+
String test2<T extends num>(E<T> e) =>
33+
switch (e) {
34+
//^^^^^^
35+
// [analyzer] unspecified
36+
// [cfe] unspecified
37+
E.a => "a",
38+
E.b => "b"
39+
};
40+
41+
String test3(E<num> e) {
42+
switch (e) {
43+
//^^^^^^
44+
// [analyzer] unspecified
45+
// [cfe] unspecified
46+
case E.a:
47+
return "ok";
48+
}
49+
}
50+
51+
String test4(E<num> e) =>
52+
switch (e) {
53+
//^^^^^^
54+
// [analyzer] unspecified
55+
// [cfe] unspecified
56+
E.a => "a"
57+
};
58+
59+
main() {
60+
test1(E.a);
61+
test2(E.c);
62+
test3(E.a);
63+
test4(E.a);
64+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) 2023, 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+
/// @description Library containing common classes for exhaustiveness tests
6+
/// @author [email protected]
7+
8+
// SharedOptions=--enable-experiment=patterns,class-modifiers
9+
10+
library exhaustiveness_lib;
11+
12+
enum Suit { club, diamond, heart, spade }
13+
14+
sealed class Card<T> {
15+
final Suit suit;
16+
17+
Card(this.suit);
18+
}
19+
20+
class Pip<T> extends Card<T> {
21+
final int pips;
22+
23+
Pip(this.pips, super.suit);
24+
}
25+
26+
sealed class Face<T> extends Card<T> {
27+
Face(super.suit);
28+
}
29+
30+
class Jack<T> extends Face<T> {
31+
final bool oneEyed;
32+
33+
Jack(super.suit, {this.oneEyed = false});
34+
}
35+
36+
class Queen<T> extends Face<T> {
37+
Queen(super.suit);
38+
}
39+
40+
class King<T> extends Face<T> {
41+
King(super.suit);
42+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright (c) 2023, 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 Switch expression with a list as a matched type can be exhaustive
6+
///
7+
/// @description Check that it is no compile-time error if a matched type of a
8+
/// switch expression is a list and all cases are exhaustive. Test rest element
9+
/// at the end of the list pattern
10+
/// @author [email protected]
11+
12+
// SharedOptions=--enable-experiment=patterns
13+
14+
import "../../../Utils/expect.dart";
15+
16+
String test1(List<int> l) =>
17+
switch (l) {
18+
<int?>[] => "0",
19+
[_] => "1",
20+
[_, _] => "2",
21+
[_, _, ...] => "2+"
22+
};
23+
24+
String test2(List<bool> l) =>
25+
switch (l) {
26+
[] => "0",
27+
[true] => "1_1",
28+
[false] => "1_2",
29+
[_, true] => "2_1",
30+
[_, false] => "2_2",
31+
[_, true, ...var r1] => "3_1",
32+
[_, false, ...final r2] => "3_2"
33+
};
34+
35+
main() {
36+
Expect.equals("0", test1([]));
37+
Expect.equals("1", test1([1]));
38+
Expect.equals("2", test1([1, 2]));
39+
Expect.equals("2+", test1([1, 2, 3]));
40+
41+
Expect.equals("0", test2([]));
42+
Expect.equals("1_1", test2([true]));
43+
Expect.equals("1_2", test2([false]));
44+
Expect.equals("2_1", test2([true, true]));
45+
Expect.equals("2_2", test2([true, false]));
46+
Expect.equals("3_1", test2([true, true, false]));
47+
Expect.equals("3_2", test2([true, false, false]));
48+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) 2023, 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 Switch expression with a list as a matched type can be exhaustive
6+
///
7+
/// @description Check that it is no compile-time error if a matched type of a
8+
/// switch expression is a list and all cases are exhaustive. Test rest element
9+
/// at the middle of the list pattern
10+
/// @author [email protected]
11+
12+
// SharedOptions=--enable-experiment=patterns
13+
14+
import "../../../Utils/expect.dart";
15+
16+
String test1(List<int> l) =>
17+
switch (l) {
18+
[] => "0",
19+
<int?>[_] => "1",
20+
[_, _] => "2",
21+
[_, ..., _] => "2+"
22+
};
23+
24+
String test2(List<bool> l) =>
25+
switch (l) {
26+
[] => "0",
27+
[true] => "1_1",
28+
[false] => "1_2",
29+
[_, true] => "2_1",
30+
[_, false] => "2_2",
31+
[_, ... var r1, true] => "3_1",
32+
[_, ... final r2, false] => "3_2"
33+
};
34+
35+
main() {
36+
Expect.equals("0", test1([]));
37+
Expect.equals("1", test1([1]));
38+
Expect.equals("2", test1([1, 2]));
39+
Expect.equals("2+", test1([1, 2, 3]));
40+
41+
Expect.equals("0", test2([]));
42+
Expect.equals("1_1", test2([true]));
43+
Expect.equals("1_2", test2([false]));
44+
Expect.equals("2_1", test2([true, true]));
45+
Expect.equals("2_2", test2([true, false]));
46+
Expect.equals("3_1", test2([true, true, true]));
47+
Expect.equals("3_2", test2([true, false, false]));
48+
49+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) 2023, 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 Switch expression with a list as a matched type can be exhaustive
6+
///
7+
/// @description Check that it is no compile-time error if a matched type of a
8+
/// switch expression is a list and all cases are exhaustive. Test rest element
9+
/// at the beginning of the list pattern
10+
/// @author [email protected]
11+
12+
// SharedOptions=--enable-experiment=patterns
13+
14+
import "../../../Utils/expect.dart";
15+
16+
String test1(List<int> l) =>
17+
switch (l) {
18+
[] => "0",
19+
[_] => "1",
20+
[_, _] => "2",
21+
<int?>[..., _, _] => "2+"
22+
};
23+
24+
String test2(List<bool> l) =>
25+
switch (l) {
26+
[] => "0",
27+
[true] => "1_1",
28+
[false] => "1_2",
29+
[_, true] => "2_1",
30+
[_, false] => "2_2",
31+
[... var r1, true] => "3_1",
32+
[... final r2, false] => "3_2"
33+
};
34+
35+
main() {
36+
Expect.equals("0", test1([]));
37+
Expect.equals("1", test1([1]));
38+
Expect.equals("2", test1([1, 2]));
39+
Expect.equals("2+", test1([1, 2, 3]));
40+
41+
Expect.equals("0", test2([]));
42+
Expect.equals("1_1", test2([true]));
43+
Expect.equals("1_2", test2([false]));
44+
Expect.equals("2_1", test2([true, true]));
45+
Expect.equals("2_2", test2([true, false]));
46+
Expect.equals("3_1", test2([true, true, true]));
47+
Expect.equals("3_2", test2([true, false, false]));
48+
49+
}

0 commit comments

Comments
 (0)