| 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 |