Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(480)

Side by Side Diff: test/backend/platform_selector/parser_test.dart

Issue 997593003: Add a scanner and parser for platform selectors. (Closed) Base URL: git@github.com:dart-lang/unittest@master
Patch Set: A few more fixes from better future knowledge Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2015, 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 import 'package:unittest/unittest.dart';
6 import 'package:unittest/src/backend/platform_selector/ast.dart';
7 import 'package:unittest/src/backend/platform_selector/parser.dart';
8
9 /// A matcher that asserts that a value is a [ConditionalNode].
10 Matcher _isConditionalNode =
11 new isInstanceOf<ConditionalNode>("ConditionalNode");
12
13 /// A matcher that asserts that a value is an [OrNode].
14 Matcher _isOrNode = new isInstanceOf<OrNode>("OrNode");
15
16 /// A matcher that asserts that a value is an [AndNode].
17 Matcher _isAndNode = new isInstanceOf<AndNode>("AndNode");
18
19 /// A matcher that asserts that a value is a [NotNode].
20 Matcher _isNotNode = new isInstanceOf<NotNode>("NotNode");
21
22 void main() {
23 group("parses a conditional expression", () {
24 test("with identifiers", () {
25 var node = _parse(" a ? b : c ");
26 expect(node, _isConditionalNode);
Bob Nystrom 2015/03/11 20:05:53 It's probably simpler just to test node.toString()
nweiz 2015/03/12 19:48:58 But the AST tests also rely on the parser to do th
27 expect(node.condition, _isVar("a"));
28 expect(node.branch1, _isVar("b"));
29 expect(node.branch2, _isVar("c"));
30
31 expect(node.span.text, equals("a ? b : c"));
32 expect(node.span.start.offset, equals(2));
33 expect(node.span.end.offset, equals(11));
34 });
35
36 test("with nested ors", () {
37 // Should parse as "(a || b) ? (c || d) : (e || f)".
38 // Should not parse as "a || (b ? (c || d) : (e || f))".
39 // Should not parse as "((a || b) ? (c || d) : e) || f".
40 // Should not parse as "a || (b ? (c || d) : e) || f".
41 var node = _parse("a || b ? c || d : e || f");
42 expect(node, _isConditionalNode);
43
44 expect(node.condition, _isOrNode);
45 expect(node.condition.branch1, _isVar("a"));
46 expect(node.condition.branch2, _isVar("b"));
47
48 expect(node.branch1, _isOrNode);
49 expect(node.branch1.branch1, _isVar("c"));
50 expect(node.branch1.branch2, _isVar("d"));
51
52 expect(node.branch2, _isOrNode);
53 expect(node.branch2.branch1, _isVar("e"));
54 expect(node.branch2.branch2, _isVar("f"));
55 });
56
57 test("with a conditional expression as branch 1", () {
58 // Should parse as "a ? (b ? c : d) : e".
59 var node = _parse("a ? b ? c : d : e");
60 expect(node, _isConditionalNode);
61 expect(node.condition, _isVar("a"));
62 expect(node.branch2, _isVar("e"));
63
64 expect(node.branch1, _isConditionalNode);
65 expect(node.branch1.condition, _isVar("b"));
66 expect(node.branch1.branch1, _isVar("c"));
67 expect(node.branch1.branch2, _isVar("d"));
68 });
69
70 test("with a conditional expression as branch 2", () {
71 // Should parse as "a ? b : (c ? d : e)".
72 // Should not parse as "(a ? b : c) ? d : e".
73 var node = _parse("a ? b : c ? d : e");
74 expect(node, _isConditionalNode);
75 expect(node.condition, _isVar("a"));
76 expect(node.branch1, _isVar("b"));
77
78 expect(node.branch2, _isConditionalNode);
79 expect(node.branch2.condition, _isVar("c"));
80 expect(node.branch2.branch1, _isVar("d"));
81 expect(node.branch2.branch2, _isVar("e"));
82 });
83
84 group("which must have", () {
85 test("an expression after the ?", () {
86 expect(() => _parse("a ?"), throwsFormatException);
87 expect(() => _parse("a ? && b"), throwsFormatException);
88 });
89
90 test("a :", () {
91 expect(() => _parse("a ? b"), throwsFormatException);
92 expect(() => _parse("a ? b && c"), throwsFormatException);
93 });
94
95 test("an expression after the :", () {
96 expect(() => _parse("a ? b :"), throwsFormatException);
97 expect(() => _parse("a ? b : && c"), throwsFormatException);
98 });
99 });
100 });
101
102 group("parses an or expression", () {
103 test("with identifiers", () {
104 var node = _parse(" a || b ");
105 expect(node, _isOrNode);
106 expect(node.branch1, _isVar("a"));
107 expect(node.branch2, _isVar("b"));
108
109 expect(node.span.text, equals("a || b"));
110 expect(node.span.start.offset, equals(2));
111 expect(node.span.end.offset, equals(8));
112 });
113
114 test("with nested ands", () {
115 // Should parse as "(a && b) || (c && d)".
116 // Should not parse as "a && (b || c) && d".
117 var node = _parse("a && b || c && d");
118 expect(node, _isOrNode);
119
120 expect(node.branch1, _isAndNode);
121 expect(node.branch1.branch1, _isVar("a"));
122 expect(node.branch1.branch2, _isVar("b"));
123
124 expect(node.branch2, _isAndNode);
125 expect(node.branch2.branch1, _isVar("c"));
126 expect(node.branch2.branch2, _isVar("d"));
127 });
128
129 test("with trailing ors", () {
130 // Should parse as "a || (b || (c || d))", although it doesn't affect the
131 // semantics.
132 var node = _parse("a || b || c || d");
133
134 for (var variable in ["a", "b", "c"]) {
135 expect(node, _isOrNode);
136 expect(node.branch1, _isVar(variable));
137 node = node.branch2;
138 }
139 expect(node, _isVar("d"));
140 });
141
142 test("which must have an expression after the ||", () {
143 expect(() => _parse("a ||"), throwsFormatException);
144 expect(() => _parse("a || && b"), throwsFormatException);
145 });
146 });
147
148 group("parses an and expression", () {
149 test("with identifiers", () {
150 var node = _parse(" a && b ");
151 expect(node, _isAndNode);
152 expect(node.branch1, _isVar("a"));
153 expect(node.branch2, _isVar("b"));
154
155 expect(node.span.text, equals("a && b"));
156 expect(node.span.start.offset, equals(2));
157 expect(node.span.end.offset, equals(8));
158 });
159
160 test("with nested nots", () {
161 // Should parse as "(!a) && (!b)", obviously.
162 // Should not parse as "!(a && (!b))".
163 var node = _parse("!a && !b");
164 expect(node, _isAndNode);
165
166 expect(node.branch1, _isNotNode);
167 expect(node.branch1.child, _isVar("a"));
168
169 expect(node.branch2, _isNotNode);
170 expect(node.branch2.child, _isVar("b"));
171 });
172
173 test("with trailing ands", () {
174 // Should parse as "a && (b && (c && d))", although it doesn't affect the
175 // semantics since .
176 var node = _parse("a && b && c && d");
177
178 for (var variable in ["a", "b", "c"]) {
179 expect(node, _isAndNode);
180 expect(node.branch1, _isVar(variable));
181 node = node.branch2;
182 }
183 expect(node, _isVar("d"));
184 });
185
186 test("which must have an expression after the &&", () {
187 expect(() => _parse("a &&"), throwsFormatException);
188 expect(() => _parse("a && && b"), throwsFormatException);
189 });
190 });
191
192 group("parses a not expression", () {
193 test("with an identifier", () {
194 var node = _parse(" ! a ");
195 expect(node, _isNotNode);
196 expect(node.child, _isVar("a"));
197
198 expect(node.span.text, equals("! a"));
199 expect(node.span.start.offset, equals(2));
200 expect(node.span.end.offset, equals(5));
201 });
202
203 test("with a parenthesized expression", () {
204 var node = _parse("!(a || b)");
205 expect(node, _isNotNode);
206
207 expect(node.child, _isOrNode);
208 expect(node.child.branch1, _isVar("a"));
209 expect(node.child.branch2, _isVar("b"));
210 });
211
212 test("with a nested not", () {
213 var node = _parse("!!a");
214 expect(node, _isNotNode);
215 expect(node.child, _isNotNode);
216 expect(node.child.child, _isVar("a"));
217 });
218
219 test("which must have an expression after the !", () {
220 expect(() => _parse("!"), throwsFormatException);
221 expect(() => _parse("! && a"), throwsFormatException);
222 });
223 });
224
225 group("parses a parenthesized expression", () {
226 test("with an identifier", () {
227 var node = _parse("(a)");
228 expect(node, _isVar("a"));
229 });
230
231 test("controls precedence", () {
232 // Without parentheses, this would parse as "(a || b) ? c : d".
233 var node = _parse("a || (b ? c : d)");
234
235 expect(node, _isOrNode);
236 expect(node.branch1, _isVar("a"));
237
238 expect(node.branch2, _isConditionalNode);
239 expect(node.branch2.condition, _isVar("b"));
240 expect(node.branch2.branch1, _isVar("c"));
241 expect(node.branch2.branch2, _isVar("d"));
242 });
243
244 group("which must have", () {
245 test("an expression within the ()", () {
246 expect(() => _parse("()"), throwsFormatException);
247 expect(() => _parse("( && a )"), throwsFormatException);
248 });
249
250 test("a matching )", () {
251 expect(() => _parse("( a"), throwsFormatException);
252 });
253 });
254 });
255
256 group("disallows", () {
257 test("an empty selector", () {
258 expect(() => _parse(""), throwsFormatException);
259 });
260
261 test("too many expressions", () {
262 expect(() => _parse("a b"), throwsFormatException);
263 });
264 });
265 }
266
267 /// Parses [selector] and returns its root node.
268 Node _parse(String selector) => new Parser(selector).parse();
269
270 /// A matcher that asserts that a value is a [VariableNode] with the given
271 /// [name].
272 Matcher _isVar(String name) => predicate(
273 (value) => value is VariableNode && value.name == name,
274 'is a variable named "$name"');
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698