Merge pull request #2046 from MartinFournier/fix/tests

Fix jest unit tests & add a github action workflow to build, test & lint
This commit is contained in:
hydroflame 2021-12-19 22:35:25 -05:00 committed by GitHub
commit 82f6bbee13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 550 additions and 435 deletions

@ -1,7 +1,27 @@
node_modules/
doc/build/
dist/
tests/*.bundle.*
input/
.dist
.tmp
.package
assets/
css/
.cypress/
cypress/
doc/
markdown/
netscript_tests/
scripts/
electron/lib
electron/greenworks.js
src/ThirdParty/*
src/JSInterpreter.js
main.bundle.js
test/*.bundle.*
editor.main.js
main.bundle.js
webpack.config.js
webpack.config-test.js

51
.github/workflows/ci.yml vendored Normal file

@ -0,0 +1,51 @@
# This is a basic workflow to help you get started with Actions
name: CI
on:
# Triggers the workflow on push or pull request events but only for the dev branch
push:
branches: [ dev ]
pull_request:
branches: [ dev ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.13.1]
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- run: echo "The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- uses: actions/checkout@v2
- run: echo "The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "The workflow is now ready to test your code on the runner."
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- name: Install npm dependencies
run: npm ci
- name: Run unit tests
run: npm run test
- name: Run linter
run: npm run lint:report
- name: Build the web app
run: npm run build
# Cannot build the electron app by default using ubuntu
# Wrapper command 'wine64' not found on the system. Consult your Linux distribution's package manager to determine how to install Wine.
# - name: Build the electron app
# run: ./package.sh
# Unable to properly run the cypress tests for now, they are throwing errors.
# - name: Run the integration tests
# run: npm run cy:test

@ -1,4 +1,5 @@
const { app, BrowserWindow, Menu, shell } = require("electron");
/* eslint-disable @typescript-eslint/no-var-requires */
const { app, BrowserWindow, Menu, shell } = require("electron");
const greenworks = require("./greenworks");
if (greenworks.init()) {
@ -127,6 +128,7 @@ function setStopProcessHandler(app, window, enabled) {
const stopProcessHandler = () => {
if (process.platform !== "darwin") {
app.quit();
// eslint-disable-next-line no-process-exit
process.exit(0);
}
};

@ -4,6 +4,8 @@ module.exports = {
transform: {
"^.+\\.(js|jsx|ts|tsx)$": "babel-jest",
},
// testMatch: ["**/?(*.)+(test).[jt]s?(x)"],
testPathIgnorePatterns: [
'.cypress', 'node_modules', 'dist',
],
testEnvironment: "jsdom",
};

@ -104,11 +104,13 @@
"build": "webpack --mode production",
"build:dev": "webpack --mode development",
"lint": "eslint --fix . --ext js,jsx,ts,tsx",
"lint:report": "eslint --ext js,jsx,ts,tsx .",
"preinstall": "node ./scripts/engines-check.js",
"test": "jest",
"test:watch": "jest --watch",
"watch": "webpack --watch --mode production",
"watch:dev": "webpack --watch --mode development",
"package-electron": "electron-packager .package bitburner --all --out .build --overwrite --icon .package/icon.png",
"electron": "cp -r electron/* .package && cp index.html .package && cp main.bundle.js .package && cp dist/vendor.bundle.js .package/dist/ && cp -r dist/ext .package/dist/ && electron-packager .package bitburner --all --out .build --overwrite --icon .package/icon.png",
"allbuild": "npm run build && npm run electron && git add --all && git commit --amend --no-edit && git push -f -u origin dev"
}

@ -32,6 +32,7 @@ function bitNodeFinishedState(): boolean {
return Player.bladeburner !== null && Player.bladeburner.blackops.hasOwnProperty("Operation Daedalus");
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function sfAchievement(): Achievement[] {
const achs: Achievement[] = [];
for (let i = 0; i <= 11; i++) {

@ -4,6 +4,7 @@ const defaultInterpreter = new Interpreter("", () => undefined);
// the acorn interpreter has a bug where it doesn't convert arrays correctly.
// so we have to more or less copy it here.
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export function toNative(pseudoObj: any): any {
if (pseudoObj == null) return null;
if (

@ -26,7 +26,7 @@ import { Locations } from "../../Locations/Locations";
import { CityName } from "../../Locations/data/CityNames";
import { LocationName } from "../../Locations/data/LocationNames";
import { Sleeve } from "../../PersonObjects/Sleeve/Sleeve";
import { calculateSkill as calculateSkillF, calculateSkillProgress as calculateSkillProgressF, getEmptySkillProgress, ISkillProgress } from "../formulas/skill";
import { calculateSkill as calculateSkillF, calculateSkillProgress as calculateSkillProgressF, ISkillProgress } from "../formulas/skill";
import { calculateIntelligenceBonus } from "../formulas/intelligence";
import {
getHackingWorkRepGain,

@ -104,8 +104,8 @@ let currentScript = {} as openScript; // Script currently being viewed
export function Root(props: IProps): React.ReactElement {
const editorRef = useRef<IStandaloneCodeEditor | null>(null);
const monacoRef = useRef<Monaco | null>(null);
const [filename, setFilename] = useState(props.filename);
const [code, setCode] = useState<string>(props.code);
const [filename] = useState(props.filename);
const [code] = useState<string>(props.code);
const [decorations, setDecorations] = useState<string[]>([]);
const [ram, setRAM] = useState("RAM: ???");
const [updatingRam, setUpdatingRam] = useState(false);

@ -246,6 +246,7 @@ export class BaseServer {
this.maxRam = ram;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
updateRamUsed(ram: number, player: IPlayer): void {
this.ramUsed = ram;
}

@ -35,7 +35,7 @@ export function removeTrailingSlash(s: string): string {
* Checks whether a string is a valid filename. Only used for the filename itself,
* not the entire filepath
*/
function isValidFilename(filename: string): boolean {
export function isValidFilename(filename: string): boolean {
// Allows alphanumerics, hyphens, underscores, and percentage signs
// Must have a file extension
const regex = /^[.a-zA-Z0-9_-]+[.][a-zA-Z0-9]+(?:-\d+(?:\.\d*)?%-INC)?$/;
@ -48,7 +48,7 @@ function isValidFilename(filename: string): boolean {
* Checks whether a string is a valid directory name. Only used for the directory itself,
* not an entire path
*/
function isValidDirectoryName(name: string): boolean {
export function isValidDirectoryName(name: string): boolean {
// Allows alphanumerics, hyphens, underscores, and percentage signs.
// Name can begin with a single period, but otherwise cannot have any
const regex = /^.?[a-zA-Z0-9_-]+$/;
@ -178,14 +178,14 @@ export function getAllParentDirectories(path: string): string {
* @param cwd The current working directory
* @returns A file path which may be absolute or relative
*/
export function getDestinationFilepath(destination: string, source: string, cwd: string) {
export function getDestinationFilepath(destination: string, source: string, cwd: string): string {
const dstDir = evaluateDirectoryPath(destination, cwd);
// If evaluating the directory for this destination fails, we have a filename or full path.
if (dstDir === null) {
return destination;
} else {
// Append the filename to the directory provided.
let t_path = removeTrailingSlash(dstDir);
const t_path = removeTrailingSlash(dstDir);
const fileName = getFileName(source);
return t_path + "/" + fileName;
}

@ -24,7 +24,7 @@ export function download(
const matchEnding = fn.length == 1 || fn === "*.*" ? null : fn.slice(1); // Treat *.* the same as *
const zip = new JSZip();
// Helper function to zip any file contents whose name matches the pattern
const zipFiles = (fileNames: string[], fileContents: string[]) => {
const zipFiles = (fileNames: string[], fileContents: string[]): void => {
for (let i = 0; i < fileContents.length; ++i) {
let name = fileNames[i];
if (name.startsWith("/")) name = name.slice(1);

@ -1,3 +1,6 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { jest, describe, expect, test } from '@jest/globals'
import { NetscriptFunctions } from "../../src/NetscriptFunctions";
import { getRamCost, RamCostConstants } from "../../src/Netscript/RamCostGenerator";
import { Environment } from "../../src/Netscript/Environment";
@ -5,6 +8,10 @@ import { RunningScript } from "../../src/Script/RunningScript";
import { Script } from "../../src/Script/Script";
import { SourceFileFlags } from "../../src/SourceFile/SourceFileFlags";
jest.mock(`!!raw-loader!../NetscriptDefinitions.d.ts`, () => '', {
virtual: true,
});
const ScriptBaseCost = RamCostConstants.ScriptBaseRamCost;
describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
@ -106,12 +113,13 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
* @param {string[]} fnDesc - describes the name of the function being tested,
* including the namespace(s). e.g. ["gang", "getMemberNames"]
*/
async function testZeroDynamicRamCost(fnDesc) {
async function testZeroDynamicRamCost(fnDesc, skipRun = false) {
if (!Array.isArray(fnDesc)) {
throw new Error("Non-array passed to testZeroDynamicRamCost()");
}
const expected = getRamCost(...fnDesc);
expect(expected).toEqual(0);
if (skipRun) return;
const code = `${fnDesc.join(".")}();`;
@ -154,7 +162,7 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
runPotentiallyAsyncFunction(curr);
} catch (e) {}
} else {
throw new Error(`Invalid function specified: [${fndesc}]`);
throw new Error(`Invalid function specified: [${fnDesc}]`);
}
testEquality(workerScript.dynamicRamUsage, ScriptBaseCost);
@ -188,13 +196,13 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
await testNonzeroDynamicRamCost(f);
});
it("hackAnalyzePercent()", async function () {
const f = ["hackAnalyzePercent"];
it("hackAnalyze()", async function () {
const f = ["hackAnalyze"];
await testNonzeroDynamicRamCost(f);
});
it("hackChance()", async function () {
const f = ["hackChance"];
it("hackAnalyzeChance()", async function () {
const f = ["hackAnalyzeChance"];
await testNonzeroDynamicRamCost(f);
});
@ -285,6 +293,7 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
it("exec()", async function () {
const f = ["exec"];
jest.spyOn(console, 'log').mockImplementation(() => {}); // eslint-disable-line
await testNonzeroDynamicRamCost(f);
});
@ -305,7 +314,7 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
it("exit()", async function () {
const f = ["exit"];
await testZeroDynamicRamCost(f);
await testZeroDynamicRamCost(f, true);
});
it("scp()", async function () {
@ -450,32 +459,32 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
it("write()", async function () {
const f = ["write"];
await testNonzeroDynamicRamCost(f);
await testZeroDynamicRamCost(f);
});
it("tryWrite()", async function () {
const f = ["tryWrite"];
await testNonzeroDynamicRamCost(f);
it("tryWritePort()", async function () {
const f = ["tryWritePort"];
await testZeroDynamicRamCost(f);
});
it("read()", async function () {
const f = ["read"];
await testNonzeroDynamicRamCost(f);
await testZeroDynamicRamCost(f);
});
it("peek()", async function () {
const f = ["peek"];
await testNonzeroDynamicRamCost(f);
await testZeroDynamicRamCost(f);
});
it("clear()", async function () {
const f = ["clear"];
await testNonzeroDynamicRamCost(f);
await testZeroDynamicRamCost(f);
});
it("getPortHandle()", async function () {
const f = ["getPortHandle"];
await testNonzeroDynamicRamCost(f);
await testZeroDynamicRamCost(f);
});
it("rm()", async function () {
@ -577,88 +586,88 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
});
describe("TIX API", function () {
it("getStockSymbols()", async function () {
const f = ["getStockSymbols"];
it("stock.getSymbols()", async function () {
const f = ["stock", "getSymbols"];
await testNonzeroDynamicRamCost(f);
});
it("getStockPrice()", async function () {
const f = ["getStockPrice"];
it("stock.getPrice()", async function () {
const f = ["stock", "getPrice"];
await testNonzeroDynamicRamCost(f);
});
it("getStockAskPrice()", async function () {
const f = ["getStockAskPrice"];
it("stock.getBidPrice()", async function () {
const f = ["stock", "getBidPrice"];
await testNonzeroDynamicRamCost(f);
});
it("getStockBidPrice()", async function () {
const f = ["getStockBidPrice"];
it("stock.getBidPrice()", async function () {
const f = ["stock", "getBidPrice"];
await testNonzeroDynamicRamCost(f);
});
it("getStockPosition()", async function () {
const f = ["getStockPosition"];
it("stock.getPosition()", async function () {
const f = ["stock", "getPosition"];
await testNonzeroDynamicRamCost(f);
});
it("getStockMaxShares()", async function () {
const f = ["getStockMaxShares"];
it("stock.getMaxShares()", async function () {
const f = ["stock", "getMaxShares"];
await testNonzeroDynamicRamCost(f);
});
it("buyStock()", async function () {
const f = ["buyStock"];
it("stock.buy()", async function () {
const f = ["stock", "buy"];
await testNonzeroDynamicRamCost(f);
});
it("sellStock()", async function () {
const f = ["sellStock"];
it("stock.sell()", async function () {
const f = ["stock", "sell"];
await testNonzeroDynamicRamCost(f);
});
it("shortStock()", async function () {
const f = ["shortStock"];
it("stock.short()", async function () {
const f = ["stock", "short"];
await testNonzeroDynamicRamCost(f);
});
it("sellShort()", async function () {
const f = ["sellShort"];
it("stock.sellShort()", async function () {
const f = ["stock", "sellShort"];
await testNonzeroDynamicRamCost(f);
});
it("placeOrder()", async function () {
const f = ["placeOrder"];
it("stock.placeOrder()", async function () {
const f = ["stock", "placeOrder"];
await testNonzeroDynamicRamCost(f);
});
it("cancelOrder()", async function () {
const f = ["cancelOrder"];
it("stock.cancelOrder()", async function () {
const f = ["stock", "cancelOrder"];
await testNonzeroDynamicRamCost(f);
});
it("getOrders()", async function () {
const f = ["getOrders"];
it("stock.getOrders()", async function () {
const f = ["stock", "getOrders"];
await testNonzeroDynamicRamCost(f);
});
it("getStockVolatility()", async function () {
const f = ["getStockVolatility"];
it("stock.getVolatility()", async function () {
const f = ["stock", "getVolatility"];
await testNonzeroDynamicRamCost(f);
});
it("getStockForecast()", async function () {
const f = ["getStockForecast"];
it("stock.getForecast()", async function () {
const f = ["stock", "getForecast"];
await testNonzeroDynamicRamCost(f);
});
it("purchase4SMarketData()", async function () {
const f = ["purchase4SMarketData"];
it("stock.purchase4SMarketData()", async function () {
const f = ["stock", "purchase4SMarketData"];
await testNonzeroDynamicRamCost(f);
});
it("purchase4SMarketDataTixApi()", async function () {
const f = ["purchase4SMarketDataTixApi"];
it("stock.purchase4SMarketDataTixApi()", async function () {
const f = ["stock", "purchase4SMarketDataTixApi"];
await testNonzeroDynamicRamCost(f);
});
});
@ -971,11 +980,6 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
await testNonzeroDynamicRamCost(f);
});
it("getCityEstimatedCommunities()", async function () {
const f = ["bladeburner", "getCityEstimatedCommunities"];
await testNonzeroDynamicRamCost(f);
});
it("getCityChaos()", async function () {
const f = ["bladeburner", "getCityChaos"];
await testNonzeroDynamicRamCost(f);

@ -1,3 +1,6 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { jest, describe, expect, test } from '@jest/globals'
import { getRamCost, RamCostConstants } from "../../src/Netscript/RamCostGenerator";
import { calculateRamUsage } from "../../src/Script/RamCalculations";
@ -81,13 +84,13 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () {
await expectNonZeroRamCost(f);
});
it("hackAnalyzePercent()", async function () {
const f = ["hackAnalyzePercent"];
it("hackAnalyze()", async function () {
const f = ["hackAnalyze"];
await expectNonZeroRamCost(f);
});
it("hackChance()", async function () {
const f = ["hackChance"];
it("hackAnalyzeChance()", async function () {
const f = ["hackAnalyzeChance"];
await expectNonZeroRamCost(f);
});
@ -343,32 +346,32 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () {
it("write()", async function () {
const f = ["write"];
await expectNonZeroRamCost(f);
await expectZeroRamCost(f);
});
it("tryWrite()", async function () {
const f = ["tryWrite"];
await expectNonZeroRamCost(f);
it("tryWritePort()", async function () {
const f = ["tryWritePort"];
await expectZeroRamCost(f);
});
it("read()", async function () {
const f = ["read"];
await expectNonZeroRamCost(f);
await expectZeroRamCost(f);
});
it("peek()", async function () {
const f = ["peek"];
await expectNonZeroRamCost(f);
await expectZeroRamCost(f);
});
it("clear()", async function () {
const f = ["clear"];
await expectNonZeroRamCost(f);
await expectZeroRamCost(f);
});
it("getPortHandle()", async function () {
const f = ["getPortHandle"];
await expectNonZeroRamCost(f);
await expectZeroRamCost(f);
});
it("rm()", async function () {
@ -508,98 +511,98 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () {
});
describe("TIX API", function () {
it("getStockSymbols()", async function () {
const f = ["getStockSymbols"];
it("stock.getSymbols()", async function () {
const f = ["stock", "getSymbols"];
await expectNonZeroRamCost(f);
});
it("getStockPrice()", async function () {
const f = ["getStockPrice"];
it("stock.getPrice()", async function () {
const f = ["stock", "getPrice"];
await expectNonZeroRamCost(f);
});
it("getStockAskPrice()", async function () {
const f = ["getStockAskPrice"];
it("stock.getAskPrice()", async function () {
const f = ["stock", "getAskPrice"];
await expectNonZeroRamCost(f);
});
it("getStockBidPrice()", async function () {
const f = ["getStockBidPrice"];
it("stock.getBidPrice()", async function () {
const f = ["stock", "getBidPrice"];
await expectNonZeroRamCost(f);
});
it("getStockPosition()", async function () {
const f = ["getStockPosition"];
it("stock.getPosition()", async function () {
const f = ["stock", "getPosition"];
await expectNonZeroRamCost(f);
});
it("getStockMaxShares()", async function () {
const f = ["getStockMaxShares"];
it("stock.getMaxShares()", async function () {
const f = ["stock", "getMaxShares"];
await expectNonZeroRamCost(f);
});
it("getStockPurchaseCost()", async function () {
const f = ["getStockPurchaseCost"];
it("stock.getPurchaseCost()", async function () {
const f = ["stock", "getPurchaseCost"];
await expectNonZeroRamCost(f);
});
it("getStockSaleGain()", async function () {
const f = ["getStockSaleGain"];
it("stock.getSaleGain()", async function () {
const f = ["stock", "getSaleGain"];
await expectNonZeroRamCost(f);
});
it("buyStock()", async function () {
const f = ["buyStock"];
it("stock.buy()", async function () {
const f = ["stock", "buy"];
await expectNonZeroRamCost(f);
});
it("sellStock()", async function () {
const f = ["sellStock"];
it("stock.sell()", async function () {
const f = ["stock", "sell"];
await expectNonZeroRamCost(f);
});
it("shortStock()", async function () {
const f = ["shortStock"];
it("stock.short()", async function () {
const f = ["stock", "short"];
await expectNonZeroRamCost(f);
});
it("sellShort()", async function () {
const f = ["sellShort"];
it("stock.sellShort()", async function () {
const f = ["stock", "sell"];
await expectNonZeroRamCost(f);
});
it("placeOrder()", async function () {
const f = ["placeOrder"];
it("stock.placeOrder()", async function () {
const f = ["stock", "placeOrder"];
await expectNonZeroRamCost(f);
});
it("cancelOrder()", async function () {
const f = ["cancelOrder"];
it("stock.cancelOrder()", async function () {
const f = ["stock", "cancelOrder"];
await expectNonZeroRamCost(f);
});
it("getOrders()", async function () {
const f = ["getOrders"];
it("stock.getOrders()", async function () {
const f = ["stock", "getOrders"];
await expectNonZeroRamCost(f);
});
it("getStockVolatility()", async function () {
const f = ["getStockVolatility"];
it("stock.getVolatility()", async function () {
const f = ["stock", "getVolatility"];
await expectNonZeroRamCost(f);
});
it("getStockForecast()", async function () {
const f = ["getStockForecast"];
it("stock.getForecast()", async function () {
const f = ["stock", "getForecast"];
await expectNonZeroRamCost(f);
});
it("purchase4SMarketData()", async function () {
const f = ["purchase4SMarketData"];
it("stock.purchase4SMarketData()", async function () {
const f = ["stock", "purchase4SMarketData"];
await expectNonZeroRamCost(f);
});
it("purchase4SMarketDataTixApi()", async function () {
const f = ["purchase4SMarketDataTixApi"];
it("stock.purchase4SMarketDataTixApi()", async function () {
const f = ["stock", "purchase4SMarketDataTixApi"];
await expectNonZeroRamCost(f);
});
});
@ -912,11 +915,6 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () {
await expectNonZeroRamCost(f);
});
it("getCityEstimatedCommunities()", async function () {
const f = ["bladeburner", "getCityEstimatedCommunities"];
await expectNonZeroRamCost(f);
});
it("getCityChaos()", async function () {
const f = ["bladeburner", "getCityChaos"];
await expectNonZeroRamCost(f);

File diff suppressed because it is too large Load Diff

@ -1,19 +1,21 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { jest, describe, expect, test } from '@jest/globals'
import { convertTimeMsToTimeElapsedString } from "../src/utils/StringHelperFunctions";
describe("StringHelperFunctions Tests", function () {
it("transforms strings", () => {
expect(convertTimeMsToTimeElapsedString(1000)).equal("1 seconds");
expect(convertTimeMsToTimeElapsedString(5 * 60 * 1000 + 34 * 1000)).equal("5 minutes 34 seconds");
expect(convertTimeMsToTimeElapsedString(2 * 60 * 60 * 24 * 1000 + 5 * 60 * 1000 + 34 * 1000)).equal(
expect(convertTimeMsToTimeElapsedString(1000)).toEqual("1 seconds");
expect(convertTimeMsToTimeElapsedString(5 * 60 * 1000 + 34 * 1000)).toEqual("5 minutes 34 seconds");
expect(convertTimeMsToTimeElapsedString(2 * 60 * 60 * 24 * 1000 + 5 * 60 * 1000 + 34 * 1000)).toEqual(
"2 days 5 minutes 34 seconds",
);
expect(convertTimeMsToTimeElapsedString(2 * 60 * 60 * 24 * 1000 + 5 * 60 * 1000 + 34 * 1000, true)).equal(
expect(convertTimeMsToTimeElapsedString(2 * 60 * 60 * 24 * 1000 + 5 * 60 * 1000 + 34 * 1000, true)).toEqual(
"2 days 5 minutes 34.000 seconds",
);
expect(convertTimeMsToTimeElapsedString(2 * 60 * 60 * 24 * 1000 + 5 * 60 * 1000 + 34 * 1000 + 123, true)).equal(
expect(convertTimeMsToTimeElapsedString(2 * 60 * 60 * 24 * 1000 + 5 * 60 * 1000 + 34 * 1000 + 123, true)).toEqual(
"2 days 5 minutes 34.123 seconds",
);
expect(convertTimeMsToTimeElapsedString(2 * 60 * 60 * 24 * 1000 + 5 * 60 * 1000 + 34 * 1000 + 123.888, true)).equal(
expect(convertTimeMsToTimeElapsedString(2 * 60 * 60 * 24 * 1000 + 5 * 60 * 1000 + 34 * 1000 + 123.888, true)).toEqual(
"2 days 5 minutes 34.123 seconds",
);
});

@ -1,3 +1,5 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { jest, describe, expect, test } from '@jest/globals'
import * as dirHelpers from "../../src/Terminal/DirectoryHelpers";
describe("Terminal Directory Tests", function () {

@ -1,3 +1,7 @@
/* eslint-disable no-await-in-loop */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { jest, describe, expect, test } from '@jest/globals'
import { Player } from "../../src/Player";
import { determineAllPossibilitiesForTabCompletion } from "../../src/Terminal/determineAllPossibilitiesForTabCompletion";
import { Server } from "../../src/Server/Server";
@ -5,6 +9,10 @@ import { AddToAllServers, prestigeAllServers } from "../../src/Server/AllServers
import { LocationName } from "../../src/Locations/data/LocationNames";
import { CodingContract } from "../../src/CodingContracts";
jest.mock(`!!raw-loader!../NetscriptDefinitions.d.ts`, () => '', {
virtual: true,
});
describe("determineAllPossibilitiesForTabCompletion", function () {
let closeServer: Server;
let farServer: Server;
@ -41,14 +49,14 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
AddToAllServers(farServer);
});
it("completes the connect command", () => {
const options = determineAllPossibilitiesForTabCompletion(Player, "connect ", 0);
expect(options).equal(["8.8.8.8", "near"]);
it("completes the connect command", async () => {
const options = await determineAllPossibilitiesForTabCompletion(Player, "connect ", 0);
expect(options).toEqual(["near"]);
});
it("completes the buy command", () => {
const options = determineAllPossibilitiesForTabCompletion(Player, "buy ", 0);
expect(options).equal([
it("completes the buy command", async () => {
const options = await determineAllPossibilitiesForTabCompletion(Player, "buy ", 0);
expect(options.sort()).toEqual([
"BruteSSH.exe",
"FTPCrack.exe",
"relaySMTP.exe",
@ -58,45 +66,48 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
"DeepscanV2.exe",
"AutoLink.exe",
"ServerProfiler.exe",
]);
"Formulas.exe",
].sort());
});
it("completes the scp command", () => {
it("completes the scp command", async () => {
Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark");
Player.getHomeComputer().messages.push("af.lit");
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
const options1 = determineAllPossibilitiesForTabCompletion(Player, "scp ", 0);
expect(options1).equal(["/www/script.js", "af.lit", "note.txt", "www/"]);
const options1 = await determineAllPossibilitiesForTabCompletion(Player, "scp ", 0);
expect(options1).toEqual(["/www/script.js", "af.lit", "note.txt", "www/"]);
const options2 = determineAllPossibilitiesForTabCompletion(Player, "scp note.txt ", 1);
expect(options2).equal([Player.getHomeComputer().ip, "home", "8.8.8.8", "near", "4.4.4.4", "far"]);
const options2 = await determineAllPossibilitiesForTabCompletion(Player, "scp note.txt ", 1);
expect(options2).toEqual(["home", "near", "far"]);
});
it("completes the kill, tail, mem, and check commands", () => {
it("completes the kill, tail, mem, and check commands", async () => {
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
for (const command of ["kill", "tail", "mem", "check"]) {
expect(determineAllPossibilitiesForTabCompletion(Player, `${command} `, 0)).equal(["/www/script.js", "www/"]);
const options = await determineAllPossibilitiesForTabCompletion(Player, `${command} `, 0);
expect(options).toEqual(["/www/script.js", "www/"]);
}
});
it("completes the nano commands", () => {
it("completes the nano commands", async () => {
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark");
expect(determineAllPossibilitiesForTabCompletion(Player, "nano ", 0)).equal([
const options = await determineAllPossibilitiesForTabCompletion(Player, "nano ", 0);
expect(options).toEqual([
"/www/script.js",
"note.txt",
".fconf",
"www/",
]);
});
it("completes the rm command", () => {
it("completes the rm command", async () => {
Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark");
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
Player.getHomeComputer().contracts.push(new CodingContract("linklist.cct"));
Player.getHomeComputer().messages.push("asl.msg");
Player.getHomeComputer().messages.push("af.lit");
expect(determineAllPossibilitiesForTabCompletion(Player, "rm ", 0)).equal([
const options = await determineAllPossibilitiesForTabCompletion(Player, "rm ", 0);
expect(options).toEqual([
"/www/script.js",
"NUKE.exe",
"af.lit",
@ -106,10 +117,11 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
]);
});
it("completes the run command", () => {
it("completes the run command", async () => {
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
Player.getHomeComputer().contracts.push(new CodingContract("linklist.cct"));
expect(determineAllPossibilitiesForTabCompletion(Player, "run ", 0)).equal([
const options = await determineAllPossibilitiesForTabCompletion(Player, "run ", 0);
expect(options).toEqual([
"/www/script.js",
"NUKE.exe",
"linklist.cct",
@ -117,11 +129,12 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
]);
});
it("completes the cat command", () => {
it("completes the cat command", async () => {
Player.getHomeComputer().writeToTextFile("/www/note.txt", "oh hai mark");
Player.getHomeComputer().messages.push("asl.msg");
Player.getHomeComputer().messages.push("af.lit");
expect(determineAllPossibilitiesForTabCompletion(Player, "cat ", 0)).equal([
const options = await determineAllPossibilitiesForTabCompletion(Player, "cat ", 0);
expect(options).toEqual([
"asl.msg",
"af.lit",
"/www/note.txt",
@ -129,11 +142,13 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
]);
});
it("completes the download and mv commands", () => {
it("completes the download and mv commands", async () => {
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark");
for (const command of ["download", "mv"]) {
expect(determineAllPossibilitiesForTabCompletion(Player, `${command} `, 0)).equal([
const options = await determineAllPossibilitiesForTabCompletion(Player, `${command} `, 0);
expect(options).toEqual([
"/www/script.js",
"note.txt",
"www/",
@ -141,21 +156,24 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
}
});
it("completes the cd command", () => {
it("completes the cd command", async () => {
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
expect(determineAllPossibilitiesForTabCompletion(Player, "cd ", 0)).equal(["www/"]);
const options = await determineAllPossibilitiesForTabCompletion(Player, "cd ", 0);
expect(options).toEqual(["www/"]);
});
it("completes the ls and cd commands", () => {
it("completes the ls and cd commands", async () => {
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
for (const command of ["ls", "cd"]) {
expect(determineAllPossibilitiesForTabCompletion(Player, `${command} `, 0)).equal(["www/"]);
const options = await determineAllPossibilitiesForTabCompletion(Player, `${command} `, 0);
expect(options).toEqual(["www/"]);
}
});
it("completes commands starting with ./", () => {
it("completes commands starting with ./", async () => {
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
expect(determineAllPossibilitiesForTabCompletion(Player, "run ./", 0)).equal([
const options = await determineAllPossibilitiesForTabCompletion(Player, "run ./", 0);
expect(options).toEqual([
".//www/script.js",
"NUKE.exe",
"./www/",