blob: cb22a9c2ee2e200a1849496fe10505b2e62e5dbd [file] [log] [blame]
Rich Lanea06d0c32013-03-25 08:52:03 -07001#!/usr/bin/env python
2# Copyright 2013, Big Switch Networks, Inc.
3#
4# LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
5# the following special exception:
6#
7# LOXI Exception
8#
9# As a special exception to the terms of the EPL, you may distribute libraries
10# generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
11# that copyright and licensing notices generated by LoxiGen are not altered or removed
12# from the LoxiGen Libraries and the notice provided below is (i) included in
13# the LoxiGen Libraries, if distributed in source code form and (ii) included in any
14# documentation for the LoxiGen Libraries, if distributed in binary form.
15#
16# Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
17#
18# You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
19# a copy of the EPL at:
20#
21# http://www.eclipse.org/legal/epl-v10.html
22#
23# Unless required by applicable law or agreed to in writing, software
24# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
25# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
26# EPL for the specific language governing permissions and limitations
27# under the EPL.
28
29import unittest
30import pyparsing
31import loxi_front_end.parser as parser
32
33class StructTests(unittest.TestCase):
34 def test_empty(self):
35 src = """\
36struct foo { };
37"""
38 ast = parser.parse(src)
Rich Lane43b2a902013-05-09 13:47:07 -070039 self.assertEquals(ast, [['struct', 'foo', []]])
Rich Lanea06d0c32013-03-25 08:52:03 -070040
41 def test_one_field(self):
42 src = """\
43struct foo {
44 uint32_t bar;
45};
46"""
47 ast = parser.parse(src)
Rich Lane43b2a902013-05-09 13:47:07 -070048 self.assertEquals(ast,
Rich Lanef424e972013-05-09 21:00:13 -070049 [['struct', 'foo', [['data', 'uint32_t', 'bar']]]])
Rich Lanea06d0c32013-03-25 08:52:03 -070050
51 def test_multiple_fields(self):
52 src = """\
53struct foo {
54 uint32_t bar;
55 uint8_t baz;
56 uint64_t abc;
57};
58"""
59 ast = parser.parse(src)
Rich Lane43b2a902013-05-09 13:47:07 -070060 self.assertEquals(ast,
Rich Lanea06d0c32013-03-25 08:52:03 -070061 [['struct', 'foo',
Rich Lanef424e972013-05-09 21:00:13 -070062 [['data', 'uint32_t', 'bar'],
63 ['data', 'uint8_t', 'baz'],
64 ['data', 'uint64_t', 'abc']]]])
Rich Lanea06d0c32013-03-25 08:52:03 -070065
66 def test_array_type(self):
67 src = """\
68struct foo {
69 uint32_t[4] bar;
70};
71"""
72 ast = parser.parse(src)
Rich Lane43b2a902013-05-09 13:47:07 -070073 self.assertEquals(ast,
Rich Lanef424e972013-05-09 21:00:13 -070074 [['struct', 'foo', [['data', 'uint32_t[4]', 'bar']]]])
Rich Lanea06d0c32013-03-25 08:52:03 -070075
76 def test_list_type(self):
77 src = """\
78struct foo {
79 list(of_action_t) bar;
80};
81"""
82 ast = parser.parse(src)
Rich Lane43b2a902013-05-09 13:47:07 -070083 self.assertEquals(ast,
Rich Lanef424e972013-05-09 21:00:13 -070084 [['struct', 'foo', [['data', 'list(of_action_t)', 'bar']]]])
Rich Lanea06d0c32013-03-25 08:52:03 -070085
Rich Lane32142872013-05-09 21:16:47 -070086 def test_pad_member(self):
Rich Lanee4d04ea2013-05-09 11:27:06 -070087 src = """\
88struct foo {
89 pad(1);
90};
91"""
92 ast = parser.parse(src)
93 self.assertEquals(ast,
94 [['struct', 'foo', [['pad', 1]]]])
95
Rich Lane32142872013-05-09 21:16:47 -070096 def test_type_member(self):
97 src = """\
98struct foo {
99 uint16_t foo == 0x10;
100};
101"""
102 ast = parser.parse(src)
103 self.assertEquals(ast,
104 [['struct', 'foo', [['type', 'uint16_t', 'foo', 0x10]]]])
105
Rich Lane517506c2013-04-08 14:08:31 -0700106class EnumTests(unittest.TestCase):
107 def test_empty(self):
108 src = """\
109enum foo {
110};
111"""
112 ast = parser.parse(src)
Rich Lane43b2a902013-05-09 13:47:07 -0700113 self.assertEquals(ast, [['enum', 'foo', []]])
Rich Lane517506c2013-04-08 14:08:31 -0700114
115 def test_one(self):
116 src = """\
117enum foo {
118 BAR = 1
119};
120"""
121 ast = parser.parse(src)
Rich Lane43b2a902013-05-09 13:47:07 -0700122 self.assertEquals(ast, [['enum', 'foo', [['BAR', 1]]]])
Rich Lane517506c2013-04-08 14:08:31 -0700123
124 def test_multiple(self):
125 src = """\
126enum foo {
127 OFP_A = 1,
128 OFP_B = 2,
129 OFP_C = 3
130};
131"""
132 ast = parser.parse(src)
Rich Lane43b2a902013-05-09 13:47:07 -0700133 self.assertEquals(ast, [['enum', 'foo', [['OFP_A', 1], ['OFP_B', 2], ['OFP_C', 3]]]])
Rich Lane517506c2013-04-08 14:08:31 -0700134
135 def test_trailing_comma(self):
136 src = """\
137enum foo {
138 OFP_A = 1,
139 OFP_B = 2,
140 OFP_C = 3,
141};
142"""
143 ast = parser.parse(src)
Rich Lane43b2a902013-05-09 13:47:07 -0700144 self.assertEquals(ast, [['enum', 'foo', [['OFP_A', 1], ['OFP_B', 2], ['OFP_C', 3]]]])
Rich Lane517506c2013-04-08 14:08:31 -0700145
Rich Lanea06d0c32013-03-25 08:52:03 -0700146class TestMetadata(unittest.TestCase):
147 def test_version(self):
148 src = """\
149#version 1
150"""
151 ast = parser.parse(src)
Rich Lane43b2a902013-05-09 13:47:07 -0700152 self.assertEquals(ast, [['metadata', 'version', '1']])
Rich Lanea06d0c32013-03-25 08:52:03 -0700153
154class TestToplevel(unittest.TestCase):
155 def test_multiple_structs(self):
156 src = """\
157struct foo { };
158struct bar { };
159"""
160 ast = parser.parse(src)
Rich Lane43b2a902013-05-09 13:47:07 -0700161 self.assertEquals(ast,
Rich Lanea06d0c32013-03-25 08:52:03 -0700162 [['struct', 'foo', []], ['struct', 'bar', []]])
163
164 def test_comments(self):
165 src = """\
166// comment 1
167struct foo { //comment 2
168// comment 3
Andreas Wundsam53256162013-05-02 14:05:53 -0700169 uint32_t a; //comment 5
Rich Lanea06d0c32013-03-25 08:52:03 -0700170// comment 6
171};
172// comment 4
173"""
174 ast = parser.parse(src)
Rich Lane43b2a902013-05-09 13:47:07 -0700175 self.assertEquals(ast,
Rich Lanef424e972013-05-09 21:00:13 -0700176 [['struct', 'foo', [['data', 'uint32_t', 'a']]]])
Rich Lanea06d0c32013-03-25 08:52:03 -0700177
178 def test_mixed(self):
179 src = """\
180#version 1
181struct foo { };
182#version 2
183struct bar { };
184"""
185 ast = parser.parse(src)
Rich Lane43b2a902013-05-09 13:47:07 -0700186 self.assertEquals(ast,
Rich Lanea06d0c32013-03-25 08:52:03 -0700187 [['metadata', 'version', '1'],
188 ['struct', 'foo', []],
189 ['metadata', 'version', '2'],
190 ['struct', 'bar', []]])
191
192class TestErrors(unittest.TestCase):
193 def syntax_error(self, src, regex):
194 with self.assertRaisesRegexp(pyparsing.ParseSyntaxException, regex):
195 parser.parse(src)
196
197 def test_missing_struct_syntax(self):
198 self.syntax_error('struct { uint32_t bar; };',
199 'Expected identifier \(at char 7\)')
200 self.syntax_error('struct foo uint32_t bar; };',
201 'Expected "{" \(at char 11\)')
202 self.syntax_error('struct foo { uint32_t bar; ;',
203 'Expected "}" \(at char 27\)')
204 self.syntax_error('struct foo { uint32_t bar; }',
205 'Expected ";" \(at char 28\)')
206
207 def test_invalid_type_name(self):
208 self.syntax_error('struct foo { list<of_action_t> bar; }',
209 'Expected "\(" \(at char 17\)')
210 self.syntax_error('struct foo { uint32_t[10 bar; }',
211 'Expected "\]" \(at char 24\)')
212
213 def test_invalid_member_syntax(self):
214 self.syntax_error('struct foo { bar; }',
215 'Expected identifier \(at char 16\)')
216 self.syntax_error('struct foo { uint32_t bar baz; }',
217 'Expected ";" \(at char 26\)')
218
219
220if __name__ == '__main__':
221 unittest.main()