mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-18 20:25:45 +01:00
BUGFIX: fix relative imports (#1305)
Relative paths work in imports, at last.
This commit is contained in:
parent
76ce2f9955
commit
f40d4f8e92
@ -8,7 +8,6 @@ import { parse } from "acorn";
|
|||||||
import { LoadedModule, ScriptURL, ScriptModule } from "./Script/LoadedModule";
|
import { LoadedModule, ScriptURL, ScriptModule } from "./Script/LoadedModule";
|
||||||
import { Script } from "./Script/Script";
|
import { Script } from "./Script/Script";
|
||||||
import { ScriptFilePath, resolveScriptFilePath } from "./Paths/ScriptFilePath";
|
import { ScriptFilePath, resolveScriptFilePath } from "./Paths/ScriptFilePath";
|
||||||
import { root } from "./Paths/Directory";
|
|
||||||
|
|
||||||
// Acorn type def is straight up incomplete so we have to fill with our own.
|
// Acorn type def is straight up incomplete so we have to fill with our own.
|
||||||
export type Node = any;
|
export type Node = any;
|
||||||
@ -125,7 +124,7 @@ function generateLoadedModule(script: Script, scripts: Map<ScriptFilePath, Scrip
|
|||||||
let newCode = script.code;
|
let newCode = script.code;
|
||||||
// Loop through each node and replace the script name with a blob url.
|
// Loop through each node and replace the script name with a blob url.
|
||||||
for (const node of importNodes) {
|
for (const node of importNodes) {
|
||||||
const filename = resolveScriptFilePath(node.filename, root, ".js");
|
const filename = resolveScriptFilePath(node.filename, script.filename, ".js");
|
||||||
if (!filename) throw new Error(`Failed to parse import: ${node.filename}`);
|
if (!filename) throw new Error(`Failed to parse import: ${node.filename}`);
|
||||||
|
|
||||||
// Find the corresponding script.
|
// Find the corresponding script.
|
||||||
@ -149,6 +148,7 @@ function generateLoadedModule(script: Script, scripts: Map<ScriptFilePath, Scrip
|
|||||||
// script dedupe properly.
|
// script dedupe properly.
|
||||||
const adjustedCode = newCode + `\n//# sourceURL=${script.server}/${script.filename}`;
|
const adjustedCode = newCode + `\n//# sourceURL=${script.server}/${script.filename}`;
|
||||||
// At this point we have the full code and can construct a new blob / assign the URL.
|
// At this point we have the full code and can construct a new blob / assign the URL.
|
||||||
|
|
||||||
const url = URL.createObjectURL(makeScriptBlob(adjustedCode)) as ScriptURL;
|
const url = URL.createObjectURL(makeScriptBlob(adjustedCode)) as ScriptURL;
|
||||||
const module = config.doImport(url).catch((e) => {
|
const module = config.doImport(url).catch((e) => {
|
||||||
script.invalidateModule();
|
script.invalidateModule();
|
||||||
|
@ -14,7 +14,7 @@ import { RamCosts, RamCostConstants } from "../Netscript/RamCostGenerator";
|
|||||||
import { Script } from "./Script";
|
import { Script } from "./Script";
|
||||||
import { Node } from "../NetscriptJSEvaluator";
|
import { Node } from "../NetscriptJSEvaluator";
|
||||||
import { ScriptFilePath, resolveScriptFilePath } from "../Paths/ScriptFilePath";
|
import { ScriptFilePath, resolveScriptFilePath } from "../Paths/ScriptFilePath";
|
||||||
import { root } from "../Paths/Directory";
|
import { ServerName } from "../Types/strings";
|
||||||
|
|
||||||
export interface RamUsageEntry {
|
export interface RamUsageEntry {
|
||||||
type: "ns" | "dom" | "fn" | "misc";
|
type: "ns" | "dom" | "fn" | "misc";
|
||||||
@ -56,12 +56,21 @@ function getNumericCost(cost: number | (() => number)): number {
|
|||||||
* Parses code into an AST and walks through it recursively to calculate
|
* Parses code into an AST and walks through it recursively to calculate
|
||||||
* RAM usage. Also accounts for imported modules.
|
* RAM usage. Also accounts for imported modules.
|
||||||
* @param otherScripts - All other scripts on the server. Used to account for imported scripts
|
* @param otherScripts - All other scripts on the server. Used to account for imported scripts
|
||||||
* @param code - The code being parsed */
|
* @param code - The code being parsed
|
||||||
function parseOnlyRamCalculate(otherScripts: Map<ScriptFilePath, Script>, code: string, ns1?: boolean): RamCalculation {
|
* @param scriptname - The name of the script that ram needs to be added to
|
||||||
|
* @param server - Servername of the scripts for Error Message
|
||||||
|
* */
|
||||||
|
function parseOnlyRamCalculate(
|
||||||
|
otherScripts: Map<ScriptFilePath, Script>,
|
||||||
|
code: string,
|
||||||
|
scriptname: ScriptFilePath,
|
||||||
|
server: ServerName,
|
||||||
|
ns1?: boolean,
|
||||||
|
): RamCalculation {
|
||||||
/**
|
/**
|
||||||
* Maps dependent identifiers to their dependencies.
|
* Maps dependent identifiers to their dependencies.
|
||||||
*
|
*
|
||||||
* The initial identifier is __SPECIAL_INITIAL_MODULE__.__GLOBAL__.
|
* The initial identifier is <name of the main script>.__GLOBAL__.
|
||||||
* It depends on all the functions declared in the module, all the global scopes
|
* It depends on all the functions declared in the module, all the global scopes
|
||||||
* of its imports, and any identifiers referenced in this global scope. Each
|
* of its imports, and any identifiers referenced in this global scope. Each
|
||||||
* function depends on all the identifiers referenced internally.
|
* function depends on all the identifiers referenced internally.
|
||||||
@ -74,10 +83,10 @@ function parseOnlyRamCalculate(otherScripts: Map<ScriptFilePath, Script>, code:
|
|||||||
const completedParses = new Set();
|
const completedParses = new Set();
|
||||||
|
|
||||||
// Scripts we've discovered that need to be parsed.
|
// Scripts we've discovered that need to be parsed.
|
||||||
const parseQueue: string[] = [];
|
const parseQueue: ScriptFilePath[] = [];
|
||||||
// Parses a chunk of code with a given module name, and updates parseQueue and dependencyMap.
|
// Parses a chunk of code with a given module name, and updates parseQueue and dependencyMap.
|
||||||
function parseCode(code: string, moduleName: string): void {
|
function parseCode(code: string, moduleName: ScriptFilePath): void {
|
||||||
const result = parseOnlyCalculateDeps(code, moduleName);
|
const result = parseOnlyCalculateDeps(code, moduleName, ns1);
|
||||||
completedParses.add(moduleName);
|
completedParses.add(moduleName);
|
||||||
|
|
||||||
// Add any additional modules to the parse queue;
|
// Add any additional modules to the parse queue;
|
||||||
@ -92,7 +101,7 @@ function parseOnlyRamCalculate(otherScripts: Map<ScriptFilePath, Script>, code:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse the initial module, which is the "main" script that is being run
|
// Parse the initial module, which is the "main" script that is being run
|
||||||
const initialModule = "__SPECIAL_INITIAL_MODULE__";
|
const initialModule = scriptname;
|
||||||
parseCode(code, initialModule);
|
parseCode(code, initialModule);
|
||||||
|
|
||||||
// Process additional modules, which occurs if the "main" script has any imports
|
// Process additional modules, which occurs if the "main" script has any imports
|
||||||
@ -101,21 +110,19 @@ function parseOnlyRamCalculate(otherScripts: Map<ScriptFilePath, Script>, code:
|
|||||||
if (nextModule === undefined) throw new Error("nextModule should not be undefined");
|
if (nextModule === undefined) throw new Error("nextModule should not be undefined");
|
||||||
if (nextModule.startsWith("https://") || nextModule.startsWith("http://")) continue;
|
if (nextModule.startsWith("https://") || nextModule.startsWith("http://")) continue;
|
||||||
|
|
||||||
// Using root as the path base right now. Difficult to implement
|
const script = otherScripts.get(nextModule);
|
||||||
const filename = resolveScriptFilePath(nextModule, root, ns1 ? ".script" : ".js");
|
|
||||||
if (!filename) {
|
|
||||||
return { errorCode: RamCalculationErrorCode.ImportError, errorMessage: `Invalid import path: "${nextModule}"` };
|
|
||||||
}
|
|
||||||
const script = otherScripts.get(filename);
|
|
||||||
if (!script) {
|
if (!script) {
|
||||||
return { errorCode: RamCalculationErrorCode.ImportError, errorMessage: `No such file on server: "${filename}"` };
|
return {
|
||||||
|
errorCode: RamCalculationErrorCode.ImportError,
|
||||||
|
errorMessage: `File: "${nextModule}" not found on server: ${server}`,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
parseCode(script.code, nextModule);
|
parseCode(script.code, nextModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, walk the reference map and generate a ram cost. The initial set of keys to scan
|
// Finally, walk the reference map and generate a ram cost. The initial set of keys to scan
|
||||||
// are those that start with __SPECIAL_INITIAL_MODULE__.
|
// are those that start with the name of the main script.
|
||||||
let ram = RamCostConstants.Base;
|
let ram = RamCostConstants.Base;
|
||||||
const detailedCosts: RamUsageEntry[] = [{ type: "misc", name: "baseCost", cost: RamCostConstants.Base }];
|
const detailedCosts: RamUsageEntry[] = [{ type: "misc", name: "baseCost", cost: RamCostConstants.Base }];
|
||||||
const unresolvedRefs = Object.keys(dependencyMap).filter((s) => s.startsWith(initialModule));
|
const unresolvedRefs = Object.keys(dependencyMap).filter((s) => s.startsWith(initialModule));
|
||||||
@ -250,7 +257,7 @@ export function checkInfiniteLoop(code: string): number[] {
|
|||||||
|
|
||||||
interface ParseDepsResult {
|
interface ParseDepsResult {
|
||||||
dependencyMap: Record<string, Set<string> | undefined>;
|
dependencyMap: Record<string, Set<string> | undefined>;
|
||||||
additionalModules: string[];
|
additionalModules: ScriptFilePath[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -259,7 +266,7 @@ interface ParseDepsResult {
|
|||||||
* for RAM usage calculations. It also returns an array of additional modules
|
* for RAM usage calculations. It also returns an array of additional modules
|
||||||
* that need to be parsed (i.e. are 'import'ed scripts).
|
* that need to be parsed (i.e. are 'import'ed scripts).
|
||||||
*/
|
*/
|
||||||
function parseOnlyCalculateDeps(code: string, currentModule: string): ParseDepsResult {
|
function parseOnlyCalculateDeps(code: string, currentModule: ScriptFilePath, ns1?: boolean): ParseDepsResult {
|
||||||
const ast = parse(code, { sourceType: "module", ecmaVersion: "latest" });
|
const ast = parse(code, { sourceType: "module", ecmaVersion: "latest" });
|
||||||
// Everything from the global scope goes in ".". Everything else goes in ".function", where only
|
// Everything from the global scope goes in ".". Everything else goes in ".function", where only
|
||||||
// the outermost layer of functions counts.
|
// the outermost layer of functions counts.
|
||||||
@ -271,7 +278,7 @@ function parseOnlyCalculateDeps(code: string, currentModule: string): ParseDepsR
|
|||||||
// Filled when we import names from other modules.
|
// Filled when we import names from other modules.
|
||||||
const internalToExternal: Record<string, string | undefined> = {};
|
const internalToExternal: Record<string, string | undefined> = {};
|
||||||
|
|
||||||
const additionalModules: string[] = [];
|
const additionalModules: ScriptFilePath[] = [];
|
||||||
|
|
||||||
// References get added pessimistically. They are added for thisModule.name, name, and for
|
// References get added pessimistically. They are added for thisModule.name, name, and for
|
||||||
// any aliases.
|
// any aliases.
|
||||||
@ -338,7 +345,12 @@ function parseOnlyCalculateDeps(code: string, currentModule: string): ParseDepsR
|
|||||||
Object.assign(
|
Object.assign(
|
||||||
{
|
{
|
||||||
ImportDeclaration: (node: Node, st: State) => {
|
ImportDeclaration: (node: Node, st: State) => {
|
||||||
const importModuleName = node.source.value;
|
const importModuleName = resolveScriptFilePath(node.source.value, currentModule, ns1 ? ".script" : ".js");
|
||||||
|
if (!importModuleName)
|
||||||
|
throw new Error(
|
||||||
|
`ScriptFilePath couldnt be resolved in ImportDeclaration. Value: ${node.source.value} ScriptFilePath: ${currentModule}`,
|
||||||
|
);
|
||||||
|
|
||||||
additionalModules.push(importModuleName);
|
additionalModules.push(importModuleName);
|
||||||
|
|
||||||
// This module's global scope refers to that module's global scope, no matter how we
|
// This module's global scope refers to that module's global scope, no matter how we
|
||||||
@ -397,16 +409,21 @@ function parseOnlyCalculateDeps(code: string, currentModule: string): ParseDepsR
|
|||||||
/**
|
/**
|
||||||
* Calculate's a scripts RAM Usage
|
* Calculate's a scripts RAM Usage
|
||||||
* @param {string} code - The script's code
|
* @param {string} code - The script's code
|
||||||
|
* @param {ScriptFilePath} scriptname - The script's name. Used to resolve relative paths
|
||||||
* @param {Script[]} otherScripts - All other scripts on the server.
|
* @param {Script[]} otherScripts - All other scripts on the server.
|
||||||
* Used to account for imported scripts
|
* Used to account for imported scripts
|
||||||
|
* @param {ServerName} server - Servername of the scripts for Error Message
|
||||||
|
* @param {boolean} ns1 - Deprecated: is the fileExtension .script or .js
|
||||||
*/
|
*/
|
||||||
export function calculateRamUsage(
|
export function calculateRamUsage(
|
||||||
code: string,
|
code: string,
|
||||||
|
scriptname: ScriptFilePath,
|
||||||
otherScripts: Map<ScriptFilePath, Script>,
|
otherScripts: Map<ScriptFilePath, Script>,
|
||||||
|
server: ServerName,
|
||||||
ns1?: boolean,
|
ns1?: boolean,
|
||||||
): RamCalculation {
|
): RamCalculation {
|
||||||
try {
|
try {
|
||||||
return parseOnlyRamCalculate(otherScripts, code, ns1);
|
return parseOnlyRamCalculate(otherScripts, code, scriptname, server, ns1);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return {
|
return {
|
||||||
errorCode: RamCalculationErrorCode.SyntaxError,
|
errorCode: RamCalculationErrorCode.SyntaxError,
|
||||||
|
@ -73,7 +73,13 @@ export class Script implements ContentFile {
|
|||||||
* @param {Script[]} otherScripts - Other scripts on the server. Used to process imports
|
* @param {Script[]} otherScripts - Other scripts on the server. Used to process imports
|
||||||
*/
|
*/
|
||||||
updateRamUsage(otherScripts: Map<ScriptFilePath, Script>): void {
|
updateRamUsage(otherScripts: Map<ScriptFilePath, Script>): void {
|
||||||
const ramCalc = calculateRamUsage(this.code, otherScripts, this.filename.endsWith(".script"));
|
const ramCalc = calculateRamUsage(
|
||||||
|
this.code,
|
||||||
|
this.filename,
|
||||||
|
otherScripts,
|
||||||
|
this.server,
|
||||||
|
this.filename.endsWith(".script"),
|
||||||
|
);
|
||||||
if (ramCalc.cost && ramCalc.cost >= RamCostConstants.Base) {
|
if (ramCalc.cost && ramCalc.cost >= RamCostConstants.Base) {
|
||||||
this.ramUsage = roundToTwo(ramCalc.cost);
|
this.ramUsage = roundToTwo(ramCalc.cost);
|
||||||
this.ramUsageEntries = ramCalc.entries as RamUsageEntry[];
|
this.ramUsageEntries = ramCalc.entries as RamUsageEntry[];
|
||||||
|
@ -8,11 +8,13 @@ import { useBoolean } from "../../ui/React/hooks";
|
|||||||
import { BaseServer } from "../../Server/BaseServer";
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
|
|
||||||
import { Options } from "./Options";
|
import { Options } from "./Options";
|
||||||
|
import { FilePath } from "../../Paths/FilePath";
|
||||||
|
import { hasScriptExtension } from "../../Paths/ScriptFilePath";
|
||||||
|
|
||||||
export interface ScriptEditorContextShape {
|
export interface ScriptEditorContextShape {
|
||||||
ram: string;
|
ram: string;
|
||||||
ramEntries: string[][];
|
ramEntries: string[][];
|
||||||
updateRAM: (newCode: string | null, server: BaseServer | null) => void;
|
updateRAM: (newCode: string | null, filename: FilePath | null, server: BaseServer | null) => void;
|
||||||
|
|
||||||
isUpdatingRAM: boolean;
|
isUpdatingRAM: boolean;
|
||||||
startUpdatingRAM: () => void;
|
startUpdatingRAM: () => void;
|
||||||
@ -28,14 +30,13 @@ export function ScriptEditorContextProvider({ children, vim }: { children: React
|
|||||||
const [ram, setRAM] = useState("RAM: ???");
|
const [ram, setRAM] = useState("RAM: ???");
|
||||||
const [ramEntries, setRamEntries] = useState<string[][]>([["???", ""]]);
|
const [ramEntries, setRamEntries] = useState<string[][]>([["???", ""]]);
|
||||||
|
|
||||||
const updateRAM: ScriptEditorContextShape["updateRAM"] = (newCode, server) => {
|
const updateRAM: ScriptEditorContextShape["updateRAM"] = (newCode, filename, server) => {
|
||||||
if (newCode === null || server === null) {
|
if (newCode == null || filename == null || server == null || !hasScriptExtension(filename)) {
|
||||||
setRAM("N/A");
|
setRAM("N/A");
|
||||||
setRamEntries([["N/A", ""]]);
|
setRamEntries([["N/A", ""]]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const ramUsage = calculateRamUsage(newCode, filename, server.scripts, server.hostname);
|
||||||
const ramUsage = calculateRamUsage(newCode, server.scripts);
|
|
||||||
if (ramUsage.cost && ramUsage.cost > 0) {
|
if (ramUsage.cost && ramUsage.cost > 0) {
|
||||||
const entries = ramUsage.entries?.sort((a, b) => b.cost - a.cost) ?? [];
|
const entries = ramUsage.entries?.sort((a, b) => b.cost - a.cost) ?? [];
|
||||||
const entriesDisp = [];
|
const entriesDisp = [];
|
||||||
|
@ -143,6 +143,7 @@ function Root(props: IProps): React.ReactElement {
|
|||||||
infLoop(newCode);
|
infLoop(newCode);
|
||||||
updateRAM(
|
updateRAM(
|
||||||
!currentScript || currentScript.isTxt ? null : newCode,
|
!currentScript || currentScript.isTxt ? null : newCode,
|
||||||
|
currentScript && currentScript.path,
|
||||||
currentScript && GetServer(currentScript.hostname),
|
currentScript && GetServer(currentScript.hostname),
|
||||||
);
|
);
|
||||||
finishUpdatingRAM();
|
finishUpdatingRAM();
|
||||||
|
@ -9,6 +9,7 @@ import { calculateRamUsage } from "../../../src/Script/RamCalculations";
|
|||||||
import { ns } from "../../../src/NetscriptFunctions";
|
import { ns } from "../../../src/NetscriptFunctions";
|
||||||
import { InternalAPI } from "src/Netscript/APIWrapper";
|
import { InternalAPI } from "src/Netscript/APIWrapper";
|
||||||
import { Singularity } from "@nsdefs";
|
import { Singularity } from "@nsdefs";
|
||||||
|
import { ScriptFilePath } from "src/Paths/ScriptFilePath";
|
||||||
|
|
||||||
type PotentiallyAsyncFunction = (arg?: unknown) => { catch?: PotentiallyAsyncFunction };
|
type PotentiallyAsyncFunction = (arg?: unknown) => { catch?: PotentiallyAsyncFunction };
|
||||||
|
|
||||||
@ -71,13 +72,15 @@ describe("Netscript RAM Calculation/Generation Tests", function () {
|
|||||||
extraLayerCost = 0,
|
extraLayerCost = 0,
|
||||||
) {
|
) {
|
||||||
const code = `${fnPath.join(".")}();\n`.repeat(3);
|
const code = `${fnPath.join(".")}();\n`.repeat(3);
|
||||||
|
const filename = "testfile.js" as ScriptFilePath;
|
||||||
const fnName = fnPath[fnPath.length - 1];
|
const fnName = fnPath[fnPath.length - 1];
|
||||||
|
const server = "testserver";
|
||||||
|
|
||||||
//check imported getRamCost fn vs. expected ram from test
|
//check imported getRamCost fn vs. expected ram from test
|
||||||
expect(getRamCost(fnPath, true)).toEqual(expectedRamCost);
|
expect(getRamCost(fnPath, true)).toEqual(expectedRamCost);
|
||||||
|
|
||||||
// Static ram check
|
// Static ram check
|
||||||
const staticCost = calculateRamUsage(code, new Map()).cost;
|
const staticCost = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||||
expect(staticCost).toBeCloseTo(Math.min(baseCost + expectedRamCost + extraLayerCost, maxCost));
|
expect(staticCost).toBeCloseTo(Math.min(baseCost + expectedRamCost + extraLayerCost, maxCost));
|
||||||
|
|
||||||
// reset workerScript for dynamic check
|
// reset workerScript for dynamic check
|
||||||
|
@ -10,6 +10,10 @@ const GrowCost = 0.15;
|
|||||||
const SleeveGetTaskCost = 4;
|
const SleeveGetTaskCost = 4;
|
||||||
const HacknetCost = 4;
|
const HacknetCost = 4;
|
||||||
const MaxCost = 1024;
|
const MaxCost = 1024;
|
||||||
|
|
||||||
|
const filename = "testfile.js" as ScriptFilePath;
|
||||||
|
const folderFilename = "test/testfile.js" as ScriptFilePath;
|
||||||
|
const server = "testserver";
|
||||||
describe("Parsing NetScript code to work out static RAM costs", function () {
|
describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||||
jest.spyOn(console, "error").mockImplementation(() => {});
|
jest.spyOn(console, "error").mockImplementation(() => {});
|
||||||
/** Tests numeric equality, allowing for floating point imprecision - and includes script base cost */
|
/** Tests numeric equality, allowing for floating point imprecision - and includes script base cost */
|
||||||
@ -24,7 +28,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
const code = `
|
const code = `
|
||||||
export async function main(ns) { }
|
export async function main(ns) { }
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||||
expectCost(calculated, 0);
|
expectCost(calculated, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -34,7 +38,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
ns.print("Slum snakes r00l!");
|
ns.print("Slum snakes r00l!");
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||||
expectCost(calculated, 0);
|
expectCost(calculated, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -44,7 +48,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
await ns.hack("joesguns");
|
await ns.hack("joesguns");
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||||
expectCost(calculated, HackCost);
|
expectCost(calculated, HackCost);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -54,7 +58,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
await X.hack("joesguns");
|
await X.hack("joesguns");
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||||
expectCost(calculated, HackCost);
|
expectCost(calculated, HackCost);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -65,7 +69,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
await ns.hack("joesguns");
|
await ns.hack("joesguns");
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||||
expectCost(calculated, HackCost);
|
expectCost(calculated, HackCost);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -76,7 +80,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
await ns.grow("joesguns");
|
await ns.grow("joesguns");
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||||
expectCost(calculated, HackCost + GrowCost);
|
expectCost(calculated, HackCost + GrowCost);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -89,7 +93,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
await ns.hack("joesguns");
|
await ns.hack("joesguns");
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||||
expectCost(calculated, HackCost);
|
expectCost(calculated, HackCost);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -104,7 +108,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
async doHacking() { await this.ns.hack("joesguns"); }
|
async doHacking() { await this.ns.hack("joesguns"); }
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||||
expectCost(calculated, HackCost);
|
expectCost(calculated, HackCost);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -119,7 +123,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
async doHacking() { await this.#ns.hack("joesguns"); }
|
async doHacking() { await this.#ns.hack("joesguns"); }
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||||
expectCost(calculated, HackCost);
|
expectCost(calculated, HackCost);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -132,7 +136,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
}
|
}
|
||||||
function get() { return 0; }
|
function get() { return 0; }
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||||
expectCost(calculated, 0);
|
expectCost(calculated, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -143,7 +147,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
}
|
}
|
||||||
function purchaseNode() { return 0; }
|
function purchaseNode() { return 0; }
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||||
// Works at present, because the parser checks the namespace only, not the function name
|
// Works at present, because the parser checks the namespace only, not the function name
|
||||||
expectCost(calculated, 0);
|
expectCost(calculated, 0);
|
||||||
});
|
});
|
||||||
@ -156,7 +160,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
}
|
}
|
||||||
function getTask() { return 0; }
|
function getTask() { return 0; }
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||||
expectCost(calculated, 0);
|
expectCost(calculated, 0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -168,7 +172,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
ns.hacknet.purchaseNode(0);
|
ns.hacknet.purchaseNode(0);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||||
expectCost(calculated, HacknetCost);
|
expectCost(calculated, HacknetCost);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -178,7 +182,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
ns.sleeve.getTask(3);
|
ns.sleeve.getTask(3);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||||
expectCost(calculated, SleeveGetTaskCost);
|
expectCost(calculated, SleeveGetTaskCost);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -196,7 +200,12 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
dummy();
|
dummy();
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map([["libTest.js" as ScriptFilePath, lib]])).cost;
|
const calculated = calculateRamUsage(
|
||||||
|
code,
|
||||||
|
filename,
|
||||||
|
new Map([["libTest.js" as ScriptFilePath, lib]]),
|
||||||
|
server,
|
||||||
|
).cost;
|
||||||
expectCost(calculated, 0);
|
expectCost(calculated, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -212,7 +221,12 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
await doHack(ns);
|
await doHack(ns);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map([["libTest.js" as ScriptFilePath, lib]])).cost;
|
const calculated = calculateRamUsage(
|
||||||
|
code,
|
||||||
|
filename,
|
||||||
|
new Map([["libTest.js" as ScriptFilePath, lib]]),
|
||||||
|
server,
|
||||||
|
).cost;
|
||||||
expectCost(calculated, HackCost);
|
expectCost(calculated, HackCost);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -229,7 +243,12 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
await doHack(ns);
|
await doHack(ns);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map([["libTest.js" as ScriptFilePath, lib]])).cost;
|
const calculated = calculateRamUsage(
|
||||||
|
code,
|
||||||
|
filename,
|
||||||
|
new Map([["libTest.js" as ScriptFilePath, lib]]),
|
||||||
|
server,
|
||||||
|
).cost;
|
||||||
expectCost(calculated, HackCost);
|
expectCost(calculated, HackCost);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -246,7 +265,12 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
await test.doHack(ns);
|
await test.doHack(ns);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map([["libTest.js" as ScriptFilePath, lib]])).cost;
|
const calculated = calculateRamUsage(
|
||||||
|
code,
|
||||||
|
filename,
|
||||||
|
new Map([["libTest.js" as ScriptFilePath, lib]]),
|
||||||
|
server,
|
||||||
|
).cost;
|
||||||
expectCost(calculated, HackCost + GrowCost);
|
expectCost(calculated, HackCost + GrowCost);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -267,7 +291,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
${lines.join("\n")};
|
${lines.join("\n")};
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||||
expectCost(calculated, MaxCost);
|
expectCost(calculated, MaxCost);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -289,7 +313,12 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
await test.doHack(ns);
|
await test.doHack(ns);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map([["libTest.js" as ScriptFilePath, lib]])).cost;
|
const calculated = calculateRamUsage(
|
||||||
|
code,
|
||||||
|
filename,
|
||||||
|
new Map([["libTest.js" as ScriptFilePath, lib]]),
|
||||||
|
server,
|
||||||
|
).cost;
|
||||||
expectCost(calculated, HackCost);
|
expectCost(calculated, HackCost);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -315,8 +344,119 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
|||||||
await growerInstance.doGrow();
|
await growerInstance.doGrow();
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const calculated = calculateRamUsage(code, new Map([["libTest.js" as ScriptFilePath, lib]])).cost;
|
const calculated = calculateRamUsage(
|
||||||
|
code,
|
||||||
|
filename,
|
||||||
|
new Map([["libTest.js" as ScriptFilePath, lib]]),
|
||||||
|
server,
|
||||||
|
).cost;
|
||||||
expectCost(calculated, GrowCost);
|
expectCost(calculated, GrowCost);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Importing with a relative path - One Layer Deep", async function () {
|
||||||
|
const libCode = `
|
||||||
|
export async function testRelative(ns) {
|
||||||
|
await ns.hack("n00dles")
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const lib = new Script("test/libTest.js" as ScriptFilePath, libCode);
|
||||||
|
const code = `
|
||||||
|
import { testRelative } from "./libTest";
|
||||||
|
|
||||||
|
export async function main(ns) {
|
||||||
|
await testRelative(ns)
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const calculated = calculateRamUsage(
|
||||||
|
code,
|
||||||
|
folderFilename,
|
||||||
|
new Map([["test/libTest.js" as ScriptFilePath, lib]]),
|
||||||
|
server,
|
||||||
|
).cost;
|
||||||
|
expectCost(calculated, HackCost);
|
||||||
|
});
|
||||||
|
it("Importing with a relative path - Two Layer Deep", async function () {
|
||||||
|
const libNameOne = "test/libTestOne.js" as ScriptFilePath;
|
||||||
|
const libNameTwo = "test/libTestTwo.js" as ScriptFilePath;
|
||||||
|
|
||||||
|
const libCodeOne = `
|
||||||
|
import { testRelativeAgain } from "./libTestTwo";
|
||||||
|
export function testRelative(ns) {
|
||||||
|
return testRelativeAgain(ns)
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const libScriptOne = new Script(libNameOne, libCodeOne);
|
||||||
|
|
||||||
|
const libCodeTwo = `
|
||||||
|
export function testRelativeAgain(ns) {
|
||||||
|
return ns.hack("n00dles")
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const libScriptTwo = new Script(libNameTwo, libCodeTwo);
|
||||||
|
|
||||||
|
const code = `
|
||||||
|
import { testRelative } from "./libTestOne";
|
||||||
|
|
||||||
|
export async function main(ns) {
|
||||||
|
await testRelative(ns)
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const calculated = calculateRamUsage(
|
||||||
|
code,
|
||||||
|
folderFilename,
|
||||||
|
new Map([
|
||||||
|
[libNameOne, libScriptOne],
|
||||||
|
[libNameTwo, libScriptTwo],
|
||||||
|
]),
|
||||||
|
server,
|
||||||
|
).cost;
|
||||||
|
expectCost(calculated, HackCost);
|
||||||
|
});
|
||||||
|
it("Importing with a relative path - possible path conflict", async function () {
|
||||||
|
const libNameOne = "foo/libTestOne.js" as ScriptFilePath;
|
||||||
|
const libNameTwo = "foo/libTestTwo.js" as ScriptFilePath;
|
||||||
|
const incorrect_libNameTwo = "test/libTestTwo.js" as ScriptFilePath;
|
||||||
|
|
||||||
|
const libCodeOne = `
|
||||||
|
import { testRelativeAgain } from "./libTestTwo";
|
||||||
|
export function testRelative(ns) {
|
||||||
|
return testRelativeAgain(ns)
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const libScriptOne = new Script(libNameOne, libCodeOne);
|
||||||
|
|
||||||
|
const libCodeTwo = `
|
||||||
|
export function testRelativeAgain(ns) {
|
||||||
|
return ns.hack("n00dles")
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const libScriptTwo = new Script(libNameTwo, libCodeTwo);
|
||||||
|
|
||||||
|
const incorrect_libCodeTwo = `
|
||||||
|
export function testRelativeAgain(ns) {
|
||||||
|
return ns.grow("n00dles")
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const incorrect_libScriptTwo = new Script(incorrect_libNameTwo, incorrect_libCodeTwo);
|
||||||
|
|
||||||
|
const code = `
|
||||||
|
import { testRelative } from "foo/libTestOne";
|
||||||
|
|
||||||
|
export async function main(ns) {
|
||||||
|
await testRelative(ns)
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const calculated = calculateRamUsage(
|
||||||
|
code,
|
||||||
|
folderFilename,
|
||||||
|
new Map([
|
||||||
|
[libNameOne, libScriptOne],
|
||||||
|
[libNameTwo, libScriptTwo],
|
||||||
|
[incorrect_libNameTwo, incorrect_libScriptTwo],
|
||||||
|
]),
|
||||||
|
server,
|
||||||
|
).cost;
|
||||||
|
expectCost(calculated, HackCost);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user