123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564 |
- #!/usr/bin/env python3
- # Copyright 2015 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 idl_schema
- import json_parse
- from js_externs_generator import JsExternsGenerator
- from datetime import datetime
- import model
- import sys
- import unittest
- # The contents of a fake idl file.
- fake_idl = """
- // 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.
- // A totally fake API.
- namespace fakeApi {
- enum Greek {
- ALPHA,
- BETA,
- GAMMA,
- DELTA
- };
- dictionary Bar {
- long num;
- };
- dictionary Baz {
- DOMString str;
- long num;
- boolean b;
- Greek letter;
- Greek? optionalLetter;
- long[] arr;
- Bar[]? optionalObjArr;
- Greek[] enumArr;
- any[] anythingGoes;
- Bar obj;
- long? maybe;
- (DOMString or Greek or long[]) choice;
- object plainObj;
- ArrayBuffer arrayBuff;
- };
- dictionary Qux {
- long notOptionalLong;
- long? optionalLong;
- // A map from string to number.
- // <jsexterns>@type {Object<string, number>}</jsexterns>
- object dict;
- static void go();
- static void stop();
- };
- callback VoidCallback = void();
- callback BazGreekCallback = void(Baz baz, Greek greek);
- callback OptionalParamCallback = void(optional Qux qux);
- interface Properties {
- static DOMString lastError();
- };
- interface Functions {
- // Does something exciting! And what's more, this is a multiline function
- // comment! It goes onto multiple lines!
- // |baz| : The baz to use.
- static void doSomething(Baz baz, VoidCallback callback);
- // |callback| : The callback which will most assuredly in all cases be
- // called; that is, of course, iff such a callback was provided and is
- // not at all null.
- static void bazGreek(optional BazGreekCallback callback);
- [deprecated="Use a new method."] static DOMString returnString();
- static void instanceOfObjectParam([instanceOf=SomeType] object obj);
- static void instanceOfBarObjectParam([instanceOf=Bar] object barObj);
- static void optionalParam(optional OptionalParamCallback callback);
- static void nonFinalOptionalParams(
- DOMString string,
- optional double num,
- object obj,
- [instanceOf = SomeType] object someType,
- [instanceOf = SomeType] optional object optionalSomeType,
- optional boolean bool,
- optional Baz baz,
- double num,
- VoidCallback callback);
- static void multipleOptionalParams(
- optional DOMString param1,
- optional DOMString param2,
- optional object obj,
- [instanceOf = SomeType] optional object optionalSomeType,
- optional VoidCallback callback);
- };
- interface Events {
- // Fired when we realize it's a trap!
- static void onTrapDetected(Baz baz);
- };
- };
- """
- # The output we expect from our fake idl file.
- fake_idl_expected = """// Copyright %s 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.
- // This file was generated by:
- // tools/json_schema_compiler/compiler.py.
- // NOTE: The format of types has changed. 'FooType' is now
- // 'chrome.fakeApi.FooType'.
- // Please run the closure compiler before committing changes.
- // See https://chromium.googlesource.com/chromium/src/+/main/docs/closure_compilation.md
- /** @fileoverview Externs generated from namespace: fakeApi */
- /** @const */
- chrome.fakeApi = {};
- /**
- * @enum {string}
- * @see https://developer.chrome.com/extensions/fakeApi#type-Greek
- */
- chrome.fakeApi.Greek = {
- ALPHA: 'ALPHA',
- BETA: 'BETA',
- GAMMA: 'GAMMA',
- DELTA: 'DELTA',
- };
- /**
- * @typedef {{
- * num: number
- * }}
- * @see https://developer.chrome.com/extensions/fakeApi#type-Bar
- */
- chrome.fakeApi.Bar;
- /**
- * @typedef {{
- * str: string,
- * num: number,
- * b: boolean,
- * letter: !chrome.fakeApi.Greek,
- * optionalLetter: (!chrome.fakeApi.Greek|undefined),
- * arr: !Array<number>,
- * optionalObjArr: (!Array<!chrome.fakeApi.Bar>|undefined),
- * enumArr: !Array<!chrome.fakeApi.Greek>,
- * anythingGoes: !Array<*>,
- * obj: !chrome.fakeApi.Bar,
- * maybe: (number|undefined),
- * choice: (string|!chrome.fakeApi.Greek|!Array<number>),
- * plainObj: Object,
- * arrayBuff: ArrayBuffer
- * }}
- * @see https://developer.chrome.com/extensions/fakeApi#type-Baz
- */
- chrome.fakeApi.Baz;
- /**
- * @constructor
- * @private
- * @see https://developer.chrome.com/extensions/fakeApi#type-Qux
- */
- chrome.fakeApi.Qux = function() {};
- /**
- * @type {number}
- * @see https://developer.chrome.com/extensions/fakeApi#type-notOptionalLong
- */
- chrome.fakeApi.Qux.prototype.notOptionalLong;
- /**
- * @type {(number|undefined)}
- * @see https://developer.chrome.com/extensions/fakeApi#type-optionalLong
- */
- chrome.fakeApi.Qux.prototype.optionalLong;
- /**
- * A map from string to number.
- * @type {Object<string, number>}
- * @see https://developer.chrome.com/extensions/fakeApi#type-dict
- */
- chrome.fakeApi.Qux.prototype.dict;
- /**
- * @see https://developer.chrome.com/extensions/fakeApi#method-go
- */
- chrome.fakeApi.Qux.prototype.go = function() {};
- /**
- * @see https://developer.chrome.com/extensions/fakeApi#method-stop
- */
- chrome.fakeApi.Qux.prototype.stop = function() {};
- /**
- * @type {string}
- * @see https://developer.chrome.com/extensions/fakeApi#type-lastError
- */
- chrome.fakeApi.lastError;
- /**
- * Does something exciting! And what's more, this is a multiline function
- * comment! It goes onto multiple lines!
- * @param {!chrome.fakeApi.Baz} baz The baz to use.
- * @param {function(): void} callback
- * @see https://developer.chrome.com/extensions/fakeApi#method-doSomething
- */
- chrome.fakeApi.doSomething = function(baz, callback) {};
- /**
- * @param {function(!chrome.fakeApi.Baz, !chrome.fakeApi.Greek): void=} callback
- * The callback which will most assuredly in all cases be called; that is,
- * of course, iff such a callback was provided and is not at all null.
- * @see https://developer.chrome.com/extensions/fakeApi#method-bazGreek
- */
- chrome.fakeApi.bazGreek = function(callback) {};
- /**
- * @return {string}
- * @deprecated Use a new method.
- * @see https://developer.chrome.com/extensions/fakeApi#method-returnString
- */
- chrome.fakeApi.returnString = function() {};
- /**
- * @param {SomeType} obj
- * @see https://developer.chrome.com/extensions/fakeApi#method-instanceOfObjectParam
- */
- chrome.fakeApi.instanceOfObjectParam = function(obj) {};
- /**
- * @param {chrome.fakeApi.Bar} barObj
- * @see https://developer.chrome.com/extensions/fakeApi#method-instanceOfBarObjectParam
- */
- chrome.fakeApi.instanceOfBarObjectParam = function(barObj) {};
- /**
- * @param {function((!chrome.fakeApi.Qux|undefined)): void=} callback
- * @see https://developer.chrome.com/extensions/fakeApi#method-optionalParam
- */
- chrome.fakeApi.optionalParam = function(callback) {};
- /**
- * @param {string} string
- * @param {?number|undefined} num
- * @param {Object} obj
- * @param {SomeType} someType
- * @param {?SomeType|undefined} optionalSomeType
- * @param {?boolean|undefined} bool
- * @param {?chrome.fakeApi.Baz|undefined} baz
- * @param {number} num
- * @param {function(): void} callback
- * @see https://developer.chrome.com/extensions/fakeApi#method-nonFinalOptionalParams
- */
- chrome.fakeApi.nonFinalOptionalParams = function(string, num, obj, someType, optionalSomeType, bool, baz, num, callback) {};
- /**
- * @param {string=} param1
- * @param {string=} param2
- * @param {Object=} obj
- * @param {SomeType=} optionalSomeType
- * @param {function(): void=} callback
- * @see https://developer.chrome.com/extensions/fakeApi#method-multipleOptionalParams
- */
- chrome.fakeApi.multipleOptionalParams = function(param1, param2, obj, optionalSomeType, callback) {};
- /**
- * Fired when we realize it's a trap!
- * @type {!ChromeEvent}
- * @see https://developer.chrome.com/extensions/fakeApi#event-onTrapDetected
- */
- chrome.fakeApi.onTrapDetected;""" % datetime.now().year
- # A subset of fake_idl. The key difference is that the namespace is private,
- # which means that @see links shouldn't be generated.
- fake_private_idl = """
- // 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.
- // A totally fake API.
- namespace fakeApiPrivate {
- enum Greek {
- ALPHA,
- BETA,
- GAMMA,
- DELTA
- };
- dictionary Bar {
- long num;
- };
- interface Events {
- // Fired when we realize it's a trap!
- static void onTrapDetected(Baz baz);
- };
- };
- """
- fake_private_idl_expected = """// Copyright %s 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.
- // This file was generated by:
- // tools/json_schema_compiler/compiler.py.
- // NOTE: The format of types has changed. 'FooType' is now
- // 'chrome.fakeApiPrivate.FooType'.
- // Please run the closure compiler before committing changes.
- // See https://chromium.googlesource.com/chromium/src/+/main/docs/closure_compilation.md
- /** @fileoverview Externs generated from namespace: fakeApiPrivate */
- /** @const */
- chrome.fakeApiPrivate = {};
- /**
- * @enum {string}
- */
- chrome.fakeApiPrivate.Greek = {
- ALPHA: 'ALPHA',
- BETA: 'BETA',
- GAMMA: 'GAMMA',
- DELTA: 'DELTA',
- };
- /**
- * @typedef {{
- * num: number
- * }}
- */
- chrome.fakeApiPrivate.Bar;
- /**
- * Fired when we realize it's a trap!
- * @type {!ChromeEvent}
- */
- chrome.fakeApiPrivate.onTrapDetected;""" % datetime.now().year
- fake_json = """// 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.
- [
- {
- "namespace": "fakeJson",
- "description": "Fake JSON API Stuff",
- "types": [
- {
- "id": "CrazyEnum",
- "type": "string",
- "enum": ["camelCaseEnum", "Non-Characters", "5NumFirst", \
- "3Just-plainOld_MEAN"]
- },
- {
- "id": "CrazyObject",
- "type": "object",
- "additionalProperties": {"type": "string"}
- }
- ],
- "properties": {
- "lastError": {
- "type": "string",
- "description": "The lastError."
- }
- },
- "functions": [ {
- "name": "funcWithInlineObj",
- "type": "function",
- "parameters": [
- {
- "type": "object",
- "name": "inlineObj",
- "description": "Evil inline object! With a super duper duper long\
- string description that causes problems!",
- "properties": {
- "foo": {
- "type": "boolean",
- "optional": "true",
- "description": "The foo."
- },
- "bar": {
- "type": "integer",
- "description": "The bar."
- },
- "baz": {
- "type": "object",
- "description": "Inception object.",
- "properties": {
- "depth": {
- "type": "integer"
- }
- }
- },
- "quu": {
- "type": "binary",
- "description": "The array buffer"
- }
- }
- },
- {
- "name": "callback",
- "type": "function",
- "parameters": [
- {
- "type": "object",
- "name": "returnObj",
- "properties": {
- "str": { "type": "string"}
- }
- }
- ],
- "description": "The callback to this heinous method"
- }
- ],
- "returns": {
- "type": "object",
- "properties": {
- "str": { "type": "string" },
- "int": { "type": "number" }
- }
- }
- },
- {
- "name": "funcWithReturnsAsync",
- "type": "function",
- "parameters": [
- {
- "type": "integer",
- "name": "someNumber",
- "description": "A number parameter"
- }
- ],
- "returns_async": {
- "name": "callback",
- "optional": true,
- "parameters": [
- {
- "name": "anotherNumber",
- "type": "integer",
- "description": "A number that comes back"
- }
- ]
- }
- } ]
- }
- ]"""
- fake_json_expected = """// Copyright %s 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.
- // This file was generated by:
- // tools/json_schema_compiler/compiler.py.
- // NOTE: The format of types has changed. 'FooType' is now
- // 'chrome.fakeJson.FooType'.
- // Please run the closure compiler before committing changes.
- // See https://chromium.googlesource.com/chromium/src/+/main/docs/closure_compilation.md
- /** @fileoverview Externs generated from namespace: fakeJson */
- /** @const */
- chrome.fakeJson = {};
- /**
- * @enum {string}
- * @see https://developer.chrome.com/extensions/fakeJson#type-CrazyEnum
- */
- chrome.fakeJson.CrazyEnum = {
- CAMEL_CASE_ENUM: 'camelCaseEnum',
- NON_CHARACTERS: 'Non-Characters',
- _5NUM_FIRST: '5NumFirst',
- _3JUST_PLAIN_OLD_MEAN: '3Just-plainOld_MEAN',
- };
- /**
- * @typedef {Object}
- * @see https://developer.chrome.com/extensions/fakeJson#type-CrazyObject
- */
- chrome.fakeJson.CrazyObject;
- /**
- * The lastError.
- * @type {string}
- * @see https://developer.chrome.com/extensions/fakeJson#type-lastError
- */
- chrome.fakeJson.lastError;
- /**
- * @param {{
- * foo: (boolean|undefined),
- * bar: number,
- * baz: {
- * depth: number
- * },
- * quu: ArrayBuffer
- * }} inlineObj Evil inline object! With a super duper duper long string
- * description that causes problems!
- * @param {function({
- * str: string
- * }): void} callback The callback to this heinous method
- * @return {{
- * str: string,
- * int: number
- * }}
- * @see https://developer.chrome.com/extensions/fakeJson#method-funcWithInlineObj
- */
- chrome.fakeJson.funcWithInlineObj = function(inlineObj, callback) {};
- /**
- * @param {number} someNumber A number parameter
- * @param {function(number): void=} callback
- * @see https://developer.chrome.com/extensions/fakeJson#method-funcWithReturnsAsync
- */
- chrome.fakeJson.funcWithReturnsAsync = function(someNumber, callback) {};""" % (
- datetime.now().year)
- class JsExternGeneratorTest(unittest.TestCase):
- def _GetNamespace(self, fake_content, filename, is_idl):
- """Returns a namespace object for the given content"""
- api_def = (idl_schema.Process(fake_content, filename) if is_idl
- else json_parse.Parse(fake_content))
- m = model.Model()
- return m.AddNamespace(api_def[0], filename)
- def setUp(self):
- self.maxDiff = None # Lets us see the full diff when inequal.
- def testBasic(self):
- namespace = self._GetNamespace(fake_idl, 'fake_api.idl', True)
- self.assertMultiLineEqual(fake_idl_expected,
- JsExternsGenerator().Generate(namespace).Render())
- def testPrivate(self):
- namespace = self._GetNamespace(fake_private_idl, 'fake_api_private.idl',
- True)
- self.assertMultiLineEqual(fake_private_idl_expected,
- JsExternsGenerator().Generate(namespace).Render())
- def testJsonWithInlineObjectsAndAsyncReturn(self):
- namespace = self._GetNamespace(fake_json, 'fake_api.json', False)
- self.assertMultiLineEqual(fake_json_expected,
- JsExternsGenerator().Generate(namespace).Render())
- if __name__ == '__main__':
- unittest.main()
|