diff options
Diffstat (limited to 'mojo/public/tools/bindings/pylib/mojom_tests/parse/parser_unittest.py')
-rw-r--r-- | mojo/public/tools/bindings/pylib/mojom_tests/parse/parser_unittest.py | 1497 |
1 files changed, 0 insertions, 1497 deletions
diff --git a/mojo/public/tools/bindings/pylib/mojom_tests/parse/parser_unittest.py b/mojo/public/tools/bindings/pylib/mojom_tests/parse/parser_unittest.py deleted file mode 100644 index 3f4ca87..0000000 --- a/mojo/public/tools/bindings/pylib/mojom_tests/parse/parser_unittest.py +++ /dev/null @@ -1,1497 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import imp -import os.path -import sys -import unittest - -def _GetDirAbove(dirname): - """Returns the directory "above" this file containing |dirname| (which must - also be "above" this file).""" - path = os.path.abspath(__file__) - while True: - path, tail = os.path.split(path) - assert tail - if tail == dirname: - return path - -try: - imp.find_module("mojom") -except ImportError: - sys.path.append(os.path.join(_GetDirAbove("pylib"), "pylib")) -import mojom.parse.ast as ast -import mojom.parse.lexer as lexer -import mojom.parse.parser as parser - - -class ParserTest(unittest.TestCase): - """Tests |parser.Parse()|.""" - - def testTrivialValidSource(self): - """Tests a trivial, but valid, .mojom source.""" - - source = """\ - // This is a comment. - - module my_module; - """ - expected = ast.Mojom( - ast.Module(('IDENTIFIER', 'my_module'), None), - ast.ImportList(), - []) - self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) - - def testSourceWithCrLfs(self): - """Tests a .mojom source with CR-LFs instead of LFs.""" - - source = "// This is a comment.\r\n\r\nmodule my_module;\r\n" - expected = ast.Mojom( - ast.Module(('IDENTIFIER', 'my_module'), None), - ast.ImportList(), - []) - self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) - - def testUnexpectedEOF(self): - """Tests a "truncated" .mojom source.""" - - source = """\ - // This is a comment. - - module my_module - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom: Error: Unexpected end of file$"): - parser.Parse(source, "my_file.mojom") - - def testCommentLineNumbers(self): - """Tests that line numbers are correctly tracked when comments are - present.""" - - source1 = """\ - // Isolated C++-style comments. - - // Foo. - asdf1 - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:4: Error: Unexpected 'asdf1':\n *asdf1$"): - parser.Parse(source1, "my_file.mojom") - - source2 = """\ - // Consecutive C++-style comments. - // Foo. - // Bar. - - struct Yada { // Baz. - // Quux. - int32 x; - }; - - asdf2 - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:10: Error: Unexpected 'asdf2':\n *asdf2$"): - parser.Parse(source2, "my_file.mojom") - - source3 = """\ - /* Single-line C-style comments. */ - /* Foobar. */ - - /* Baz. */ - asdf3 - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:5: Error: Unexpected 'asdf3':\n *asdf3$"): - parser.Parse(source3, "my_file.mojom") - - source4 = """\ - /* Multi-line C-style comments. - */ - /* - Foo. - Bar. - */ - - /* Baz - Quux. */ - asdf4 - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:10: Error: Unexpected 'asdf4':\n *asdf4$"): - parser.Parse(source4, "my_file.mojom") - - - def testSimpleStruct(self): - """Tests a simple .mojom source that just defines a struct.""" - - source = """\ - module my_module; - - struct MyStruct { - int32 a; - double b; - }; - """ - expected = ast.Mojom( - ast.Module(('IDENTIFIER', 'my_module'), None), - ast.ImportList(), - [ast.Struct( - 'MyStruct', - None, - ast.StructBody( - [ast.StructField('a', None, None, 'int32', None), - ast.StructField('b', None, None, 'double', None)]))]) - self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) - - def testSimpleStructWithoutModule(self): - """Tests a simple struct without an explict module statement.""" - - source = """\ - struct MyStruct { - int32 a; - double b; - }; - """ - expected = ast.Mojom( - None, - ast.ImportList(), - [ast.Struct( - 'MyStruct', - None, - ast.StructBody( - [ast.StructField('a', None, None, 'int32', None), - ast.StructField('b', None, None, 'double', None)]))]) - self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) - - def testValidStructDefinitions(self): - """Tests all types of definitions that can occur in a struct.""" - - source = """\ - struct MyStruct { - enum MyEnum { VALUE }; - const double kMyConst = 1.23; - int32 a; - SomeOtherStruct b; // Invalidity detected at another stage. - }; - """ - expected = ast.Mojom( - None, - ast.ImportList(), - [ast.Struct( - 'MyStruct', - None, - ast.StructBody( - [ast.Enum('MyEnum', - None, - ast.EnumValueList( - ast.EnumValue('VALUE', None, None))), - ast.Const('kMyConst', 'double', '1.23'), - ast.StructField('a', None, None, 'int32', None), - ast.StructField('b', None, None, 'SomeOtherStruct', None)]))]) - self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) - - def testInvalidStructDefinitions(self): - """Tests that definitions that aren't allowed in a struct are correctly - detected.""" - - source1 = """\ - struct MyStruct { - MyMethod(int32 a); - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected '\(':\n" - r" *MyMethod\(int32 a\);$"): - parser.Parse(source1, "my_file.mojom") - - source2 = """\ - struct MyStruct { - struct MyInnerStruct { - int32 a; - }; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected 'struct':\n" - r" *struct MyInnerStruct {$"): - parser.Parse(source2, "my_file.mojom") - - source3 = """\ - struct MyStruct { - interface MyInterface { - MyMethod(int32 a); - }; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected 'interface':\n" - r" *interface MyInterface {$"): - parser.Parse(source3, "my_file.mojom") - - def testMissingModuleName(self): - """Tests an (invalid) .mojom with a missing module name.""" - - source1 = """\ - // Missing module name. - module ; - struct MyStruct { - int32 a; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected ';':\n *module ;$"): - parser.Parse(source1, "my_file.mojom") - - # Another similar case, but make sure that line-number tracking/reporting - # is correct. - source2 = """\ - module - // This line intentionally left unblank. - - struct MyStruct { - int32 a; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:4: Error: Unexpected 'struct':\n" - r" *struct MyStruct {$"): - parser.Parse(source2, "my_file.mojom") - - def testMultipleModuleStatements(self): - """Tests an (invalid) .mojom with multiple module statements.""" - - source = """\ - module foo; - module bar; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Multiple \"module\" statements not " - r"allowed:\n *module bar;$"): - parser.Parse(source, "my_file.mojom") - - def testModuleStatementAfterImport(self): - """Tests an (invalid) .mojom with a module statement after an import.""" - - source = """\ - import "foo.mojom"; - module foo; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: \"module\" statements must precede imports " - r"and definitions:\n *module foo;$"): - parser.Parse(source, "my_file.mojom") - - def testModuleStatementAfterDefinition(self): - """Tests an (invalid) .mojom with a module statement after a definition.""" - - source = """\ - struct MyStruct { - int32 a; - }; - module foo; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:4: Error: \"module\" statements must precede imports " - r"and definitions:\n *module foo;$"): - parser.Parse(source, "my_file.mojom") - - def testImportStatementAfterDefinition(self): - """Tests an (invalid) .mojom with an import statement after a definition.""" - - source = """\ - struct MyStruct { - int32 a; - }; - import "foo.mojom"; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:4: Error: \"import\" statements must precede " - r"definitions:\n *import \"foo.mojom\";$"): - parser.Parse(source, "my_file.mojom") - - def testEnums(self): - """Tests that enum statements are correctly parsed.""" - - source = """\ - module my_module; - enum MyEnum1 { VALUE1, VALUE2 }; // No trailing comma. - enum MyEnum2 { - VALUE1 = -1, - VALUE2 = 0, - VALUE3 = + 987, // Check that space is allowed. - VALUE4 = 0xAF12, - VALUE5 = -0x09bcd, - VALUE6 = VALUE5, - VALUE7, // Leave trailing comma. - }; - """ - expected = ast.Mojom( - ast.Module(('IDENTIFIER', 'my_module'), None), - ast.ImportList(), - [ast.Enum( - 'MyEnum1', - None, - ast.EnumValueList([ast.EnumValue('VALUE1', None, None), - ast.EnumValue('VALUE2', None, None)])), - ast.Enum( - 'MyEnum2', - None, - ast.EnumValueList([ast.EnumValue('VALUE1', None, '-1'), - ast.EnumValue('VALUE2', None, '0'), - ast.EnumValue('VALUE3', None, '+987'), - ast.EnumValue('VALUE4', None, '0xAF12'), - ast.EnumValue('VALUE5', None, '-0x09bcd'), - ast.EnumValue('VALUE6', None, ('IDENTIFIER', - 'VALUE5')), - ast.EnumValue('VALUE7', None, None)]))]) - self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) - - def testInvalidEnumInitializers(self): - """Tests that invalid enum initializers are correctly detected.""" - - # No values. - source1 = """\ - enum MyEnum { - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected '}':\n" - r" *};$"): - parser.Parse(source1, "my_file.mojom") - - # Floating point value. - source2 = "enum MyEnum { VALUE = 0.123 };" - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:1: Error: Unexpected '0\.123':\n" - r"enum MyEnum { VALUE = 0\.123 };$"): - parser.Parse(source2, "my_file.mojom") - - # Boolean value. - source2 = "enum MyEnum { VALUE = true };" - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:1: Error: Unexpected 'true':\n" - r"enum MyEnum { VALUE = true };$"): - parser.Parse(source2, "my_file.mojom") - - def testConsts(self): - """Tests some constants and struct members initialized with them.""" - - source = """\ - module my_module; - - struct MyStruct { - const int8 kNumber = -1; - int8 number@0 = kNumber; - }; - """ - expected = ast.Mojom( - ast.Module(('IDENTIFIER', 'my_module'), None), - ast.ImportList(), - [ast.Struct( - 'MyStruct', None, - ast.StructBody( - [ast.Const('kNumber', 'int8', '-1'), - ast.StructField('number', None, ast.Ordinal(0), 'int8', - ('IDENTIFIER', 'kNumber'))]))]) - self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) - - def testNoConditionals(self): - """Tests that ?: is not allowed.""" - - source = """\ - module my_module; - - enum MyEnum { - MY_ENUM_1 = 1 ? 2 : 3 - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:4: Error: Unexpected '\?':\n" - r" *MY_ENUM_1 = 1 \? 2 : 3$"): - parser.Parse(source, "my_file.mojom") - - def testSimpleOrdinals(self): - """Tests that (valid) ordinal values are scanned correctly.""" - - source = """\ - module my_module; - - // This isn't actually valid .mojom, but the problem (missing ordinals) - // should be handled at a different level. - struct MyStruct { - int32 a0@0; - int32 a1@1; - int32 a2@2; - int32 a9@9; - int32 a10 @10; - int32 a11 @11; - int32 a29 @29; - int32 a1234567890 @1234567890; - }; - """ - expected = ast.Mojom( - ast.Module(('IDENTIFIER', 'my_module'), None), - ast.ImportList(), - [ast.Struct( - 'MyStruct', - None, - ast.StructBody( - [ast.StructField('a0', None, ast.Ordinal(0), 'int32', None), - ast.StructField('a1', None, ast.Ordinal(1), 'int32', None), - ast.StructField('a2', None, ast.Ordinal(2), 'int32', None), - ast.StructField('a9', None, ast.Ordinal(9), 'int32', None), - ast.StructField('a10', None, ast.Ordinal(10), 'int32', None), - ast.StructField('a11', None, ast.Ordinal(11), 'int32', None), - ast.StructField('a29', None, ast.Ordinal(29), 'int32', None), - ast.StructField('a1234567890', None, ast.Ordinal(1234567890), - 'int32', None)]))]) - self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) - - def testInvalidOrdinals(self): - """Tests that (lexically) invalid ordinals are correctly detected.""" - - source1 = """\ - module my_module; - - struct MyStruct { - int32 a_missing@; - }; - """ - with self.assertRaisesRegexp( - lexer.LexError, - r"^my_file\.mojom:4: Error: Missing ordinal value$"): - parser.Parse(source1, "my_file.mojom") - - source2 = """\ - module my_module; - - struct MyStruct { - int32 a_octal@01; - }; - """ - with self.assertRaisesRegexp( - lexer.LexError, - r"^my_file\.mojom:4: Error: " - r"Octal and hexadecimal ordinal values not allowed$"): - parser.Parse(source2, "my_file.mojom") - - source3 = """\ - module my_module; struct MyStruct { int32 a_invalid_octal@08; }; - """ - with self.assertRaisesRegexp( - lexer.LexError, - r"^my_file\.mojom:1: Error: " - r"Octal and hexadecimal ordinal values not allowed$"): - parser.Parse(source3, "my_file.mojom") - - source4 = "module my_module; struct MyStruct { int32 a_hex@0x1aB9; };" - with self.assertRaisesRegexp( - lexer.LexError, - r"^my_file\.mojom:1: Error: " - r"Octal and hexadecimal ordinal values not allowed$"): - parser.Parse(source4, "my_file.mojom") - - source5 = "module my_module; struct MyStruct { int32 a_hex@0X0; };" - with self.assertRaisesRegexp( - lexer.LexError, - r"^my_file\.mojom:1: Error: " - r"Octal and hexadecimal ordinal values not allowed$"): - parser.Parse(source5, "my_file.mojom") - - source6 = """\ - struct MyStruct { - int32 a_too_big@999999999999; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: " - r"Ordinal value 999999999999 too large:\n" - r" *int32 a_too_big@999999999999;$"): - parser.Parse(source6, "my_file.mojom") - - def testNestedNamespace(self): - """Tests that "nested" namespaces work.""" - - source = """\ - module my.mod; - - struct MyStruct { - int32 a; - }; - """ - expected = ast.Mojom( - ast.Module(('IDENTIFIER', 'my.mod'), None), - ast.ImportList(), - [ast.Struct( - 'MyStruct', - None, - ast.StructBody(ast.StructField('a', None, None, 'int32', None)))]) - self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) - - def testValidHandleTypes(self): - """Tests (valid) handle types.""" - - source = """\ - struct MyStruct { - handle a; - handle<data_pipe_consumer> b; - handle <data_pipe_producer> c; - handle < message_pipe > d; - handle - < shared_buffer - > e; - }; - """ - expected = ast.Mojom( - None, - ast.ImportList(), - [ast.Struct( - 'MyStruct', - None, - ast.StructBody( - [ast.StructField('a', None, None, 'handle', None), - ast.StructField('b', None, None, 'handle<data_pipe_consumer>', - None), - ast.StructField('c', None, None, 'handle<data_pipe_producer>', - None), - ast.StructField('d', None, None, 'handle<message_pipe>', None), - ast.StructField('e', None, None, 'handle<shared_buffer>', - None)]))]) - self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) - - def testInvalidHandleType(self): - """Tests an invalid (unknown) handle type.""" - - source = """\ - struct MyStruct { - handle<wtf_is_this> foo; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: " - r"Invalid handle type 'wtf_is_this':\n" - r" *handle<wtf_is_this> foo;$"): - parser.Parse(source, "my_file.mojom") - - def testValidDefaultValues(self): - """Tests default values that are valid (to the parser).""" - - source = """\ - struct MyStruct { - int16 a0 = 0; - uint16 a1 = 0x0; - uint16 a2 = 0x00; - uint16 a3 = 0x01; - uint16 a4 = 0xcd; - int32 a5 = 12345; - int64 a6 = -12345; - int64 a7 = +12345; - uint32 a8 = 0x12cd3; - uint32 a9 = -0x12cD3; - uint32 a10 = +0x12CD3; - bool a11 = true; - bool a12 = false; - float a13 = 1.2345; - float a14 = -1.2345; - float a15 = +1.2345; - float a16 = 123.; - float a17 = .123; - double a18 = 1.23E10; - double a19 = 1.E-10; - double a20 = .5E+10; - double a21 = -1.23E10; - double a22 = +.123E10; - }; - """ - expected = ast.Mojom( - None, - ast.ImportList(), - [ast.Struct( - 'MyStruct', - None, - ast.StructBody( - [ast.StructField('a0', None, None, 'int16', '0'), - ast.StructField('a1', None, None, 'uint16', '0x0'), - ast.StructField('a2', None, None, 'uint16', '0x00'), - ast.StructField('a3', None, None, 'uint16', '0x01'), - ast.StructField('a4', None, None, 'uint16', '0xcd'), - ast.StructField('a5' , None, None, 'int32', '12345'), - ast.StructField('a6', None, None, 'int64', '-12345'), - ast.StructField('a7', None, None, 'int64', '+12345'), - ast.StructField('a8', None, None, 'uint32', '0x12cd3'), - ast.StructField('a9', None, None, 'uint32', '-0x12cD3'), - ast.StructField('a10', None, None, 'uint32', '+0x12CD3'), - ast.StructField('a11', None, None, 'bool', 'true'), - ast.StructField('a12', None, None, 'bool', 'false'), - ast.StructField('a13', None, None, 'float', '1.2345'), - ast.StructField('a14', None, None, 'float', '-1.2345'), - ast.StructField('a15', None, None, 'float', '+1.2345'), - ast.StructField('a16', None, None, 'float', '123.'), - ast.StructField('a17', None, None, 'float', '.123'), - ast.StructField('a18', None, None, 'double', '1.23E10'), - ast.StructField('a19', None, None, 'double', '1.E-10'), - ast.StructField('a20', None, None, 'double', '.5E+10'), - ast.StructField('a21', None, None, 'double', '-1.23E10'), - ast.StructField('a22', None, None, 'double', '+.123E10')]))]) - self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) - - def testValidFixedSizeArray(self): - """Tests parsing a fixed size array.""" - - source = """\ - struct MyStruct { - array<int32> normal_array; - array<int32, 1> fixed_size_array_one_entry; - array<int32, 10> fixed_size_array_ten_entries; - array<array<array<int32, 1>>, 2> nested_arrays; - }; - """ - expected = ast.Mojom( - None, - ast.ImportList(), - [ast.Struct( - 'MyStruct', - None, - ast.StructBody( - [ast.StructField('normal_array', None, None, 'int32[]', None), - ast.StructField('fixed_size_array_one_entry', None, None, - 'int32[1]', None), - ast.StructField('fixed_size_array_ten_entries', None, None, - 'int32[10]', None), - ast.StructField('nested_arrays', None, None, - 'int32[1][][2]', None)]))]) - self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) - - def testValidNestedArray(self): - """Tests parsing a nested array.""" - - source = "struct MyStruct { array<array<int32>> nested_array; };" - expected = ast.Mojom( - None, - ast.ImportList(), - [ast.Struct( - 'MyStruct', - None, - ast.StructBody( - ast.StructField('nested_array', None, None, 'int32[][]', - None)))]) - self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) - - def testInvalidFixedArraySize(self): - """Tests that invalid fixed array bounds are correctly detected.""" - - source1 = """\ - struct MyStruct { - array<int32, 0> zero_size_array; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Fixed array size 0 invalid:\n" - r" *array<int32, 0> zero_size_array;$"): - parser.Parse(source1, "my_file.mojom") - - source2 = """\ - struct MyStruct { - array<int32, 999999999999> too_big_array; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Fixed array size 999999999999 invalid:\n" - r" *array<int32, 999999999999> too_big_array;$"): - parser.Parse(source2, "my_file.mojom") - - source3 = """\ - struct MyStruct { - array<int32, abcdefg> not_a_number; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected 'abcdefg':\n" - r" *array<int32, abcdefg> not_a_number;"): - parser.Parse(source3, "my_file.mojom") - - def testValidAssociativeArrays(self): - """Tests that we can parse valid associative array structures.""" - - source1 = "struct MyStruct { map<string, uint8> data; };" - expected1 = ast.Mojom( - None, - ast.ImportList(), - [ast.Struct( - 'MyStruct', - None, - ast.StructBody( - [ast.StructField('data', None, None, 'uint8{string}', None)]))]) - self.assertEquals(parser.Parse(source1, "my_file.mojom"), expected1) - - source2 = "interface MyInterface { MyMethod(map<string, uint8> a); };" - expected2 = ast.Mojom( - None, - ast.ImportList(), - [ast.Interface( - 'MyInterface', - None, - ast.InterfaceBody( - ast.Method( - 'MyMethod', - None, - None, - ast.ParameterList( - ast.Parameter('a', None, None, 'uint8{string}')), - None)))]) - self.assertEquals(parser.Parse(source2, "my_file.mojom"), expected2) - - source3 = "struct MyStruct { map<string, array<uint8>> data; };" - expected3 = ast.Mojom( - None, - ast.ImportList(), - [ast.Struct( - 'MyStruct', - None, - ast.StructBody( - [ast.StructField('data', None, None, 'uint8[]{string}', - None)]))]) - self.assertEquals(parser.Parse(source3, "my_file.mojom"), expected3) - - def testValidMethod(self): - """Tests parsing method declarations.""" - - source1 = "interface MyInterface { MyMethod(int32 a); };" - expected1 = ast.Mojom( - None, - ast.ImportList(), - [ast.Interface( - 'MyInterface', - None, - ast.InterfaceBody( - ast.Method( - 'MyMethod', - None, - None, - ast.ParameterList(ast.Parameter('a', None, None, 'int32')), - None)))]) - self.assertEquals(parser.Parse(source1, "my_file.mojom"), expected1) - - source2 = """\ - interface MyInterface { - MyMethod1@0(int32 a@0, int64 b@1); - MyMethod2@1() => (); - }; - """ - expected2 = ast.Mojom( - None, - ast.ImportList(), - [ast.Interface( - 'MyInterface', - None, - ast.InterfaceBody( - [ast.Method( - 'MyMethod1', - None, - ast.Ordinal(0), - ast.ParameterList([ast.Parameter('a', None, ast.Ordinal(0), - 'int32'), - ast.Parameter('b', None, ast.Ordinal(1), - 'int64')]), - None), - ast.Method( - 'MyMethod2', - None, - ast.Ordinal(1), - ast.ParameterList(), - ast.ParameterList())]))]) - self.assertEquals(parser.Parse(source2, "my_file.mojom"), expected2) - - source3 = """\ - interface MyInterface { - MyMethod(string a) => (int32 a, bool b); - }; - """ - expected3 = ast.Mojom( - None, - ast.ImportList(), - [ast.Interface( - 'MyInterface', - None, - ast.InterfaceBody( - ast.Method( - 'MyMethod', - None, - None, - ast.ParameterList(ast.Parameter('a', None, None, 'string')), - ast.ParameterList([ast.Parameter('a', None, None, 'int32'), - ast.Parameter('b', None, None, - 'bool')]))))]) - self.assertEquals(parser.Parse(source3, "my_file.mojom"), expected3) - - def testInvalidMethods(self): - """Tests that invalid method declarations are correctly detected.""" - - # No trailing commas. - source1 = """\ - interface MyInterface { - MyMethod(string a,); - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected '\)':\n" - r" *MyMethod\(string a,\);$"): - parser.Parse(source1, "my_file.mojom") - - # No leading commas. - source2 = """\ - interface MyInterface { - MyMethod(, string a); - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected ',':\n" - r" *MyMethod\(, string a\);$"): - parser.Parse(source2, "my_file.mojom") - - def testValidInterfaceDefinitions(self): - """Tests all types of definitions that can occur in an interface.""" - - source = """\ - interface MyInterface { - enum MyEnum { VALUE }; - const int32 kMyConst = 123; - MyMethod(int32 x) => (MyEnum y); - }; - """ - expected = ast.Mojom( - None, - ast.ImportList(), - [ast.Interface( - 'MyInterface', - None, - ast.InterfaceBody( - [ast.Enum('MyEnum', - None, - ast.EnumValueList( - ast.EnumValue('VALUE', None, None))), - ast.Const('kMyConst', 'int32', '123'), - ast.Method( - 'MyMethod', - None, - None, - ast.ParameterList(ast.Parameter('x', None, None, 'int32')), - ast.ParameterList(ast.Parameter('y', None, None, - 'MyEnum')))]))]) - self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) - - def testInvalidInterfaceDefinitions(self): - """Tests that definitions that aren't allowed in an interface are correctly - detected.""" - - source1 = """\ - interface MyInterface { - struct MyStruct { - int32 a; - }; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected 'struct':\n" - r" *struct MyStruct {$"): - parser.Parse(source1, "my_file.mojom") - - source2 = """\ - interface MyInterface { - interface MyInnerInterface { - MyMethod(int32 x); - }; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected 'interface':\n" - r" *interface MyInnerInterface {$"): - parser.Parse(source2, "my_file.mojom") - - source3 = """\ - interface MyInterface { - int32 my_field; - }; - """ - # The parser thinks that "int32" is a plausible name for a method, so it's - # "my_field" that gives it away. - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected 'my_field':\n" - r" *int32 my_field;$"): - parser.Parse(source3, "my_file.mojom") - - def testValidAttributes(self): - """Tests parsing attributes (and attribute lists).""" - - # Note: We use structs because they have (optional) attribute lists. - - # Empty attribute list. - source1 = "[] struct MyStruct {};" - expected1 = ast.Mojom( - None, - ast.ImportList(), - [ast.Struct('MyStruct', ast.AttributeList(), ast.StructBody())]) - self.assertEquals(parser.Parse(source1, "my_file.mojom"), expected1) - - # One-element attribute list, with name value. - source2 = "[MyAttribute=MyName] struct MyStruct {};" - expected2 = ast.Mojom( - None, - ast.ImportList(), - [ast.Struct( - 'MyStruct', - ast.AttributeList(ast.Attribute("MyAttribute", "MyName")), - ast.StructBody())]) - self.assertEquals(parser.Parse(source2, "my_file.mojom"), expected2) - - # Two-element attribute list, with one string value and one integer value. - source3 = "[MyAttribute1 = \"hello\", MyAttribute2 = 5] struct MyStruct {};" - expected3 = ast.Mojom( - None, - ast.ImportList(), - [ast.Struct( - 'MyStruct', - ast.AttributeList([ast.Attribute("MyAttribute1", "hello"), - ast.Attribute("MyAttribute2", 5)]), - ast.StructBody())]) - self.assertEquals(parser.Parse(source3, "my_file.mojom"), expected3) - - # Various places that attribute list is allowed. - source4 = """\ - [Attr0=0] module my_module; - - [Attr1=1] struct MyStruct { - [Attr2=2] int32 a; - }; - [Attr3=3] union MyUnion { - [Attr4=4] int32 a; - }; - [Attr5=5] enum MyEnum { - [Attr6=6] a - }; - [Attr7=7] interface MyInterface { - [Attr8=8] MyMethod([Attr9=9] int32 a) => ([Attr10=10] bool b); - }; - """ - expected4 = ast.Mojom( - ast.Module(('IDENTIFIER', 'my_module'), - ast.AttributeList([ast.Attribute("Attr0", 0)])), - ast.ImportList(), - [ast.Struct( - 'MyStruct', - ast.AttributeList(ast.Attribute("Attr1", 1)), - ast.StructBody( - ast.StructField( - 'a', ast.AttributeList([ast.Attribute("Attr2", 2)]), - None, 'int32', None))), - ast.Union( - 'MyUnion', - ast.AttributeList(ast.Attribute("Attr3", 3)), - ast.UnionBody( - ast.UnionField( - 'a', ast.AttributeList([ast.Attribute("Attr4", 4)]), None, - 'int32'))), - ast.Enum( - 'MyEnum', - ast.AttributeList(ast.Attribute("Attr5", 5)), - ast.EnumValueList( - ast.EnumValue( - 'VALUE', ast.AttributeList([ast.Attribute("Attr6", 6)]), - None))), - ast.Interface( - 'MyInterface', - ast.AttributeList(ast.Attribute("Attr7", 7)), - ast.InterfaceBody( - ast.Method( - 'MyMethod', - ast.AttributeList(ast.Attribute("Attr8", 8)), - None, - ast.ParameterList( - ast.Parameter( - 'a', ast.AttributeList([ast.Attribute("Attr9", 9)]), - None, 'int32')), - ast.ParameterList( - ast.Parameter( - 'b', - ast.AttributeList([ast.Attribute("Attr10", 10)]), - None, 'bool')))))]) - self.assertEquals(parser.Parse(source4, "my_file.mojom"), expected4) - - # TODO(vtl): Boolean attributes don't work yet. (In fact, we just |eval()| - # literal (non-name) values, which is extremely dubious.) - - def testInvalidAttributes(self): - """Tests that invalid attributes and attribute lists are correctly - detected.""" - - # Trailing commas not allowed. - source1 = "[MyAttribute=MyName,] struct MyStruct {};" - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:1: Error: Unexpected '\]':\n" - r"\[MyAttribute=MyName,\] struct MyStruct {};$"): - parser.Parse(source1, "my_file.mojom") - - # Missing value. - source2 = "[MyAttribute=] struct MyStruct {};" - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:1: Error: Unexpected '\]':\n" - r"\[MyAttribute=\] struct MyStruct {};$"): - parser.Parse(source2, "my_file.mojom") - - # Missing key. - source3 = "[=MyName] struct MyStruct {};" - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:1: Error: Unexpected '=':\n" - r"\[=MyName\] struct MyStruct {};$"): - parser.Parse(source3, "my_file.mojom") - - def testValidImports(self): - """Tests parsing import statements.""" - - # One import (no module statement). - source1 = "import \"somedir/my.mojom\";" - expected1 = ast.Mojom( - None, - ast.ImportList(ast.Import("somedir/my.mojom")), - []) - self.assertEquals(parser.Parse(source1, "my_file.mojom"), expected1) - - # Two imports (no module statement). - source2 = """\ - import "somedir/my1.mojom"; - import "somedir/my2.mojom"; - """ - expected2 = ast.Mojom( - None, - ast.ImportList([ast.Import("somedir/my1.mojom"), - ast.Import("somedir/my2.mojom")]), - []) - self.assertEquals(parser.Parse(source2, "my_file.mojom"), expected2) - - # Imports with module statement. - source3 = """\ - module my_module; - import "somedir/my1.mojom"; - import "somedir/my2.mojom"; - """ - expected3 = ast.Mojom( - ast.Module(('IDENTIFIER', 'my_module'), None), - ast.ImportList([ast.Import("somedir/my1.mojom"), - ast.Import("somedir/my2.mojom")]), - []) - self.assertEquals(parser.Parse(source3, "my_file.mojom"), expected3) - - def testInvalidImports(self): - """Tests that invalid import statements are correctly detected.""" - - source1 = """\ - // Make the error occur on line 2. - import invalid - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected 'invalid':\n" - r" *import invalid$"): - parser.Parse(source1, "my_file.mojom") - - source2 = """\ - import // Missing string. - struct MyStruct { - int32 a; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected 'struct':\n" - r" *struct MyStruct {$"): - parser.Parse(source2, "my_file.mojom") - - source3 = """\ - import "foo.mojom" // Missing semicolon. - struct MyStruct { - int32 a; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected 'struct':\n" - r" *struct MyStruct {$"): - parser.Parse(source3, "my_file.mojom") - - def testValidNullableTypes(self): - """Tests parsing nullable types.""" - - source = """\ - struct MyStruct { - int32? a; // This is actually invalid, but handled at a different - // level. - string? b; - array<int32> ? c; - array<string ? > ? d; - array<array<int32>?>? e; - array<int32, 1>? f; - array<string?, 1>? g; - some_struct? h; - handle? i; - handle<data_pipe_consumer>? j; - handle<data_pipe_producer>? k; - handle<message_pipe>? l; - handle<shared_buffer>? m; - some_interface&? n; - }; - """ - expected = ast.Mojom( - None, - ast.ImportList(), - [ast.Struct( - 'MyStruct', - None, - ast.StructBody( - [ast.StructField('a', None, None,'int32?', None), - ast.StructField('b', None, None,'string?', None), - ast.StructField('c', None, None,'int32[]?', None), - ast.StructField('d', None, None,'string?[]?', None), - ast.StructField('e', None, None,'int32[]?[]?', None), - ast.StructField('f', None, None,'int32[1]?', None), - ast.StructField('g', None, None,'string?[1]?', None), - ast.StructField('h', None, None,'some_struct?', None), - ast.StructField('i', None, None,'handle?', None), - ast.StructField('j', None, None,'handle<data_pipe_consumer>?', - None), - ast.StructField('k', None, None,'handle<data_pipe_producer>?', - None), - ast.StructField('l', None, None,'handle<message_pipe>?', None), - ast.StructField('m', None, None,'handle<shared_buffer>?', - None), - ast.StructField('n', None, None,'some_interface&?', None)]))]) - self.assertEquals(parser.Parse(source, "my_file.mojom"), expected) - - def testInvalidNullableTypes(self): - """Tests that invalid nullable types are correctly detected.""" - source1 = """\ - struct MyStruct { - string?? a; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected '\?':\n" - r" *string\?\? a;$"): - parser.Parse(source1, "my_file.mojom") - - source2 = """\ - struct MyStruct { - handle?<data_pipe_consumer> a; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected '<':\n" - r" *handle\?<data_pipe_consumer> a;$"): - parser.Parse(source2, "my_file.mojom") - - source3 = """\ - struct MyStruct { - some_interface?& a; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected '&':\n" - r" *some_interface\?& a;$"): - parser.Parse(source3, "my_file.mojom") - - def testSimpleUnion(self): - """Tests a simple .mojom source that just defines a union.""" - source = """\ - module my_module; - - union MyUnion { - int32 a; - double b; - }; - """ - expected = ast.Mojom( - ast.Module(('IDENTIFIER', 'my_module'), None), - ast.ImportList(), - [ast.Union( - 'MyUnion', - None, - ast.UnionBody([ - ast.UnionField('a', None, None, 'int32'), - ast.UnionField('b', None, None, 'double') - ]))]) - actual = parser.Parse(source, "my_file.mojom") - self.assertEquals(actual, expected) - - def testUnionWithOrdinals(self): - """Test that ordinals are assigned to fields.""" - source = """\ - module my_module; - - union MyUnion { - int32 a @10; - double b @30; - }; - """ - expected = ast.Mojom( - ast.Module(('IDENTIFIER', 'my_module'), None), - ast.ImportList(), - [ast.Union( - 'MyUnion', - None, - ast.UnionBody([ - ast.UnionField('a', None, ast.Ordinal(10), 'int32'), - ast.UnionField('b', None, ast.Ordinal(30), 'double') - ]))]) - actual = parser.Parse(source, "my_file.mojom") - self.assertEquals(actual, expected) - - def testUnionWithStructMembers(self): - """Test that struct members are accepted.""" - source = """\ - module my_module; - - union MyUnion { - SomeStruct s; - }; - """ - expected = ast.Mojom( - ast.Module(('IDENTIFIER', 'my_module'), None), - ast.ImportList(), - [ast.Union( - 'MyUnion', - None, - ast.UnionBody([ - ast.UnionField('s', None, None, 'SomeStruct') - ]))]) - actual = parser.Parse(source, "my_file.mojom") - self.assertEquals(actual, expected) - - def testUnionWithArrayMember(self): - """Test that array members are accepted.""" - source = """\ - module my_module; - - union MyUnion { - array<int32> a; - }; - """ - expected = ast.Mojom( - ast.Module(('IDENTIFIER', 'my_module'), None), - ast.ImportList(), - [ast.Union( - 'MyUnion', - None, - ast.UnionBody([ - ast.UnionField('a', None, None, 'int32[]') - ]))]) - actual = parser.Parse(source, "my_file.mojom") - self.assertEquals(actual, expected) - - def testUnionWithMapMember(self): - """Test that map members are accepted.""" - source = """\ - module my_module; - - union MyUnion { - map<int32, string> m; - }; - """ - expected = ast.Mojom( - ast.Module(('IDENTIFIER', 'my_module'), None), - ast.ImportList(), - [ast.Union( - 'MyUnion', - None, - ast.UnionBody([ - ast.UnionField('m', None, None, 'string{int32}') - ]))]) - actual = parser.Parse(source, "my_file.mojom") - self.assertEquals(actual, expected) - - def testUnionDisallowNestedStruct(self): - """Tests that structs cannot be nested in unions.""" - source = """\ - module my_module; - - union MyUnion { - struct MyStruct { - int32 a; - }; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:4: Error: Unexpected 'struct':\n" - r" *struct MyStruct {$"): - parser.Parse(source, "my_file.mojom") - - def testUnionDisallowNestedInterfaces(self): - """Tests that interfaces cannot be nested in unions.""" - source = """\ - module my_module; - - union MyUnion { - interface MyInterface { - MyMethod(int32 a); - }; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:4: Error: Unexpected 'interface':\n" - r" *interface MyInterface {$"): - parser.Parse(source, "my_file.mojom") - - def testUnionDisallowNestedUnion(self): - """Tests that unions cannot be nested in unions.""" - source = """\ - module my_module; - - union MyUnion { - union MyOtherUnion { - int32 a; - }; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:4: Error: Unexpected 'union':\n" - r" *union MyOtherUnion {$"): - parser.Parse(source, "my_file.mojom") - - def testUnionDisallowNestedEnum(self): - """Tests that enums cannot be nested in unions.""" - source = """\ - module my_module; - - union MyUnion { - enum MyEnum { - A, - }; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:4: Error: Unexpected 'enum':\n" - r" *enum MyEnum {$"): - parser.Parse(source, "my_file.mojom") - - def testValidAssociatedKinds(self): - """Tests parsing associated interfaces and requests.""" - source1 = """\ - struct MyStruct { - associated MyInterface a; - associated MyInterface& b; - associated MyInterface? c; - associated MyInterface&? d; - }; - """ - expected1 = ast.Mojom( - None, - ast.ImportList(), - [ast.Struct( - 'MyStruct', - None, - ast.StructBody( - [ast.StructField('a', None, None,'asso<MyInterface>', None), - ast.StructField('b', None, None,'asso<MyInterface&>', None), - ast.StructField('c', None, None,'asso<MyInterface>?', None), - ast.StructField('d', None, None,'asso<MyInterface&>?', - None)]))]) - self.assertEquals(parser.Parse(source1, "my_file.mojom"), expected1) - - source2 = """\ - interface MyInterface { - MyMethod(associated A a) =>(associated B& b); - };""" - expected2 = ast.Mojom( - None, - ast.ImportList(), - [ast.Interface( - 'MyInterface', - None, - ast.InterfaceBody( - ast.Method( - 'MyMethod', - None, - None, - ast.ParameterList( - ast.Parameter('a', None, None, 'asso<A>')), - ast.ParameterList( - ast.Parameter('b', None, None, 'asso<B&>')))))]) - self.assertEquals(parser.Parse(source2, "my_file.mojom"), expected2) - - def testInvalidAssociatedKinds(self): - """Tests that invalid associated interfaces and requests are correctly - detected.""" - source1 = """\ - struct MyStruct { - associated associated SomeInterface a; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected 'associated':\n" - r" *associated associated SomeInterface a;$"): - parser.Parse(source1, "my_file.mojom") - - source2 = """\ - struct MyStruct { - associated handle a; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected 'handle':\n" - r" *associated handle a;$"): - parser.Parse(source2, "my_file.mojom") - - source3 = """\ - struct MyStruct { - associated? MyInterface& a; - }; - """ - with self.assertRaisesRegexp( - parser.ParseError, - r"^my_file\.mojom:2: Error: Unexpected '\?':\n" - r" *associated\? MyInterface& a;$"): - parser.Parse(source3, "my_file.mojom") - - -if __name__ == "__main__": - unittest.main() |