mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-18 12:15:44 +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 { Script } from "./Script/Script";
|
||||
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.
|
||||
export type Node = any;
|
||||
@ -125,7 +124,7 @@ function generateLoadedModule(script: Script, scripts: Map<ScriptFilePath, Scrip
|
||||
let newCode = script.code;
|
||||
// Loop through each node and replace the script name with a blob url.
|
||||
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}`);
|
||||
|
||||
// Find the corresponding script.
|
||||
@ -149,6 +148,7 @@ function generateLoadedModule(script: Script, scripts: Map<ScriptFilePath, Scrip
|
||||
// script dedupe properly.
|
||||
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.
|
||||
|
||||
const url = URL.createObjectURL(makeScriptBlob(adjustedCode)) as ScriptURL;
|
||||
const module = config.doImport(url).catch((e) => {
|
||||
script.invalidateModule();
|
||||
|
@ -14,7 +14,7 @@ import { RamCosts, RamCostConstants } from "../Netscript/RamCostGenerator";
|
||||
import { Script } from "./Script";
|
||||
import { Node } from "../NetscriptJSEvaluator";
|
||||
import { ScriptFilePath, resolveScriptFilePath } from "../Paths/ScriptFilePath";
|
||||
import { root } from "../Paths/Directory";
|
||||
import { ServerName } from "../Types/strings";
|
||||
|
||||
export interface RamUsageEntry {
|
||||
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
|
||||
* RAM usage. Also accounts for imported modules.
|
||||
* @param otherScripts - All other scripts on the server. Used to account for imported scripts
|
||||
* @param code - The code being parsed */
|
||||
function parseOnlyRamCalculate(otherScripts: Map<ScriptFilePath, Script>, code: string, ns1?: boolean): RamCalculation {
|
||||
* @param code - The code being parsed
|
||||
* @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.
|
||||
*
|
||||
* 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
|
||||
* of its imports, and any identifiers referenced in this global scope. Each
|
||||
* function depends on all the identifiers referenced internally.
|
||||
@ -74,10 +83,10 @@ function parseOnlyRamCalculate(otherScripts: Map<ScriptFilePath, Script>, code:
|
||||
const completedParses = new Set();
|
||||
|
||||
// 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.
|
||||
function parseCode(code: string, moduleName: string): void {
|
||||
const result = parseOnlyCalculateDeps(code, moduleName);
|
||||
function parseCode(code: string, moduleName: ScriptFilePath): void {
|
||||
const result = parseOnlyCalculateDeps(code, moduleName, ns1);
|
||||
completedParses.add(moduleName);
|
||||
|
||||
// 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
|
||||
const initialModule = "__SPECIAL_INITIAL_MODULE__";
|
||||
const initialModule = scriptname;
|
||||
parseCode(code, initialModule);
|
||||
|
||||
// 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.startsWith("https://") || nextModule.startsWith("http://")) continue;
|
||||
|
||||
// Using root as the path base right now. Difficult to implement
|
||||
const filename = resolveScriptFilePath(nextModule, root, ns1 ? ".script" : ".js");
|
||||
if (!filename) {
|
||||
return { errorCode: RamCalculationErrorCode.ImportError, errorMessage: `Invalid import path: "${nextModule}"` };
|
||||
}
|
||||
const script = otherScripts.get(filename);
|
||||
const script = otherScripts.get(nextModule);
|
||||
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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
const detailedCosts: RamUsageEntry[] = [{ type: "misc", name: "baseCost", cost: RamCostConstants.Base }];
|
||||
const unresolvedRefs = Object.keys(dependencyMap).filter((s) => s.startsWith(initialModule));
|
||||
@ -250,7 +257,7 @@ export function checkInfiniteLoop(code: string): number[] {
|
||||
|
||||
interface ParseDepsResult {
|
||||
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
|
||||
* 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" });
|
||||
// Everything from the global scope goes in ".". Everything else goes in ".function", where only
|
||||
// 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.
|
||||
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
|
||||
// any aliases.
|
||||
@ -338,7 +345,12 @@ function parseOnlyCalculateDeps(code: string, currentModule: string): ParseDepsR
|
||||
Object.assign(
|
||||
{
|
||||
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);
|
||||
|
||||
// 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
|
||||
* @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.
|
||||
* 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(
|
||||
code: string,
|
||||
scriptname: ScriptFilePath,
|
||||
otherScripts: Map<ScriptFilePath, Script>,
|
||||
server: ServerName,
|
||||
ns1?: boolean,
|
||||
): RamCalculation {
|
||||
try {
|
||||
return parseOnlyRamCalculate(otherScripts, code, ns1);
|
||||
return parseOnlyRamCalculate(otherScripts, code, scriptname, server, ns1);
|
||||
} catch (e) {
|
||||
return {
|
||||
errorCode: RamCalculationErrorCode.SyntaxError,
|
||||
|
@ -73,7 +73,13 @@ export class Script implements ContentFile {
|
||||
* @param {Script[]} otherScripts - Other scripts on the server. Used to process imports
|
||||
*/
|
||||
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) {
|
||||
this.ramUsage = roundToTwo(ramCalc.cost);
|
||||
this.ramUsageEntries = ramCalc.entries as RamUsageEntry[];
|
||||
|
@ -8,11 +8,13 @@ import { useBoolean } from "../../ui/React/hooks";
|
||||
import { BaseServer } from "../../Server/BaseServer";
|
||||
|
||||
import { Options } from "./Options";
|
||||
import { FilePath } from "../../Paths/FilePath";
|
||||
import { hasScriptExtension } from "../../Paths/ScriptFilePath";
|
||||
|
||||
export interface ScriptEditorContextShape {
|
||||
ram: string;
|
||||
ramEntries: string[][];
|
||||
updateRAM: (newCode: string | null, server: BaseServer | null) => void;
|
||||
updateRAM: (newCode: string | null, filename: FilePath | null, server: BaseServer | null) => void;
|
||||
|
||||
isUpdatingRAM: boolean;
|
||||
startUpdatingRAM: () => void;
|
||||
@ -28,14 +30,13 @@ export function ScriptEditorContextProvider({ children, vim }: { children: React
|
||||
const [ram, setRAM] = useState("RAM: ???");
|
||||
const [ramEntries, setRamEntries] = useState<string[][]>([["???", ""]]);
|
||||
|
||||
const updateRAM: ScriptEditorContextShape["updateRAM"] = (newCode, server) => {
|
||||
if (newCode === null || server === null) {
|
||||
const updateRAM: ScriptEditorContextShape["updateRAM"] = (newCode, filename, server) => {
|
||||
if (newCode == null || filename == null || server == null || !hasScriptExtension(filename)) {
|
||||
setRAM("N/A");
|
||||
setRamEntries([["N/A", ""]]);
|
||||
return;
|
||||
}
|
||||
|
||||
const ramUsage = calculateRamUsage(newCode, server.scripts);
|
||||
const ramUsage = calculateRamUsage(newCode, filename, server.scripts, server.hostname);
|
||||
if (ramUsage.cost && ramUsage.cost > 0) {
|
||||
const entries = ramUsage.entries?.sort((a, b) => b.cost - a.cost) ?? [];
|
||||
const entriesDisp = [];
|
||||
|
@ -143,6 +143,7 @@ function Root(props: IProps): React.ReactElement {
|
||||
infLoop(newCode);
|
||||
updateRAM(
|
||||
!currentScript || currentScript.isTxt ? null : newCode,
|
||||
currentScript && currentScript.path,
|
||||
currentScript && GetServer(currentScript.hostname),
|
||||
);
|
||||
finishUpdatingRAM();
|
||||
|
@ -9,6 +9,7 @@ import { calculateRamUsage } from "../../../src/Script/RamCalculations";
|
||||
import { ns } from "../../../src/NetscriptFunctions";
|
||||
import { InternalAPI } from "src/Netscript/APIWrapper";
|
||||
import { Singularity } from "@nsdefs";
|
||||
import { ScriptFilePath } from "src/Paths/ScriptFilePath";
|
||||
|
||||
type PotentiallyAsyncFunction = (arg?: unknown) => { catch?: PotentiallyAsyncFunction };
|
||||
|
||||
@ -71,13 +72,15 @@ describe("Netscript RAM Calculation/Generation Tests", function () {
|
||||
extraLayerCost = 0,
|
||||
) {
|
||||
const code = `${fnPath.join(".")}();\n`.repeat(3);
|
||||
const filename = "testfile.js" as ScriptFilePath;
|
||||
const fnName = fnPath[fnPath.length - 1];
|
||||
const server = "testserver";
|
||||
|
||||
//check imported getRamCost fn vs. expected ram from test
|
||||
expect(getRamCost(fnPath, true)).toEqual(expectedRamCost);
|
||||
|
||||
// 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));
|
||||
|
||||
// reset workerScript for dynamic check
|
||||
|
@ -10,6 +10,10 @@ const GrowCost = 0.15;
|
||||
const SleeveGetTaskCost = 4;
|
||||
const HacknetCost = 4;
|
||||
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 () {
|
||||
jest.spyOn(console, "error").mockImplementation(() => {});
|
||||
/** 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 = `
|
||||
export async function main(ns) { }
|
||||
`;
|
||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
||||
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||
expectCost(calculated, 0);
|
||||
});
|
||||
|
||||
@ -34,7 +38,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
ns.print("Slum snakes r00l!");
|
||||
}
|
||||
`;
|
||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
||||
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||
expectCost(calculated, 0);
|
||||
});
|
||||
|
||||
@ -44,7 +48,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
await ns.hack("joesguns");
|
||||
}
|
||||
`;
|
||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
||||
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||
expectCost(calculated, HackCost);
|
||||
});
|
||||
|
||||
@ -54,7 +58,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
await X.hack("joesguns");
|
||||
}
|
||||
`;
|
||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
||||
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||
expectCost(calculated, HackCost);
|
||||
});
|
||||
|
||||
@ -65,7 +69,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
await ns.hack("joesguns");
|
||||
}
|
||||
`;
|
||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
||||
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||
expectCost(calculated, HackCost);
|
||||
});
|
||||
|
||||
@ -76,7 +80,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
await ns.grow("joesguns");
|
||||
}
|
||||
`;
|
||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
||||
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||
expectCost(calculated, HackCost + GrowCost);
|
||||
});
|
||||
|
||||
@ -89,7 +93,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
await ns.hack("joesguns");
|
||||
}
|
||||
`;
|
||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
||||
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||
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"); }
|
||||
}
|
||||
`;
|
||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
||||
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||
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"); }
|
||||
}
|
||||
`;
|
||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
||||
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||
expectCost(calculated, HackCost);
|
||||
});
|
||||
});
|
||||
@ -132,7 +136,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
}
|
||||
function get() { return 0; }
|
||||
`;
|
||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
||||
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||
expectCost(calculated, 0);
|
||||
});
|
||||
|
||||
@ -143,7 +147,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
}
|
||||
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
|
||||
expectCost(calculated, 0);
|
||||
});
|
||||
@ -156,7 +160,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
}
|
||||
function getTask() { return 0; }
|
||||
`;
|
||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
||||
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||
expectCost(calculated, 0);
|
||||
});
|
||||
});
|
||||
@ -168,7 +172,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
ns.hacknet.purchaseNode(0);
|
||||
}
|
||||
`;
|
||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
||||
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||
expectCost(calculated, HacknetCost);
|
||||
});
|
||||
|
||||
@ -178,7 +182,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
ns.sleeve.getTask(3);
|
||||
}
|
||||
`;
|
||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
||||
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||
expectCost(calculated, SleeveGetTaskCost);
|
||||
});
|
||||
});
|
||||
@ -196,7 +200,12 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
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);
|
||||
});
|
||||
|
||||
@ -212,7 +221,12 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
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);
|
||||
});
|
||||
|
||||
@ -229,7 +243,12 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
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);
|
||||
});
|
||||
|
||||
@ -246,7 +265,12 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
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);
|
||||
});
|
||||
|
||||
@ -267,7 +291,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
${lines.join("\n")};
|
||||
}
|
||||
`;
|
||||
const calculated = calculateRamUsage(code, new Map()).cost;
|
||||
const calculated = calculateRamUsage(code, filename, new Map(), server).cost;
|
||||
expectCost(calculated, MaxCost);
|
||||
});
|
||||
|
||||
@ -289,7 +313,12 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
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);
|
||||
});
|
||||
|
||||
@ -315,8 +344,119 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
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);
|
||||
});
|
||||
|
||||
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