OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2015 The Chromium Authors. All rights reserved. | 2 # Copyright 2015 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 import idl_schema | 6 import idl_schema |
7 import json_parse | 7 import json_parse |
8 from js_externs_generator import JsExternsGenerator | 8 from js_interface_generator import JsInterfaceGenerator |
9 from datetime import datetime | 9 from datetime import datetime |
10 import model | 10 import model |
11 import sys | 11 import sys |
12 import unittest | 12 import unittest |
13 | 13 |
14 COPYRIGHT = ("""// Copyright %s The Chromium Authors. All rights reserved. | |
15 // Use of this source code is governed by a BSD-style license that can be | |
16 // found in the LICENSE file. | |
17 """ % datetime.now().year) | |
18 | |
19 INFO = """// This file was generated by: | |
20 // %s. | |
21 // NOTE: The format of types has changed. 'FooType' is now | |
22 // 'chrome.%s.FooType'. | |
23 // Please run the closure compiler before committing changes. | |
24 // See https://code.google.com/p/chromium/wiki/ClosureCompilation. | |
25 """ | |
26 | |
27 # The contents of a fake idl file. | 14 # The contents of a fake idl file. |
28 fake_idl = """ | 15 fake_idl = """ |
29 // Copyright 2014 The Chromium Authors. All rights reserved. | 16 // Copyright 2014 The Chromium Authors. All rights reserved. |
30 // Use of this source code is governed by a BSD-style license that can be | 17 // Use of this source code is governed by a BSD-style license that can be |
31 // found in the LICENSE file. | 18 // found in the LICENSE file. |
32 | 19 |
33 // A totally fake API. | 20 // A totally fake API. |
34 namespace fakeApi { | 21 namespace fakeApi { |
35 enum Greek { | 22 enum Greek { |
36 ALPHA, | 23 ALPHA, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 }; | 65 }; |
79 | 66 |
80 interface Events { | 67 interface Events { |
81 // Fired when we realize it's a trap! | 68 // Fired when we realize it's a trap! |
82 static void onTrapDetected(Baz baz); | 69 static void onTrapDetected(Baz baz); |
83 }; | 70 }; |
84 }; | 71 }; |
85 """ | 72 """ |
86 | 73 |
87 # The output we expect from our fake idl file. | 74 # The output we expect from our fake idl file. |
88 expected_output = COPYRIGHT + "\n" + (INFO % (sys.argv[0], "fakeApi")) + """ | 75 expected_output = JsInterfaceGenerator.GetHeader(sys.argv[0], 'fakeApi') + """ |
89 /** @fileoverview Externs generated from namespace: fakeApi */ | |
90 | 76 |
91 /** | 77 /** @interface */ |
92 * @const | 78 function FakeApi() {} |
93 */ | |
94 chrome.fakeApi = {}; | |
95 | 79 |
96 /** | 80 FakeApi.prototype = { |
97 * @enum {string} | 81 /** |
98 * @see https://developer.chrome.com/extensions/fakeApi#type-Greek | 82 * Does something exciting! And what's more, this is a multiline function |
99 */ | 83 * comment! It goes onto multiple lines! |
100 chrome.fakeApi.Greek = { | 84 * @param {!chrome.fakeApi.Baz} baz The baz to use. |
101 ALPHA: 'ALPHA', | 85 * @param {function():void} callback |
102 BETA: 'BETA', | 86 * @see https://developer.chrome.com/extensions/fakeApi#method-doSomething |
103 GAMMA: 'GAMMA', | 87 */ |
104 DELTA: 'DELTA', | 88 doSomething: assertNotReached, |
105 }; | |
106 | 89 |
107 /** | 90 /** |
108 * @typedef {{ | 91 * @param {function(!chrome.fakeApi.Baz, !chrome.fakeApi.Greek):void=} callbac
k |
109 * num: number | 92 * The callback which will most assuredly in all cases be called; that is, |
110 * }} | 93 * of course, iff such a callback was provided and is not at all null. |
111 * @see https://developer.chrome.com/extensions/fakeApi#type-Bar | 94 * @see https://developer.chrome.com/extensions/fakeApi#method-bazGreek |
112 */ | 95 */ |
113 chrome.fakeApi.Bar; | 96 bazGreek: assertNotReached, |
114 | 97 |
115 /** | 98 /** |
116 * @typedef {{ | 99 * Fired when we realize it's a trap! |
117 * str: string, | 100 * @type {!ChromeEvent} |
118 * num: number, | 101 * @see https://developer.chrome.com/extensions/fakeApi#event-onTrapDetected |
119 * b: boolean, | 102 */ |
120 * letter: !chrome.fakeApi.Greek, | 103 onTrapDetected: new ChromeEvent(), |
121 * optionalLetter: (!chrome.fakeApi.Greek|undefined), | 104 };""" |
122 * arr: !Array<number>, | |
123 * optionalObjArr: (!Array<!chrome.fakeApi.Bar>|undefined), | |
124 * enumArr: !Array<!chrome.fakeApi.Greek>, | |
125 * anythingGoes: !Array<*>, | |
126 * obj: !chrome.fakeApi.Bar, | |
127 * maybe: (number|undefined), | |
128 * choice: (string|!chrome.fakeApi.Greek|!Array<number>), | |
129 * plainObj: Object | |
130 * }} | |
131 * @see https://developer.chrome.com/extensions/fakeApi#type-Baz | |
132 */ | |
133 chrome.fakeApi.Baz; | |
134 | |
135 /** | |
136 * Does something exciting! And what's more, this is a multiline function | |
137 * comment! It goes onto multiple lines! | |
138 * @param {!chrome.fakeApi.Baz} baz The baz to use. | |
139 * @param {function():void} callback | |
140 * @see https://developer.chrome.com/extensions/fakeApi#method-doSomething | |
141 */ | |
142 chrome.fakeApi.doSomething = function(baz, callback) {}; | |
143 | |
144 /** | |
145 * @param {function(!chrome.fakeApi.Baz, !chrome.fakeApi.Greek):void=} callback | |
146 * The callback which will most assuredly in all cases be called; that is, | |
147 * of course, iff such a callback was provided and is not at all null. | |
148 * @see https://developer.chrome.com/extensions/fakeApi#method-bazGreek | |
149 */ | |
150 chrome.fakeApi.bazGreek = function(callback) {}; | |
151 | |
152 /** | |
153 * @return {string} | |
154 * @deprecated Use a new method. | |
155 * @see https://developer.chrome.com/extensions/fakeApi#method-returnString | |
156 */ | |
157 chrome.fakeApi.returnString = function() {}; | |
158 | |
159 /** | |
160 * Fired when we realize it's a trap! | |
161 * @type {!ChromeEvent} | |
162 * @see https://developer.chrome.com/extensions/fakeApi#event-onTrapDetected | |
163 */ | |
164 chrome.fakeApi.onTrapDetected; | |
165 """ | |
166 | |
167 | |
168 fake_json = """// Copyright 2014 The Chromium Authors. All rights reserved. | |
169 // Use of this source code is governed by a BSD-style license that can be | |
170 // found in the LICENSE file. | |
171 | |
172 [ | |
173 { | |
174 "namespace": "fakeJson", | |
175 "description": "Fake JSON API Stuff", | |
176 "types": [ { | |
177 "id": "CrazyEnum", | |
178 "type": "string", | |
179 "enum": ["camelCaseEnum", "Non-Characters", "5NumFirst", \ | |
180 "3Just-plainOld_MEAN"] | |
181 } ], | |
182 "functions": [ { | |
183 "name": "funcWithInlineObj", | |
184 "type": "function", | |
185 "parameters": [ | |
186 { | |
187 "type": "object", | |
188 "name": "inlineObj", | |
189 "description": "Evil inline object! With a super duper duper long\ | |
190 string description that causes problems!", | |
191 "properties": { | |
192 "foo": { | |
193 "type": "boolean", | |
194 "optional": "true", | |
195 "description": "The foo." | |
196 }, | |
197 "bar": { | |
198 "type": "integer", | |
199 "description": "The bar." | |
200 }, | |
201 "baz": { | |
202 "type": "object", | |
203 "description": "Inception object.", | |
204 "properties": { | |
205 "depth": { | |
206 "type": "integer" | |
207 } | |
208 } | |
209 } | |
210 } | |
211 }, | |
212 { | |
213 "name": "callback", | |
214 "type": "function", | |
215 "parameters": [ | |
216 { | |
217 "type": "object", | |
218 "name": "returnObj", | |
219 "properties": { | |
220 "str": { "type": "string"} | |
221 } | |
222 } | |
223 ], | |
224 "description": "The callback to this heinous method" | |
225 } | |
226 ], | |
227 "returns": { | |
228 "type": "object", | |
229 "properties": { | |
230 "str": { "type": "string" }, | |
231 "int": { "type": "number" } | |
232 } | |
233 } | |
234 } ] | |
235 } | |
236 ]""" | |
237 | |
238 json_expected = COPYRIGHT + "\n" + (INFO % (sys.argv[0], "fakeJson")) + """ | |
239 /** @fileoverview Externs generated from namespace: fakeJson */ | |
240 | |
241 /** | |
242 * @const | |
243 */ | |
244 chrome.fakeJson = {}; | |
245 | |
246 /** | |
247 * @enum {string} | |
248 * @see https://developer.chrome.com/extensions/fakeJson#type-CrazyEnum | |
249 */ | |
250 chrome.fakeJson.CrazyEnum = { | |
251 CAMEL_CASE_ENUM: 'camelCaseEnum', | |
252 NON_CHARACTERS: 'Non-Characters', | |
253 _5NUM_FIRST: '5NumFirst', | |
254 _3JUST_PLAIN_OLD_MEAN: '3Just-plainOld_MEAN', | |
255 }; | |
256 | |
257 /** | |
258 * @param {{ | |
259 * foo: (boolean|undefined), | |
260 * bar: number, | |
261 * baz: { | |
262 * depth: number | |
263 * } | |
264 * }} inlineObj Evil inline object! With a super duper duper long string | |
265 * description that causes problems! | |
266 * @param {function({ | |
267 * str: string | |
268 * }):void} callback The callback to this heinous method | |
269 * @return {{ | |
270 * str: string, | |
271 * int: number | |
272 * }} | |
273 * @see https://developer.chrome.com/extensions/fakeJson#method-funcWithInlineOb
j | |
274 */ | |
275 chrome.fakeJson.funcWithInlineObj = function(inlineObj, callback) {}; | |
276 """ | |
277 | |
278 | 105 |
279 class JsExternGeneratorTest(unittest.TestCase): | 106 class JsExternGeneratorTest(unittest.TestCase): |
280 def _GetNamespace(self, fake_content, filename, is_idl): | 107 def _GetNamespace(self, fake_content, filename): |
281 """Returns a namespace object for the given content""" | 108 """Returns a namespace object for the given content""" |
282 api_def = (idl_schema.Process(fake_content, filename) if is_idl | 109 api_def = idl_schema.Process(fake_content, filename) |
283 else json_parse.Parse(fake_content)) | |
284 m = model.Model() | 110 m = model.Model() |
285 return m.AddNamespace(api_def[0], filename) | 111 return m.AddNamespace(api_def[0], filename) |
286 | 112 |
287 def setUp(self): | 113 def setUp(self): |
288 self.maxDiff = None # Lets us see the full diff when inequal. | 114 self.maxDiff = None # Lets us see the full diff when inequal. |
289 | 115 |
290 def testBasic(self): | 116 def testBasic(self): |
291 namespace = self._GetNamespace(fake_idl, 'fake_api.idl', True) | 117 namespace = self._GetNamespace(fake_idl, 'fake_api.idl') |
292 self.assertMultiLineEqual(expected_output, | 118 self.assertMultiLineEqual( |
293 JsExternsGenerator().Generate(namespace).Render()) | 119 expected_output, |
294 | 120 JsInterfaceGenerator().Generate(namespace).Render()) |
295 def testJsonWithInlineObjects(self): | |
296 namespace = self._GetNamespace(fake_json, 'fake_api.json', False) | |
297 self.assertMultiLineEqual(json_expected, | |
298 JsExternsGenerator().Generate(namespace).Render()) | |
299 | 121 |
300 | 122 |
301 if __name__ == '__main__': | 123 if __name__ == '__main__': |
302 unittest.main() | 124 unittest.main() |
OLD | NEW |