JEST: Refactor tests that add home server manually (#2358)

This commit is contained in:
catloversg
2025-10-22 07:57:14 +07:00
committed by GitHub
parent c6684431b5
commit a703e8753b
2 changed files with 85 additions and 53 deletions

View File

@@ -1,4 +1,4 @@
import { Player, setPlayer } from "@player";
import { Player } from "@player";
import { AugmentationName, GoColor, GoOpponent, GoPlayType } from "@enums";
import { Go } from "../../../src/Go/Go";
import {
@@ -22,33 +22,21 @@ import {
resetBoardState,
validateMove,
} from "../../../src/Go/effects/netscriptGoImplementation";
import { PlayerObject } from "../../../src/PersonObjects/Player/PlayerObject";
import "../../../src/Faction/Factions";
import { getNewBoardState, getNewBoardStateFromSimpleBoard } from "../../../src/Go/boardState/boardState";
import { installAugmentations } from "../../../src/Augmentation/AugmentationHelpers";
import { AddToAllServers } from "../../../src/Server/AllServers";
import { Server } from "../../../src/Server/Server";
import { initSourceFiles } from "../../../src/SourceFile/SourceFiles";
import { getMockedNetscriptContext } from "../Utilities";
import { getMockedNetscriptContext, initGameEnvironment, setupBasicTestingEnvironment } from "../Utilities";
jest.mock("../../../src/Faction/Factions", () => ({
Factions: {},
}));
initGameEnvironment();
beforeEach(() => {
setupBasicTestingEnvironment();
});
jest.mock("../../../src/ui/GameRoot", () => ({
Router: {
page: () => ({}),
toPage: () => ({}),
},
}));
const mockLogger: (s: string) => void = jest.fn();
const mockCtx = getMockedNetscriptContext((_: string, txt: () => string) => {
mockLogger(txt());
});
setPlayer(new PlayerObject());
AddToAllServers(new Server({ hostname: "home" }));
describe("Netscript Go API unit tests", () => {
describe("makeMove() tests", () => {
it("should handle invalid moves", () => {
@@ -365,7 +353,6 @@ describe("Netscript Go API unit tests", () => {
it("should have a scaled chance based on layer cheat success level", () => {
Player.setBitNodeNumber(13);
initSourceFiles();
Player.queueAugmentation(AugmentationName.BrachiBlades);
Player.queueAugmentation(AugmentationName.GrapheneBrachiBlades);
Player.queueAugmentation(AugmentationName.INFRARet);

View File

@@ -1,63 +1,108 @@
import { checkForMessagesToSend } from "../../../src/Message/MessageHelpers";
import * as dialogBoxCreate from "../../../src/ui/React/DialogBox";
import { Player } from "@player";
import "../../../src/ui/GameRoot";
import { AugmentationName } from "@enums";
import { AddToAllServers } from "../../../src/Server/AllServers";
import { Server } from "../../../src/Server/Server";
import { Router } from "../../../src/ui/GameRoot";
import { AugmentationName, MessageFilename } from "@enums";
import { installAugmentations } from "../../../src/Augmentation/AugmentationHelpers";
import { initSourceFiles } from "../../../src/SourceFile/SourceFiles";
import { initGameEnvironment, setupBasicTestingEnvironment } from "../Utilities";
import prettyFormat from "pretty-format";
jest.mock("../../../src/ui/GameRoot", () => ({
Router: {
page: () => ({}),
toPage: () => ({}),
hidingMessages: () => false,
},
}));
initGameEnvironment();
jest.mock("../../../src/ui/React/DialogBox", () => ({
dialogBoxCreate: jest.fn(),
}));
/**
* Router.hidingMessages returns true by default. It's only initialized after the first render of GameRoot, but it won't
* happen in Jest tests. If Router.hidingMessages returns true, checkForMessagesToSend will return immediately, so we
* need to override it.
*/
Router.hidingMessages = () => false;
AddToAllServers(new Server({ hostname: "home" }));
beforeEach(() => {
setupBasicTestingEnvironment();
});
/**
* Ideally, we should spy on sendMessage/showMessage and check its string param (the message file's name). However,
* they are in the same module of checkForMessagesToSend, so expect().toHaveBeenCalledTimes() does not work as expected.
* For more information, please check https://github.com/jestjs/jest/issues/936.
*/
let spiedDialogBoxCreate: jest.Spied<typeof dialogBoxCreate.dialogBoxCreate>;
function expectLastCallShowingMessageFile(name: MessageFilename): void {
/**
* showMessage passes a React element containing the message file's name. "prettyFormat" (a Jest's dependency) helps
* us convert this element to a string that can be checked by toContain.
*/
expect(prettyFormat(spiedDialogBoxCreate.mock.lastCall?.[0])).toContain(name);
}
describe("MessageHelpers tests", () => {
beforeEach(() => {
spiedDialogBoxCreate = jest.spyOn(dialogBoxCreate, "dialogBoxCreate");
});
afterEach(() => {
jest.clearAllMocks();
spiedDialogBoxCreate.mockRestore();
});
it("Should repeatedly send the Icarus message on the player's first bitnode", () => {
it("Should repeatedly send the Icarus message on the player's first BitNode", () => {
/**
* In the first BitNode, the player does not have any SF, but setupBasicTestingEnvironment adds SF4, so we need to
* clear Player.sourceFiles.
*/
Player.sourceFiles.clear();
// Queue and install TRP.
expect(Player.augmentations.length).toStrictEqual(0);
Player.queueAugmentation(AugmentationName.TheRedPill);
expect(spiedDialogBoxCreate).toHaveBeenCalledTimes(0);
installAugmentations();
expect(spiedDialogBoxCreate).toHaveBeenCalledTimes(1);
expect(Player.augmentations[0].name).toStrictEqual(AugmentationName.TheRedPill);
// Get tons of hacking exp to make sure Player.skills.hacking is greater than worldDaemon.requiredHackingSkill
Player.gainHackingExp(2 ** 200);
const showMessageSpy = jest.spyOn(dialogBoxCreate, "dialogBoxCreate");
// Receive the icarus message.
checkForMessagesToSend();
expect(spiedDialogBoxCreate).toHaveBeenCalledTimes(2);
expectLastCallShowingMessageFile(MessageFilename.RedPill);
// Receive the icarus message again.
checkForMessagesToSend();
// Called once for installing augmentations, and once for each
// checkForMessagesToSend() sending an Icarus message
expect(showMessageSpy).toHaveBeenCalledTimes(3);
expect(spiedDialogBoxCreate).toHaveBeenCalledTimes(3);
expectLastCallShowingMessageFile(MessageFilename.RedPill);
});
it("Should not repeatedly send the Icarus message after the player's first bitnode completion", () => {
initSourceFiles();
it("Should not repeatedly send the Icarus message after the player's first BitNode completion", () => {
/**
* After the player completes their first BitNode, they will have SF1.1. In theory, we don't have to do this because
* setupBasicTestingEnvironment already adds SF4. However, we still should set SF1, just in case we change how
* setupBasicTestingEnvironment works.
*/
Player.sourceFiles.set(1, 1);
// Queue and install TRP.
expect(Player.augmentations.length).toStrictEqual(0);
Player.queueAugmentation(AugmentationName.TheRedPill);
expect(spiedDialogBoxCreate).toHaveBeenCalledTimes(0);
installAugmentations();
expect(spiedDialogBoxCreate).toHaveBeenCalledTimes(1);
expect(Player.augmentations[0].name).toStrictEqual(AugmentationName.TheRedPill);
// Get tons of hacking exp to make sure Player.skills.hacking is greater than worldDaemon.requiredHackingSkill
Player.gainHackingExp(2 ** 200);
const showMessageSpy = jest.spyOn(dialogBoxCreate, "dialogBoxCreate");
// Receive the icarus message.
checkForMessagesToSend();
expect(spiedDialogBoxCreate).toHaveBeenCalledTimes(2);
expectLastCallShowingMessageFile(MessageFilename.RedPill);
// Receive the truthgazer message.
checkForMessagesToSend();
expect(spiedDialogBoxCreate).toHaveBeenCalledTimes(3);
expectLastCallShowingMessageFile(MessageFilename.TruthGazer);
// Not receive any more messages.
checkForMessagesToSend();
expect(spiedDialogBoxCreate).toHaveBeenCalledTimes(3);
expectLastCallShowingMessageFile(MessageFilename.TruthGazer);
checkForMessagesToSend();
checkForMessagesToSend();
checkForMessagesToSend();
// Called once for installing augmentations, and only once for any number of
// checkForMessagesToSend() ( sending an Icarus message only the first time)
expect(showMessageSpy).toHaveBeenCalledTimes(2);
expect(spiedDialogBoxCreate).toHaveBeenCalledTimes(3);
expectLastCallShowingMessageFile(MessageFilename.TruthGazer);
});
});