zjquery: Prevent direct patches to $.

We prohibit code from making direct patches to
$ unless you use override().
This commit is contained in:
Steve Howell 2021-02-22 11:18:06 +00:00 committed by Steve Howell
parent b40d8d5790
commit 89ab76920f
2 changed files with 48 additions and 3 deletions

View File

@ -122,14 +122,31 @@ exports.with_overrides = function (test_function) {
unused_funcs.get(obj).set(func_name, true);
const old_f = obj[func_name];
obj[func_name] = function (...args) {
let old_f = obj[func_name];
if (old_f === undefined) {
// Create a dummy function so that we can
// attach _patched_with_override to it.
old_f = () => {
throw new Error(`There is no ${func_name}() field for this object.`);
};
}
const new_f = function (...args) {
unused_funcs.get(obj).delete(func_name);
return f.apply(this, args);
};
// Let zjquery know this function was patched with override,
// so it doesn't complain about us modifying it. (Other
// code can also use this, as needed.)
new_f._patched_with_override = true;
obj[func_name] = new_f;
restore_callbacks.push(() => {
old_f._patched_with_override = true;
obj[func_name] = old_f;
delete old_f._patched_with_override;
});
};

View File

@ -558,4 +558,32 @@ function make_zjquery() {
return zjquery;
}
module.exports = make_zjquery();
const $ = new Proxy(make_zjquery(), {
set(obj, prop, value) {
if (value._patched_with_override) {
obj[prop] = value;
return true;
}
throw new Error(`
Please don't modify $.${prop} if you are using zjquery.
You can do this instead:
override($, "${prop}", () => {...});
Or you can do this if you don't actually
need zjquery and just want to simulate one function.
set_global("$", {
${prop}(...) {...},
});
It's also possible that you are testing code with
node tests when it would be a better strategy to
use puppeteer tests.
`);
},
});
module.exports = $;