3 function assertIsGetter(obj, prop) {
4 let desc = Object.getOwnPropertyDescriptor(obj, prop);
6 ok(desc, `Property ${prop} exists on object`);
7 equal(typeof desc.get, "function", `Getter function exists for property ${prop}`);
8 equal(typeof desc.set, "function", `Setter function exists for property ${prop}`);
9 equal(desc.enumerable, true, `Property ${prop} is enumerable`);
10 equal(desc.configurable, true, `Property ${prop} is configurable`);
13 function assertIsValue(obj, prop, value) {
14 let desc = Object.getOwnPropertyDescriptor(obj, prop);
16 ok(desc, `Property ${prop} exists on object`);
18 ok("value" in desc, `${prop} is a data property`);
19 equal(desc.value, value, `${prop} has the expected value`);
21 equal(desc.enumerable, true, `Property ${prop} is enumerable`);
22 equal(desc.configurable, true, `Property ${prop} is configurable`);
23 equal(desc.writable, true, `Property ${prop} is writable`);
26 add_task(async function() {
28 ChromeUtils.import("resource://test/TestFile.jsm", temp);
31 let child = Object.create(obj);
32 let sealed = Object.seal(Object.create(obj));
37 ChromeUtils.defineModuleGetter(obj, "TestFile",
38 "resource://test/TestFile.jsm");
40 assertIsGetter(obj, "TestFile");
41 equal(child.TestFile, temp.TestFile, "Getter works on descendent object");
42 assertIsValue(child, "TestFile", temp.TestFile);
43 assertIsGetter(obj, "TestFile");
45 Assert.throws(() => sealed.TestFile, /Object is not extensible/,
46 "Cannot access lazy getter from sealed object");
47 Assert.throws(() => sealed.TestFile = null, /Object is not extensible/,
48 "Cannot access lazy setter from sealed object");
49 assertIsGetter(obj, "TestFile");
51 equal(obj.TestFile, temp.TestFile, "Getter works on object");
52 assertIsValue(obj, "TestFile", temp.TestFile);
55 // Test overwriting via setter
57 child = Object.create(obj);
59 ChromeUtils.defineModuleGetter(obj, "TestFile",
60 "resource://test/TestFile.jsm");
62 assertIsGetter(obj, "TestFile");
64 child.TestFile = "foo";
65 assertIsValue(child, "TestFile", "foo");
66 assertIsGetter(obj, "TestFile");
69 assertIsValue(obj, "TestFile", "foo");
72 // Test import missing property
74 ChromeUtils.defineModuleGetter(obj, "meh",
75 "resource://test/TestFile.jsm");
76 assertIsGetter(obj, "meh");
77 equal(obj.meh, undefined, "Missing property returns undefined");
78 assertIsValue(obj, "meh", undefined);
81 // Test import broken module
83 ChromeUtils.defineModuleGetter(obj, "broken",
84 "resource://test/bogus_exports_type.jsm");
85 assertIsGetter(obj, "broken");
87 let errorPattern = /EXPORTED_SYMBOLS is not an array/;
88 Assert.throws(() => child.broken, errorPattern,
89 "Broken import throws on child");
90 Assert.throws(() => child.broken, errorPattern,
91 "Broken import throws on child again");
92 Assert.throws(() => sealed.broken, errorPattern,
93 "Broken import throws on sealed child");
94 Assert.throws(() => obj.broken, errorPattern,
95 "Broken import throws on object");
96 assertIsGetter(obj, "broken");
99 // Test import missing module
101 ChromeUtils.defineModuleGetter(obj, "missing",
102 "resource://test/does_not_exist.jsm");
103 assertIsGetter(obj, "missing");
105 Assert.throws(() => obj.missing, /NS_ERROR_FILE_NOT_FOUND/,
106 "missing import throws on object");
107 assertIsGetter(obj, "missing");
110 // Test overwriting broken import via setter
112 assertIsGetter(obj, "broken");
114 assertIsValue(obj, "broken", "foo");