Skip to content

Commit e8ff0c8

Browse files
committed
Add tests for null safety boolean conversion.
Tests for the null safety spec clarification landed in dart-lang/language#917 . Change-Id: Ieafe5315c31919c01ff816a26d29fa0d1cbc8c9a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/142782 Reviewed-by: Erik Ernst <[email protected]>
1 parent 9f65693 commit e8ff0c8

File tree

4 files changed

+436
-0
lines changed

4 files changed

+436
-0
lines changed
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
// Copyright (c) 2020, 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+
void main() {
6+
Never never = throw "Unreachable";
7+
bool boolean = true;
8+
dynamic any = 3;
9+
Null nil = null;
10+
Object object = Object();
11+
Object? objectOrNull = null;
12+
13+
{
14+
// Check that values of type `Never` are usable as booleans.
15+
if (never) {}
16+
[if (never) 3];
17+
never ? 3 : 4;
18+
while (never) {}
19+
do {} while (never);
20+
never || true;
21+
never && true;
22+
true || never;
23+
true && never;
24+
for (int i = 0; never; i++) {}
25+
[for (int i = 0; never; i++) 3];
26+
}
27+
{
28+
// Check that values of type `boolean` are usable as booleans.
29+
if (boolean) {}
30+
[if (boolean) 3];
31+
boolean ? 3 : 4;
32+
while (boolean) {}
33+
do {} while (boolean);
34+
boolean || true;
35+
boolean && true;
36+
true || boolean;
37+
true && boolean;
38+
for (int i = 0; boolean; i++) {}
39+
[for (int i = 0; boolean; i++) 3];
40+
}
41+
{
42+
// Check that values of type `dynamic` are usable as booleans.
43+
if (any) {}
44+
[if (any) 3];
45+
any ? 3 : 4;
46+
while (any) {}
47+
do {} while (any);
48+
any || true;
49+
any && true;
50+
true || any;
51+
true && any;
52+
for (int i = 0; any; i++) {}
53+
[for (int i = 0; any; i++) 3];
54+
}
55+
{
56+
// Check that values of type `Null` are not usable as booleans.
57+
if (nil) {}
58+
// ^^^
59+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
60+
// [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
61+
[if (nil) 3];
62+
// ^^^
63+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
64+
// [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
65+
nil ? 3 : 4;
66+
// ^^^
67+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
68+
// [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
69+
while (nil) {}
70+
// ^^^
71+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
72+
// [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
73+
do {} while (nil);
74+
// ^^^
75+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
76+
// [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
77+
nil || true;
78+
// ^^^
79+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
80+
// [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
81+
nil && true;
82+
// ^^^
83+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
84+
// [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
85+
true || nil;
86+
// ^^^
87+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
88+
// [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
89+
true && nil;
90+
// ^^^
91+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
92+
// [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
93+
for (int i = 0; nil; i++) {}
94+
// ^^^
95+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
96+
// [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
97+
[for (int i = 0; nil; i++) 3];
98+
// ^^^
99+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
100+
// [cfe] A value of type 'Null?' can't be assigned to a variable of type 'bool'.
101+
}
102+
{
103+
// Check that values of type `Object` are not usable as booleans.
104+
if (object) {}
105+
// ^^^^^^
106+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
107+
// [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
108+
[if (object) 3];
109+
// ^^^^^^
110+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
111+
// [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
112+
object ? 3 : 4;
113+
// ^^^^^^
114+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
115+
// [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
116+
while (object) {}
117+
// ^^^^^^
118+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
119+
// [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
120+
do {} while (object);
121+
// ^^^^^^
122+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
123+
// [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
124+
object || true;
125+
// ^^^^^^
126+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
127+
// [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
128+
object && true;
129+
// ^^^^^^
130+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
131+
// [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
132+
true || object;
133+
// ^^^^^^
134+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
135+
// [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
136+
true && object;
137+
// ^^^^^^
138+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
139+
// [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
140+
for (int i = 0; object; i++) {}
141+
// ^^^^^^
142+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
143+
// [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
144+
[for (int i = 0; object; i++) 3];
145+
// ^^^^^^
146+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
147+
// [cfe] A value of type 'Object' can't be assigned to a variable of type 'bool'.
148+
}
149+
{
150+
// Check that values of type `Object?` are not usable as booleans.
151+
if (objectOrNull) {}
152+
// ^^^^^^^^^^^^
153+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
154+
// [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
155+
[if (objectOrNull) 3];
156+
// ^^^^^^^^^^^^
157+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
158+
// [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
159+
objectOrNull ? 3 : 4;
160+
// ^^^^^^^^^^^^
161+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
162+
// [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
163+
while (objectOrNull) {}
164+
// ^^^^^^^^^^^^
165+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
166+
// [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
167+
do {} while (objectOrNull);
168+
// ^^^^^^^^^^^^
169+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
170+
// [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
171+
objectOrNull || true;
172+
// ^^^^^^^^^^^^
173+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
174+
// [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
175+
objectOrNull && true;
176+
// ^^^^^^^^^^^^
177+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
178+
// [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
179+
true || objectOrNull;
180+
// ^^^^^^^^^^^^
181+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
182+
// [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
183+
true && objectOrNull;
184+
// ^^^^^^^^^^^^
185+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_OPERAND
186+
// [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
187+
for (int i = 0; objectOrNull; i++) {}
188+
// ^^^^^^^^^^^^
189+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
190+
// [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
191+
[for (int i = 0; objectOrNull; i++) 3];
192+
// ^^^^^^^^^^^^
193+
// [analyzer] STATIC_TYPE_WARNING.NON_BOOL_CONDITION
194+
// [cfe] A value of type 'Object?' can't be assigned to a variable of type 'bool'.
195+
}
196+
}
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
// Copyright (c) 2020, 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+
// This library defines a set of test functions 'xxxAsBoolean" and a check
6+
// combinator called `check` which test the runtime behavior of conversions
7+
// of values in boolean condional positions (e.g. the condition of a conditional
8+
// statement).
9+
//
10+
// For example: calling `check(dynamicAsBoolean, value, expectation)` tests that
11+
// using `value` as the condition in a number of different syntactic constructs
12+
// with static type `dynamic` behaves as expected by `expectation`, where
13+
// `expectation` should be one of:
14+
// Expect.throwsAssertionError if a null conversion error is expected
15+
// Expect.throwsTypeError if an implicit cast error is expected
16+
// expectOk if no runtime error is expected.
17+
18+
void expectOk(void Function() f) {
19+
f();
20+
}
21+
22+
final int constructsTested = 11;
23+
24+
void check<T>(void Function(T, int) test, T value,
25+
void Function(void Function()) expectation) {
26+
for (int i = 0; i < constructsTested; i++) {
27+
expectation(() => test(value, i));
28+
}
29+
}
30+
31+
void neverAsBoolean(Never value, int index) {
32+
// Check that values of type `Never` are boolean converted appropriately
33+
// In strong checking mode, this code is unreachable. In weak checking mode,
34+
// we may get passed `null` for `value`, and so we check that the `null` value
35+
// causes an assertion error to be thrown appropriately.
36+
switch (index) {
37+
case 0:
38+
if (value) {}
39+
break;
40+
case 1:
41+
[if (value) 3];
42+
break;
43+
case 2:
44+
value ? 3 : 4;
45+
break;
46+
case 3:
47+
while (value) {
48+
break;
49+
}
50+
break;
51+
case 4:
52+
var done = false;
53+
do {
54+
if (done) break;
55+
done = true;
56+
} while (value);
57+
break;
58+
case 5:
59+
value || true;
60+
break;
61+
case 6:
62+
value && true;
63+
break;
64+
case 7:
65+
false || value;
66+
break;
67+
case 8:
68+
true && value;
69+
break;
70+
case 9:
71+
for (int i = 0; value; i++) {
72+
break;
73+
}
74+
break;
75+
case 10:
76+
[for (int i = 0; value; i++) 3];
77+
break;
78+
default:
79+
throw "Invalid index";
80+
}
81+
}
82+
83+
void booleanAsBoolean(bool value, int index) {
84+
// Check that values of type `boolean` are boolean converted appropriately
85+
switch (index) {
86+
case 0:
87+
if (value) {}
88+
break;
89+
case 1:
90+
[if (value) 3];
91+
break;
92+
case 2:
93+
value ? 3 : 4;
94+
break;
95+
case 3:
96+
while (value) {
97+
break;
98+
}
99+
break;
100+
case 4:
101+
var done = false;
102+
do {
103+
if (done) break;
104+
done = true;
105+
} while (value);
106+
break;
107+
case 5:
108+
value || true;
109+
break;
110+
case 6:
111+
value && true;
112+
break;
113+
case 7:
114+
false || value;
115+
break;
116+
case 8:
117+
true && value;
118+
break;
119+
case 9:
120+
for (int i = 0; value; i++) {
121+
break;
122+
}
123+
break;
124+
case 10:
125+
[for (int i = 0; value; value = false) 3];
126+
break;
127+
default:
128+
throw "Invalid index";
129+
}
130+
}
131+
132+
void dynamicAsBoolean(dynamic value, int index) {
133+
// Check that values of type `dynamic` are boolean converted appropriately
134+
switch (index) {
135+
case 0:
136+
if (value) {}
137+
break;
138+
case 1:
139+
[if (value) 3];
140+
break;
141+
case 2:
142+
value ? 3 : 4;
143+
break;
144+
case 3:
145+
while (value) {
146+
break;
147+
}
148+
break;
149+
case 4:
150+
var done = false;
151+
do {
152+
if (done) break;
153+
done = true;
154+
} while (value);
155+
break;
156+
case 5:
157+
value || true;
158+
break;
159+
case 6:
160+
value && true;
161+
break;
162+
case 7:
163+
false || value;
164+
break;
165+
case 8:
166+
true && value;
167+
break;
168+
case 9:
169+
for (int i = 0; value; i++) {
170+
break;
171+
}
172+
break;
173+
case 10:
174+
[for (int i = 0; value; value = false) 3];
175+
break;
176+
default:
177+
throw "Invalid index";
178+
}
179+
}

0 commit comments

Comments
 (0)