OLD | NEW |
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import imp | 5 import imp |
6 import os.path | 6 import os.path |
7 import sys | 7 import sys |
8 import unittest | 8 import unittest |
9 | 9 |
10 # Disable lint check for finding modules: | 10 # Disable lint check for finding modules: |
(...skipping 23 matching lines...) Expand all Loading... |
34 | 34 |
35 def testTrivialValidSource(self): | 35 def testTrivialValidSource(self): |
36 """Tests a trivial, but valid, .mojom source.""" | 36 """Tests a trivial, but valid, .mojom source.""" |
37 | 37 |
38 source = """\ | 38 source = """\ |
39 // This is a comment. | 39 // This is a comment. |
40 | 40 |
41 module my_module { | 41 module my_module { |
42 } | 42 } |
43 """ | 43 """ |
44 expected = [('MODULE', ('IDENTIFIER', 'my_module'), None, None)] | 44 expected = ast.Mojom( |
| 45 ast.Module(('IDENTIFIER', 'my_module'), None), |
| 46 ast.ImportList(), |
| 47 []) |
45 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 48 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
46 | 49 |
47 def testSourceWithCrLfs(self): | 50 def testSourceWithCrLfs(self): |
48 """Tests a .mojom source with CR-LFs instead of LFs.""" | 51 """Tests a .mojom source with CR-LFs instead of LFs.""" |
49 | 52 |
50 source = "// This is a comment.\r\n\r\nmodule my_module {\r\n}\r\n" | 53 source = "// This is a comment.\r\n\r\nmodule my_module {\r\n}\r\n" |
51 expected = [('MODULE', ('IDENTIFIER', 'my_module'), None, None)] | 54 expected = ast.Mojom( |
| 55 ast.Module(('IDENTIFIER', 'my_module'), None), |
| 56 ast.ImportList(), |
| 57 []) |
52 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 58 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
53 | 59 |
54 def testUnexpectedEOF(self): | 60 def testUnexpectedEOF(self): |
55 """Tests a "truncated" .mojom source.""" | 61 """Tests a "truncated" .mojom source.""" |
56 | 62 |
57 source = """\ | 63 source = """\ |
58 // This is a comment. | 64 // This is a comment. |
59 | 65 |
60 module my_module { | 66 module my_module { |
61 """ | 67 """ |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 source = """\ | 138 source = """\ |
133 module my_module { | 139 module my_module { |
134 | 140 |
135 struct MyStruct { | 141 struct MyStruct { |
136 int32 a; | 142 int32 a; |
137 double b; | 143 double b; |
138 }; | 144 }; |
139 | 145 |
140 } // module my_module | 146 } // module my_module |
141 """ | 147 """ |
142 expected = \ | 148 expected = ast.Mojom( |
143 [('MODULE', | 149 ast.Module(('IDENTIFIER', 'my_module'), None), |
144 ('IDENTIFIER', 'my_module'), | 150 ast.ImportList(), |
| 151 [('STRUCT', |
| 152 'MyStruct', |
145 None, | 153 None, |
146 [('STRUCT', | 154 [('FIELD', 'int32', 'a', ast.Ordinal(None), None), |
147 'MyStruct', | 155 ('FIELD', 'double', 'b', ast.Ordinal(None), None)])]) |
148 None, | |
149 [('FIELD', 'int32', 'a', ast.Ordinal(None), None), | |
150 ('FIELD', 'double', 'b', ast.Ordinal(None), None)])])] | |
151 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 156 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
152 | 157 |
153 def testSimpleStructWithoutModule(self): | 158 def testSimpleStructWithoutModule(self): |
154 """Tests a simple struct without an enclosing module.""" | 159 """Tests a simple struct without an enclosing module.""" |
155 | 160 |
156 source = """\ | 161 source = """\ |
157 struct MyStruct { | 162 struct MyStruct { |
158 int32 a; | 163 int32 a; |
159 double b; | 164 double b; |
160 }; | 165 }; |
161 """ | 166 """ |
162 expected = \ | 167 expected = ast.Mojom( |
163 [('MODULE', | 168 None, |
| 169 ast.ImportList(), |
| 170 [('STRUCT', |
| 171 'MyStruct', |
164 None, | 172 None, |
165 None, | 173 [('FIELD', 'int32', 'a', ast.Ordinal(None), None), |
166 [('STRUCT', | 174 ('FIELD', 'double', 'b', ast.Ordinal(None), None)])]) |
167 'MyStruct', | |
168 None, | |
169 [('FIELD', 'int32', 'a', ast.Ordinal(None), None), | |
170 ('FIELD', 'double', 'b', ast.Ordinal(None), None)])])] | |
171 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 175 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
172 | 176 |
173 def testMissingModuleName(self): | 177 def testMissingModuleName(self): |
174 """Tests an (invalid) .mojom with a missing module name.""" | 178 """Tests an (invalid) .mojom with a missing module name.""" |
175 | 179 |
176 source1 = """\ | 180 source1 = """\ |
177 // Missing module name. | 181 // Missing module name. |
178 module { | 182 module { |
179 struct MyStruct { | 183 struct MyStruct { |
180 int32 a; | 184 int32 a; |
(...skipping 29 matching lines...) Expand all Loading... |
210 VALUE1 = -1, | 214 VALUE1 = -1, |
211 VALUE2 = 0, | 215 VALUE2 = 0, |
212 VALUE3 = + 987, // Check that space is allowed. | 216 VALUE3 = + 987, // Check that space is allowed. |
213 VALUE4 = 0xAF12, | 217 VALUE4 = 0xAF12, |
214 VALUE5 = -0x09bcd, | 218 VALUE5 = -0x09bcd, |
215 VALUE6 = VALUE5, | 219 VALUE6 = VALUE5, |
216 VALUE7, // Leave trailing comma. | 220 VALUE7, // Leave trailing comma. |
217 }; | 221 }; |
218 } // my_module | 222 } // my_module |
219 """ | 223 """ |
220 expected = \ | 224 expected = ast.Mojom( |
221 [('MODULE', | 225 ast.Module(('IDENTIFIER', 'my_module'), None), |
222 ('IDENTIFIER', 'my_module'), | 226 ast.ImportList(), |
223 None, | 227 [('ENUM', |
224 [('ENUM', | 228 'MyEnum1', |
225 'MyEnum1', | 229 [('ENUM_VALUE', 'VALUE1', None), |
226 [('ENUM_VALUE', 'VALUE1', None), | 230 ('ENUM_VALUE', 'VALUE2', None)]), |
227 ('ENUM_VALUE', 'VALUE2', None)]), | 231 ('ENUM', |
228 ('ENUM', | 232 'MyEnum2', |
229 'MyEnum2', | 233 [('ENUM_VALUE', 'VALUE1', '-1'), |
230 [('ENUM_VALUE', 'VALUE1', '-1'), | 234 ('ENUM_VALUE', 'VALUE2', '0'), |
231 ('ENUM_VALUE', 'VALUE2', '0'), | 235 ('ENUM_VALUE', 'VALUE3', '+987'), |
232 ('ENUM_VALUE', 'VALUE3', '+987'), | 236 ('ENUM_VALUE', 'VALUE4', '0xAF12'), |
233 ('ENUM_VALUE', 'VALUE4', '0xAF12'), | 237 ('ENUM_VALUE', 'VALUE5', '-0x09bcd'), |
234 ('ENUM_VALUE', 'VALUE5', '-0x09bcd'), | 238 ('ENUM_VALUE', 'VALUE6', ('IDENTIFIER', 'VALUE5')), |
235 ('ENUM_VALUE', 'VALUE6', ('IDENTIFIER', 'VALUE5')), | 239 ('ENUM_VALUE', 'VALUE7', None)])]) |
236 ('ENUM_VALUE', 'VALUE7', None)])])] | |
237 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 240 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
238 | 241 |
239 def testInvalidEnumInitializers(self): | 242 def testInvalidEnumInitializers(self): |
240 """Tests that invalid enum initializers are correctly detected.""" | 243 """Tests that invalid enum initializers are correctly detected.""" |
241 | 244 |
242 # No values. | 245 # No values. |
243 source1 = """\ | 246 source1 = """\ |
244 enum MyEnum { | 247 enum MyEnum { |
245 }; | 248 }; |
246 """ | 249 """ |
(...skipping 25 matching lines...) Expand all Loading... |
272 source = """\ | 275 source = """\ |
273 module my_module { | 276 module my_module { |
274 | 277 |
275 struct MyStruct { | 278 struct MyStruct { |
276 const int8 kNumber = -1; | 279 const int8 kNumber = -1; |
277 int8 number@0 = kNumber; | 280 int8 number@0 = kNumber; |
278 }; | 281 }; |
279 | 282 |
280 } // my_module | 283 } // my_module |
281 """ | 284 """ |
282 expected = \ | 285 expected = ast.Mojom( |
283 [('MODULE', | 286 ast.Module(('IDENTIFIER', 'my_module'), None), |
284 ('IDENTIFIER', 'my_module'), | 287 ast.ImportList(), |
285 None, | 288 [('STRUCT', |
286 [('STRUCT', | 289 'MyStruct', None, |
287 'MyStruct', None, | 290 [('CONST', 'int8', 'kNumber', '-1'), |
288 [('CONST', 'int8', 'kNumber', '-1'), | 291 ('FIELD', 'int8', 'number', |
289 ('FIELD', 'int8', 'number', | 292 ast.Ordinal(0), ('IDENTIFIER', 'kNumber'))])]) |
290 ast.Ordinal(0), ('IDENTIFIER', 'kNumber'))])])] | |
291 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 293 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
292 | 294 |
293 def testNoConditionals(self): | 295 def testNoConditionals(self): |
294 """Tests that ?: is not allowed.""" | 296 """Tests that ?: is not allowed.""" |
295 | 297 |
296 source = """\ | 298 source = """\ |
297 module my_module { | 299 module my_module { |
298 | 300 |
299 enum MyEnum { | 301 enum MyEnum { |
300 MY_ENUM_1 = 1 ? 2 : 3 | 302 MY_ENUM_1 = 1 ? 2 : 3 |
(...skipping 20 matching lines...) Expand all Loading... |
321 int32 a2@2; | 323 int32 a2@2; |
322 int32 a9@9; | 324 int32 a9@9; |
323 int32 a10 @10; | 325 int32 a10 @10; |
324 int32 a11 @11; | 326 int32 a11 @11; |
325 int32 a29 @29; | 327 int32 a29 @29; |
326 int32 a1234567890 @1234567890; | 328 int32 a1234567890 @1234567890; |
327 }; | 329 }; |
328 | 330 |
329 } // module my_module | 331 } // module my_module |
330 """ | 332 """ |
331 expected = \ | 333 expected = ast.Mojom( |
332 [('MODULE', | 334 ast.Module(('IDENTIFIER', 'my_module'), None), |
333 ('IDENTIFIER', 'my_module'), | 335 ast.ImportList(), |
| 336 [('STRUCT', |
| 337 'MyStruct', |
334 None, | 338 None, |
335 [('STRUCT', | 339 [('FIELD', 'int32', 'a0', ast.Ordinal(0), None), |
336 'MyStruct', | 340 ('FIELD', 'int32', 'a1', ast.Ordinal(1), None), |
337 None, | 341 ('FIELD', 'int32', 'a2', ast.Ordinal(2), None), |
338 [('FIELD', 'int32', 'a0', ast.Ordinal(0), None), | 342 ('FIELD', 'int32', 'a9', ast.Ordinal(9), None), |
339 ('FIELD', 'int32', 'a1', ast.Ordinal(1), None), | 343 ('FIELD', 'int32', 'a10', ast.Ordinal(10), None), |
340 ('FIELD', 'int32', 'a2', ast.Ordinal(2), None), | 344 ('FIELD', 'int32', 'a11', ast.Ordinal(11), None), |
341 ('FIELD', 'int32', 'a9', ast.Ordinal(9), None), | 345 ('FIELD', 'int32', 'a29', ast.Ordinal(29), None), |
342 ('FIELD', 'int32', 'a10', ast.Ordinal(10), None), | 346 ('FIELD', 'int32', 'a1234567890', ast.Ordinal(1234567890), None)])]) |
343 ('FIELD', 'int32', 'a11', ast.Ordinal(11), None), | |
344 ('FIELD', 'int32', 'a29', ast.Ordinal(29), None), | |
345 ('FIELD', 'int32', 'a1234567890', ast.Ordinal(1234567890), | |
346 None)])])] | |
347 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 347 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
348 | 348 |
349 def testInvalidOrdinals(self): | 349 def testInvalidOrdinals(self): |
350 """Tests that (lexically) invalid ordinals are correctly detected.""" | 350 """Tests that (lexically) invalid ordinals are correctly detected.""" |
351 | 351 |
352 source1 = """\ | 352 source1 = """\ |
353 module my_module { | 353 module my_module { |
354 | 354 |
355 struct MyStruct { | 355 struct MyStruct { |
356 int32 a_missing@; | 356 int32 a_missing@; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 | 418 |
419 source = """\ | 419 source = """\ |
420 module my.mod { | 420 module my.mod { |
421 | 421 |
422 struct MyStruct { | 422 struct MyStruct { |
423 int32 a; | 423 int32 a; |
424 }; | 424 }; |
425 | 425 |
426 } // module my.mod | 426 } // module my.mod |
427 """ | 427 """ |
428 expected = \ | 428 expected = ast.Mojom( |
429 [('MODULE', | 429 ast.Module(('IDENTIFIER', 'my.mod'), None), |
430 ('IDENTIFIER', 'my.mod'), | 430 ast.ImportList(), |
| 431 [('STRUCT', |
| 432 'MyStruct', |
431 None, | 433 None, |
432 [('STRUCT', | 434 [('FIELD', 'int32', 'a', ast.Ordinal(None), None)])]) |
433 'MyStruct', | |
434 None, | |
435 [('FIELD', 'int32', 'a', ast.Ordinal(None), None)])])] | |
436 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 435 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
437 | 436 |
438 def testValidHandleTypes(self): | 437 def testValidHandleTypes(self): |
439 """Tests (valid) handle types.""" | 438 """Tests (valid) handle types.""" |
440 | 439 |
441 source = """\ | 440 source = """\ |
442 struct MyStruct { | 441 struct MyStruct { |
443 handle a; | 442 handle a; |
444 handle<data_pipe_consumer> b; | 443 handle<data_pipe_consumer> b; |
445 handle <data_pipe_producer> c; | 444 handle <data_pipe_producer> c; |
446 handle < message_pipe > d; | 445 handle < message_pipe > d; |
447 handle | 446 handle |
448 < shared_buffer | 447 < shared_buffer |
449 > e; | 448 > e; |
450 }; | 449 }; |
451 """ | 450 """ |
452 expected = \ | 451 expected = ast.Mojom( |
453 [('MODULE', | 452 None, |
| 453 ast.ImportList(), |
| 454 [('STRUCT', |
| 455 'MyStruct', |
454 None, | 456 None, |
455 None, | 457 [('FIELD', 'handle', 'a', ast.Ordinal(None), None), |
456 [('STRUCT', | 458 ('FIELD', 'handle<data_pipe_consumer>', 'b', ast.Ordinal(None), |
457 'MyStruct', | 459 None), |
458 None, | 460 ('FIELD', 'handle<data_pipe_producer>', 'c', ast.Ordinal(None), |
459 [('FIELD', 'handle', 'a', ast.Ordinal(None), None), | 461 None), |
460 ('FIELD', 'handle<data_pipe_consumer>', 'b', ast.Ordinal(None), | 462 ('FIELD', 'handle<message_pipe>', 'd', ast.Ordinal(None), None), |
461 None), | 463 ('FIELD', 'handle<shared_buffer>', 'e', ast.Ordinal(None), None)])]) |
462 ('FIELD', 'handle<data_pipe_producer>', 'c', ast.Ordinal(None), | |
463 None), | |
464 ('FIELD', 'handle<message_pipe>', 'd', ast.Ordinal(None), None), | |
465 ('FIELD', 'handle<shared_buffer>', 'e', ast.Ordinal(None), | |
466 None)])])] | |
467 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 464 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
468 | 465 |
469 def testInvalidHandleType(self): | 466 def testInvalidHandleType(self): |
470 """Tests an invalid (unknown) handle type.""" | 467 """Tests an invalid (unknown) handle type.""" |
471 | 468 |
472 source = """\ | 469 source = """\ |
473 struct MyStruct { | 470 struct MyStruct { |
474 handle<wtf_is_this> foo; | 471 handle<wtf_is_this> foo; |
475 }; | 472 }; |
476 """ | 473 """ |
(...skipping 27 matching lines...) Expand all Loading... |
504 float a15 = +1.2345; | 501 float a15 = +1.2345; |
505 float a16 = 123.; | 502 float a16 = 123.; |
506 float a17 = .123; | 503 float a17 = .123; |
507 double a18 = 1.23E10; | 504 double a18 = 1.23E10; |
508 double a19 = 1.E-10; | 505 double a19 = 1.E-10; |
509 double a20 = .5E+10; | 506 double a20 = .5E+10; |
510 double a21 = -1.23E10; | 507 double a21 = -1.23E10; |
511 double a22 = +.123E10; | 508 double a22 = +.123E10; |
512 }; | 509 }; |
513 """ | 510 """ |
514 expected = \ | 511 expected = ast.Mojom( |
515 [('MODULE', | 512 None, |
| 513 ast.ImportList(), |
| 514 [('STRUCT', |
| 515 'MyStruct', |
516 None, | 516 None, |
517 None, | 517 [('FIELD', 'int16', 'a0', ast.Ordinal(None), '0'), |
518 [('STRUCT', | 518 ('FIELD', 'uint16', 'a1', ast.Ordinal(None), '0x0'), |
519 'MyStruct', | 519 ('FIELD', 'uint16', 'a2', ast.Ordinal(None), '0x00'), |
520 None, | 520 ('FIELD', 'uint16', 'a3', ast.Ordinal(None), '0x01'), |
521 [('FIELD', 'int16', 'a0', ast.Ordinal(None), '0'), | 521 ('FIELD', 'uint16', 'a4', ast.Ordinal(None), '0xcd'), |
522 ('FIELD', 'uint16', 'a1', ast.Ordinal(None), '0x0'), | 522 ('FIELD', 'int32', 'a5' , ast.Ordinal(None), '12345'), |
523 ('FIELD', 'uint16', 'a2', ast.Ordinal(None), '0x00'), | 523 ('FIELD', 'int64', 'a6', ast.Ordinal(None), '-12345'), |
524 ('FIELD', 'uint16', 'a3', ast.Ordinal(None), '0x01'), | 524 ('FIELD', 'int64', 'a7', ast.Ordinal(None), '+12345'), |
525 ('FIELD', 'uint16', 'a4', ast.Ordinal(None), '0xcd'), | 525 ('FIELD', 'uint32', 'a8', ast.Ordinal(None), '0x12cd3'), |
526 ('FIELD', 'int32', 'a5' , ast.Ordinal(None), '12345'), | 526 ('FIELD', 'uint32', 'a9', ast.Ordinal(None), '-0x12cD3'), |
527 ('FIELD', 'int64', 'a6', ast.Ordinal(None), '-12345'), | 527 ('FIELD', 'uint32', 'a10', ast.Ordinal(None), '+0x12CD3'), |
528 ('FIELD', 'int64', 'a7', ast.Ordinal(None), '+12345'), | 528 ('FIELD', 'bool', 'a11', ast.Ordinal(None), 'true'), |
529 ('FIELD', 'uint32', 'a8', ast.Ordinal(None), '0x12cd3'), | 529 ('FIELD', 'bool', 'a12', ast.Ordinal(None), 'false'), |
530 ('FIELD', 'uint32', 'a9', ast.Ordinal(None), '-0x12cD3'), | 530 ('FIELD', 'float', 'a13', ast.Ordinal(None), '1.2345'), |
531 ('FIELD', 'uint32', 'a10', ast.Ordinal(None), '+0x12CD3'), | 531 ('FIELD', 'float', 'a14', ast.Ordinal(None), '-1.2345'), |
532 ('FIELD', 'bool', 'a11', ast.Ordinal(None), 'true'), | 532 ('FIELD', 'float', 'a15', ast.Ordinal(None), '+1.2345'), |
533 ('FIELD', 'bool', 'a12', ast.Ordinal(None), 'false'), | 533 ('FIELD', 'float', 'a16', ast.Ordinal(None), '123.'), |
534 ('FIELD', 'float', 'a13', ast.Ordinal(None), '1.2345'), | 534 ('FIELD', 'float', 'a17', ast.Ordinal(None), '.123'), |
535 ('FIELD', 'float', 'a14', ast.Ordinal(None), '-1.2345'), | 535 ('FIELD', 'double', 'a18', ast.Ordinal(None), '1.23E10'), |
536 ('FIELD', 'float', 'a15', ast.Ordinal(None), '+1.2345'), | 536 ('FIELD', 'double', 'a19', ast.Ordinal(None), '1.E-10'), |
537 ('FIELD', 'float', 'a16', ast.Ordinal(None), '123.'), | 537 ('FIELD', 'double', 'a20', ast.Ordinal(None), '.5E+10'), |
538 ('FIELD', 'float', 'a17', ast.Ordinal(None), '.123'), | 538 ('FIELD', 'double', 'a21', ast.Ordinal(None), '-1.23E10'), |
539 ('FIELD', 'double', 'a18', ast.Ordinal(None), '1.23E10'), | 539 ('FIELD', 'double', 'a22', ast.Ordinal(None), '+.123E10')])]) |
540 ('FIELD', 'double', 'a19', ast.Ordinal(None), '1.E-10'), | |
541 ('FIELD', 'double', 'a20', ast.Ordinal(None), '.5E+10'), | |
542 ('FIELD', 'double', 'a21', ast.Ordinal(None), '-1.23E10'), | |
543 ('FIELD', 'double', 'a22', ast.Ordinal(None), '+.123E10')])])] | |
544 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 540 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
545 | 541 |
546 def testValidFixedSizeArray(self): | 542 def testValidFixedSizeArray(self): |
547 """Tests parsing a fixed size array.""" | 543 """Tests parsing a fixed size array.""" |
548 | 544 |
549 source = """\ | 545 source = """\ |
550 struct MyStruct { | 546 struct MyStruct { |
551 int32[] normal_array; | 547 int32[] normal_array; |
552 int32[1] fixed_size_array_one_entry; | 548 int32[1] fixed_size_array_one_entry; |
553 int32[10] fixed_size_array_ten_entries; | 549 int32[10] fixed_size_array_ten_entries; |
554 }; | 550 }; |
555 """ | 551 """ |
556 expected = \ | 552 expected = ast.Mojom( |
557 [('MODULE', | 553 None, |
| 554 ast.ImportList(), |
| 555 [('STRUCT', |
| 556 'MyStruct', |
558 None, | 557 None, |
559 None, | 558 [('FIELD', 'int32[]', 'normal_array', ast.Ordinal(None), None), |
560 [('STRUCT', | 559 ('FIELD', 'int32[1]', 'fixed_size_array_one_entry', |
561 'MyStruct', | 560 ast.Ordinal(None), None), |
562 None, | 561 ('FIELD', 'int32[10]', 'fixed_size_array_ten_entries', |
563 [('FIELD', 'int32[]', 'normal_array', ast.Ordinal(None), None), | 562 ast.Ordinal(None), None)])]) |
564 ('FIELD', 'int32[1]', 'fixed_size_array_one_entry', | |
565 ast.Ordinal(None), None), | |
566 ('FIELD', 'int32[10]', 'fixed_size_array_ten_entries', | |
567 ast.Ordinal(None), None)])])] | |
568 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 563 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
569 | 564 |
570 def testValidNestedArray(self): | 565 def testValidNestedArray(self): |
571 """Tests parsing a nested array.""" | 566 """Tests parsing a nested array.""" |
572 | 567 |
573 source = "struct MyStruct { int32[][] nested_array; };" | 568 source = "struct MyStruct { int32[][] nested_array; };" |
574 expected = \ | 569 expected = ast.Mojom( |
575 [('MODULE', | 570 None, |
| 571 ast.ImportList(), |
| 572 [('STRUCT', |
| 573 'MyStruct', |
576 None, | 574 None, |
577 None, | 575 [('FIELD', 'int32[][]', 'nested_array', ast.Ordinal(None), None)])]) |
578 [('STRUCT', | |
579 'MyStruct', | |
580 None, | |
581 [('FIELD', 'int32[][]', 'nested_array', ast.Ordinal(None), | |
582 None)])])] | |
583 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 576 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
584 | 577 |
585 def testInvalidFixedArraySize(self): | 578 def testInvalidFixedArraySize(self): |
586 """Tests that invalid fixed array bounds are correctly detected.""" | 579 """Tests that invalid fixed array bounds are correctly detected.""" |
587 | 580 |
588 source1 = """\ | 581 source1 = """\ |
589 struct MyStruct { | 582 struct MyStruct { |
590 int32[0] zero_size_array; | 583 int32[0] zero_size_array; |
591 }; | 584 }; |
592 """ | 585 """ |
(...skipping 22 matching lines...) Expand all Loading... |
615 with self.assertRaisesRegexp( | 608 with self.assertRaisesRegexp( |
616 parser.ParseError, | 609 parser.ParseError, |
617 r"^my_file\.mojom:2: Error: Unexpected 'abcdefg':\n" | 610 r"^my_file\.mojom:2: Error: Unexpected 'abcdefg':\n" |
618 r" *int32\[abcdefg\] not_a_number;"): | 611 r" *int32\[abcdefg\] not_a_number;"): |
619 parser.Parse(source3, "my_file.mojom") | 612 parser.Parse(source3, "my_file.mojom") |
620 | 613 |
621 def testValidMethod(self): | 614 def testValidMethod(self): |
622 """Tests parsing method declarations.""" | 615 """Tests parsing method declarations.""" |
623 | 616 |
624 source1 = "interface MyInterface { MyMethod(int32 a); };" | 617 source1 = "interface MyInterface { MyMethod(int32 a); };" |
625 expected1 = \ | 618 expected1 = ast.Mojom( |
626 [('MODULE', | 619 None, |
| 620 ast.ImportList(), |
| 621 [('INTERFACE', |
| 622 'MyInterface', |
627 None, | 623 None, |
628 None, | 624 [('METHOD', |
629 [('INTERFACE', | 625 'MyMethod', |
630 'MyInterface', | 626 ast.ParameterList(ast.Parameter('int32', 'a', ast.Ordinal(None))), |
631 None, | 627 ast.Ordinal(None), |
632 [('METHOD', | 628 None)])]) |
633 'MyMethod', | |
634 ast.ParameterList(ast.Parameter('int32', 'a', ast.Ordinal(None))), | |
635 ast.Ordinal(None), | |
636 None)])])] | |
637 self.assertEquals(parser.Parse(source1, "my_file.mojom"), expected1) | 629 self.assertEquals(parser.Parse(source1, "my_file.mojom"), expected1) |
638 | 630 |
639 source2 = """\ | 631 source2 = """\ |
640 interface MyInterface { | 632 interface MyInterface { |
641 MyMethod1@0(int32 a@0, int64 b@1); | 633 MyMethod1@0(int32 a@0, int64 b@1); |
642 MyMethod2@1() => (); | 634 MyMethod2@1() => (); |
643 }; | 635 }; |
644 """ | 636 """ |
645 expected2 = \ | 637 expected2 = ast.Mojom( |
646 [('MODULE', | 638 None, |
| 639 ast.ImportList(), |
| 640 [('INTERFACE', |
| 641 'MyInterface', |
647 None, | 642 None, |
648 None, | 643 [('METHOD', |
649 [('INTERFACE', | 644 'MyMethod1', |
650 'MyInterface', | 645 ast.ParameterList([ast.Parameter('int32', 'a', ast.Ordinal(0)), |
651 None, | 646 ast.Parameter('int64', 'b', ast.Ordinal(1))]), |
652 [('METHOD', | 647 ast.Ordinal(0), |
653 'MyMethod1', | 648 None), |
654 ast.ParameterList([ast.Parameter('int32', 'a', ast.Ordinal(0)), | 649 ('METHOD', |
655 ast.Parameter('int64', 'b', ast.Ordinal(1))]), | 650 'MyMethod2', |
656 ast.Ordinal(0), | 651 ast.ParameterList(), |
657 None), | 652 ast.Ordinal(1), |
658 ('METHOD', | 653 ast.ParameterList())])]) |
659 'MyMethod2', | |
660 ast.ParameterList(), | |
661 ast.Ordinal(1), | |
662 ast.ParameterList())])])] | |
663 self.assertEquals(parser.Parse(source2, "my_file.mojom"), expected2) | 654 self.assertEquals(parser.Parse(source2, "my_file.mojom"), expected2) |
664 | 655 |
665 source3 = """\ | 656 source3 = """\ |
666 interface MyInterface { | 657 interface MyInterface { |
667 MyMethod(string a) => (int32 a, bool b); | 658 MyMethod(string a) => (int32 a, bool b); |
668 }; | 659 }; |
669 """ | 660 """ |
670 expected3 = \ | 661 expected3 = ast.Mojom( |
671 [('MODULE', | 662 None, |
| 663 ast.ImportList(), |
| 664 [('INTERFACE', |
| 665 'MyInterface', |
672 None, | 666 None, |
673 None, | 667 [('METHOD', |
674 [('INTERFACE', | 668 'MyMethod', |
675 'MyInterface', | 669 ast.ParameterList(ast.Parameter('string', 'a', |
676 None, | 670 ast.Ordinal(None))), |
677 [('METHOD', | 671 ast.Ordinal(None), |
678 'MyMethod', | 672 ast.ParameterList([ast.Parameter('int32', 'a', ast.Ordinal(None)), |
679 ast.ParameterList(ast.Parameter('string', 'a', | 673 ast.Parameter('bool', 'b', |
680 ast.Ordinal(None))), | 674 ast.Ordinal(None))]))])]) |
681 ast.Ordinal(None), | |
682 ast.ParameterList([ast.Parameter('int32', 'a', ast.Ordinal(None)), | |
683 ast.Parameter('bool', 'b', | |
684 ast.Ordinal(None))]))])])] | |
685 self.assertEquals(parser.Parse(source3, "my_file.mojom"), expected3) | 675 self.assertEquals(parser.Parse(source3, "my_file.mojom"), expected3) |
686 | 676 |
687 def testInvalidMethods(self): | 677 def testInvalidMethods(self): |
688 """Tests that invalid method declarations are correctly detected.""" | 678 """Tests that invalid method declarations are correctly detected.""" |
689 | 679 |
690 # No trailing commas. | 680 # No trailing commas. |
691 source1 = """\ | 681 source1 = """\ |
692 interface MyInterface { | 682 interface MyInterface { |
693 MyMethod(string a,); | 683 MyMethod(string a,); |
694 }; | 684 }; |
(...skipping 16 matching lines...) Expand all Loading... |
711 r" *MyMethod\(, string a\);$"): | 701 r" *MyMethod\(, string a\);$"): |
712 parser.Parse(source2, "my_file.mojom") | 702 parser.Parse(source2, "my_file.mojom") |
713 | 703 |
714 def testValidAttributes(self): | 704 def testValidAttributes(self): |
715 """Tests parsing attributes (and attribute lists).""" | 705 """Tests parsing attributes (and attribute lists).""" |
716 | 706 |
717 # Note: We use structs because they have (optional) attribute lists. | 707 # Note: We use structs because they have (optional) attribute lists. |
718 | 708 |
719 # Empty attribute list. | 709 # Empty attribute list. |
720 source1 = "[] struct MyStruct {};" | 710 source1 = "[] struct MyStruct {};" |
721 expected1 = \ | 711 expected1 = ast.Mojom( |
722 [('MODULE', | 712 None, |
723 None, | 713 ast.ImportList(), |
724 None, | 714 [('STRUCT', |
725 [('STRUCT', | 715 'MyStruct', |
726 'MyStruct', | 716 ast.AttributeList(), |
727 ast.AttributeList(), | 717 None)]) |
728 None)])] | |
729 self.assertEquals(parser.Parse(source1, "my_file.mojom"), expected1) | 718 self.assertEquals(parser.Parse(source1, "my_file.mojom"), expected1) |
730 | 719 |
731 # One-element attribute list, with name value. | 720 # One-element attribute list, with name value. |
732 source2 = "[MyAttribute=MyName] struct MyStruct {};" | 721 source2 = "[MyAttribute=MyName] struct MyStruct {};" |
733 expected2 = \ | 722 expected2 = ast.Mojom( |
734 [('MODULE', | 723 None, |
735 None, | 724 ast.ImportList(), |
736 None, | 725 [('STRUCT', |
737 [('STRUCT', | 726 'MyStruct', |
738 'MyStruct', | 727 ast.AttributeList(ast.Attribute("MyAttribute", "MyName")), |
739 ast.AttributeList(ast.Attribute("MyAttribute", "MyName")), | 728 None)]) |
740 None)])] | |
741 self.assertEquals(parser.Parse(source2, "my_file.mojom"), expected2) | 729 self.assertEquals(parser.Parse(source2, "my_file.mojom"), expected2) |
742 | 730 |
743 # Two-element attribute list, with one string value and one integer value. | 731 # Two-element attribute list, with one string value and one integer value. |
744 source3 = "[MyAttribute1 = \"hello\", MyAttribute2 = 5] struct MyStruct {};" | 732 source3 = "[MyAttribute1 = \"hello\", MyAttribute2 = 5] struct MyStruct {};" |
745 expected3 = \ | 733 expected3 = ast.Mojom( |
746 [('MODULE', | 734 None, |
747 None, | 735 ast.ImportList(), |
748 None, | 736 [('STRUCT', |
749 [('STRUCT', | 737 'MyStruct', |
750 'MyStruct', | 738 ast.AttributeList([ast.Attribute("MyAttribute1", "hello"), |
751 ast.AttributeList([ast.Attribute("MyAttribute1", "hello"), | 739 ast.Attribute("MyAttribute2", 5)]), |
752 ast.Attribute("MyAttribute2", 5)]), | 740 None)]) |
753 None)])] | |
754 self.assertEquals(parser.Parse(source3, "my_file.mojom"), expected3) | 741 self.assertEquals(parser.Parse(source3, "my_file.mojom"), expected3) |
755 | 742 |
756 # TODO(vtl): Boolean attributes don't work yet. (In fact, we just |eval()| | 743 # TODO(vtl): Boolean attributes don't work yet. (In fact, we just |eval()| |
757 # literal (non-name) values, which is extremely dubious.) | 744 # literal (non-name) values, which is extremely dubious.) |
758 | 745 |
759 def testInvalidAttributes(self): | 746 def testInvalidAttributes(self): |
760 """Tests that invalid attributes and attribute lists are correctly | 747 """Tests that invalid attributes and attribute lists are correctly |
761 detected.""" | 748 detected.""" |
762 | 749 |
763 # Trailing commas not allowed. | 750 # Trailing commas not allowed. |
(...skipping 13 matching lines...) Expand all Loading... |
777 parser.Parse(source2, "my_file.mojom") | 764 parser.Parse(source2, "my_file.mojom") |
778 | 765 |
779 # Missing key. | 766 # Missing key. |
780 source3 = "[=MyName] struct MyStruct {};" | 767 source3 = "[=MyName] struct MyStruct {};" |
781 with self.assertRaisesRegexp( | 768 with self.assertRaisesRegexp( |
782 parser.ParseError, | 769 parser.ParseError, |
783 r"^my_file\.mojom:1: Error: Unexpected '=':\n" | 770 r"^my_file\.mojom:1: Error: Unexpected '=':\n" |
784 r"\[=MyName\] struct MyStruct {};$"): | 771 r"\[=MyName\] struct MyStruct {};$"): |
785 parser.Parse(source3, "my_file.mojom") | 772 parser.Parse(source3, "my_file.mojom") |
786 | 773 |
| 774 def testValidImports(self): |
| 775 """Tests parsing import statements.""" |
| 776 |
| 777 # One import (no module statement). |
| 778 source1 = "import \"somedir/my.mojom\"" |
| 779 expected1 = ast.Mojom( |
| 780 None, |
| 781 ast.ImportList(ast.Import("somedir/my.mojom")), |
| 782 []) |
| 783 self.assertEquals(parser.Parse(source1, "my_file.mojom"), expected1) |
| 784 |
| 785 # Two imports (no module statement). |
| 786 source2 = """\ |
| 787 import "somedir/my1.mojom" |
| 788 import "somedir/my2.mojom" |
| 789 """ |
| 790 expected2 = ast.Mojom( |
| 791 None, |
| 792 ast.ImportList([ast.Import("somedir/my1.mojom"), |
| 793 ast.Import("somedir/my2.mojom")]), |
| 794 []) |
| 795 self.assertEquals(parser.Parse(source2, "my_file.mojom"), expected2) |
| 796 |
| 797 # Imports with module statement. |
| 798 source3 = """\ |
| 799 import "somedir/my1.mojom" |
| 800 import "somedir/my2.mojom" |
| 801 module my_module {} |
| 802 """ |
| 803 expected3 = ast.Mojom( |
| 804 ast.Module(('IDENTIFIER', 'my_module'), None), |
| 805 ast.ImportList([ast.Import("somedir/my1.mojom"), |
| 806 ast.Import("somedir/my2.mojom")]), |
| 807 []) |
| 808 |
| 809 def testInvalidImports(self): |
| 810 """Tests that invalid import statements are correctly detected.""" |
| 811 |
| 812 source1 = """\ |
| 813 // Make the error occur on line 2. |
| 814 import invalid |
| 815 """ |
| 816 with self.assertRaisesRegexp( |
| 817 parser.ParseError, |
| 818 r"^my_file\.mojom:2: Error: Unexpected 'invalid':\n" |
| 819 r" *import invalid$"): |
| 820 parser.Parse(source1, "my_file.mojom") |
| 821 |
| 822 source2 = """\ |
| 823 import // Missing string. |
| 824 module {} |
| 825 """ |
| 826 with self.assertRaisesRegexp( |
| 827 parser.ParseError, |
| 828 r"^my_file\.mojom:2: Error: Unexpected 'module':\n" |
| 829 r" *module {}$"): |
| 830 parser.Parse(source2, "my_file.mojom") |
| 831 |
| 832 |
787 if __name__ == "__main__": | 833 if __name__ == "__main__": |
788 unittest.main() | 834 unittest.main() |
OLD | NEW |