MISC: Make TIX access independent from WSE account (#2342)

This commit is contained in:
catloversg
2025-10-12 07:28:45 +07:00
committed by GitHub
parent bd4e34fae0
commit d421d4fcf9
17 changed files with 278 additions and 67 deletions

View File

@@ -285,7 +285,9 @@ Place order for stocks.
</td><td>
Purchase 4S Market Data Access.
Purchase 4S Market Data UI access (UI only).
You need to have a WSE account. Note that this feature only unlocks access to 4S Market Data in the Stock Market UI. If you want to access 4S Market Data via NS APIs, you have to unlock "4S Market Data TIX API access" via [purchase4SMarketDataTixApi](./bitburner.tix.purchase4smarketdatatixapi.md)<!-- -->, which is unrelated to this feature.
</td></tr>
@@ -296,7 +298,9 @@ Purchase 4S Market Data Access.
</td><td>
Purchase 4S Market Data TIX API Access.
Purchase 4S Market Data TIX API access (NS APIs only).
You need to have TIX API access. Note that this feature only unlocks access to 4S Market Data via NS APIs.
</td></tr>
@@ -307,7 +311,9 @@ Purchase 4S Market Data TIX API Access.
</td><td>
Purchase TIX API Access
Purchase TIX API access.
You need to have TIX API access to perform actions via NS APIs. Note that you can buy TIX API access without a WSE account.
</td></tr>
@@ -318,7 +324,9 @@ Purchase TIX API Access
</td><td>
Purchase WSE Account.
Purchase a WSE account.
You need to have this account to perform actions via the Stock Market UI. Note that if you want to perform actions via NS APIs, you need to have TIX API access, not this account.
</td></tr>

View File

@@ -4,7 +4,9 @@
## TIX.purchase4SMarketData() method
Purchase 4S Market Data Access.
Purchase 4S Market Data UI access (UI only).
You need to have a WSE account. Note that this feature only unlocks access to 4S Market Data in the Stock Market UI. If you want to access 4S Market Data via NS APIs, you have to unlock "4S Market Data TIX API access" via [purchase4SMarketDataTixApi](./bitburner.tix.purchase4smarketdatatixapi.md)<!-- -->, which is unrelated to this feature.
**Signature:**

View File

@@ -4,7 +4,9 @@
## TIX.purchase4SMarketDataTixApi() method
Purchase 4S Market Data TIX API Access.
Purchase 4S Market Data TIX API access (NS APIs only).
You need to have TIX API access. Note that this feature only unlocks access to 4S Market Data via NS APIs.
**Signature:**

View File

@@ -4,7 +4,9 @@
## TIX.purchaseTixApi() method
Purchase TIX API Access
Purchase TIX API access.
You need to have TIX API access to perform actions via NS APIs. Note that you can buy TIX API access without a WSE account.
**Signature:**

View File

@@ -4,7 +4,9 @@
## TIX.purchaseWseAccount() method
Purchase WSE Account.
Purchase a WSE account.
You need to have this account to perform actions via the Stock Market UI. Note that if you want to perform actions via NS APIs, you need to have TIX API access, not this account.
**Signature:**

View File

@@ -28,6 +28,7 @@ import { EntropyDev } from "./DevMenu/ui/EntropyDev";
import { Exploit } from "./Exploits/Exploit";
import { useRerender } from "./ui/React/hooks";
import { AutoExpandContext, getAutoExpandData, setAutoExpandData } from "./ui/AutoExpand/AutoExpandContext";
import { canAccessStockMarket } from "./StockMarket/StockMarket";
export function DevMenuRoot(): React.ReactElement {
const autoExpandContextValue = useRef({
@@ -65,7 +66,7 @@ export function DevMenuRoot(): React.ReactElement {
<CodingContractsDev />
{Player.hasWseAccount && <StockMarketDev />}
{canAccessStockMarket() && <StockMarketDev />}
{Player.sleeves.length > 0 && <SleevesDev />}
{Player.augmentations.some((aug) => aug.name === AugmentationName.StaneksGift1) && <StanekDev />}

View File

@@ -7,6 +7,7 @@ import {
cancelOrder,
initStockMarket,
StockMarketPromise,
isStockMarketInitialized,
} from "../StockMarket/StockMarket";
import { getBuyTransactionCost, getSellTransactionGain } from "../StockMarket/StockMarketHelpers";
import { StockSymbol } from "@enums";
@@ -26,9 +27,6 @@ import { getEnumHelper } from "../utils/EnumHelper";
export function NetscriptStockMarket(): InternalAPI<TIX> {
/** Checks if the player has TIX API access. Throws an error if the player does not */
const checkTixApiAccess = function (ctx: NetscriptContext): void {
if (!Player.hasWseAccount) {
throw helpers.errorMessage(ctx, `You don't have WSE Access! Cannot use ${ctx.function}()`);
}
if (!Player.hasTixApiAccess) {
throw helpers.errorMessage(ctx, `You don't have TIX API Access! Cannot use ${ctx.function}()`);
}
@@ -256,6 +254,11 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
return true;
}
if (!Player.hasWseAccount) {
helpers.log(ctx, () => "You need to have a WSE account.");
return false;
}
if (Player.money < getStockMarket4SDataCost()) {
helpers.log(ctx, () => "Not enough money to purchase 4S Market Data.");
return false;
@@ -301,7 +304,9 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
}
Player.hasWseAccount = true;
initStockMarket();
if (!isStockMarketInitialized()) {
initStockMarket();
}
Player.loseMoney(getStockMarketWseCost(), "stock");
helpers.log(ctx, () => "Purchased WSE Account Access");
return true;
@@ -318,6 +323,9 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
}
Player.hasTixApiAccess = true;
if (!isStockMarketInitialized()) {
initStockMarket();
}
Player.loseMoney(getStockMarketTixApiCost(), "stock");
helpers.log(ctx, () => "Purchased TIX API");
return true;

View File

@@ -14,7 +14,7 @@ import { resetPidCounter } from "./Netscript/Pid";
import { GetServer, AddToAllServers, initForeignServers, prestigeAllServers } from "./Server/AllServers";
import { prestigeHomeComputer } from "./Server/ServerHelpers";
import { SpecialServers } from "./Server/data/SpecialServers";
import { deleteStockMarket, initStockMarket } from "./StockMarket/StockMarket";
import { canAccessStockMarket, deleteStockMarket, initStockMarket } from "./StockMarket/StockMarket";
import { Terminal } from "./Terminal";
import { dialogBoxCreate } from "./ui/React/DialogBox";
@@ -161,7 +161,7 @@ export function prestigeAugmentation(): void {
}
// Reset Stock market
if (Player.hasWseAccount) {
if (canAccessStockMarket()) {
initStockMarket();
}
@@ -291,7 +291,7 @@ export function prestigeSourceFile(isFlume: boolean): void {
if (Player.bitNodeN === 8) {
Player.money = BitNode8StartingMoney;
}
if (Player.bitNodeN === 8 || Player.activeSourceFileLvl(8) > 0) {
if (canAccessBitNodeFeature(8)) {
Player.hasWseAccount = true;
Player.hasTixApiAccess = true;
}
@@ -314,7 +314,7 @@ export function prestigeSourceFile(isFlume: boolean): void {
}
// Reset Stock market, gang, and corporation
if (Player.hasWseAccount) {
if (canAccessStockMarket()) {
initStockMarket();
} else {
deleteStockMarket();

View File

@@ -1635,28 +1635,44 @@ export interface TIX {
getForecast(sym: string): number;
/**
* Purchase 4S Market Data Access.
* Purchase 4S Market Data UI access (UI only).
*
* You need to have a WSE account. Note that this feature only unlocks access to 4S Market Data in the Stock Market
* UI. If you want to access 4S Market Data via NS APIs, you have to unlock "4S Market Data TIX API access" via
* {@link TIX.purchase4SMarketDataTixApi | purchase4SMarketDataTixApi}, which is unrelated to this feature.
*
* @remarks RAM cost: 2.5 GB
* @returns True if you successfully purchased it or if you already have access, false otherwise.
*/
purchase4SMarketData(): boolean;
/**
* Purchase 4S Market Data TIX API Access.
* Purchase 4S Market Data TIX API access (NS APIs only).
*
* You need to have TIX API access. Note that this feature only unlocks access to 4S Market Data via NS APIs.
*
* @remarks RAM cost: 2.5 GB
* @returns True if you successfully purchased it or if you already have access, false otherwise.
*/
purchase4SMarketDataTixApi(): boolean;
/**
* Purchase WSE Account.
* Purchase a WSE account.
*
* You need to have this account to perform actions via the Stock Market UI. Note that if you want to perform actions
* via NS APIs, you need to have TIX API access, not this account.
*
* @remarks RAM cost: 2.5 GB
* @returns True if you successfully purchased it or if you already have access, false otherwise.
*/
purchaseWseAccount(): boolean;
/**
* Purchase TIX API Access
* Purchase TIX API access.
*
* You need to have TIX API access to perform actions via NS APIs. Note that you can buy TIX API access without a WSE
* account.
*
* @remarks RAM cost: 2.5 GB
* @returns True if you successfully purchased it or if you already have access, false otherwise.
*/

View File

@@ -150,7 +150,7 @@ export function loadStockMarket(saveString: string): void {
console.error(error);
console.error("Invalid StockMarketSave:", saveString);
deleteStockMarket();
if (Player.hasWseAccount) {
if (canAccessStockMarket()) {
initStockMarket();
}
const errorMessage = `Cannot load data of StockMarket. StockMarket is reset.`;
@@ -163,6 +163,18 @@ export function loadStockMarket(saveString: string): void {
StockMarket = stockMarketData as IStockMarket;
}
export function canAccessStockMarket(): boolean {
return Player.hasWseAccount || Player.hasTixApiAccess;
}
export function isStockMarketInitialized(): boolean {
return StockMarket.lastUpdate > 0;
}
/**
* After calling this function, the stock market will be back to the uninitialized state (i.e.,
* isStockMarketInitialized() returns false).
*/
export function deleteStockMarket(): void {
StockMarket = getDefaultEmptyStockMarket();
}
@@ -187,7 +199,7 @@ export function initStockMarket(): void {
StockMarket.Orders = orders;
StockMarket.storedCycles = 0;
StockMarket.lastUpdate = 0;
StockMarket.lastUpdate = Date.now();
StockMarket.ticksUntilCycle = getRandomIntInclusive(1, StockMarketConstants.TicksPerCycle);
initSymbolToStockMap();
}

View File

@@ -10,7 +10,7 @@ import { getStockMarket4SDataCost, getStockMarket4STixApiCost } from "../StockMa
import { StockMarketConstants } from "../data/Constants";
import { Player } from "@player";
import { Money } from "../../ui/React/Money";
import { initStockMarket } from "../StockMarket";
import { initStockMarket, isStockMarketInitialized } from "../StockMarket";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
@@ -47,7 +47,7 @@ function Purchase4SMarketDataTixApiAccessButton(props: IProps): React.ReactEleme
if (Player.has4SDataTixApi) {
return (
<Typography>
Market Data TIX API Access <CheckIcon />
4S Market Data TIX API Access <CheckIcon />
</Typography>
);
}
@@ -91,19 +91,21 @@ function PurchaseWseAccountButton(props: IProps): React.ReactElement {
return;
}
Player.hasWseAccount = true;
initStockMarket();
if (!isStockMarketInitialized()) {
initStockMarket();
}
Player.loseMoney(StockMarketConstants.WseAccountCost, "stock");
props.rerender();
}
const cost = StockMarketConstants.WseAccountCost;
let tooltipTitle = "Let you trade stock";
let tooltipTitle = "Let you trade stock via UI";
if (!Player.canAfford(cost)) {
tooltipTitle = "You do not have enough money";
}
return (
<>
<Typography>To begin trading, you must first purchase an account:</Typography>
<Typography>If you want to trade via Stock Market dashboard (UI), you must purchase a WSE account.</Typography>
<Tooltip title={<Typography>{tooltipTitle}</Typography>}>
<span>
<Button disabled={!Player.canAfford(cost)} onClick={purchaseWseAccount}>
@@ -121,13 +123,13 @@ function PurchaseTixApiAccessButton(props: IProps): React.ReactElement {
if (Player.hasTixApiAccess) {
return;
}
if (!Player.hasWseAccount) {
return;
}
if (!Player.canAfford(StockMarketConstants.TixApiCost)) {
return;
}
Player.hasTixApiAccess = true;
if (!isStockMarketInitialized()) {
initStockMarket();
}
Player.loseMoney(StockMarketConstants.TixApiCost, "stock");
props.rerender();
}
@@ -140,21 +142,26 @@ function PurchaseTixApiAccessButton(props: IProps): React.ReactElement {
);
}
const cost = StockMarketConstants.TixApiCost;
let tooltipTitle = "Let you trade stock through Netscript";
if (!Player.hasWseAccount) {
tooltipTitle = "Requires WSE Account";
} else if (!Player.canAfford(cost)) {
let tooltipTitle = "Let you trade stock via NS APIs";
if (!Player.canAfford(cost)) {
tooltipTitle = "You do not have enough money";
}
return (
<Tooltip title={<Typography>{tooltipTitle}</Typography>}>
<span>
<Button disabled={!Player.hasWseAccount || !Player.canAfford(cost)} onClick={purchaseTixApiAccess}>
Buy Trade Information eXchange (TIX) API Access -&nbsp;
<Money money={cost} forPurchase={true} />
</Button>
</span>
</Tooltip>
<>
<Typography>
TIX, short for Trade Information eXchange, is the communications protocol used by the WSE. Purchasing access to
the TIX API lets you write code to create your own algorithmic/automated trading strategies.
</Typography>
<Typography>If you want to trade via NS APIs, you must purchase TIX API access.</Typography>
<Tooltip title={<Typography>{tooltipTitle}</Typography>}>
<span>
<Button disabled={!Player.canAfford(cost)} onClick={purchaseTixApiAccess}>
Buy Trade Information eXchange (TIX) API Access -&nbsp;
<Money money={cost} forPurchase={true} />
</Button>
</span>
</Tooltip>
</>
);
}
@@ -179,7 +186,7 @@ function Purchase4SMarketDataButton(props: IProps): React.ReactElement {
if (Player.has4SData) {
return (
<Typography>
4S Market Data Access <CheckIcon />
4S Market Data UI Access <CheckIcon />
</Typography>
);
}
@@ -213,16 +220,16 @@ export function InfoAndPurchases(props: IProps): React.ReactElement {
<>
<Typography variant="h4">Welcome to the World Stock Exchange (WSE)!</Typography>
<Typography variant="h5" color="primary">
WSE Account
</Typography>
<PurchaseWseAccountButton {...props} />
<Typography variant="h5" color="primary">
Trade Information eXchange (TIX) API
</Typography>
<Typography>
TIX, short for Trade Information eXchange, is the communications protocol used by the WSE. Purchasing access to
the TIX API lets you write code to create your own algorithmic/automated trading strategies.
</Typography>
<PurchaseTixApiAccessButton {...props} />
<Typography variant="h5" color="primary">
{FactionName.FourSigma} (4S) Market Data Feed
</Typography>
@@ -235,6 +242,7 @@ export function InfoAndPurchases(props: IProps): React.ReactElement {
</Typography>
<Purchase4SMarketDataTixApiAccessButton {...props} />
<Purchase4SMarketDataButton {...props} />
<Typography>
Commission Fees: Every transaction you make has a{" "}
<Money money={StockMarketConstants.StockMarketCommission} forPurchase={true} /> commission fee.

View File

@@ -25,7 +25,7 @@ import { saveObject, loadGame } from "./SaveObject";
import { GetAllServers, initForeignServers } from "./Server/AllServers";
import { Settings } from "./Settings/Settings";
import { FormatsNeedToChange } from "./ui/formatNumber";
import { initSymbolToStockMap, processStockPrices } from "./StockMarket/StockMarket";
import { canAccessStockMarket, initSymbolToStockMap, processStockPrices } from "./StockMarket/StockMarket";
import { Terminal } from "./Terminal";
import { Money } from "./ui/React/Money";
@@ -92,7 +92,7 @@ const Engine = {
Player.processWork(numCycles);
// Update stock prices
if (Player.hasWseAccount) {
if (canAccessStockMarket()) {
processStockPrices(numCycles);
}
@@ -236,7 +236,7 @@ const Engine = {
if (await loadGame(saveData)) {
FormatsNeedToChange.emit();
initBitNodeMultipliers();
if (Player.hasWseAccount) {
if (canAccessStockMarket()) {
initSymbolToStockMap();
}
@@ -307,7 +307,7 @@ const Engine = {
processPassiveFactionRepGain(numCyclesOffline);
// Stock Market offline progress
if (Player.hasWseAccount) {
if (canAccessStockMarket()) {
processStockPrices(numCyclesOffline);
}

View File

@@ -384,5 +384,12 @@ export const breakingChanges300: VersionBreakingChange = {
`- "White Ferrari" was renamed to "${convertV2GangEquipmentNames("White Ferrari")}".\n`,
showWarning: false,
},
{
brokenAPIs: [{ name: "purchase4SMarketData" }],
info:
"You have to purchase a WSE account before purchasing 4S Market Data UI access via ns.stock.purchase4SMarketData().\n" +
"Note that this change does not affect 4S Market Data TIX API access (ns.stock.purchase4SMarketDataTixApi()).",
showWarning: false,
},
],
};

View File

@@ -29,8 +29,7 @@ import { installAugmentations } from "../../../src/Augmentation/AugmentationHelp
import { AddToAllServers } from "../../../src/Server/AllServers";
import { Server } from "../../../src/Server/Server";
import { initSourceFiles } from "../../../src/SourceFile/SourceFiles";
import type { NetscriptContext } from "../../../src/Netscript/APIWrapper";
import type { WorkerScript } from "../../../src/Netscript/WorkerScript";
import { getMockedNetscriptContext } from "../Utilities";
jest.mock("../../../src/Faction/Factions", () => ({
Factions: {},
@@ -43,18 +42,9 @@ jest.mock("../../../src/ui/GameRoot", () => ({
},
}));
const mockLogger: (s: string) => void = jest.fn();
const mockCtx: NetscriptContext = {
function: "",
functionPath: "",
workerScript: {
log: (_: string, text: () => string) => {
mockLogger(text());
},
scriptRef: {
dependencies: [],
},
} as unknown as WorkerScript,
};
const mockCtx = getMockedNetscriptContext((_: string, txt: () => string) => {
mockLogger(txt());
});
setPlayer(new PlayerObject());
AddToAllServers(new Server({ hostname: "home" }));

View File

@@ -0,0 +1,133 @@
import { Player } from "@player";
import { getMockedNetscriptContext, getNS, initGameEnvironment, setupBasicTestingEnvironment } from "../Utilities";
import { deleteStockMarket, getDefaultEmptyStockMarket, StockMarket } from "../../../src/StockMarket/StockMarket";
import { Stock } from "../../../src/StockMarket/Stock";
import { buyStock } from "../../../src/StockMarket/BuyingAndSelling";
function expectUninitializedStockMarket(): void {
expect(StockMarket).toStrictEqual(getDefaultEmptyStockMarket());
}
function expectInitializedStockMarket(): void {
const symbols = Object.keys(StockMarket.Orders);
expect(symbols.length).toBeGreaterThan(0);
expect(symbols.includes("ECP")).toStrictEqual(true);
expect(StockMarket["ECorp"] instanceof Stock).toStrictEqual(true);
expect(StockMarket.lastUpdate).toBeGreaterThan(0);
}
function buyShareOfECP(): void {
const eCorpStock = StockMarket["ECorp"];
expect(eCorpStock.playerShares).toStrictEqual(0);
expect(buyStock(eCorpStock, 1, getMockedNetscriptContext(), {})).toStrictEqual(true);
expect(eCorpStock.playerShares).toStrictEqual(1);
}
beforeAll(() => {
initGameEnvironment();
});
beforeEach(() => {
setupBasicTestingEnvironment();
Player.money = 1e100;
deleteStockMarket();
expectUninitializedStockMarket();
});
describe("WSE account and TIX API access", () => {
test("purchaseWseAccount then purchaseTixApi", () => {
const ns = getNS();
// Check if purchaseWseAccount works
expect(Player.hasWseAccount).toStrictEqual(false);
expect(ns.stock.purchaseWseAccount()).toStrictEqual(true);
expect(Player.hasWseAccount).toStrictEqual(true);
expectInitializedStockMarket();
buyShareOfECP();
// Check if purchaseTixApi works
expect(Player.hasTixApiAccess).toStrictEqual(false);
expect(ns.stock.purchaseTixApi()).toStrictEqual(true);
expect(Player.hasTixApiAccess).toStrictEqual(true);
// Check if stock market data is reset
expect(StockMarket["ECorp"].playerShares).toStrictEqual(1);
});
test("purchaseTixApi then purchaseWseAccount", () => {
const ns = getNS();
// Check if purchaseTixApi works
expect(Player.hasTixApiAccess).toStrictEqual(false);
expect(ns.stock.purchaseTixApi()).toStrictEqual(true);
expect(Player.hasTixApiAccess).toStrictEqual(true);
expectInitializedStockMarket();
buyShareOfECP();
// Check if purchaseWseAccount works
expect(Player.hasWseAccount).toStrictEqual(false);
expect(ns.stock.purchaseWseAccount()).toStrictEqual(true);
expect(Player.hasWseAccount).toStrictEqual(true);
// Check if stock market data is reset
expect(StockMarket["ECorp"].playerShares).toStrictEqual(1);
});
});
describe("4S Market Data", () => {
test("purchase4SMarketData", () => {
const ns = getNS();
expect(ns.stock.purchase4SMarketData()).toStrictEqual(false);
ns.stock.purchaseWseAccount();
expect(ns.stock.purchase4SMarketData()).toStrictEqual(true);
expect(Player.has4SData).toStrictEqual(true);
});
test("purchase4SMarketDataTixApi", () => {
const ns = getNS();
expect(() => ns.stock.purchase4SMarketDataTixApi()).toThrow("You don't have TIX API Access");
ns.stock.purchaseTixApi();
expect(ns.stock.purchase4SMarketDataTixApi()).toStrictEqual(true);
expect(Player.has4SDataTixApi).toStrictEqual(true);
});
});
describe("Prestige", () => {
test("soft reset without initializing stock market", () => {
const ns = getNS();
ns.singularity.softReset();
expectUninitializedStockMarket();
});
test("soft reset after initializing stock market", () => {
const ns = getNS();
ns.stock.purchaseTixApi();
expectInitializedStockMarket();
buyShareOfECP();
expect(StockMarket["ECorp"].playerShares).toStrictEqual(1);
ns.singularity.softReset();
expect(StockMarket["ECorp"].playerShares).toStrictEqual(0);
});
test("b1tflum3", () => {
const ns = getNS();
ns.stock.purchaseTixApi();
expectInitializedStockMarket();
buyShareOfECP();
ns.singularity.b1tflum3(1);
expectUninitializedStockMarket();
});
test("b1tflum3 with SF8", () => {
const ns = getNS();
ns.stock.purchaseTixApi();
expectInitializedStockMarket();
buyShareOfECP();
Player.sourceFiles.set(8, 1);
ns.singularity.b1tflum3(1);
expectInitializedStockMarket();
expect(StockMarket["ECorp"].playerShares).toStrictEqual(0);
});
});

View File

@@ -382,6 +382,7 @@ describe("Stock Market Tests", function () {
const stocks: string[] = [];
beforeEach(function () {
expect(deleteStockMarket).not.toThrow();
expect(initStockMarket).not.toThrow();
expect(initSymbolToStockMap).not.toThrow();
});
@@ -413,7 +414,7 @@ describe("Stock Market Tests", function () {
expect(StockMarket).toHaveProperty("storedCycles");
expect(StockMarket["storedCycles"]).toEqual(0);
expect(StockMarket).toHaveProperty("lastUpdate");
expect(StockMarket["lastUpdate"]).toEqual(0);
expect(StockMarket["lastUpdate"]).toBeGreaterThan(0);
expect(StockMarket).toHaveProperty("ticksUntilCycle");
expect(typeof StockMarket["ticksUntilCycle"]).toBe("number");
});
@@ -1069,6 +1070,7 @@ describe("Stock Market Tests", function () {
describe("Order Placing & Processing", function () {
beforeEach(function () {
expect(deleteStockMarket).not.toThrow();
expect(initStockMarket).not.toThrow();
expect(initSymbolToStockMap).not.toThrow();
@@ -1155,6 +1157,7 @@ describe("Stock Market Tests", function () {
let processOrdersRefs: IProcessOrderRefs;
beforeEach(function () {
expect(deleteStockMarket).not.toThrow();
expect(initStockMarket).not.toThrow();
expect(initSymbolToStockMap).not.toThrow();
@@ -1289,6 +1292,7 @@ describe("Stock Market Tests", function () {
});
beforeEach(function () {
expect(deleteStockMarket).not.toThrow();
expect(initStockMarket).not.toThrow();
expect(initSymbolToStockMap).not.toThrow();

View File

@@ -10,6 +10,7 @@ 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";
declare const importActual: (typeof config)["doImport"];
@@ -71,3 +72,18 @@ export function getNS(): NSFull {
}
return ns;
}
export function getMockedNetscriptContext(
workerScriptLogFunction: (func: string, txt: () => string) => void = () => {},
): NetscriptContext {
return {
function: "",
functionPath: "",
workerScript: {
log: workerScriptLogFunction,
scriptRef: {
dependencies: [],
},
} as unknown as WorkerScript,
};
}