"use strict"; Components.utils.import("resource://gre/modules/Schemas.jsm"); let schemaJson = [ { namespace: "noAllowedContexts", properties: { prop1: {type: "object"}, prop2: {type: "object", allowedContexts: ["test_zero", "test_one"]}, prop3: {type: "number", value: 1}, prop4: {type: "number", value: 1, allowedContexts: ["numeric_one"]}, }, }, { namespace: "defaultContexts", defaultContexts: ["test_two"], properties: { prop1: {type: "object"}, prop2: {type: "object", allowedContexts: ["test_three"]}, prop3: {type: "number", value: 1}, prop4: {type: "number", value: 1, allowedContexts: ["numeric_two"]}, }, }, { namespace: "withAllowedContexts", allowedContexts: ["test_four"], properties: { prop1: {type: "object"}, prop2: {type: "object", allowedContexts: ["test_five"]}, prop3: {type: "number", value: 1}, prop4: {type: "number", value: 1, allowedContexts: ["numeric_three"]}, }, }, { namespace: "withAllowedContextsAndDefault", allowedContexts: ["test_six"], defaultContexts: ["test_seven"], properties: { prop1: {type: "object"}, prop2: {type: "object", allowedContexts: ["test_eight"]}, prop3: {type: "number", value: 1}, prop4: {type: "number", value: 1, allowedContexts: ["numeric_four"]}, }, }, { namespace: "with_submodule", defaultContexts: ["test_nine"], types: [{ id: "subtype", type: "object", functions: [{ name: "noAllowedContexts", type: "function", parameters: [], }, { name: "allowedContexts", allowedContexts: ["test_ten"], type: "function", parameters: [], }], }], properties: { prop1: {$ref: "subtype"}, prop2: {$ref: "subtype", allowedContexts: ["test_eleven"]}, }, }, ]; add_task(function* testRestrictions() { let url = "data:," + JSON.stringify(schemaJson); yield Schemas.load(url); let results = {}; let localWrapper = { shouldInject(ns, name, allowedContexts) { name = name === null ? ns : ns + "." + name; results[name] = allowedContexts.join(","); return true; }, getImplementation() { // The actual implementation is not significant for this test. // Let's take this opportunity to see if schema generation is free of // exceptions even when somehow getImplementation does not return an // implementation. }, }; let root = {}; Schemas.inject(root, localWrapper); function verify(path, expected) { let obj = root; for (let thing of path.split(".")) { try { obj = obj[thing]; } catch (e) { // Blech. } } let result = results[path]; equal(result, expected); } verify("noAllowedContexts", ""); verify("noAllowedContexts.prop1", ""); verify("noAllowedContexts.prop2", "test_zero,test_one"); verify("noAllowedContexts.prop3", ""); verify("noAllowedContexts.prop4", "numeric_one"); verify("defaultContexts", ""); verify("defaultContexts.prop1", "test_two"); verify("defaultContexts.prop2", "test_three"); verify("defaultContexts.prop3", "test_two"); verify("defaultContexts.prop4", "numeric_two"); verify("withAllowedContexts", "test_four"); verify("withAllowedContexts.prop1", ""); verify("withAllowedContexts.prop2", "test_five"); verify("withAllowedContexts.prop3", ""); verify("withAllowedContexts.prop4", "numeric_three"); verify("withAllowedContextsAndDefault", "test_six"); verify("withAllowedContextsAndDefault.prop1", "test_seven"); verify("withAllowedContextsAndDefault.prop2", "test_eight"); verify("withAllowedContextsAndDefault.prop3", "test_seven"); verify("withAllowedContextsAndDefault.prop4", "numeric_four"); verify("with_submodule", ""); verify("with_submodule.prop1", "test_nine"); verify("with_submodule.prop1.noAllowedContexts", "test_nine"); verify("with_submodule.prop1.allowedContexts", "test_ten"); verify("with_submodule.prop2", "test_eleven"); // Note: test_nine inherits allowed contexts from the namespace, not from // submodule. There is no "defaultContexts" for submodule types to not // complicate things. verify("with_submodule.prop1.noAllowedContexts", "test_nine"); verify("with_submodule.prop1.allowedContexts", "test_ten"); // This is a constant, so it does not matter that getImplementation does not // return an implementation since the API injector should take care of it. equal(root.noAllowedContexts.prop3, 1); Assert.throws(() => root.noAllowedContexts.prop1, /undefined/, "Should throw when the implementation is absent."); });