Source code
Revision control
Copy as Markdown
Other Tools
// Test case |typeof| folding in simple comparison contexts.
// Create functions to test if |typeof x| is equal to a constant string.
// - Covers all possible |typeof| results, plus the invalid string "bad".
// - Covers all four possible equality comparison operators.
function createFunctions() {
return [
"undefined",
"object",
"function",
"string",
"number",
"boolean",
"symbol",
"bigint",
"bad",
].flatMap(type => [
"==",
"===",
"!=",
"!=="
].map(op => ({
type,
equal: op[0] === "=",
fn: Function("thing", `return typeof thing ${op} "${type}"`)
})));
}
let functions = createFunctions();
function test() {
const ccwGlobal = newGlobal({newCompartment: true});
const xs = [
// "undefined"
// Plain undefined and object emulating undefined, including various proxy wrapper cases.
undefined,
createIsHTMLDDA(),
wrapWithProto(createIsHTMLDDA(), null),
ccwGlobal.eval("createIsHTMLDDA()"),
// "object"
// Plain object and various proxy wrapper cases.
{},
this,
new Proxy({}, {}),
wrapWithProto({}, null),
transplantableObject({proxy: true}).object,
ccwGlobal.Object(),
// "function"
// Plain function and various proxy wrapper cases.
function(){},
new Proxy(function(){}, {}),
new Proxy(createIsHTMLDDA(), {}),
wrapWithProto(function(){}, null),
ccwGlobal.Function(),
// "string"
"",
// "number"
// Int32 and Double numbers.
0,
1.23,
// "boolean"
true,
// "symbol"
Symbol(),
// "bigint"
0n,
];
for (let i = 0; i < 200; ++i) {
let x = xs[i % xs.length];
for (let {type, equal, fn} of functions) {
assertEq(fn(x), (typeof x === type) === equal);
}
}
}
for (let i = 0; i < 2; ++i) test();
// Fresh set of functions to gather new type info.
let functionsObject = createFunctions();
// Additional test when the input is always an object.
function testObject() {
const ccwGlobal = newGlobal({newCompartment: true});
// All elements of this array are objects to cover the case when |MTypeOf| has
// a |MIRType::Object| input.
const xs = [
// "undefined"
// Object emulating undefined, including various proxy wrapper cases.
createIsHTMLDDA(),
wrapWithProto(createIsHTMLDDA(), null),
ccwGlobal.eval("createIsHTMLDDA()"),
// "object"
// Plain object and various proxy wrapper cases.
{},
this,
new Proxy({}, {}),
wrapWithProto({}, null),
transplantableObject({proxy: true}).object,
ccwGlobal.Object(),
// "function"
// Plain function and various proxy wrapper cases.
function(){},
new Proxy(function(){}, {}),
new Proxy(createIsHTMLDDA(), {}),
wrapWithProto(function(){}, null),
ccwGlobal.Function(),
];
for (let i = 0; i < 200; ++i) {
let x = xs[i % xs.length];
for (let {type, equal, fn} of functionsObject) {
assertEq(fn(x), (typeof x === type) === equal);
}
}
}
for (let i = 0; i < 2; ++i) testObject();