2023-05-16 00:06:57 +02:00
|
|
|
import type { Script } from "../../../src/Script/Script";
|
|
|
|
import type { ScriptFilePath } from "../../../src/Paths/ScriptFilePath";
|
2022-11-29 13:32:08 +01:00
|
|
|
import { startWorkerScript } from "../../../src/NetscriptWorker";
|
2023-05-01 01:31:29 +02:00
|
|
|
import { workerScripts } from "../../../src/Netscript/WorkerScripts";
|
2023-04-01 13:45:23 +02:00
|
|
|
import { config as EvaluatorConfig } from "../../../src/NetscriptJSEvaluator";
|
2022-11-29 13:32:08 +01:00
|
|
|
import { Server } from "../../../src/Server/Server";
|
|
|
|
import { RunningScript } from "../../../src/Script/RunningScript";
|
|
|
|
import { AddToAllServers, DeleteServer } from "../../../src/Server/AllServers";
|
|
|
|
import { AlertEvents } from "../../../src/ui/React/AlertManager";
|
2023-05-16 00:06:57 +02:00
|
|
|
|
2023-10-08 00:52:48 +02:00
|
|
|
declare const importActual: (typeof EvaluatorConfig)["doImport"];
|
2022-11-29 13:32:08 +01:00
|
|
|
|
2023-04-01 13:45:23 +02:00
|
|
|
// Replace Blob/ObjectURL functions, because they don't work natively in Jest
|
|
|
|
global.Blob = class extends Blob {
|
|
|
|
code: string;
|
2024-11-27 09:06:11 +01:00
|
|
|
constructor(blobParts?: BlobPart[], __options?: BlobPropertyBag) {
|
2023-04-01 13:45:23 +02:00
|
|
|
super();
|
2024-11-27 09:06:11 +01:00
|
|
|
this.code = String((blobParts ?? [])[0]);
|
2023-04-01 13:45:23 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
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;
|
|
|
|
|
2022-11-29 13:32:08 +01:00
|
|
|
test.each([
|
|
|
|
{
|
|
|
|
name: "NS1 test /w import",
|
|
|
|
expected: ["false home 8", "Script finished running"],
|
|
|
|
scripts: [
|
|
|
|
{
|
|
|
|
name: "import.script",
|
|
|
|
code: `
|
|
|
|
export function getInfo() {
|
|
|
|
return stock.has4SData();
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "simple_test.script",
|
|
|
|
code: `
|
|
|
|
import { getInfo } from "import.script";
|
|
|
|
|
|
|
|
var access = getInfo();
|
|
|
|
var server = getServer();
|
|
|
|
printf("%s %s %d", access, server.hostname, server.maxRam);
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
2023-04-01 13:45:23 +02:00
|
|
|
{
|
|
|
|
name: "NS2 test /w import",
|
|
|
|
expected: ["false home 8", "Script finished running"],
|
2022-11-29 13:32:08 +01:00
|
|
|
scripts: [
|
2023-04-01 13:45:23 +02:00
|
|
|
{
|
|
|
|
name: "import.js",
|
|
|
|
code: `
|
|
|
|
export function getInfo(ns) {
|
|
|
|
return ns.stock.has4SData();
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "simple_test.js",
|
|
|
|
code: `
|
|
|
|
import { getInfo } from "./import.js";
|
|
|
|
|
2022-11-29 13:32:08 +01:00
|
|
|
export async function main(ns) {
|
2023-04-01 13:45:23 +02:00
|
|
|
var access = getInfo(ns);
|
2022-11-29 13:32:08 +01:00
|
|
|
var server = ns.getServer();
|
|
|
|
ns.printf("%s %s %d", access, server.hostname, server.maxRam);
|
|
|
|
}
|
2023-04-01 13:45:23 +02:00
|
|
|
`,
|
|
|
|
},
|
2022-11-29 13:32:08 +01:00
|
|
|
],
|
2023-04-01 13:45:23 +02:00
|
|
|
},
|
2022-11-29 13:32:08 +01:00
|
|
|
])("Netscript execution: $name", async function ({ expected: expectedLog, scripts }) {
|
2023-04-01 13:45:23 +02:00
|
|
|
global.URL.createObjectURL = function (blob) {
|
2024-11-27 09:06:11 +01:00
|
|
|
return "data:text/javascript," + encodeURIComponent((blob as unknown as { code: string }).code);
|
2023-04-01 13:45:23 +02:00
|
|
|
};
|
|
|
|
|
FILES: Path rework & typesafety (#479)
* Added new types for various file paths, all in the Paths folder.
* TypeSafety and other helper functions related to these types
* Added basic globbing support with * and ?. Currently only implemented for Script/Text, on nano and download terminal commands
* Enforcing the new types throughout the codebase, plus whatever rewrites happened along the way
* Server.textFiles is now a map
* TextFile no longer uses a fn property, now it is filename
* Added a shared ContentFile interface for shared functionality between TextFile and Script.
* related to ContentFile change above, the player is now allowed to move a text file to a script file and vice versa.
* File paths no longer conditionally start with slashes, and all directory names other than root have ending slashes. The player is still able to provide paths starting with / but this now indicates that the player is specifying an absolute path instead of one relative to root.
* Singularized the MessageFilename and LiteratureName enums
* Because they now only accept correct types, server.writeToXFile functions now always succeed (the only reasons they could fail before were invalid filepath).
* Fix several issues with tab completion, which included pretty much a complete rewrite
* Changed the autocomplete display options so there's less chance it clips outside the display area.
* Turned CompletedProgramName into an enum.
* Got rid of programsMetadata, and programs and DarkWebItems are now initialized immediately instead of relying on initializers called from the engine.
* For any executable (program, cct, or script file) pathing can be used directly to execute without using the run command (previously the command had to start with ./ and it wasn't actually using pathing).
2023-04-24 16:26:57 +02:00
|
|
|
let server = {} as Server;
|
2024-11-27 09:06:11 +01:00
|
|
|
const eventDelete = () => {};
|
2023-04-01 13:45:23 +02:00
|
|
|
let alertDelete = () => {};
|
2022-11-29 13:32:08 +01:00
|
|
|
try {
|
|
|
|
const alerted = new Promise((resolve) => {
|
|
|
|
alertDelete = AlertEvents.subscribe((x) => resolve(x));
|
|
|
|
});
|
2023-03-06 04:39:42 +01:00
|
|
|
server = new Server({ hostname: "home", adminRights: true, maxRam: 8 });
|
2022-11-29 13:32:08 +01:00
|
|
|
AddToAllServers(server);
|
|
|
|
for (const s of scripts) {
|
FILES: Path rework & typesafety (#479)
* Added new types for various file paths, all in the Paths folder.
* TypeSafety and other helper functions related to these types
* Added basic globbing support with * and ?. Currently only implemented for Script/Text, on nano and download terminal commands
* Enforcing the new types throughout the codebase, plus whatever rewrites happened along the way
* Server.textFiles is now a map
* TextFile no longer uses a fn property, now it is filename
* Added a shared ContentFile interface for shared functionality between TextFile and Script.
* related to ContentFile change above, the player is now allowed to move a text file to a script file and vice versa.
* File paths no longer conditionally start with slashes, and all directory names other than root have ending slashes. The player is still able to provide paths starting with / but this now indicates that the player is specifying an absolute path instead of one relative to root.
* Singularized the MessageFilename and LiteratureName enums
* Because they now only accept correct types, server.writeToXFile functions now always succeed (the only reasons they could fail before were invalid filepath).
* Fix several issues with tab completion, which included pretty much a complete rewrite
* Changed the autocomplete display options so there's less chance it clips outside the display area.
* Turned CompletedProgramName into an enum.
* Got rid of programsMetadata, and programs and DarkWebItems are now initialized immediately instead of relying on initializers called from the engine.
* For any executable (program, cct, or script file) pathing can be used directly to execute without using the run command (previously the command had to start with ./ and it wasn't actually using pathing).
2023-04-24 16:26:57 +02:00
|
|
|
expect(server.writeToScriptFile(s.name as ScriptFilePath, s.code)).toEqual({ overwritten: false });
|
2022-11-29 13:32:08 +01:00
|
|
|
}
|
|
|
|
|
FILES: Path rework & typesafety (#479)
* Added new types for various file paths, all in the Paths folder.
* TypeSafety and other helper functions related to these types
* Added basic globbing support with * and ?. Currently only implemented for Script/Text, on nano and download terminal commands
* Enforcing the new types throughout the codebase, plus whatever rewrites happened along the way
* Server.textFiles is now a map
* TextFile no longer uses a fn property, now it is filename
* Added a shared ContentFile interface for shared functionality between TextFile and Script.
* related to ContentFile change above, the player is now allowed to move a text file to a script file and vice versa.
* File paths no longer conditionally start with slashes, and all directory names other than root have ending slashes. The player is still able to provide paths starting with / but this now indicates that the player is specifying an absolute path instead of one relative to root.
* Singularized the MessageFilename and LiteratureName enums
* Because they now only accept correct types, server.writeToXFile functions now always succeed (the only reasons they could fail before were invalid filepath).
* Fix several issues with tab completion, which included pretty much a complete rewrite
* Changed the autocomplete display options so there's less chance it clips outside the display area.
* Turned CompletedProgramName into an enum.
* Got rid of programsMetadata, and programs and DarkWebItems are now initialized immediately instead of relying on initializers called from the engine.
* For any executable (program, cct, or script file) pathing can be used directly to execute without using the run command (previously the command had to start with ./ and it wasn't actually using pathing).
2023-04-24 16:26:57 +02:00
|
|
|
const script = server.scripts.get(scripts[scripts.length - 1].name as ScriptFilePath) as Script;
|
2022-11-29 13:32:08 +01:00
|
|
|
expect(script.filename).toEqual(scripts[scripts.length - 1].name);
|
|
|
|
|
2023-03-06 04:39:42 +01:00
|
|
|
const ramUsage = script.getRamUsage(server.scripts);
|
2023-04-18 09:19:45 +02:00
|
|
|
if (!ramUsage) throw new Error(`ramUsage calculated to be ${ramUsage}`);
|
2024-11-27 09:06:11 +01:00
|
|
|
const runningScript = new RunningScript(script, ramUsage);
|
2023-05-01 01:31:29 +02:00
|
|
|
const pid = startWorkerScript(runningScript, server);
|
|
|
|
expect(pid).toBeGreaterThan(0);
|
|
|
|
// Manually attach an atExit to the now-created WorkerScript, so we can
|
|
|
|
// await script death.
|
|
|
|
const ws = workerScripts.get(pid);
|
|
|
|
expect(ws).toBeDefined();
|
2024-03-06 01:22:45 +01:00
|
|
|
const result = await Promise.race([
|
|
|
|
alerted,
|
2024-11-27 09:06:11 +01:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- ws was asserted above
|
2024-03-06 01:22:45 +01:00
|
|
|
new Promise<void>((resolve) => (ws!.atExit = new Map([["default", resolve]]))),
|
|
|
|
]);
|
2022-11-29 13:32:08 +01:00
|
|
|
// If an error alert was thrown, we catch it here.
|
2023-05-01 01:31:29 +02:00
|
|
|
expect(result).not.toBeDefined();
|
2022-11-29 13:32:08 +01:00
|
|
|
expect(runningScript.logs).toEqual(expectedLog);
|
|
|
|
} finally {
|
2023-04-01 13:45:23 +02:00
|
|
|
eventDelete();
|
2022-11-29 13:32:08 +01:00
|
|
|
if (server) DeleteServer(server.hostname);
|
2023-04-01 13:45:23 +02:00
|
|
|
alertDelete();
|
2022-11-29 13:32:08 +01:00
|
|
|
}
|
|
|
|
});
|