mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-19 12:45:45 +01:00
TEST: Add a NS2 test (finally) (#458)
This commit is contained in:
parent
c730d6ed82
commit
8c4b992d59
15
FixJSDOMEnvironment.ts
Normal file
15
FixJSDOMEnvironment.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import JSDOMEnvironment from "jest-environment-jsdom";
|
||||||
|
|
||||||
|
// https://github.com/facebook/jest/blob/v29.4.3/website/versioned_docs/version-29.4/Configuration.md#testenvironment-string
|
||||||
|
export default class FixJSDOMEnvironment extends JSDOMEnvironment {
|
||||||
|
constructor(...args: ConstructorParameters<typeof JSDOMEnvironment>) {
|
||||||
|
super(...args);
|
||||||
|
|
||||||
|
// FIXME https://github.com/nodejs/node/issues/35889
|
||||||
|
// Add missing importActual() function to mirror requireActual(),
|
||||||
|
// which lets us work around the ESM bug.
|
||||||
|
// Wrap the construction of the function in eval, so that transpilers
|
||||||
|
// don't touch the import() call.
|
||||||
|
this.global.importActual = eval("url => import(url)");
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,11 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
|
roots: ["<rootDir>/src/", "<rootDir>/test/"],
|
||||||
moduleFileExtensions: ["ts", "tsx", "js", "jsx"],
|
moduleFileExtensions: ["ts", "tsx", "js", "jsx"],
|
||||||
transform: {
|
transform: {
|
||||||
"^.+\\.(js|jsx|ts|tsx)$": "babel-jest",
|
"^.+\\.(js|jsx|ts|tsx)$": "babel-jest",
|
||||||
},
|
},
|
||||||
testPathIgnorePatterns: [".cypress", "node_modules", "dist"],
|
testPathIgnorePatterns: [".cypress", "node_modules", "dist"],
|
||||||
testEnvironment: "jsdom",
|
testEnvironment: "./FixJSDOMEnvironment.ts",
|
||||||
moduleNameMapper: {
|
moduleNameMapper: {
|
||||||
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
|
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
|
||||||
"<rootDir>/test/__mocks__/fileMock.js",
|
"<rootDir>/test/__mocks__/fileMock.js",
|
||||||
|
@ -18,6 +18,22 @@ function makeScriptBlob(code: string): Blob {
|
|||||||
return new Blob([code], { type: "text/javascript" });
|
return new Blob([code], { type: "text/javascript" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Webpack likes to turn the import into a require, which sort of
|
||||||
|
// but not really behaves like import. So we use a "magic comment"
|
||||||
|
// to disable that and leave it as a dynamic import.
|
||||||
|
//
|
||||||
|
// However, we need to be able to replace this implementation in tests. Ideally
|
||||||
|
// it would be fine, but Jest causes segfaults when using dynamic import: see
|
||||||
|
// https://github.com/nodejs/node/issues/35889 and
|
||||||
|
// https://github.com/facebook/jest/issues/11438
|
||||||
|
// import() is not a function, so it can't be replaced. We need this separate
|
||||||
|
// config object to provide a hook point.
|
||||||
|
export const config = {
|
||||||
|
doImport(url: string): Promise<ScriptModule> {
|
||||||
|
return import(/*webpackIgnore:true*/ url);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export async function compile(script: Script, scripts: Script[]): Promise<ScriptModule> {
|
export async function compile(script: Script, scripts: Script[]): Promise<ScriptModule> {
|
||||||
//!shouldCompile ensures that script.module is non-null, hence the "as".
|
//!shouldCompile ensures that script.module is non-null, hence the "as".
|
||||||
if (!shouldCompile(script, scripts)) return script.module as Promise<ScriptModule>;
|
if (!shouldCompile(script, scripts)) return script.module as Promise<ScriptModule>;
|
||||||
@ -36,12 +52,7 @@ export async function compile(script: Script, scripts: Script[]): Promise<Script
|
|||||||
script.url = uurls[uurls.length - 1].url;
|
script.url = uurls[uurls.length - 1].url;
|
||||||
// The URL at the top is the one we want to import. It will
|
// The URL at the top is the one we want to import. It will
|
||||||
// recursively import all the other modules in the urlStack.
|
// recursively import all the other modules in the urlStack.
|
||||||
//
|
script.module = config.doImport(uurls[uurls.length - 1].url);
|
||||||
// Webpack likes to turn the import into a require, which sort of
|
|
||||||
// but not really behaves like import. Particularly, it cannot
|
|
||||||
// load fully dynamic content. So we hide the import from webpack
|
|
||||||
// by placing it inside an eval call.
|
|
||||||
script.module = new Promise((resolve) => resolve(eval("import(uurls[uurls.length - 1].url)")));
|
|
||||||
script.dependencies = uurls;
|
script.dependencies = uurls;
|
||||||
return script.module;
|
return script.module;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,25 @@
|
|||||||
import { startWorkerScript } from "../../../src/NetscriptWorker";
|
import { startWorkerScript } from "../../../src/NetscriptWorker";
|
||||||
|
import { config as EvaluatorConfig } from "../../../src/NetscriptJSEvaluator";
|
||||||
import { Server } from "../../../src/Server/Server";
|
import { Server } from "../../../src/Server/Server";
|
||||||
import { RunningScript } from "../../../src/Script/RunningScript";
|
import { RunningScript } from "../../../src/Script/RunningScript";
|
||||||
import { AddToAllServers, DeleteServer } from "../../../src/Server/AllServers";
|
import { AddToAllServers, DeleteServer } from "../../../src/Server/AllServers";
|
||||||
import { WorkerScriptStartStopEventEmitter } from "../../../src/Netscript/WorkerScriptStartStopEventEmitter";
|
import { WorkerScriptStartStopEventEmitter } from "../../../src/Netscript/WorkerScriptStartStopEventEmitter";
|
||||||
import { AlertEvents } from "../../../src/ui/React/AlertManager";
|
import { AlertEvents } from "../../../src/ui/React/AlertManager";
|
||||||
|
|
||||||
|
// Replace Blob/ObjectURL functions, because they don't work natively in Jest
|
||||||
|
global.Blob = class extends Blob {
|
||||||
|
code: string;
|
||||||
|
constructor(blobParts?: BlobPart[], options?: BlobPropertyBag) {
|
||||||
|
super();
|
||||||
|
this.code = (blobParts ?? [])[0] + "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
global.URL.revokeObjectURL = function () {};
|
||||||
|
// Critical: We have to overwrite this, otherwise we get Jest's hooked
|
||||||
|
// implementation, which will not work without passing special flags to Node,
|
||||||
|
// and tends to crash even if you do.
|
||||||
|
EvaluatorConfig.doImport = importActual;
|
||||||
|
|
||||||
test.each([
|
test.each([
|
||||||
{
|
{
|
||||||
name: "NS1 test /w import",
|
name: "NS1 test /w import",
|
||||||
@ -30,24 +45,40 @@ test.each([
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
/* { // Doesn't work, due to issues with URL.createObjectURL
|
{
|
||||||
name: "NS2 test, no import",
|
name: "NS2 test /w import",
|
||||||
expected: [
|
expected: ["false home 8", "Script finished running"],
|
||||||
"false home 8",
|
|
||||||
"Script finished running",
|
|
||||||
],
|
|
||||||
scripts: [
|
scripts: [
|
||||||
{name: "simple_test.js", code: `
|
{
|
||||||
|
name: "import.js",
|
||||||
|
code: `
|
||||||
|
export function getInfo(ns) {
|
||||||
|
return ns.stock.has4SData();
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "simple_test.js",
|
||||||
|
code: `
|
||||||
|
import { getInfo } from "./import.js";
|
||||||
|
|
||||||
export async function main(ns) {
|
export async function main(ns) {
|
||||||
var access = ns.stock.has4SData();
|
var access = getInfo(ns);
|
||||||
var server = ns.getServer();
|
var server = ns.getServer();
|
||||||
ns.printf("%s %s %d", access, server.hostname, server.maxRam);
|
ns.printf("%s %s %d", access, server.hostname, server.maxRam);
|
||||||
}
|
}
|
||||||
`},
|
`,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},*/
|
},
|
||||||
])("Netscript execution: $name", async function ({ expected: expectedLog, scripts }) {
|
])("Netscript execution: $name", async function ({ expected: expectedLog, scripts }) {
|
||||||
let server, eventDelete, alertDelete;
|
global.URL.createObjectURL = function (blob) {
|
||||||
|
return "data:text/javascript," + encodeURIComponent(blob.code);
|
||||||
|
};
|
||||||
|
|
||||||
|
let server;
|
||||||
|
let eventDelete = () => {};
|
||||||
|
let alertDelete = () => {};
|
||||||
try {
|
try {
|
||||||
const alerted = new Promise((resolve) => {
|
const alerted = new Promise((resolve) => {
|
||||||
alertDelete = AlertEvents.subscribe((x) => resolve(x));
|
alertDelete = AlertEvents.subscribe((x) => resolve(x));
|
||||||
@ -75,8 +106,8 @@ test.each([
|
|||||||
expect(result).toBeNull();
|
expect(result).toBeNull();
|
||||||
expect(runningScript.logs).toEqual(expectedLog);
|
expect(runningScript.logs).toEqual(expectedLog);
|
||||||
} finally {
|
} finally {
|
||||||
if (eventDelete) eventDelete();
|
eventDelete();
|
||||||
if (server) DeleteServer(server.hostname);
|
if (server) DeleteServer(server.hostname);
|
||||||
if (alertDelete) alertDelete();
|
alertDelete();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user