mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 15:24:46 -05:00
chore: remove primordial usage from 40_testing.js (#21140)
Towards #21136
This commit is contained in:
parent
1ece7dfd90
commit
81fd514613
1 changed files with 50 additions and 70 deletions
|
@ -1,5 +1,10 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
// Do not use primordials because we do not want to depend on the __bootstrap
|
||||||
|
// namespace.
|
||||||
|
//
|
||||||
|
// deno-lint-ignore-file prefer-primordials
|
||||||
|
|
||||||
const core = globalThis.Deno.core;
|
const core = globalThis.Deno.core;
|
||||||
const ops = core.ops;
|
const ops = core.ops;
|
||||||
import { setExitHandler } from "ext:runtime/30_os.js";
|
import { setExitHandler } from "ext:runtime/30_os.js";
|
||||||
|
@ -7,29 +12,6 @@ import { Console } from "ext:deno_console/01_console.js";
|
||||||
import { serializePermissions } from "ext:runtime/10_permissions.js";
|
import { serializePermissions } from "ext:runtime/10_permissions.js";
|
||||||
import { setTimeout } from "ext:deno_web/02_timers.js";
|
import { setTimeout } from "ext:deno_web/02_timers.js";
|
||||||
import { assert } from "ext:deno_web/00_infra.js";
|
import { assert } from "ext:deno_web/00_infra.js";
|
||||||
const primordials = globalThis.__bootstrap.primordials;
|
|
||||||
const {
|
|
||||||
ArrayPrototypeFilter,
|
|
||||||
ArrayPrototypeJoin,
|
|
||||||
ArrayPrototypePush,
|
|
||||||
ArrayPrototypeShift,
|
|
||||||
DateNow,
|
|
||||||
Error,
|
|
||||||
FunctionPrototype,
|
|
||||||
Map,
|
|
||||||
MapPrototypeGet,
|
|
||||||
MapPrototypeHas,
|
|
||||||
MapPrototypeSet,
|
|
||||||
MathCeil,
|
|
||||||
ObjectKeys,
|
|
||||||
ObjectPrototypeIsPrototypeOf,
|
|
||||||
Promise,
|
|
||||||
SafeArrayIterator,
|
|
||||||
Set,
|
|
||||||
StringPrototypeReplaceAll,
|
|
||||||
SymbolToStringTag,
|
|
||||||
TypeError,
|
|
||||||
} = primordials;
|
|
||||||
|
|
||||||
const opSanitizerDelayResolveQueue = [];
|
const opSanitizerDelayResolveQueue = [];
|
||||||
let hasSetOpSanitizerDelayMacrotask = false;
|
let hasSetOpSanitizerDelayMacrotask = false;
|
||||||
|
@ -59,14 +41,14 @@ function opSanitizerDelay(hasPendingWorkerOps) {
|
||||||
// timeout callback will mean that the resolver gets called in the same
|
// timeout callback will mean that the resolver gets called in the same
|
||||||
// event loop tick as the timeout callback.
|
// event loop tick as the timeout callback.
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
ArrayPrototypePush(opSanitizerDelayResolveQueue, resolve);
|
opSanitizerDelayResolveQueue.push(resolve);
|
||||||
}, hasPendingWorkerOps ? 1 : 0);
|
}, hasPendingWorkerOps ? 1 : 0);
|
||||||
});
|
});
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleOpSanitizerDelayMacrotask() {
|
function handleOpSanitizerDelayMacrotask() {
|
||||||
const resolve = ArrayPrototypeShift(opSanitizerDelayResolveQueue);
|
const resolve = opSanitizerDelayResolveQueue.shift();
|
||||||
if (resolve) {
|
if (resolve) {
|
||||||
resolve();
|
resolve();
|
||||||
return opSanitizerDelayResolveQueue.length === 0;
|
return opSanitizerDelayResolveQueue.length === 0;
|
||||||
|
@ -235,17 +217,17 @@ function assertOps(fn) {
|
||||||
const traces = [];
|
const traces = [];
|
||||||
for (const [id, { opName: traceOpName, stack }] of postTraces) {
|
for (const [id, { opName: traceOpName, stack }] of postTraces) {
|
||||||
if (traceOpName !== opName) continue;
|
if (traceOpName !== opName) continue;
|
||||||
if (MapPrototypeHas(preTraces, id)) continue;
|
if (preTraces.has(id)) continue;
|
||||||
ArrayPrototypePush(traces, stack);
|
traces.push(stack);
|
||||||
}
|
}
|
||||||
if (traces.length === 1) {
|
if (traces.length === 1) {
|
||||||
message += " The operation was started here:\n";
|
message += " The operation was started here:\n";
|
||||||
message += traces[0];
|
message += traces[0];
|
||||||
} else if (traces.length > 1) {
|
} else if (traces.length > 1) {
|
||||||
message += " The operations were started here:\n";
|
message += " The operations were started here:\n";
|
||||||
message += ArrayPrototypeJoin(traces, "\n\n");
|
message += traces.join("\n\n");
|
||||||
}
|
}
|
||||||
ArrayPrototypePush(details, message);
|
details.push(message);
|
||||||
} else if (diff < 0) {
|
} else if (diff < 0) {
|
||||||
const [name, hint] = OP_DETAILS[opName] || [opName, null];
|
const [name, hint] = OP_DETAILS[opName] || [opName, null];
|
||||||
const count = -diff;
|
const count = -diff;
|
||||||
|
@ -262,17 +244,17 @@ function assertOps(fn) {
|
||||||
const traces = [];
|
const traces = [];
|
||||||
for (const [id, { opName: traceOpName, stack }] of preTraces) {
|
for (const [id, { opName: traceOpName, stack }] of preTraces) {
|
||||||
if (opName !== traceOpName) continue;
|
if (opName !== traceOpName) continue;
|
||||||
if (MapPrototypeHas(postTraces, id)) continue;
|
if (postTraces.has(id)) continue;
|
||||||
ArrayPrototypePush(traces, stack);
|
traces.push(stack);
|
||||||
}
|
}
|
||||||
if (traces.length === 1) {
|
if (traces.length === 1) {
|
||||||
message += " The operation was started here:\n";
|
message += " The operation was started here:\n";
|
||||||
message += traces[0];
|
message += traces[0];
|
||||||
} else if (traces.length > 1) {
|
} else if (traces.length > 1) {
|
||||||
message += " The operations were started here:\n";
|
message += " The operations were started here:\n";
|
||||||
message += ArrayPrototypeJoin(traces, "\n\n");
|
message += traces.join("\n\n");
|
||||||
}
|
}
|
||||||
ArrayPrototypePush(details, message);
|
details.push(message);
|
||||||
} else {
|
} else {
|
||||||
throw new Error("unreachable");
|
throw new Error("unreachable");
|
||||||
}
|
}
|
||||||
|
@ -428,8 +410,8 @@ function assertResources(fn) {
|
||||||
const post = core.resources();
|
const post = core.resources();
|
||||||
|
|
||||||
const allResources = new Set([
|
const allResources = new Set([
|
||||||
...new SafeArrayIterator(ObjectKeys(pre)),
|
...Object.keys(pre),
|
||||||
...new SafeArrayIterator(ObjectKeys(post)),
|
...Object.keys(post),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const details = [];
|
const details = [];
|
||||||
|
@ -443,12 +425,12 @@ function assertResources(fn) {
|
||||||
const hint = resourceCloseHint(postResource);
|
const hint = resourceCloseHint(postResource);
|
||||||
const detail =
|
const detail =
|
||||||
`${name} (rid ${resource}) was ${action1} during the test, but not ${action2} during the test. ${hint}`;
|
`${name} (rid ${resource}) was ${action1} during the test, but not ${action2} during the test. ${hint}`;
|
||||||
ArrayPrototypePush(details, detail);
|
details.push(detail);
|
||||||
} else {
|
} else {
|
||||||
const [name, action1, action2] = prettyResourceNames(preResource);
|
const [name, action1, action2] = prettyResourceNames(preResource);
|
||||||
const detail =
|
const detail =
|
||||||
`${name} (rid ${resource}) was ${action1} before the test started, but was ${action2} during the test. Do not close resources in a test that were not created during that test.`;
|
`${name} (rid ${resource}) was ${action1} before the test started, but was ${action2} during the test. Do not close resources in a test that were not created during that test.`;
|
||||||
ArrayPrototypePush(details, detail);
|
details.push(detail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (details.length == 0) {
|
if (details.length == 0) {
|
||||||
|
@ -472,7 +454,7 @@ function assertExit(fn, isTest) {
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const innerResult = await fn(...new SafeArrayIterator(params));
|
const innerResult = await fn(...params);
|
||||||
if (innerResult) return innerResult;
|
if (innerResult) return innerResult;
|
||||||
} finally {
|
} finally {
|
||||||
setExitHandler(null);
|
setExitHandler(null);
|
||||||
|
@ -490,7 +472,7 @@ function wrapOuter(fn, desc) {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return { failed: { jsError: core.destructureError(error) } };
|
return { failed: { jsError: core.destructureError(error) } };
|
||||||
} finally {
|
} finally {
|
||||||
const state = MapPrototypeGet(testStates, desc.id);
|
const state = testStates.get(desc.id);
|
||||||
for (const childDesc of state.children) {
|
for (const childDesc of state.children) {
|
||||||
stepReportResult(childDesc, { failed: "incomplete" }, 0);
|
stepReportResult(childDesc, { failed: "incomplete" }, 0);
|
||||||
}
|
}
|
||||||
|
@ -506,14 +488,14 @@ function wrapInner(fn) {
|
||||||
const results = [];
|
const results = [];
|
||||||
let childDesc = desc;
|
let childDesc = desc;
|
||||||
while (childDesc.parent != null) {
|
while (childDesc.parent != null) {
|
||||||
const state = MapPrototypeGet(testStates, childDesc.parent.id);
|
const state = testStates.get(childDesc.parent.id);
|
||||||
for (const siblingDesc of state.children) {
|
for (const siblingDesc of state.children) {
|
||||||
if (siblingDesc.id == childDesc.id) {
|
if (siblingDesc.id == childDesc.id) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const siblingState = MapPrototypeGet(testStates, siblingDesc.id);
|
const siblingState = testStates.get(siblingDesc.id);
|
||||||
if (!siblingState.completed) {
|
if (!siblingState.completed) {
|
||||||
ArrayPrototypePush(results, siblingDesc);
|
results.push(siblingDesc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
childDesc = childDesc.parent;
|
childDesc = childDesc.parent;
|
||||||
|
@ -521,8 +503,7 @@ function wrapInner(fn) {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
const runningStepDescs = getRunningStepDescs();
|
const runningStepDescs = getRunningStepDescs();
|
||||||
const runningStepDescsWithSanitizers = ArrayPrototypeFilter(
|
const runningStepDescsWithSanitizers = runningStepDescs.filter(
|
||||||
runningStepDescs,
|
|
||||||
(d) => usesSanitizer(d),
|
(d) => usesSanitizer(d),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -541,10 +522,10 @@ function wrapInner(fn) {
|
||||||
failed: { hasSanitizersAndOverlaps: runningStepDescs.map(getFullName) },
|
failed: { hasSanitizersAndOverlaps: runningStepDescs.map(getFullName) },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
await fn(MapPrototypeGet(testStates, desc.id).context);
|
await fn(testStates.get(desc.id).context);
|
||||||
let failedSteps = 0;
|
let failedSteps = 0;
|
||||||
for (const childDesc of MapPrototypeGet(testStates, desc.id).children) {
|
for (const childDesc of testStates.get(desc.id).children) {
|
||||||
const state = MapPrototypeGet(testStates, childDesc.id);
|
const state = testStates.get(childDesc.id);
|
||||||
if (!state.completed) {
|
if (!state.completed) {
|
||||||
return { failed: "incompleteSteps" };
|
return { failed: "incompleteSteps" };
|
||||||
}
|
}
|
||||||
|
@ -571,7 +552,7 @@ function withPermissions(fn, permissions) {
|
||||||
const token = pledgePermissions(permissions);
|
const token = pledgePermissions(permissions);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await fn(...new SafeArrayIterator(params));
|
return await fn(...params);
|
||||||
} finally {
|
} finally {
|
||||||
restorePermissions(token);
|
restorePermissions(token);
|
||||||
}
|
}
|
||||||
|
@ -598,7 +579,7 @@ function escapeName(name) {
|
||||||
if (ch <= 13 && ch >= 8) {
|
if (ch <= 13 && ch >= 8) {
|
||||||
// Slow path: We do need to escape it
|
// Slow path: We do need to escape it
|
||||||
for (const [escape, replaceWith] of ESCAPE_ASCII_CHARS) {
|
for (const [escape, replaceWith] of ESCAPE_ASCII_CHARS) {
|
||||||
name = StringPrototypeReplaceAll(name, escape, replaceWith);
|
name = name.replaceAll(escape, replaceWith);
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -790,7 +771,7 @@ function testInner(
|
||||||
);
|
);
|
||||||
testDesc.id = registerTestIdRetBuf[0];
|
testDesc.id = registerTestIdRetBuf[0];
|
||||||
testDesc.origin = origin;
|
testDesc.origin = origin;
|
||||||
MapPrototypeSet(testStates, testDesc.id, {
|
testStates.set(testDesc.id, {
|
||||||
context: createTestContext(testDesc),
|
context: createTestContext(testDesc),
|
||||||
children: [],
|
children: [],
|
||||||
completed: false,
|
completed: false,
|
||||||
|
@ -951,11 +932,11 @@ function benchStats(n, highPrecision, usedExplicitTimers, avg, min, max, all) {
|
||||||
n,
|
n,
|
||||||
min,
|
min,
|
||||||
max,
|
max,
|
||||||
p75: all[MathCeil(n * (75 / 100)) - 1],
|
p75: all[Math.ceil(n * (75 / 100)) - 1],
|
||||||
p99: all[MathCeil(n * (99 / 100)) - 1],
|
p99: all[Math.ceil(n * (99 / 100)) - 1],
|
||||||
p995: all[MathCeil(n * (99.5 / 100)) - 1],
|
p995: all[Math.ceil(n * (99.5 / 100)) - 1],
|
||||||
p999: all[MathCeil(n * (99.9 / 100)) - 1],
|
p999: all[Math.ceil(n * (99.9 / 100)) - 1],
|
||||||
avg: !highPrecision ? (avg / n) : MathCeil(avg / n),
|
avg: !highPrecision ? (avg / n) : Math.ceil(avg / n),
|
||||||
highPrecision,
|
highPrecision,
|
||||||
usedExplicitTimers,
|
usedExplicitTimers,
|
||||||
};
|
};
|
||||||
|
@ -1042,7 +1023,7 @@ async function benchMeasure(timeBudget, fn, async, context) {
|
||||||
n++;
|
n++;
|
||||||
avg += measuredTime;
|
avg += measuredTime;
|
||||||
budget -= totalTime;
|
budget -= totalTime;
|
||||||
ArrayPrototypePush(all, measuredTime);
|
all.push(measuredTime);
|
||||||
if (measuredTime < min) min = measuredTime;
|
if (measuredTime < min) min = measuredTime;
|
||||||
if (measuredTime > max) max = measuredTime;
|
if (measuredTime > max) max = measuredTime;
|
||||||
}
|
}
|
||||||
|
@ -1065,7 +1046,7 @@ async function benchMeasure(timeBudget, fn, async, context) {
|
||||||
n++;
|
n++;
|
||||||
avg += measuredTime;
|
avg += measuredTime;
|
||||||
budget -= totalTime;
|
budget -= totalTime;
|
||||||
ArrayPrototypePush(all, measuredTime);
|
all.push(measuredTime);
|
||||||
if (measuredTime < min) min = measuredTime;
|
if (measuredTime < min) min = measuredTime;
|
||||||
if (measuredTime > max) max = measuredTime;
|
if (measuredTime > max) max = measuredTime;
|
||||||
}
|
}
|
||||||
|
@ -1086,7 +1067,7 @@ async function benchMeasure(timeBudget, fn, async, context) {
|
||||||
|
|
||||||
n++;
|
n++;
|
||||||
avg += iterationTime;
|
avg += iterationTime;
|
||||||
ArrayPrototypePush(all, iterationTime);
|
all.push(iterationTime);
|
||||||
if (iterationTime < min) min = iterationTime;
|
if (iterationTime < min) min = iterationTime;
|
||||||
if (iterationTime > max) max = iterationTime;
|
if (iterationTime > max) max = iterationTime;
|
||||||
budget -= iterationTime * lowPrecisionThresholdInNs;
|
budget -= iterationTime * lowPrecisionThresholdInNs;
|
||||||
|
@ -1103,7 +1084,7 @@ async function benchMeasure(timeBudget, fn, async, context) {
|
||||||
|
|
||||||
n++;
|
n++;
|
||||||
avg += iterationTime;
|
avg += iterationTime;
|
||||||
ArrayPrototypePush(all, iterationTime);
|
all.push(iterationTime);
|
||||||
if (iterationTime < min) min = iterationTime;
|
if (iterationTime < min) min = iterationTime;
|
||||||
if (iterationTime > max) max = iterationTime;
|
if (iterationTime > max) max = iterationTime;
|
||||||
budget -= iterationTime * lowPrecisionThresholdInNs;
|
budget -= iterationTime * lowPrecisionThresholdInNs;
|
||||||
|
@ -1126,7 +1107,7 @@ async function benchMeasure(timeBudget, fn, async, context) {
|
||||||
/** @param desc {BenchDescription} */
|
/** @param desc {BenchDescription} */
|
||||||
function createBenchContext(desc) {
|
function createBenchContext(desc) {
|
||||||
return {
|
return {
|
||||||
[SymbolToStringTag]: "BenchContext",
|
[Symbol.toStringTag]: "BenchContext",
|
||||||
name: desc.name,
|
name: desc.name,
|
||||||
origin: desc.origin,
|
origin: desc.origin,
|
||||||
start() {
|
start() {
|
||||||
|
@ -1215,7 +1196,7 @@ function usesSanitizer(desc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function stepReportResult(desc, result, elapsed) {
|
function stepReportResult(desc, result, elapsed) {
|
||||||
const state = MapPrototypeGet(testStates, desc.id);
|
const state = testStates.get(desc.id);
|
||||||
for (const childDesc of state.children) {
|
for (const childDesc of state.children) {
|
||||||
stepReportResult(childDesc, { failed: "incomplete" }, 0);
|
stepReportResult(childDesc, { failed: "incomplete" }, 0);
|
||||||
}
|
}
|
||||||
|
@ -1235,7 +1216,7 @@ function createTestContext(desc) {
|
||||||
let rootId;
|
let rootId;
|
||||||
let rootName;
|
let rootName;
|
||||||
if ("parent" in desc) {
|
if ("parent" in desc) {
|
||||||
parent = MapPrototypeGet(testStates, desc.parent.id).context;
|
parent = testStates.get(desc.parent.id).context;
|
||||||
level = desc.level;
|
level = desc.level;
|
||||||
rootId = desc.rootId;
|
rootId = desc.rootId;
|
||||||
rootName = desc.rootName;
|
rootName = desc.rootName;
|
||||||
|
@ -1246,7 +1227,7 @@ function createTestContext(desc) {
|
||||||
rootName = desc.name;
|
rootName = desc.name;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
[SymbolToStringTag]: "TestContext",
|
[Symbol.toStringTag]: "TestContext",
|
||||||
/**
|
/**
|
||||||
* The current test name.
|
* The current test name.
|
||||||
*/
|
*/
|
||||||
|
@ -1264,7 +1245,7 @@ function createTestContext(desc) {
|
||||||
* @param maybeFn {((t: TestContext) => void | Promise<void>) | undefined}
|
* @param maybeFn {((t: TestContext) => void | Promise<void>) | undefined}
|
||||||
*/
|
*/
|
||||||
async step(nameOrFnOrOptions, maybeFn) {
|
async step(nameOrFnOrOptions, maybeFn) {
|
||||||
if (MapPrototypeGet(testStates, desc.id).completed) {
|
if (testStates.get(desc.id).completed) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Cannot run test step after parent scope has finished execution. " +
|
"Cannot run test step after parent scope has finished execution. " +
|
||||||
"Ensure any `.step(...)` calls are executed before their parent scope completes execution.",
|
"Ensure any `.step(...)` calls are executed before their parent scope completes execution.",
|
||||||
|
@ -1273,7 +1254,7 @@ function createTestContext(desc) {
|
||||||
|
|
||||||
let stepDesc;
|
let stepDesc;
|
||||||
if (typeof nameOrFnOrOptions === "string") {
|
if (typeof nameOrFnOrOptions === "string") {
|
||||||
if (!(ObjectPrototypeIsPrototypeOf(FunctionPrototype, maybeFn))) {
|
if (!Object.prototype.isPrototypeOf.call(Function.prototype, maybeFn)) {
|
||||||
throw new TypeError("Expected function for second argument.");
|
throw new TypeError("Expected function for second argument.");
|
||||||
}
|
}
|
||||||
stepDesc = {
|
stepDesc = {
|
||||||
|
@ -1329,16 +1310,15 @@ function createTestContext(desc) {
|
||||||
failed: false,
|
failed: false,
|
||||||
completed: false,
|
completed: false,
|
||||||
};
|
};
|
||||||
MapPrototypeSet(testStates, stepDesc.id, state);
|
testStates.set(stepDesc.id, state);
|
||||||
ArrayPrototypePush(
|
testStates.get(stepDesc.parent.id).children.push(
|
||||||
MapPrototypeGet(testStates, stepDesc.parent.id).children,
|
|
||||||
stepDesc,
|
stepDesc,
|
||||||
);
|
);
|
||||||
|
|
||||||
ops.op_test_event_step_wait(stepDesc.id);
|
ops.op_test_event_step_wait(stepDesc.id);
|
||||||
const earlier = DateNow();
|
const earlier = Date.now();
|
||||||
const result = await stepDesc.fn(stepDesc);
|
const result = await stepDesc.fn(stepDesc);
|
||||||
const elapsed = DateNow() - earlier;
|
const elapsed = Date.now() - earlier;
|
||||||
state.failed = !!result.failed;
|
state.failed = !!result.failed;
|
||||||
stepReportResult(stepDesc, result, elapsed);
|
stepReportResult(stepDesc, result, elapsed);
|
||||||
return result == "ok";
|
return result == "ok";
|
||||||
|
|
Loading…
Reference in a new issue