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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 struct MyStruct { | 141 struct MyStruct { |
142 int32 a; | 142 int32 a; |
143 double b; | 143 double b; |
144 }; | 144 }; |
145 | 145 |
146 } // module my_module | 146 } // module my_module |
147 """ | 147 """ |
148 expected = ast.Mojom( | 148 expected = ast.Mojom( |
149 ast.Module(('IDENTIFIER', 'my_module'), None), | 149 ast.Module(('IDENTIFIER', 'my_module'), None), |
150 ast.ImportList(), | 150 ast.ImportList(), |
151 [('STRUCT', | 151 [ast.Struct( |
152 'MyStruct', | 152 'MyStruct', |
153 None, | 153 None, |
154 [ast.StructField('a', None, 'int32', None), | 154 ast.StructBody( |
155 ast.StructField('b', None, 'double', None)])]) | 155 [ast.StructField('a', None, 'int32', None), |
| 156 ast.StructField('b', None, 'double', None)]))]) |
156 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 157 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
157 | 158 |
158 def testSimpleStructWithoutModule(self): | 159 def testSimpleStructWithoutModule(self): |
159 """Tests a simple struct without an enclosing module.""" | 160 """Tests a simple struct without an enclosing module.""" |
160 | 161 |
161 source = """\ | 162 source = """\ |
162 struct MyStruct { | 163 struct MyStruct { |
163 int32 a; | 164 int32 a; |
164 double b; | 165 double b; |
165 }; | 166 }; |
166 """ | 167 """ |
167 expected = ast.Mojom( | 168 expected = ast.Mojom( |
168 None, | 169 None, |
169 ast.ImportList(), | 170 ast.ImportList(), |
170 [('STRUCT', | 171 [ast.Struct( |
171 'MyStruct', | 172 'MyStruct', |
172 None, | 173 None, |
173 [ast.StructField('a', None, 'int32', None), | 174 ast.StructBody( |
174 ast.StructField('b', None, 'double', None)])]) | 175 [ast.StructField('a', None, 'int32', None), |
| 176 ast.StructField('b', None, 'double', None)]))]) |
175 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 177 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
176 | 178 |
177 def testMissingModuleName(self): | 179 def testMissingModuleName(self): |
178 """Tests an (invalid) .mojom with a missing module name.""" | 180 """Tests an (invalid) .mojom with a missing module name.""" |
179 | 181 |
180 source1 = """\ | 182 source1 = """\ |
181 // Missing module name. | 183 // Missing module name. |
182 module { | 184 module { |
183 struct MyStruct { | 185 struct MyStruct { |
184 int32 a; | 186 int32 a; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 struct MyStruct { | 281 struct MyStruct { |
280 const int8 kNumber = -1; | 282 const int8 kNumber = -1; |
281 int8 number@0 = kNumber; | 283 int8 number@0 = kNumber; |
282 }; | 284 }; |
283 | 285 |
284 } // my_module | 286 } // my_module |
285 """ | 287 """ |
286 expected = ast.Mojom( | 288 expected = ast.Mojom( |
287 ast.Module(('IDENTIFIER', 'my_module'), None), | 289 ast.Module(('IDENTIFIER', 'my_module'), None), |
288 ast.ImportList(), | 290 ast.ImportList(), |
289 [('STRUCT', | 291 [ast.Struct( |
290 'MyStruct', None, | 292 'MyStruct', None, |
291 [ast.Const('kNumber', 'int8', '-1'), | 293 ast.StructBody( |
292 ast.StructField('number', ast.Ordinal(0), 'int8', | 294 [ast.Const('kNumber', 'int8', '-1'), |
293 ('IDENTIFIER', 'kNumber'))])]) | 295 ast.StructField('number', ast.Ordinal(0), 'int8', |
| 296 ('IDENTIFIER', 'kNumber'))]))]) |
294 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 297 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
295 | 298 |
296 def testNoConditionals(self): | 299 def testNoConditionals(self): |
297 """Tests that ?: is not allowed.""" | 300 """Tests that ?: is not allowed.""" |
298 | 301 |
299 source = """\ | 302 source = """\ |
300 module my_module { | 303 module my_module { |
301 | 304 |
302 enum MyEnum { | 305 enum MyEnum { |
303 MY_ENUM_1 = 1 ? 2 : 3 | 306 MY_ENUM_1 = 1 ? 2 : 3 |
(...skipping 23 matching lines...) Expand all Loading... |
327 int32 a11 @11; | 330 int32 a11 @11; |
328 int32 a29 @29; | 331 int32 a29 @29; |
329 int32 a1234567890 @1234567890; | 332 int32 a1234567890 @1234567890; |
330 }; | 333 }; |
331 | 334 |
332 } // module my_module | 335 } // module my_module |
333 """ | 336 """ |
334 expected = ast.Mojom( | 337 expected = ast.Mojom( |
335 ast.Module(('IDENTIFIER', 'my_module'), None), | 338 ast.Module(('IDENTIFIER', 'my_module'), None), |
336 ast.ImportList(), | 339 ast.ImportList(), |
337 [('STRUCT', | 340 [ast.Struct( |
338 'MyStruct', | 341 'MyStruct', |
339 None, | 342 None, |
340 [ast.StructField('a0', ast.Ordinal(0), 'int32', None), | 343 ast.StructBody( |
341 ast.StructField('a1', ast.Ordinal(1), 'int32', None), | 344 [ast.StructField('a0', ast.Ordinal(0), 'int32', None), |
342 ast.StructField('a2', ast.Ordinal(2), 'int32', None), | 345 ast.StructField('a1', ast.Ordinal(1), 'int32', None), |
343 ast.StructField('a9', ast.Ordinal(9), 'int32', None), | 346 ast.StructField('a2', ast.Ordinal(2), 'int32', None), |
344 ast.StructField('a10', ast.Ordinal(10), 'int32', None), | 347 ast.StructField('a9', ast.Ordinal(9), 'int32', None), |
345 ast.StructField('a11', ast.Ordinal(11), 'int32', None), | 348 ast.StructField('a10', ast.Ordinal(10), 'int32', None), |
346 ast.StructField('a29', ast.Ordinal(29), 'int32', None), | 349 ast.StructField('a11', ast.Ordinal(11), 'int32', None), |
347 ast.StructField('a1234567890', ast.Ordinal(1234567890), 'int32', | 350 ast.StructField('a29', ast.Ordinal(29), 'int32', None), |
348 None)])]) | 351 ast.StructField('a1234567890', ast.Ordinal(1234567890), |
| 352 'int32', None)]))]) |
349 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 353 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
350 | 354 |
351 def testInvalidOrdinals(self): | 355 def testInvalidOrdinals(self): |
352 """Tests that (lexically) invalid ordinals are correctly detected.""" | 356 """Tests that (lexically) invalid ordinals are correctly detected.""" |
353 | 357 |
354 source1 = """\ | 358 source1 = """\ |
355 module my_module { | 359 module my_module { |
356 | 360 |
357 struct MyStruct { | 361 struct MyStruct { |
358 int32 a_missing@; | 362 int32 a_missing@; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 | 427 |
424 struct MyStruct { | 428 struct MyStruct { |
425 int32 a; | 429 int32 a; |
426 }; | 430 }; |
427 | 431 |
428 } // module my.mod | 432 } // module my.mod |
429 """ | 433 """ |
430 expected = ast.Mojom( | 434 expected = ast.Mojom( |
431 ast.Module(('IDENTIFIER', 'my.mod'), None), | 435 ast.Module(('IDENTIFIER', 'my.mod'), None), |
432 ast.ImportList(), | 436 ast.ImportList(), |
433 [('STRUCT', | 437 [ast.Struct( |
434 'MyStruct', | 438 'MyStruct', |
435 None, | 439 None, |
436 [ast.StructField('a', None, 'int32', None)])]) | 440 ast.StructBody(ast.StructField('a', None, 'int32', None)))]) |
437 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 441 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
438 | 442 |
439 def testValidHandleTypes(self): | 443 def testValidHandleTypes(self): |
440 """Tests (valid) handle types.""" | 444 """Tests (valid) handle types.""" |
441 | 445 |
442 source = """\ | 446 source = """\ |
443 struct MyStruct { | 447 struct MyStruct { |
444 handle a; | 448 handle a; |
445 handle<data_pipe_consumer> b; | 449 handle<data_pipe_consumer> b; |
446 handle <data_pipe_producer> c; | 450 handle <data_pipe_producer> c; |
447 handle < message_pipe > d; | 451 handle < message_pipe > d; |
448 handle | 452 handle |
449 < shared_buffer | 453 < shared_buffer |
450 > e; | 454 > e; |
451 }; | 455 }; |
452 """ | 456 """ |
453 expected = ast.Mojom( | 457 expected = ast.Mojom( |
454 None, | 458 None, |
455 ast.ImportList(), | 459 ast.ImportList(), |
456 [('STRUCT', | 460 [ast.Struct( |
457 'MyStruct', | 461 'MyStruct', |
458 None, | 462 None, |
459 [ast.StructField('a', None, 'handle', None), | 463 ast.StructBody( |
460 ast.StructField('b', None, 'handle<data_pipe_consumer>', None), | 464 [ast.StructField('a', None, 'handle', None), |
461 ast.StructField('c', None, 'handle<data_pipe_producer>', None), | 465 ast.StructField('b', None, 'handle<data_pipe_consumer>', None), |
462 ast.StructField('d', None, 'handle<message_pipe>', None), | 466 ast.StructField('c', None, 'handle<data_pipe_producer>', None), |
463 ast.StructField('e', None, 'handle<shared_buffer>', None)])]) | 467 ast.StructField('d', None, 'handle<message_pipe>', None), |
| 468 ast.StructField('e', None, 'handle<shared_buffer>', None)]))]) |
464 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 469 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
465 | 470 |
466 def testInvalidHandleType(self): | 471 def testInvalidHandleType(self): |
467 """Tests an invalid (unknown) handle type.""" | 472 """Tests an invalid (unknown) handle type.""" |
468 | 473 |
469 source = """\ | 474 source = """\ |
470 struct MyStruct { | 475 struct MyStruct { |
471 handle<wtf_is_this> foo; | 476 handle<wtf_is_this> foo; |
472 }; | 477 }; |
473 """ | 478 """ |
(...skipping 30 matching lines...) Expand all Loading... |
504 double a18 = 1.23E10; | 509 double a18 = 1.23E10; |
505 double a19 = 1.E-10; | 510 double a19 = 1.E-10; |
506 double a20 = .5E+10; | 511 double a20 = .5E+10; |
507 double a21 = -1.23E10; | 512 double a21 = -1.23E10; |
508 double a22 = +.123E10; | 513 double a22 = +.123E10; |
509 }; | 514 }; |
510 """ | 515 """ |
511 expected = ast.Mojom( | 516 expected = ast.Mojom( |
512 None, | 517 None, |
513 ast.ImportList(), | 518 ast.ImportList(), |
514 [('STRUCT', | 519 [ast.Struct( |
515 'MyStruct', | 520 'MyStruct', |
516 None, | 521 None, |
517 [ast.StructField('a0', None, 'int16', '0'), | 522 ast.StructBody( |
518 ast.StructField('a1', None, 'uint16', '0x0'), | 523 [ast.StructField('a0', None, 'int16', '0'), |
519 ast.StructField('a2', None, 'uint16', '0x00'), | 524 ast.StructField('a1', None, 'uint16', '0x0'), |
520 ast.StructField('a3', None, 'uint16', '0x01'), | 525 ast.StructField('a2', None, 'uint16', '0x00'), |
521 ast.StructField('a4', None, 'uint16', '0xcd'), | 526 ast.StructField('a3', None, 'uint16', '0x01'), |
522 ast.StructField('a5' , None, 'int32', '12345'), | 527 ast.StructField('a4', None, 'uint16', '0xcd'), |
523 ast.StructField('a6', None, 'int64', '-12345'), | 528 ast.StructField('a5' , None, 'int32', '12345'), |
524 ast.StructField('a7', None, 'int64', '+12345'), | 529 ast.StructField('a6', None, 'int64', '-12345'), |
525 ast.StructField('a8', None, 'uint32', '0x12cd3'), | 530 ast.StructField('a7', None, 'int64', '+12345'), |
526 ast.StructField('a9', None, 'uint32', '-0x12cD3'), | 531 ast.StructField('a8', None, 'uint32', '0x12cd3'), |
527 ast.StructField('a10', None, 'uint32', '+0x12CD3'), | 532 ast.StructField('a9', None, 'uint32', '-0x12cD3'), |
528 ast.StructField('a11', None, 'bool', 'true'), | 533 ast.StructField('a10', None, 'uint32', '+0x12CD3'), |
529 ast.StructField('a12', None, 'bool', 'false'), | 534 ast.StructField('a11', None, 'bool', 'true'), |
530 ast.StructField('a13', None, 'float', '1.2345'), | 535 ast.StructField('a12', None, 'bool', 'false'), |
531 ast.StructField('a14', None, 'float', '-1.2345'), | 536 ast.StructField('a13', None, 'float', '1.2345'), |
532 ast.StructField('a15', None, 'float', '+1.2345'), | 537 ast.StructField('a14', None, 'float', '-1.2345'), |
533 ast.StructField('a16', None, 'float', '123.'), | 538 ast.StructField('a15', None, 'float', '+1.2345'), |
534 ast.StructField('a17', None, 'float', '.123'), | 539 ast.StructField('a16', None, 'float', '123.'), |
535 ast.StructField('a18', None, 'double', '1.23E10'), | 540 ast.StructField('a17', None, 'float', '.123'), |
536 ast.StructField('a19', None, 'double', '1.E-10'), | 541 ast.StructField('a18', None, 'double', '1.23E10'), |
537 ast.StructField('a20', None, 'double', '.5E+10'), | 542 ast.StructField('a19', None, 'double', '1.E-10'), |
538 ast.StructField('a21', None, 'double', '-1.23E10'), | 543 ast.StructField('a20', None, 'double', '.5E+10'), |
539 ast.StructField('a22', None, 'double', '+.123E10')])]) | 544 ast.StructField('a21', None, 'double', '-1.23E10'), |
| 545 ast.StructField('a22', None, 'double', '+.123E10')]))]) |
540 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 546 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
541 | 547 |
542 def testValidFixedSizeArray(self): | 548 def testValidFixedSizeArray(self): |
543 """Tests parsing a fixed size array.""" | 549 """Tests parsing a fixed size array.""" |
544 | 550 |
545 source = """\ | 551 source = """\ |
546 struct MyStruct { | 552 struct MyStruct { |
547 int32[] normal_array; | 553 int32[] normal_array; |
548 int32[1] fixed_size_array_one_entry; | 554 int32[1] fixed_size_array_one_entry; |
549 int32[10] fixed_size_array_ten_entries; | 555 int32[10] fixed_size_array_ten_entries; |
550 }; | 556 }; |
551 """ | 557 """ |
552 expected = ast.Mojom( | 558 expected = ast.Mojom( |
553 None, | 559 None, |
554 ast.ImportList(), | 560 ast.ImportList(), |
555 [('STRUCT', | 561 [ast.Struct( |
556 'MyStruct', | 562 'MyStruct', |
557 None, | 563 None, |
558 [ast.StructField('normal_array', None, 'int32[]', None), | 564 ast.StructBody( |
559 ast.StructField('fixed_size_array_one_entry', None, 'int32[1]', | 565 [ast.StructField('normal_array', None, 'int32[]', None), |
560 None), | 566 ast.StructField('fixed_size_array_one_entry', None, 'int32[1]', |
561 ast.StructField('fixed_size_array_ten_entries', None, 'int32[10]', | 567 None), |
562 None)])]) | 568 ast.StructField('fixed_size_array_ten_entries', None, |
| 569 'int32[10]', None)]))]) |
563 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 570 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
564 | 571 |
565 def testValidNestedArray(self): | 572 def testValidNestedArray(self): |
566 """Tests parsing a nested array.""" | 573 """Tests parsing a nested array.""" |
567 | 574 |
568 source = "struct MyStruct { int32[][] nested_array; };" | 575 source = "struct MyStruct { int32[][] nested_array; };" |
569 expected = ast.Mojom( | 576 expected = ast.Mojom( |
570 None, | 577 None, |
571 ast.ImportList(), | 578 ast.ImportList(), |
572 [('STRUCT', | 579 [ast.Struct( |
573 'MyStruct', | 580 'MyStruct', |
574 None, | 581 None, |
575 [ast.StructField('nested_array', None, 'int32[][]', None)])]) | 582 ast.StructBody( |
| 583 ast.StructField('nested_array', None, 'int32[][]', None)))]) |
576 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) | 584 self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) |
577 | 585 |
578 def testInvalidFixedArraySize(self): | 586 def testInvalidFixedArraySize(self): |
579 """Tests that invalid fixed array bounds are correctly detected.""" | 587 """Tests that invalid fixed array bounds are correctly detected.""" |
580 | 588 |
581 source1 = """\ | 589 source1 = """\ |
582 struct MyStruct { | 590 struct MyStruct { |
583 int32[0] zero_size_array; | 591 int32[0] zero_size_array; |
584 }; | 592 }; |
585 """ | 593 """ |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 def testValidAttributes(self): | 710 def testValidAttributes(self): |
703 """Tests parsing attributes (and attribute lists).""" | 711 """Tests parsing attributes (and attribute lists).""" |
704 | 712 |
705 # Note: We use structs because they have (optional) attribute lists. | 713 # Note: We use structs because they have (optional) attribute lists. |
706 | 714 |
707 # Empty attribute list. | 715 # Empty attribute list. |
708 source1 = "[] struct MyStruct {};" | 716 source1 = "[] struct MyStruct {};" |
709 expected1 = ast.Mojom( | 717 expected1 = ast.Mojom( |
710 None, | 718 None, |
711 ast.ImportList(), | 719 ast.ImportList(), |
712 [('STRUCT', | 720 [ast.Struct('MyStruct', ast.AttributeList(), ast.StructBody())]) |
713 'MyStruct', | |
714 ast.AttributeList(), | |
715 None)]) | |
716 self.assertEquals(parser.Parse(source1, "my_file.mojom"), expected1) | 721 self.assertEquals(parser.Parse(source1, "my_file.mojom"), expected1) |
717 | 722 |
718 # One-element attribute list, with name value. | 723 # One-element attribute list, with name value. |
719 source2 = "[MyAttribute=MyName] struct MyStruct {};" | 724 source2 = "[MyAttribute=MyName] struct MyStruct {};" |
720 expected2 = ast.Mojom( | 725 expected2 = ast.Mojom( |
721 None, | 726 None, |
722 ast.ImportList(), | 727 ast.ImportList(), |
723 [('STRUCT', | 728 [ast.Struct( |
724 'MyStruct', | 729 'MyStruct', |
725 ast.AttributeList(ast.Attribute("MyAttribute", "MyName")), | 730 ast.AttributeList(ast.Attribute("MyAttribute", "MyName")), |
726 None)]) | 731 ast.StructBody())]) |
727 self.assertEquals(parser.Parse(source2, "my_file.mojom"), expected2) | 732 self.assertEquals(parser.Parse(source2, "my_file.mojom"), expected2) |
728 | 733 |
729 # Two-element attribute list, with one string value and one integer value. | 734 # Two-element attribute list, with one string value and one integer value. |
730 source3 = "[MyAttribute1 = \"hello\", MyAttribute2 = 5] struct MyStruct {};" | 735 source3 = "[MyAttribute1 = \"hello\", MyAttribute2 = 5] struct MyStruct {};" |
731 expected3 = ast.Mojom( | 736 expected3 = ast.Mojom( |
732 None, | 737 None, |
733 ast.ImportList(), | 738 ast.ImportList(), |
734 [('STRUCT', | 739 [ast.Struct( |
735 'MyStruct', | 740 'MyStruct', |
736 ast.AttributeList([ast.Attribute("MyAttribute1", "hello"), | 741 ast.AttributeList([ast.Attribute("MyAttribute1", "hello"), |
737 ast.Attribute("MyAttribute2", 5)]), | 742 ast.Attribute("MyAttribute2", 5)]), |
738 None)]) | 743 ast.StructBody())]) |
739 self.assertEquals(parser.Parse(source3, "my_file.mojom"), expected3) | 744 self.assertEquals(parser.Parse(source3, "my_file.mojom"), expected3) |
740 | 745 |
741 # TODO(vtl): Boolean attributes don't work yet. (In fact, we just |eval()| | 746 # TODO(vtl): Boolean attributes don't work yet. (In fact, we just |eval()| |
742 # literal (non-name) values, which is extremely dubious.) | 747 # literal (non-name) values, which is extremely dubious.) |
743 | 748 |
744 def testInvalidAttributes(self): | 749 def testInvalidAttributes(self): |
745 """Tests that invalid attributes and attribute lists are correctly | 750 """Tests that invalid attributes and attribute lists are correctly |
746 detected.""" | 751 detected.""" |
747 | 752 |
748 # Trailing commas not allowed. | 753 # Trailing commas not allowed. |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 """ | 828 """ |
824 with self.assertRaisesRegexp( | 829 with self.assertRaisesRegexp( |
825 parser.ParseError, | 830 parser.ParseError, |
826 r"^my_file\.mojom:2: Error: Unexpected 'module':\n" | 831 r"^my_file\.mojom:2: Error: Unexpected 'module':\n" |
827 r" *module {}$"): | 832 r" *module {}$"): |
828 parser.Parse(source2, "my_file.mojom") | 833 parser.Parse(source2, "my_file.mojom") |
829 | 834 |
830 | 835 |
831 if __name__ == "__main__": | 836 if __name__ == "__main__": |
832 unittest.main() | 837 unittest.main() |
OLD | NEW |