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