Bug 1370077 - Avoid deprecation message when background.persistent is true r=robwu,aswan
authoredward.i.wu <edward.i.wu@gmail.com>
Thu, 10 Jan 2019 01:11:44 +0000
changeset 510304 e676737b9689ff7e95741e6f4a67baf3abf8c7ee
parent 510303 0d7629792afb8a8d932c4bef3359f39d83af13a5
child 510305 b21a65e29e757f22e297f75ab2e8dfe43ca747bc
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrobwu, aswan
bugs1370077
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1370077 - Avoid deprecation message when background.persistent is true r=robwu,aswan Add support for enumerations to boolean types, and use it to only show a deprecation message when background.persistent is false. Differential Revision: https://phabricator.services.mozilla.com/D15507
toolkit/components/extensions/Schemas.jsm
toolkit/components/extensions/schemas/manifest.json
toolkit/components/extensions/test/xpcshell/test_ext_eventpage_warning.js
toolkit/components/extensions/test/xpcshell/test_ext_schemas.js
--- a/toolkit/components/extensions/Schemas.jsm
+++ b/toolkit/components/extensions/Schemas.jsm
@@ -1899,18 +1899,43 @@ class IntegerType extends Type {
   }
 
   checkBaseType(baseType) {
     return baseType == "integer";
   }
 }
 
 class BooleanType extends Type {
+  static get EXTRA_PROPERTIES() {
+    return ["enum", ...super.EXTRA_PROPERTIES];
+  }
+
+  static parseSchema(root, schema, path, extraProperties = []) {
+    this.checkSchemaProperties(schema, path, extraProperties);
+    let enumeration = schema.enum || null;
+    return new this(schema, enumeration);
+  }
+
+  constructor(schema, enumeration) {
+    super(schema);
+    this.enumeration = enumeration;
+  }
+
   normalize(value, context) {
-    return this.normalizeBase("boolean", value, context);
+    if (!this.checkBaseType(getValueBaseType(value))) {
+      return context.error(() => `Expected boolean instead of ${JSON.stringify(value)}`,
+                           `be a boolean`);
+    }
+    value = this.preprocess(value, context);
+    if (this.enumeration && !this.enumeration.includes(value)) {
+      return context.error(() => `Invalid value ${JSON.stringify(value)}`,
+                           `be ${this.enumeration}`);
+    }
+    this.checkDeprecated(context, value);
+    return {value};
   }
 
   checkBaseType(baseType) {
     return baseType == "boolean";
   }
 }
 
 class ArrayType extends Type {
--- a/toolkit/components/extensions/schemas/manifest.json
+++ b/toolkit/components/extensions/schemas/manifest.json
@@ -573,14 +573,23 @@
       },
       {
         "id": "UnrecognizedProperty",
         "type": "any",
         "deprecated": "An unexpected property was found in the WebExtension manifest."
       },
       {
         "id": "PersistentBackgroundProperty",
-        "type": "boolean",
-        "deprecated": "Event pages are not currently supported. This will run as a persistent background page."
+        "choices": [
+          {
+            "type": "boolean",
+            "enum": [true]
+          },
+          {
+            "type": "boolean",
+            "enum": [false],
+            "deprecated": "Event pages are not currently supported. This will run as a persistent background page."
+          }
+        ]
       }
     ]
   }
 ]
--- a/toolkit/components/extensions/test/xpcshell/test_ext_eventpage_warning.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_eventpage_warning.js
@@ -39,16 +39,30 @@ add_task(async function test_eventpages(
     },
     {
       message: "testing additional unrecognized properties on background page",
       eventPage: {
         "scripts": ["event_page_script.js"],
         "nonExistentProp": true,
       },
     },
+    {
+      message: "testing persistent background page",
+      eventPage: {
+        "page": "event-page.html",
+        "persistent": true,
+      },
+    },
+    {
+      message: "testing scripts with persistent background running as a background page",
+      eventPage: {
+        "scripts": ["event_page_script.js"],
+        "persistent": true,
+      },
+    },
   ];
 
   let {messages} = await promiseConsoleOutput(async () => {
     for (let test of testCases) {
       info(test.message);
 
       let extension = createEventPageExtension(test.eventPage);
       await extension.startup();
@@ -56,10 +70,10 @@ add_task(async function test_eventpages(
       equal(x, 1, "got correct value from extension");
       await extension.unload();
     }
   });
   AddonTestUtils.checkMessages(messages, {expected: [
     {message: /Event pages are not currently supported./},
     {message: /Event pages are not currently supported./},
     {message: /Reading manifest: Error processing background.nonExistentProp: An unexpected property was found/},
-  ]});
+  ]}, true);
 });
--- a/toolkit/components/extensions/test/xpcshell/test_ext_schemas.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_schemas.js
@@ -1734,8 +1734,47 @@ add_task(async function testReturns() {
     Assert.throws(() => root.returns.invalid(),
                   /Type error for result value \(Property "size" is required\)/,
                   "Should throw for invalid result in DEBUG builds");
   } else {
     deepEqual(root.returns.invalid(), {},
               "Doesn't throw for invalid result value in release builds");
   }
 });
+
+let booleanEnumJson = [{
+  namespace: "booleanEnum",
+
+  types: [
+    {
+      "id": "enumTrue",
+      "type": "boolean",
+      "enum": [true],
+    },
+  ],
+  functions: [
+    {
+      name: "paramMustBeTrue",
+      type: "function",
+      parameters: [
+        {name: "arg", "$ref": "enumTrue"},
+      ],
+    },
+  ],
+}];
+
+add_task(async function testBooleanEnum() {
+  let url = "data:," + JSON.stringify(booleanEnumJson);
+  Schemas._rootSchema = null;
+  await Schemas.load(url);
+
+  let root = {};
+  tallied = null;
+  Schemas.inject(root, wrapper);
+  Assert.equal(tallied, null);
+
+  ok(root.booleanEnum, "namespace exists");
+  root.booleanEnum.paramMustBeTrue(true);
+  verify("call", "booleanEnum", "paramMustBeTrue", [true]);
+  Assert.throws(() => root.booleanEnum.paramMustBeTrue(false),
+                /Type error for parameter arg \(Invalid value false\) for booleanEnum\.paramMustBeTrue\./,
+                "should throw because enum of the type restricts parameter to true");
+});