OLD | NEW |
| (Empty) |
1 #!/usr/bin/env python | |
2 | |
3 # Copyright 2016 The Chromium Authors. All rights reserved. | |
4 # Use of this source code is governed by a BSD-style license that can be | |
5 # found in the LICENSE file. | |
6 | |
7 import client_api_generator | |
8 import shutil | |
9 import sys | |
10 import tempfile | |
11 import unittest | |
12 | |
13 | |
14 class ClientApiGeneratorTest(unittest.TestCase): | |
15 | |
16 def test_ArgumentParsing(self): | |
17 with tempfile.NamedTemporaryFile() as f: | |
18 f.write('{"foo": true}') | |
19 f.flush() | |
20 json_api, output_dir = client_api_generator.ParseArguments([ | |
21 '--protocol', f.name, '--output_dir', 'out']) | |
22 self.assertEqual({'foo': True}, json_api) | |
23 self.assertEqual('out', output_dir) | |
24 | |
25 def test_ToTitleCase(self): | |
26 self.assertEqual(client_api_generator.ToTitleCase('fooBar'), 'FooBar') | |
27 | |
28 def test_DashToCamelCase(self): | |
29 self.assertEqual(client_api_generator.DashToCamelCase('foo-bar'), 'FooBar') | |
30 self.assertEqual(client_api_generator.DashToCamelCase('foo-'), 'Foo') | |
31 self.assertEqual(client_api_generator.DashToCamelCase('-bar'), 'Bar') | |
32 | |
33 def test_CamelCaseToHackerStyle(self): | |
34 self.assertEqual(client_api_generator.CamelCaseToHackerStyle('FooBar'), | |
35 'foo_bar') | |
36 self.assertEqual(client_api_generator.CamelCaseToHackerStyle('LoLoLoL'), | |
37 'lo_lo_lol') | |
38 | |
39 def test_SanitizeLiteralEnum(self): | |
40 self.assertEqual(client_api_generator.SanitizeLiteral('foo'), 'foo') | |
41 self.assertEqual(client_api_generator.SanitizeLiteral('null'), 'none') | |
42 self.assertEqual(client_api_generator.SanitizeLiteral('Infinity'), | |
43 'InfinityValue') | |
44 | |
45 def test_PatchFullQualifiedRefs(self): | |
46 json_api = { | |
47 'domains': [ | |
48 { | |
49 'domain': 'domain0', | |
50 '$ref': 'reference', | |
51 }, | |
52 { | |
53 'domain': 'domain1', | |
54 '$ref': 'reference', | |
55 'more': [{'$ref': 'domain0.thing'}], | |
56 } | |
57 ] | |
58 } | |
59 expected_json_api = { | |
60 'domains': [ | |
61 { | |
62 'domain': 'domain0', | |
63 '$ref': 'domain0.reference', | |
64 }, | |
65 { | |
66 'domain': 'domain1', | |
67 '$ref': 'domain1.reference', | |
68 'more': [{'$ref': 'domain0.thing'}], | |
69 } | |
70 ] | |
71 } | |
72 client_api_generator.PatchFullQualifiedRefs(json_api) | |
73 self.assertDictEqual(json_api, expected_json_api) | |
74 | |
75 def test_NumberType(self): | |
76 json_api = { | |
77 'domains': [ | |
78 { | |
79 'domain': 'domain', | |
80 'types': [ | |
81 { | |
82 'id': 'TestType', | |
83 'type': 'number', | |
84 }, | |
85 ] | |
86 }, | |
87 ] | |
88 } | |
89 client_api_generator.CreateTypeDefinitions(json_api) | |
90 type = json_api['domains'][0]['types'][0] | |
91 resolved = client_api_generator.ResolveType(type) | |
92 self.assertEqual('double', resolved['raw_type']) | |
93 | |
94 def test_IntegerType(self): | |
95 json_api = { | |
96 'domains': [ | |
97 { | |
98 'domain': 'domain', | |
99 'types': [ | |
100 { | |
101 'id': 'TestType', | |
102 'type': 'integer', | |
103 }, | |
104 ] | |
105 }, | |
106 ] | |
107 } | |
108 client_api_generator.CreateTypeDefinitions(json_api) | |
109 type = json_api['domains'][0]['types'][0] | |
110 resolved = client_api_generator.ResolveType(type) | |
111 self.assertEqual('int', resolved['raw_type']) | |
112 | |
113 def test_BooleanType(self): | |
114 json_api = { | |
115 'domains': [ | |
116 { | |
117 'domain': 'domain', | |
118 'types': [ | |
119 { | |
120 'id': 'TestType', | |
121 'type': 'boolean', | |
122 }, | |
123 ] | |
124 }, | |
125 ] | |
126 } | |
127 client_api_generator.CreateTypeDefinitions(json_api) | |
128 type = json_api['domains'][0]['types'][0] | |
129 resolved = client_api_generator.ResolveType(type) | |
130 self.assertEqual('bool', resolved['raw_type']) | |
131 | |
132 def test_StringType(self): | |
133 json_api = { | |
134 'domains': [ | |
135 { | |
136 'domain': 'domain', | |
137 'types': [ | |
138 { | |
139 'id': 'TestType', | |
140 'type': 'string', | |
141 }, | |
142 ] | |
143 }, | |
144 ] | |
145 } | |
146 client_api_generator.CreateTypeDefinitions(json_api) | |
147 type = json_api['domains'][0]['types'][0] | |
148 resolved = client_api_generator.ResolveType(type) | |
149 self.assertEqual('std::string', resolved['raw_type']) | |
150 | |
151 def test_ObjectType(self): | |
152 json_api = { | |
153 'domains': [ | |
154 { | |
155 'domain': 'domain', | |
156 'types': [ | |
157 { | |
158 'id': 'TestType', | |
159 'type': 'object', | |
160 'properties': [ | |
161 {'name': 'p1', 'type': 'number'}, | |
162 {'name': 'p2', 'type': 'integer'}, | |
163 {'name': 'p3', 'type': 'boolean'}, | |
164 {'name': 'p4', 'type': 'string'}, | |
165 {'name': 'p5', 'type': 'any'}, | |
166 {'name': 'p6', 'type': 'object', '$ref': 'TestType'}, | |
167 ], | |
168 'returns': [ | |
169 {'name': 'r1', 'type': 'number'}, | |
170 {'name': 'r2', 'type': 'integer'}, | |
171 {'name': 'r3', 'type': 'boolean'}, | |
172 {'name': 'r4', 'type': 'string'}, | |
173 {'name': 'r5', 'type': 'any'}, | |
174 {'name': 'r6', 'type': 'object', '$ref': 'TestType'}, | |
175 ], | |
176 }, | |
177 ] | |
178 }, | |
179 ] | |
180 } | |
181 client_api_generator.CreateTypeDefinitions(json_api) | |
182 type = json_api['domains'][0]['types'][0] | |
183 resolved = client_api_generator.ResolveType(type) | |
184 self.assertEqual('TestType', resolved['raw_type']) | |
185 | |
186 def test_AnyType(self): | |
187 json_api = { | |
188 'domains': [ | |
189 { | |
190 'domain': 'domain', | |
191 'types': [ | |
192 { | |
193 'id': 'TestType', | |
194 'type': 'any', | |
195 }, | |
196 ] | |
197 }, | |
198 ] | |
199 } | |
200 client_api_generator.CreateTypeDefinitions(json_api) | |
201 type = json_api['domains'][0]['types'][0] | |
202 resolved = client_api_generator.ResolveType(type) | |
203 self.assertEqual('base::Value', resolved['raw_type']) | |
204 | |
205 def test_ArrayType(self): | |
206 json_api = { | |
207 'domains': [ | |
208 { | |
209 'domain': 'domain', | |
210 'types': [ | |
211 { | |
212 'id': 'TestType', | |
213 'type': 'array', | |
214 'items': {'type': 'integer'} | |
215 }, | |
216 ] | |
217 }, | |
218 ] | |
219 } | |
220 client_api_generator.CreateTypeDefinitions(json_api) | |
221 type = json_api['domains'][0]['types'][0] | |
222 resolved = client_api_generator.ResolveType(type) | |
223 self.assertEqual('std::vector<int>', resolved['raw_type']) | |
224 | |
225 def test_EnumType(self): | |
226 json_api = { | |
227 'domains': [ | |
228 { | |
229 'domain': 'domain', | |
230 'types': [ | |
231 { | |
232 'id': 'TestType', | |
233 'type': 'string', | |
234 'enum': ['a', 'b', 'c'] | |
235 }, | |
236 ] | |
237 }, | |
238 ] | |
239 } | |
240 client_api_generator.CreateTypeDefinitions(json_api) | |
241 type = json_api['domains'][0]['types'][0] | |
242 resolved = client_api_generator.ResolveType(type) | |
243 self.assertEqual('headless::domain::TestType', resolved['raw_type']) | |
244 | |
245 def test_SynthesizeCommandTypes(self): | |
246 json_api = { | |
247 'domains': [ | |
248 { | |
249 'domain': 'domain', | |
250 'commands': [ | |
251 { | |
252 'name': 'TestCommand', | |
253 'parameters': [ | |
254 {'name': 'p1', 'type': 'number'}, | |
255 {'name': 'p2', 'type': 'integer'}, | |
256 {'name': 'p3', 'type': 'boolean'}, | |
257 {'name': 'p4', 'type': 'string'}, | |
258 {'name': 'p5', 'type': 'any'}, | |
259 {'name': 'p6', 'type': 'object', '$ref': 'TestType'}, | |
260 ], | |
261 'returns': [ | |
262 {'name': 'r1', 'type': 'number'}, | |
263 {'name': 'r2', 'type': 'integer'}, | |
264 {'name': 'r3', 'type': 'boolean'}, | |
265 {'name': 'r4', 'type': 'string'}, | |
266 {'name': 'r5', 'type': 'any'}, | |
267 {'name': 'r6', 'type': 'object', '$ref': 'TestType'}, | |
268 ], | |
269 }, | |
270 ] | |
271 }, | |
272 ] | |
273 } | |
274 expected_types = [ | |
275 { | |
276 'type': 'object', | |
277 'id': 'TestCommandParams', | |
278 'description': 'Parameters for the TestCommand command.', | |
279 'properties': [ | |
280 {'type': 'number', 'name': 'p1'}, | |
281 {'type': 'integer', 'name': 'p2'}, | |
282 {'type': 'boolean', 'name': 'p3'}, | |
283 {'type': 'string', 'name': 'p4'}, | |
284 {'type': 'any', 'name': 'p5'}, | |
285 {'type': 'object', 'name': 'p6', '$ref': 'TestType'} | |
286 ], | |
287 }, | |
288 { | |
289 'type': 'object', | |
290 'id': 'TestCommandResult', | |
291 'description': 'Result for the TestCommand command.', | |
292 'properties': [ | |
293 {'type': 'number', 'name': 'r1'}, | |
294 {'type': 'integer', 'name': 'r2'}, | |
295 {'type': 'boolean', 'name': 'r3'}, | |
296 {'type': 'string', 'name': 'r4'}, | |
297 {'type': 'any', 'name': 'r5'}, | |
298 {'type': 'object', 'name': 'r6', '$ref': 'TestType'} | |
299 ], | |
300 } | |
301 ] | |
302 client_api_generator.SynthesizeCommandTypes(json_api) | |
303 types = json_api['domains'][0]['types'] | |
304 self.assertListEqual(types, expected_types) | |
305 | |
306 def test_SynthesizeEventTypes(self): | |
307 json_api = { | |
308 'domains': [ | |
309 { | |
310 'domain': 'domain', | |
311 'events': [ | |
312 { | |
313 'name': 'TestEvent', | |
314 'parameters': [ | |
315 {'name': 'p1', 'type': 'number'}, | |
316 {'name': 'p2', 'type': 'integer'}, | |
317 {'name': 'p3', 'type': 'boolean'}, | |
318 {'name': 'p4', 'type': 'string'}, | |
319 {'name': 'p5', 'type': 'any'}, | |
320 {'name': 'p6', 'type': 'object', '$ref': 'TestType'}, | |
321 ] | |
322 }, | |
323 { | |
324 'name': 'TestEventWithNoParams', | |
325 } | |
326 ] | |
327 } | |
328 ] | |
329 } | |
330 expected_types = [ | |
331 { | |
332 'type': 'object', | |
333 'id': 'TestEventParams', | |
334 'description': 'Parameters for the TestEvent event.', | |
335 'properties': [ | |
336 {'type': 'number', 'name': 'p1'}, | |
337 {'type': 'integer', 'name': 'p2'}, | |
338 {'type': 'boolean', 'name': 'p3'}, | |
339 {'type': 'string', 'name': 'p4'}, | |
340 {'type': 'any', 'name': 'p5'}, | |
341 {'type': 'object', 'name': 'p6', '$ref': 'TestType'} | |
342 ] | |
343 }, | |
344 { | |
345 'type': 'object', | |
346 'id': 'TestEventWithNoParamsParams', | |
347 'description': 'Parameters for the TestEventWithNoParams event.', | |
348 'properties': [], | |
349 } | |
350 ] | |
351 client_api_generator.SynthesizeEventTypes(json_api) | |
352 types = json_api['domains'][0]['types'] | |
353 self.assertListEqual(types, expected_types) | |
354 | |
355 def test_PatchExperimentalDomains(self): | |
356 json_api = { | |
357 'domains': [ | |
358 { | |
359 'domain': 'domain', | |
360 'experimental': True, | |
361 'commands': [ | |
362 { | |
363 'name': 'FooCommand', | |
364 } | |
365 ], | |
366 'events': [ | |
367 { | |
368 'name': 'BarEvent', | |
369 } | |
370 ] | |
371 } | |
372 ] | |
373 } | |
374 client_api_generator.PatchExperimentalCommandsAndEvents(json_api) | |
375 for command in json_api['domains'][0]['commands']: | |
376 self.assertTrue(command['experimental']) | |
377 for event in json_api['domains'][0]['events']: | |
378 self.assertTrue(command['experimental']) | |
379 | |
380 def test_EnsureCommandsHaveParametersAndReturnTypes(self): | |
381 json_api = { | |
382 'domains': [ | |
383 { | |
384 'domain': 'domain', | |
385 'commands': [ | |
386 { | |
387 'name': 'FooCommand', | |
388 } | |
389 ], | |
390 'events': [ | |
391 { | |
392 'name': 'BarEvent', | |
393 } | |
394 ] | |
395 } | |
396 ] | |
397 } | |
398 expected_types = [ | |
399 { | |
400 'type': 'object', | |
401 'id': 'FooCommandParams', | |
402 'description': 'Parameters for the FooCommand command.', | |
403 'properties': [], | |
404 }, | |
405 { | |
406 'type': 'object', | |
407 'id': 'FooCommandResult', | |
408 'description': 'Result for the FooCommand command.', | |
409 'properties': [], | |
410 }, | |
411 { | |
412 'type': 'object', | |
413 'id': 'BarEventParams', | |
414 'description': 'Parameters for the BarEvent event.', | |
415 'properties': [], | |
416 } | |
417 ] | |
418 client_api_generator.EnsureCommandsHaveParametersAndReturnTypes(json_api) | |
419 client_api_generator.SynthesizeCommandTypes(json_api) | |
420 client_api_generator.SynthesizeEventTypes(json_api) | |
421 types = json_api['domains'][0]['types'] | |
422 self.assertListEqual(types, expected_types) | |
423 | |
424 def test_Generate(self): | |
425 json_api = { | |
426 'domains': [ | |
427 { | |
428 'domain': 'domain', | |
429 'types': [ | |
430 { | |
431 'id': 'TestType', | |
432 'type': 'object', | |
433 'properties': [ | |
434 {'name': 'p1', 'type': 'number'}, | |
435 {'name': 'p2', 'type': 'integer'}, | |
436 {'name': 'p3', 'type': 'boolean'}, | |
437 {'name': 'p4', 'type': 'string'}, | |
438 {'name': 'p5', 'type': 'any'}, | |
439 {'name': 'p6', 'type': 'object', '$ref': 'domain.TestType'}, | |
440 ], | |
441 'returns': [ | |
442 {'name': 'r1', 'type': 'number'}, | |
443 {'name': 'r2', 'type': 'integer'}, | |
444 {'name': 'r3', 'type': 'boolean'}, | |
445 {'name': 'r4', 'type': 'string'}, | |
446 {'name': 'r5', 'type': 'any'}, | |
447 {'name': 'r6', 'type': 'object', '$ref': 'domain.TestType'}, | |
448 ], | |
449 }, | |
450 ] | |
451 }, | |
452 ] | |
453 } | |
454 try: | |
455 dirname = tempfile.mkdtemp() | |
456 jinja_env = client_api_generator.InitializeJinjaEnv(dirname) | |
457 client_api_generator.CreateTypeDefinitions(json_api) | |
458 client_api_generator.Generate(jinja_env, dirname, json_api, 'types', | |
459 ['cc']) | |
460 client_api_generator.Generate(jinja_env, dirname, json_api, 'types', | |
461 ['h']) | |
462 # This is just a smoke test; we don't actually verify the generated output | |
463 # here. | |
464 finally: | |
465 shutil.rmtree(dirname) | |
466 | |
467 def test_GenerateDomains(self): | |
468 json_api = { | |
469 'domains': [ | |
470 { | |
471 'domain': 'domain0', | |
472 'types': [ | |
473 { | |
474 'id': 'TestType', | |
475 'type': 'object', | |
476 }, | |
477 ] | |
478 }, | |
479 { | |
480 'domain': 'domain1', | |
481 'types': [ | |
482 { | |
483 'id': 'TestType', | |
484 'type': 'object', | |
485 }, | |
486 ] | |
487 }, | |
488 ] | |
489 } | |
490 try: | |
491 dirname = tempfile.mkdtemp() | |
492 jinja_env = client_api_generator.InitializeJinjaEnv(dirname) | |
493 client_api_generator.GenerateDomains(jinja_env, dirname, json_api, | |
494 'domain', ['cc', 'h']) | |
495 # This is just a smoke test; we don't actually verify the generated output | |
496 # here. | |
497 finally: | |
498 shutil.rmtree(dirname) | |
499 | |
500 | |
501 if __name__ == '__main__': | |
502 unittest.main(verbosity=2, exit=False, argv=sys.argv) | |
OLD | NEW |