summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/test/xpcshell/test_ext_schemas_roots.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/extensions/test/xpcshell/test_ext_schemas_roots.js')
-rw-r--r--toolkit/components/extensions/test/xpcshell/test_ext_schemas_roots.js242
1 files changed, 242 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_schemas_roots.js b/toolkit/components/extensions/test/xpcshell/test_ext_schemas_roots.js
new file mode 100644
index 0000000000..21434228a3
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_schemas_roots.js
@@ -0,0 +1,242 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+const { SchemaRoot } = ChromeUtils.importESModule(
+ "resource://gre/modules/Schemas.sys.mjs"
+);
+
+let { SchemaAPIInterface } = ExtensionCommon;
+
+const global = this;
+
+let baseSchemaJSON = [
+ {
+ namespace: "base",
+
+ properties: {
+ PROP1: { value: 42 },
+ },
+
+ types: [
+ {
+ id: "type1",
+ type: "string",
+ enum: ["value1", "value2", "value3"],
+ },
+ ],
+
+ functions: [
+ {
+ name: "foo",
+ type: "function",
+ parameters: [{ name: "arg1", $ref: "type1" }],
+ },
+ ],
+ },
+];
+
+let experimentFooJSON = [
+ {
+ namespace: "experiments.foo",
+ types: [
+ {
+ id: "typeFoo",
+ type: "string",
+ enum: ["foo1", "foo2", "foo3"],
+ },
+ ],
+
+ functions: [
+ {
+ name: "foo",
+ type: "function",
+ parameters: [
+ { name: "arg1", $ref: "typeFoo" },
+ { name: "arg2", $ref: "base.type1" },
+ ],
+ },
+ ],
+ },
+];
+
+let experimentBarJSON = [
+ {
+ namespace: "experiments.bar",
+ types: [
+ {
+ id: "typeBar",
+ type: "string",
+ enum: ["bar1", "bar2", "bar3"],
+ },
+ ],
+
+ functions: [
+ {
+ name: "bar",
+ type: "function",
+ parameters: [
+ { name: "arg1", $ref: "typeBar" },
+ { name: "arg2", $ref: "base.type1" },
+ ],
+ },
+ ],
+ },
+];
+
+let tallied = null;
+
+function tally(kind, ns, name, args) {
+ tallied = [kind, ns, name, args];
+}
+
+function verify(...args) {
+ equal(JSON.stringify(tallied), JSON.stringify(args));
+ tallied = null;
+}
+
+let talliedErrors = [];
+
+let permissions = new Set();
+
+class TallyingAPIImplementation extends SchemaAPIInterface {
+ constructor(namespace, name) {
+ super();
+ this.namespace = namespace;
+ this.name = name;
+ }
+
+ callFunction(args) {
+ tally("call", this.namespace, this.name, args);
+ if (this.name === "sub_foo") {
+ return 13;
+ }
+ }
+
+ callFunctionNoReturn(args) {
+ tally("call", this.namespace, this.name, args);
+ }
+
+ getProperty() {
+ tally("get", this.namespace, this.name);
+ }
+
+ setProperty(value) {
+ tally("set", this.namespace, this.name, value);
+ }
+
+ addListener(listener, args) {
+ tally("addListener", this.namespace, this.name, [listener, args]);
+ }
+
+ removeListener(listener) {
+ tally("removeListener", this.namespace, this.name, [listener]);
+ }
+
+ hasListener(listener) {
+ tally("hasListener", this.namespace, this.name, [listener]);
+ }
+}
+
+let wrapper = {
+ url: "moz-extension://b66e3509-cdb3-44f6-8eb8-c8b39b3a1d27/",
+ manifestVersion: 2,
+
+ cloneScope: global,
+
+ checkLoadURL(url) {
+ return !url.startsWith("chrome:");
+ },
+
+ preprocessors: {
+ localize(value, context) {
+ return value.replace(/__MSG_(.*?)__/g, (m0, m1) => `${m1.toUpperCase()}`);
+ },
+ },
+
+ logError(message) {
+ talliedErrors.push(message);
+ },
+
+ hasPermission(permission) {
+ return permissions.has(permission);
+ },
+
+ shouldInject(ns, name) {
+ return name != "do-not-inject";
+ },
+
+ getImplementation(namespace, name) {
+ return new TallyingAPIImplementation(namespace, name);
+ },
+};
+
+add_task(async function () {
+ let baseSchemas = new Map([["resource://schemas/base.json", baseSchemaJSON]]);
+ let experimentSchemas = new Map([
+ ["resource://experiment-foo/schema.json", experimentFooJSON],
+ ["resource://experiment-bar/schema.json", experimentBarJSON],
+ ]);
+
+ let baseSchema = new SchemaRoot(null, baseSchemas);
+ let schema = new SchemaRoot(baseSchema, experimentSchemas);
+
+ baseSchema.parseSchemas();
+ schema.parseSchemas();
+
+ let root = {};
+ let base = {};
+
+ tallied = null;
+
+ baseSchema.inject(base, wrapper);
+ schema.inject(root, wrapper);
+
+ equal(typeof base.base, "object", "base.base exists");
+ equal(typeof root.base, "object", "root.base exists");
+ equal(typeof base.experiments, "undefined", "base.experiments exists not");
+ equal(typeof root.experiments, "object", "root.experiments exists");
+ equal(typeof root.experiments.foo, "object", "root.experiments.foo exists");
+ equal(typeof root.experiments.bar, "object", "root.experiments.bar exists");
+
+ equal(tallied, null);
+
+ equal(root.base.PROP1, 42, "root.base.PROP1");
+ equal(base.base.PROP1, 42, "root.base.PROP1");
+
+ root.base.foo("value2");
+ verify("call", "base", "foo", ["value2"]);
+
+ base.base.foo("value3");
+ verify("call", "base", "foo", ["value3"]);
+
+ root.experiments.foo.foo("foo2", "value1");
+ verify("call", "experiments.foo", "foo", ["foo2", "value1"]);
+
+ root.experiments.bar.bar("bar2", "value1");
+ verify("call", "experiments.bar", "bar", ["bar2", "value1"]);
+
+ Assert.throws(
+ () => root.base.foo("Meh."),
+ /Type error for parameter arg1/,
+ "root.base.foo()"
+ );
+
+ Assert.throws(
+ () => base.base.foo("Meh."),
+ /Type error for parameter arg1/,
+ "base.base.foo()"
+ );
+
+ Assert.throws(
+ () => root.experiments.foo.foo("Meh."),
+ /Incorrect argument types/,
+ "root.experiments.foo.foo()"
+ );
+
+ Assert.throws(
+ () => root.experiments.bar.bar("Meh."),
+ /Incorrect argument types/,
+ "root.experiments.bar.bar()"
+ );
+});