mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-16 14:28:36 +02:00
141 lines
5.1 KiB
TypeScript
141 lines
5.1 KiB
TypeScript
import { WorkerScript } from "../../src/Netscript/WorkerScript";
|
|
import { NetscriptFunctions, type NSFull } from "../../src/NetscriptFunctions";
|
|
import type { ScriptFilePath } from "../../src/Paths/ScriptFilePath";
|
|
import { PlayerObject } from "../../src/PersonObjects/Player/PlayerObject";
|
|
import { Player, setPlayer } from "../../src/Player";
|
|
import { RunningScript } from "../../src/Script/RunningScript";
|
|
import { GetServerOrThrow, prestigeAllServers } from "../../src/Server/AllServers";
|
|
import { SpecialServers } from "../../src/Server/data/SpecialServers";
|
|
import { initSourceFiles } from "../../src/SourceFile/SourceFiles";
|
|
import { FormatsNeedToChange } from "../../src/ui/formatNumber";
|
|
import { Router } from "../../src/ui/GameRoot";
|
|
import { config } from "../../src/NetscriptJSEvaluator";
|
|
import type { NetscriptContext } from "../../src/Netscript/APIWrapper";
|
|
import { purchaseServer } from "../../src/Server/ServerPurchases";
|
|
import { purchaseHacknet } from "../../src/Hacknet/HacknetHelpers";
|
|
import { initForeignServers } from "../../src/Server/ServerHelpers";
|
|
import { generateNextPid } from "../../src/Netscript/Pid";
|
|
import { initBitNodeMultipliers } from "../../src/BitNode/BitNode";
|
|
import { resetGoPromises } from "../../src/Go/boardAnalysis/goAI";
|
|
import { enterBitNode } from "../../src/RedPill";
|
|
import { getDefaultBitNodeOptions } from "../../src/BitNode/BitNodeUtils";
|
|
|
|
declare const importActual: (typeof config)["doImport"];
|
|
|
|
export function fixDoImportIssue() {
|
|
// 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 = String((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.
|
|
config.doImport = importActual;
|
|
|
|
global.URL.createObjectURL = function (blob) {
|
|
return "data:text/javascript," + encodeURIComponent((blob as unknown as { code: string }).code);
|
|
};
|
|
}
|
|
|
|
export function initGameEnvironment() {
|
|
// We need to patch this function. Some APIs call it, but it only works properly after the main UI is loaded.
|
|
Router.toPage = () => {};
|
|
|
|
/**
|
|
* In src\ui\formatNumber.ts, there are some variables that need to be initialized before other functions can be
|
|
* called. We have to call FormatsNeedToChange.emit() to initialize those variables.
|
|
*/
|
|
FormatsNeedToChange.emit();
|
|
|
|
initSourceFiles();
|
|
}
|
|
|
|
export function setupBasicTestingEnvironment(
|
|
{ purchaseHacknetServer, purchasePServer } = { purchasePServer: false, purchaseHacknetServer: false },
|
|
): void {
|
|
// We need to delete all servers before calling initForeignServers.
|
|
prestigeAllServers();
|
|
setPlayer(new PlayerObject());
|
|
|
|
// Basic steps of initializing a new save file. These are the steps that we do in Engine.load() when there is no save
|
|
// data.
|
|
initBitNodeMultipliers();
|
|
Player.init();
|
|
initForeignServers(Player.getHomeComputer());
|
|
Player.reapplyAllAugmentations();
|
|
resetGoPromises();
|
|
|
|
// Grant SF4 for conveniently using Singularity APIs in tests.
|
|
Player.sourceFiles.set(4, 3);
|
|
// Simulate bitflume. This step is very important. It ensures all global states (e.g., Factions, Companies, BN mults)
|
|
// are reset.
|
|
enterBitNode(true, Player.bitNodeN, 1, getDefaultBitNodeOptions());
|
|
// Get some money.
|
|
Player.money = 1e15;
|
|
|
|
if (purchasePServer) {
|
|
purchaseServer("test-server-1", 2);
|
|
}
|
|
if (purchaseHacknetServer) {
|
|
Player.sourceFiles.set(9, 3);
|
|
purchaseHacknet();
|
|
}
|
|
}
|
|
|
|
export function getWorkerScriptAndNS(hostname: string = SpecialServers.Home): {
|
|
ws: WorkerScript;
|
|
ns: NSFull;
|
|
} {
|
|
const home = GetServerOrThrow(hostname);
|
|
home.maxRam = 1024;
|
|
const filePath = "test.js" as ScriptFilePath;
|
|
home.writeToScriptFile(filePath, "");
|
|
const script = home.scripts.get(filePath);
|
|
if (!script) {
|
|
throw new Error("Invalid script");
|
|
}
|
|
const runningScript = new RunningScript(script, 1024);
|
|
const workerScript = new WorkerScript(runningScript, generateNextPid(), NetscriptFunctions);
|
|
const ns = workerScript.env.vars;
|
|
if (!ns) {
|
|
throw new Error("Invalid NS instance");
|
|
}
|
|
return {
|
|
ws: workerScript,
|
|
ns,
|
|
};
|
|
}
|
|
|
|
export function getNS(hostname: string = SpecialServers.Home): NSFull {
|
|
return getWorkerScriptAndNS(hostname).ns;
|
|
}
|
|
|
|
export function getMockedNetscriptContext(
|
|
workerScriptLogFunction: (func: string, txt: () => string) => void = () => {},
|
|
): NetscriptContext {
|
|
return {
|
|
function: "",
|
|
functionPath: "",
|
|
workerScript: {
|
|
log: workerScriptLogFunction,
|
|
scriptRef: {
|
|
dependencies: [],
|
|
},
|
|
} as unknown as WorkerScript,
|
|
};
|
|
}
|
|
|
|
// WIP: Improve this function to get a better stack trace or use jest-expect-message
|
|
export function expectWithMessage(actual: unknown, expected: unknown, customMessage: string) {
|
|
try {
|
|
expect(actual).toStrictEqual(expected);
|
|
} catch (error) {
|
|
throw new Error(customMessage, { cause: error });
|
|
}
|
|
}
|