mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-09 17:23:53 +01:00
Adding more directory-related unit tests. Several more bug fixes and QoL improvements
This commit is contained in:
parent
1775ea86ff
commit
fef7aaba8f
@ -1,10 +1,10 @@
|
||||
grow() Netscript Function
|
||||
=========================
|
||||
|
||||
.. js:function:: grow(hostname/ip)
|
||||
.. js:function:: grow(hostname/ip[, opts={}])
|
||||
|
||||
:param string hostname/ip: IP or hostname of the target server to grow
|
||||
:param object options: Optional parameters for configuring function behavior. Properties:
|
||||
:param object opts: Optional parameters for configuring function behavior. Properties:
|
||||
|
||||
* threads (*number*) - Number of threads to use for this function.
|
||||
Must be less than or equal to the number of threads the script is running with.
|
||||
|
@ -1,10 +1,10 @@
|
||||
hack() Netscript Function
|
||||
=========================
|
||||
|
||||
.. js:function:: hack(hostname/ip)
|
||||
.. js:function:: hack(hostname/ip[, opts={}])
|
||||
|
||||
:param string hostname/ip: IP or hostname of the target server to hack
|
||||
:param object options: Optional parameters for configuring function behavior. Properties:
|
||||
:param object opts: Optional parameters for configuring function behavior. Properties:
|
||||
|
||||
* threads (*number*) - Number of threads to use for this function.
|
||||
Must be less than or equal to the number of threads the script is running with.
|
||||
|
@ -1,10 +1,10 @@
|
||||
weaken() Netscript Function
|
||||
===========================
|
||||
|
||||
.. js:function:: weaken(hostname/ip, options={})
|
||||
.. js:function:: weaken(hostname/ip[, opts={}])
|
||||
|
||||
:param string hostname/ip: IP or hostname of the target server to weaken
|
||||
:param object options: Optional parameters for configuring function behavior. Properties:
|
||||
:param object opts: Optional parameters for configuring function behavior. Properties:
|
||||
|
||||
* threads (*number*) - Number of threads to use for this function.
|
||||
Must be less than or equal to the number of threads the script is running with.
|
||||
|
@ -1,13 +1,20 @@
|
||||
attempt() Netscript Function
|
||||
============================
|
||||
|
||||
.. js:function:: attempt(answer, fn[, hostname/ip=current ip])
|
||||
.. js:function:: attempt(answer, fn[, hostname/ip=current ip, opts={}])
|
||||
|
||||
:param answer: Solution for the contract
|
||||
:param string fn: Filename of the contract
|
||||
:param string hostname/ip: Hostname or IP of the server containing the contract.
|
||||
Optional. Defaults to current server if not provided
|
||||
:param object opts: Optional parameters for configuring function behavior. Properties:
|
||||
|
||||
* returnReward (*boolean*) If truthy, then the function will return a string
|
||||
that states the contract's reward when it is successfully solved.
|
||||
|
||||
Attempts to solve the Coding Contract with the provided solution.
|
||||
|
||||
:returns: Boolean indicating whether the solution was correct
|
||||
:returns: Boolean indicating whether the solution was correct. If the :code:`returnReward`
|
||||
option is configured, then the function will instead return a string. If the
|
||||
contract is successfully solved, the string will contain a description of the
|
||||
contract's reward. Otherwise, it will be an empty string.
|
||||
|
@ -2311,6 +2311,13 @@ function displaySourceFiles(listElement, sourceFiles) {
|
||||
}
|
||||
}
|
||||
|
||||
export function isRepeatableAug(aug) {
|
||||
const augName = (aug instanceof Augmentation) ? aug.name : aug;
|
||||
|
||||
if (augName === AugmentationNames.NeuroFluxGovernor) { return true; }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export {installAugmentations,
|
||||
initAugmentations, applyAugmentation, augmentationExists,
|
||||
|
@ -17,9 +17,6 @@ import { createElement } from "../utils/uiHelpers/createElement";
|
||||
import { createPopup } from "../utils/uiHelpers/createPopup";
|
||||
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
||||
|
||||
|
||||
|
||||
|
||||
/* tslint:disable:no-magic-numbers completed-docs max-classes-per-file no-console */
|
||||
|
||||
/* Represents different types of problems that a Coding Contract can have */
|
||||
|
@ -234,11 +234,16 @@ export let CONSTANTS: IMap<any> = {
|
||||
** This is just a temporary patch until the mechanic gets re-worked
|
||||
|
||||
* hack(), grow(), and weaken() functions now take optional arguments for number of threads to use (by MasonD)
|
||||
|
||||
* codingcontract.attempt() now takes an optional argument that allows you to configure the function to return a contract's reward
|
||||
* Adjusted RAM costs of Netscript Singularity functions (mostly increased)
|
||||
* Adjusted RAM cost of codingcontract.getNumTriesRemaining() Netscript function
|
||||
* Netscript Singularity functions no longer cost extra RAM outside of BitNode-4
|
||||
* Corporation employees no longer have an "age" stat
|
||||
* Gang Wanted level gain rate capped at 100 (per employee)
|
||||
* Script startup/kill is now processed every 3 seconds, instead of 6 seconds
|
||||
* getHackTime(), getGrowTime(), and getWeakenTime() now return Infinity if called on a Hacknet Server
|
||||
* Money/Income tracker now displays money lost from hospitalizations
|
||||
* Exported saves now have a unique filename based on current BitNode and timestamp
|
||||
* Bug Fix: Corporation employees stats should no longer become negative
|
||||
* Bug Fix: Fixed sleeve.getInformation() throwing error in certain scenarios
|
||||
* Bug Fix: Coding contracts should no longer generate on the w0r1d_d43m0n server
|
||||
@ -253,5 +258,7 @@ export let CONSTANTS: IMap<any> = {
|
||||
* Bug Fix: Terminal 'wget' command now correctly evaluates directory paths
|
||||
* Bug Fix: wget(), write(), and scp() Netscript functions now fail if an invalid filepath is passed in
|
||||
* Bug Fix: Having Corporation warehouses at full capacity should no longer freeze game in certain conditions
|
||||
* Bug Fix: Prevented an exploit that allows you to buy multiple copies of an Augmentation by holding the 'Enter' button
|
||||
* Bug Fix: gang.getOtherGangInformation() now properly returns a deep copy
|
||||
`
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import ReactDOM from "react-dom";
|
||||
import { FactionRoot } from "./ui/Root";
|
||||
|
||||
import { Augmentations } from "../Augmentation/Augmentations";
|
||||
import { isRepeatableAug } from "../Augmentation/AugmentationHelpers";
|
||||
import { PlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation";
|
||||
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
|
||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||
@ -93,7 +94,12 @@ export function purchaseAugmentationBoxCreate(aug, fac) {
|
||||
const yesBtn = yesNoBoxGetYesButton();
|
||||
yesBtn.innerHTML = "Purchase";
|
||||
yesBtn.addEventListener("click", function() {
|
||||
if (!isRepeatableAug(aug) && Player.hasAugmentation(aug)) {
|
||||
return;
|
||||
}
|
||||
|
||||
purchaseAugmentation(aug, fac);
|
||||
yesNoBoxClose();
|
||||
});
|
||||
|
||||
const noBtn = yesNoBoxGetNoButton();
|
||||
@ -204,7 +210,6 @@ export function purchaseAugmentation(aug, fac, sing=false) {
|
||||
"Please report this to the game developer with an explanation of how to " +
|
||||
"reproduce this.");
|
||||
}
|
||||
yesNoBoxClose();
|
||||
}
|
||||
|
||||
export function getNextNeurofluxLevel() {
|
||||
|
@ -700,7 +700,7 @@ GangMember.prototype.calculateWantedLevelGain = function(gang) {
|
||||
|
||||
// Put an arbitrary cap on this to prevent wanted level from rising too fast if the
|
||||
// denominator is very small. Might want to rethink formula later
|
||||
return Math.max(100, calc);
|
||||
return Math.min(100, calc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -350,7 +350,7 @@ export function purchaseCoreUpgrade(node, levels=1) {
|
||||
|
||||
export function purchaseCacheUpgrade(node, levels=1) {
|
||||
const sanitizedLevels = Math.round(levels);
|
||||
const cost = node.calculateCoreUpgradeCost(sanitizedLevels);
|
||||
const cost = node.calculateCacheUpgradeCost(sanitizedLevels);
|
||||
if (isNaN(cost) || cost <= 0 || sanitizedLevels < 0) {
|
||||
return false;
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ export const RamCosts: IMap<any> = {
|
||||
getContractType: () => RamCostConstants.ScriptCodingContractBaseRamCost / 2,
|
||||
getData: () => RamCostConstants.ScriptCodingContractBaseRamCost / 2,
|
||||
getDescription: () => RamCostConstants.ScriptCodingContractBaseRamCost / 2,
|
||||
getNumTriesRemaining: () => RamCostConstants.ScriptCodingContractBaseRamCost / 2,
|
||||
getNumTriesRemaining: () => RamCostConstants.ScriptCodingContractBaseRamCost / 5,
|
||||
},
|
||||
|
||||
// Duplicate Sleeve API
|
||||
|
@ -2142,29 +2142,23 @@ function NetscriptFunctions(workerScript) {
|
||||
},
|
||||
getHackTime: function(ip, hack, int) {
|
||||
updateDynamicRam("getHackTime", getRamCost("getHackTime"));
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getHackTime() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getHackTime() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
const server = safeGetServer(ip, "getHackTime");
|
||||
if (failOnHacknetServer(server, "getHackTime")) { return Infinity; }
|
||||
|
||||
return calculateHackingTime(server, hack, int); // Returns seconds
|
||||
},
|
||||
getGrowTime: function(ip, hack, int) {
|
||||
updateDynamicRam("getGrowTime", getRamCost("getGrowTime"));
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getGrowTime() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getGrowTime() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
const server = safeGetServer(ip, "getGrowTime");
|
||||
if (failOnHacknetServer(server, "getGrowTime")) { return Infinity; }
|
||||
|
||||
return calculateGrowTime(server, hack, int); // Returns seconds
|
||||
},
|
||||
getWeakenTime: function(ip, hack, int) {
|
||||
updateDynamicRam("getWeakenTime", getRamCost("getWeakenTime"));
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getWeakenTime() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getWeakenTime() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
const server = safeGetServer(ip, "getWeakenTime");
|
||||
if (failOnHacknetServer(server, "getWeakenTime")) { return Infinity; }
|
||||
|
||||
return calculateWeakenTime(server, hack, int); // Returns seconds
|
||||
},
|
||||
getScriptIncome: function(scriptname, ip) {
|
||||
@ -3453,7 +3447,13 @@ function NetscriptFunctions(workerScript) {
|
||||
nsGang.checkGangApiAccess(workerScript, "getOtherGangInformation");
|
||||
|
||||
try {
|
||||
return Object.assign(AllGangs);
|
||||
// We have to make a deep copy
|
||||
const cpy = {};
|
||||
for (const gang in AllGangs) {
|
||||
cpy[gang] = Object.assign({}, AllGangs[gang]);
|
||||
}
|
||||
|
||||
return cpy;
|
||||
} catch(e) {
|
||||
throw makeRuntimeRejectMsg(workerScript, nsGang.unknownGangApiExceptionMessage("getOtherGangInformation", e));
|
||||
}
|
||||
@ -4137,7 +4137,7 @@ function NetscriptFunctions(workerScript) {
|
||||
|
||||
// Coding Contract API
|
||||
codingcontract: {
|
||||
attempt: function(answer, fn, ip=workerScript.serverIp) {
|
||||
attempt: function(answer, fn, ip=workerScript.serverIp, { returnReward } = {}) {
|
||||
updateDynamicRam("attempt", getRamCost("codingcontract", "attempt"));
|
||||
const contract = getCodingContract(fn, ip);
|
||||
if (contract == null) {
|
||||
@ -4163,7 +4163,7 @@ function NetscriptFunctions(workerScript) {
|
||||
const reward = Player.gainCodingContractReward(contract.reward, contract.getDifficulty());
|
||||
workerScript.log(`Successfully completed Coding Contract ${fn}. Reward: ${reward}`);
|
||||
serv.removeContract(fn);
|
||||
return true;
|
||||
return returnReward ? reward : true;
|
||||
} else {
|
||||
++contract.tries;
|
||||
if (contract.tries >= contract.getMaxNumTries()) {
|
||||
@ -4172,7 +4172,8 @@ function NetscriptFunctions(workerScript) {
|
||||
} else {
|
||||
workerScript.log(`Coding Contract ${fn} failed. ${contract.getMaxNumTries() - contract.tries} attempts remaining`);
|
||||
}
|
||||
return false;
|
||||
|
||||
return returnReward ? "" : false;
|
||||
}
|
||||
},
|
||||
getContractType: function(fn, ip=workerScript.serverIp) {
|
||||
|
@ -415,24 +415,24 @@ function processNetscript1Imports(code, workerScript) {
|
||||
|
||||
// Loop through workerScripts and run every script that is not currently running
|
||||
export function runScriptsLoop() {
|
||||
var scriptDeleted = false;
|
||||
let scriptDeleted = false;
|
||||
|
||||
// Delete any scripts that finished or have been killed. Loop backwards bc removing items screws up indexing
|
||||
for (var i = workerScripts.length - 1; i >= 0; i--) {
|
||||
for (let i = workerScripts.length - 1; i >= 0; i--) {
|
||||
if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == true) {
|
||||
scriptDeleted = true;
|
||||
// Delete script from the runningScripts array on its host serverIp
|
||||
var ip = workerScripts[i].serverIp;
|
||||
var name = workerScripts[i].name;
|
||||
const ip = workerScripts[i].serverIp;
|
||||
const name = workerScripts[i].name;
|
||||
|
||||
//recalculate ram used
|
||||
// Recalculate ram used
|
||||
AllServers[ip].ramUsed = 0;
|
||||
for (let j = 0; j < workerScripts.length; j++) {
|
||||
if (workerScripts[j].serverIp !== ip) {
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
if (j === i) { // not this one
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
AllServers[ip].ramUsed += workerScripts[j].ramUsage;
|
||||
}
|
||||
@ -440,7 +440,7 @@ export function runScriptsLoop() {
|
||||
// Delete script from Active Scripts
|
||||
deleteActiveScriptsItem(workerScripts[i]);
|
||||
|
||||
for (var j = 0; j < AllServers[ip].runningScripts.length; j++) {
|
||||
for (let j = 0; j < AllServers[ip].runningScripts.length; j++) {
|
||||
if (AllServers[ip].runningScripts[j].filename == name &&
|
||||
compareArrays(AllServers[ip].runningScripts[j].args, workerScripts[i].args)) {
|
||||
AllServers[ip].runningScripts.splice(j, 1);
|
||||
@ -456,7 +456,7 @@ export function runScriptsLoop() {
|
||||
|
||||
|
||||
// Run any scripts that haven't been started
|
||||
for (var i = 0; i < workerScripts.length; i++) {
|
||||
for (let i = 0; i < workerScripts.length; i++) {
|
||||
// If it isn't running, start the script
|
||||
if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == false) {
|
||||
let p = null; // p is the script's result promise.
|
||||
@ -517,7 +517,7 @@ export function runScriptsLoop() {
|
||||
}
|
||||
}
|
||||
|
||||
setTimeoutRef(runScriptsLoop, 6000);
|
||||
setTimeoutRef(runScriptsLoop, 3e3);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,3 +1,4 @@
|
||||
import * as augmentationMethods from "./PlayerObjectAugmentationMethods";
|
||||
import * as bladeburnerMethods from "./PlayerObjectBladeburnerMethods";
|
||||
import * as corporationMethods from "./PlayerObjectCorporationMethods";
|
||||
import * as gangMethods from "./PlayerObjectGangMethods";
|
||||
@ -209,7 +210,8 @@ Object.assign(
|
||||
serverMethods,
|
||||
bladeburnerMethods,
|
||||
corporationMethods,
|
||||
gangMethods
|
||||
gangMethods,
|
||||
augmentationMethods
|
||||
);
|
||||
|
||||
PlayerObject.prototype.toJSON = function() {
|
||||
|
20
src/PersonObjects/Player/PlayerObjectAugmentationMethods.ts
Normal file
20
src/PersonObjects/Player/PlayerObjectAugmentationMethods.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Augmentation-related methods for the Player class (PlayerObject)
|
||||
*/
|
||||
import { IPlayer } from "../IPlayer";
|
||||
|
||||
import { Augmentation } from "../../Augmentation/Augmentation";
|
||||
|
||||
export function hasAugmentation(this: IPlayer, aug: string | Augmentation): boolean {
|
||||
const augName: string = (aug instanceof Augmentation) ? aug.name : aug;
|
||||
|
||||
for (const owned of this.augmentations) {
|
||||
if (owned.name === augName) { return true; }
|
||||
}
|
||||
|
||||
for (const owned of this.queuedAugmentations) {
|
||||
if (owned.name === augName) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -219,6 +219,11 @@ export function prestigeSourceFile() {
|
||||
}
|
||||
}
|
||||
|
||||
const characterMenuHeader = document.getElementById("character-menu-header");
|
||||
if (characterMenuHeader instanceof HTMLElement) {
|
||||
characterMenuHeader.click(); characterMenuHeader.click();
|
||||
}
|
||||
|
||||
this.isWorking = false;
|
||||
this.currentWorkFactionName = "";
|
||||
this.currentWorkFactionDescription = "";
|
||||
@ -1567,7 +1572,9 @@ export function hospitalize() {
|
||||
);
|
||||
}
|
||||
|
||||
this.loseMoney(this.max_hp * CONSTANTS.HospitalCostPerHp);
|
||||
const cost = this.max_hp * CONSTANTS.HospitalCostPerHp
|
||||
this.loseMoney(cost);
|
||||
this.recordMoneySource(-1 * cost, "hospitalization");
|
||||
this.hp = this.max_hp;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ import {
|
||||
loadSpecialServerIps,
|
||||
SpecialServerIps
|
||||
} from "./Server/SpecialServerIps";
|
||||
import { SourceFileFlags } from "./SourceFile/SourceFileFlags";
|
||||
import { loadStockMarket, StockMarket } from "./StockMarket/StockMarket";
|
||||
|
||||
import { createStatusText } from "./ui/createStatusText";
|
||||
@ -541,23 +542,12 @@ function loadImportedGame(saveObj, saveString) {
|
||||
}
|
||||
|
||||
BitburnerSaveObject.prototype.exportGame = function() {
|
||||
this.PlayerSave = JSON.stringify(Player);
|
||||
this.AllServersSave = JSON.stringify(AllServers);
|
||||
this.CompaniesSave = JSON.stringify(Companies);
|
||||
this.FactionsSave = JSON.stringify(Factions);
|
||||
this.SpecialServerIpsSave = JSON.stringify(SpecialServerIps);
|
||||
this.AliasesSave = JSON.stringify(Aliases);
|
||||
this.GlobalAliasesSave = JSON.stringify(GlobalAliases);
|
||||
this.MessagesSave = JSON.stringify(Messages);
|
||||
this.StockMarketSave = JSON.stringify(StockMarket);
|
||||
this.SettingsSave = JSON.stringify(Settings);
|
||||
this.VersionSave = JSON.stringify(CONSTANTS.Version);
|
||||
if (Player.inGang()) {
|
||||
this.AllGangsSave = JSON.stringify(AllGangs);
|
||||
}
|
||||
const saveString = this.getSaveString();
|
||||
|
||||
var saveString = btoa(unescape(encodeURIComponent(JSON.stringify(this))));
|
||||
var filename = "bitburnerSave.json";
|
||||
// Save file name is based on current timestamp and BitNode
|
||||
const epochTime = Math.round(Date.now() / 1000);
|
||||
const bn = Player.bitNodeN;
|
||||
const filename = `bitburnerSave_BN${bn}x${SourceFileFlags[bn]}_${epochTime}.json`;
|
||||
var file = new Blob([saveString], {type: 'text/plain'});
|
||||
if (window.navigator.msSaveOrOpenBlob) {// IE10+
|
||||
window.navigator.msSaveOrOpenBlob(file, filename);
|
||||
@ -565,7 +555,7 @@ BitburnerSaveObject.prototype.exportGame = function() {
|
||||
var a = document.createElement("a"),
|
||||
url = URL.createObjectURL(file);
|
||||
a.href = url;
|
||||
a.download = "bitburnerSave.json";
|
||||
a.download = filename;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
setTimeoutRef(function() {
|
||||
|
@ -37,8 +37,8 @@ export function removeTrailingSlash(s: string): string {
|
||||
*/
|
||||
export function isValidFilename(filename: string): boolean {
|
||||
// Allows alphanumerics, hyphens, underscores.
|
||||
// Must have a file exntesion
|
||||
const regex = /^[.a-zA-Z0-9_-]+[.][.a-zA-Z0-9_-]+$/;
|
||||
// Must have a file extension
|
||||
const regex = /^[.a-zA-Z0-9_-]+[.][.a-zA-Z0-9]+$/;
|
||||
|
||||
// match() returns null if no match is found
|
||||
return filename.match(regex) != null;
|
||||
@ -98,6 +98,7 @@ export function isValidDirectoryPath(path: string): boolean {
|
||||
* proper formatting. It dose NOT check if the file actually exists on Terminal
|
||||
*/
|
||||
export function isValidFilePath(path: string): boolean {
|
||||
if (path == null || typeof path !== "string") { return false; }
|
||||
let t_path = path;
|
||||
|
||||
// Impossible for filename to have less than length of 3
|
||||
|
@ -1179,6 +1179,7 @@ const Engine = {
|
||||
initAugmentations();
|
||||
initMessages();
|
||||
initLiterature();
|
||||
updateSourceFileFlags(Player);
|
||||
|
||||
// Open main menu accordions for new game
|
||||
const hackingHdr = document.getElementById("hacking-menu-header");
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* This is an object that is used to keep track of where all of the player's
|
||||
* money is coming from
|
||||
* money is coming from (or going to)
|
||||
*/
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
|
||||
|
||||
@ -17,6 +17,7 @@ export class MoneySourceTracker {
|
||||
gang: number = 0;
|
||||
hacking: number = 0;
|
||||
hacknetnode: number = 0;
|
||||
hospitalization: number = 0;
|
||||
infiltration: number = 0;
|
||||
stock: number = 0;
|
||||
total: number = 0;
|
||||
|
291
test/Terminal/DirectoryTests.js
Normal file
291
test/Terminal/DirectoryTests.js
Normal file
@ -0,0 +1,291 @@
|
||||
import * as dirHelpers from "../../src/Terminal/DirectoryHelpers";
|
||||
|
||||
import { expect } from "chai";
|
||||
|
||||
console.log("Beginning Terminal Directory Tests");
|
||||
|
||||
describe("Terminal Directory Tests", function() {
|
||||
describe("removeLeadingSlash()", function() {
|
||||
const removeLeadingSlash = dirHelpers.removeLeadingSlash;
|
||||
|
||||
it("should remove first slash in a string", function() {
|
||||
expect(removeLeadingSlash("/")).to.equal("");
|
||||
expect(removeLeadingSlash("/foo.txt")).to.equal("foo.txt");
|
||||
expect(removeLeadingSlash("/foo/file.txt")).to.equal("foo/file.txt");
|
||||
});
|
||||
|
||||
it("should only remove one slash", function() {
|
||||
expect(removeLeadingSlash("///")).to.equal("//");
|
||||
expect(removeLeadingSlash("//foo")).to.equal("/foo");
|
||||
});
|
||||
|
||||
it("should do nothing for a string that doesn't start with a slash", function() {
|
||||
expect(removeLeadingSlash("foo.txt")).to.equal("foo.txt");
|
||||
expect(removeLeadingSlash("foo/test.txt")).to.equal("foo/test.txt");
|
||||
});
|
||||
|
||||
it("should not fail on an empty string", function() {
|
||||
expect(removeLeadingSlash.bind(null, "")).to.not.throw();
|
||||
expect(removeLeadingSlash("")).to.equal("");
|
||||
});
|
||||
});
|
||||
|
||||
describe("removeTrailingSlash()", function() {
|
||||
const removeTrailingSlash = dirHelpers.removeTrailingSlash;
|
||||
|
||||
it("should remove last slash in a string", function() {
|
||||
expect(removeTrailingSlash("/")).to.equal("");
|
||||
expect(removeTrailingSlash("foo.txt/")).to.equal("foo.txt");
|
||||
expect(removeTrailingSlash("foo/file.txt/")).to.equal("foo/file.txt");
|
||||
});
|
||||
|
||||
it("should only remove one slash", function() {
|
||||
expect(removeTrailingSlash("///")).to.equal("//");
|
||||
expect(removeTrailingSlash("foo//")).to.equal("foo/");
|
||||
});
|
||||
|
||||
it("should do nothing for a string that doesn't end with a slash", function() {
|
||||
expect(removeTrailingSlash("foo.txt")).to.equal("foo.txt");
|
||||
expect(removeTrailingSlash("foo/test.txt")).to.equal("foo/test.txt");
|
||||
});
|
||||
|
||||
it("should not fail on an empty string", function() {
|
||||
expect(removeTrailingSlash.bind(null, "")).to.not.throw();
|
||||
expect(removeTrailingSlash("")).to.equal("");
|
||||
});
|
||||
});
|
||||
|
||||
describe("isValidFilename()", function() {
|
||||
const isValidFilename = dirHelpers.isValidFilename;
|
||||
|
||||
it("should return true for valid filenames", function() {
|
||||
expect(isValidFilename("test.txt")).to.equal(true);
|
||||
expect(isValidFilename("123.script")).to.equal(true);
|
||||
expect(isValidFilename("foo123.b")).to.equal(true);
|
||||
expect(isValidFilename("my_script.script")).to.equal(true);
|
||||
expect(isValidFilename("my-script.script")).to.equal(true);
|
||||
expect(isValidFilename("_foo.lit")).to.equal(true);
|
||||
expect(isValidFilename("mult.periods.script")).to.equal(true);
|
||||
expect(isValidFilename("mult.per-iods.again.script")).to.equal(true);
|
||||
});
|
||||
|
||||
it("should return false for invalid filenames", function() {
|
||||
expect(isValidFilename("foo")).to.equal(false);
|
||||
expect(isValidFilename("my script.script")).to.equal(false);
|
||||
expect(isValidFilename("a^.txt")).to.equal(false);
|
||||
expect(isValidFilename("b#.lit")).to.equal(false);
|
||||
expect(isValidFilename("lib().js")).to.equal(false);
|
||||
expect(isValidFilename("foo.script_")).to.equal(false);
|
||||
expect(isValidFilename("foo._script")).to.equal(false);
|
||||
expect(isValidFilename("foo.hyphened-ext")).to.equal(false);
|
||||
expect(isValidFilename("")).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isValidDirectoryName()", function() {
|
||||
const isValidDirectoryName = dirHelpers.isValidDirectoryName;
|
||||
|
||||
it("should return true for valid directory names", function() {
|
||||
expect(isValidDirectoryName("a")).to.equal(true);
|
||||
expect(isValidDirectoryName("foo")).to.equal(true);
|
||||
expect(isValidDirectoryName("foo-dir")).to.equal(true);
|
||||
expect(isValidDirectoryName("foo_dir")).to.equal(true);
|
||||
expect(isValidDirectoryName(".a")).to.equal(true);
|
||||
expect(isValidDirectoryName("1")).to.equal(true);
|
||||
expect(isValidDirectoryName("a1")).to.equal(true);
|
||||
expect(isValidDirectoryName(".a1")).to.equal(true);
|
||||
expect(isValidDirectoryName("._foo")).to.equal(true);
|
||||
expect(isValidDirectoryName("_foo")).to.equal(true);
|
||||
});
|
||||
|
||||
it("should return false for invalid directory names", function() {
|
||||
expect(isValidDirectoryName("")).to.equal(false);
|
||||
expect(isValidDirectoryName("foo.dir")).to.equal(false);
|
||||
expect(isValidDirectoryName("1.")).to.equal(false);
|
||||
expect(isValidDirectoryName("foo.")).to.equal(false);
|
||||
expect(isValidDirectoryName("dir#")).to.equal(false);
|
||||
expect(isValidDirectoryName("dir!")).to.equal(false);
|
||||
expect(isValidDirectoryName("dir*")).to.equal(false);
|
||||
expect(isValidDirectoryName(".")).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isValidDirectoryPath()", function() {
|
||||
const isValidDirectoryPath = dirHelpers.isValidDirectoryPath;
|
||||
|
||||
it("should return false for empty strings", function() {
|
||||
expect(isValidDirectoryPath("")).to.equal(false);
|
||||
});
|
||||
|
||||
it("should return true only for the forward slash if the string has length 1", function() {
|
||||
expect(isValidDirectoryPath("/")).to.equal(true);
|
||||
expect(isValidDirectoryPath(" ")).to.equal(false);
|
||||
expect(isValidDirectoryPath(".")).to.equal(false);
|
||||
expect(isValidDirectoryPath("a")).to.equal(false);
|
||||
});
|
||||
|
||||
it("should return true for valid directory paths", function() {
|
||||
expect(isValidDirectoryPath("/a")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/dir/a")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/dir/foo")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/.dir/foo-dir")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/.dir/foo_dir")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/.dir/.a")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/dir1/1")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/dir1/a1")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/dir1/.a1")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/dir_/._foo")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/dir-/_foo")).to.equal(true);
|
||||
});
|
||||
|
||||
it("should return false if the path does not have a leading slash", function() {
|
||||
expect(isValidDirectoryPath("a")).to.equal(false);
|
||||
expect(isValidDirectoryPath("dir/a")).to.equal(false);
|
||||
expect(isValidDirectoryPath("dir/foo")).to.equal(false);
|
||||
expect(isValidDirectoryPath(".dir/foo-dir")).to.equal(false);
|
||||
expect(isValidDirectoryPath(".dir/foo_dir")).to.equal(false);
|
||||
expect(isValidDirectoryPath(".dir/.a")).to.equal(false);
|
||||
expect(isValidDirectoryPath("dir1/1")).to.equal(false);
|
||||
expect(isValidDirectoryPath("dir1/a1")).to.equal(false);
|
||||
expect(isValidDirectoryPath("dir1/.a1")).to.equal(false);
|
||||
expect(isValidDirectoryPath("dir_/._foo")).to.equal(false);
|
||||
expect(isValidDirectoryPath("dir-/_foo")).to.equal(false);
|
||||
});
|
||||
|
||||
it("should accept dot notation", function() {
|
||||
expect(isValidDirectoryPath("/dir/./a")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/dir/../foo")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/.dir/./foo-dir")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/.dir/../foo_dir")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/.dir/./.a")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/dir1/1/.")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/dir1/a1/..")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/dir1/.a1/..")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/dir_/._foo/.")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/./dir-/_foo")).to.equal(true);
|
||||
expect(isValidDirectoryPath("/../dir-/_foo")).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isValidFilePath()", function() {
|
||||
const isValidFilePath = dirHelpers.isValidFilePath;
|
||||
|
||||
it("should return false for strings that are too short", function() {
|
||||
expect(isValidFilePath("/a")).to.equal(false);
|
||||
expect(isValidFilePath("a.")).to.equal(false);
|
||||
expect(isValidFilePath(".a")).to.equal(false);
|
||||
expect(isValidFilePath("/.")).to.equal(false);
|
||||
});
|
||||
|
||||
it("should return true for arguments that are just filenames", function() {
|
||||
expect(isValidFilePath("test.txt")).to.equal(true);
|
||||
expect(isValidFilePath("123.script")).to.equal(true);
|
||||
expect(isValidFilePath("foo123.b")).to.equal(true);
|
||||
expect(isValidFilePath("my_script.script")).to.equal(true);
|
||||
expect(isValidFilePath("my-script.script")).to.equal(true);
|
||||
expect(isValidFilePath("_foo.lit")).to.equal(true);
|
||||
expect(isValidFilePath("mult.periods.script")).to.equal(true);
|
||||
expect(isValidFilePath("mult.per-iods.again.script")).to.equal(true);
|
||||
});
|
||||
|
||||
it("should return true for valid filepaths", function() {
|
||||
expect(isValidFilePath("/foo/test.txt")).to.equal(true);
|
||||
expect(isValidFilePath("/../123.script")).to.equal(true);
|
||||
expect(isValidFilePath("/./foo123.b")).to.equal(true);
|
||||
expect(isValidFilePath("/dir/my_script.script")).to.equal(true);
|
||||
expect(isValidFilePath("/dir1/dir2/dir3/my-script.script")).to.equal(true);
|
||||
expect(isValidFilePath("/dir1/dir2/././../_foo.lit")).to.equal(true);
|
||||
expect(isValidFilePath("/.dir1/./../.dir2/mult.periods.script")).to.equal(true);
|
||||
expect(isValidFilePath("/_dir/../dir2/mult.per-iods.again.script")).to.equal(true);
|
||||
});
|
||||
|
||||
it("should return false for strings that end with a slash", function() {
|
||||
expect(isValidFilePath("/foo/")).to.equal(false);
|
||||
expect(isValidFilePath("foo.txt/")).to.equal(false);
|
||||
expect(isValidFilePath("/")).to.equal(false);
|
||||
expect(isValidFilePath("/_dir/")).to.equal(false);
|
||||
});
|
||||
|
||||
it("should return false for invalid arguments", function() {
|
||||
expect(isValidFilePath(null)).to.equal(false);
|
||||
expect(isValidFilePath()).to.equal(false);
|
||||
expect(isValidFilePath(5)).to.equal(false);
|
||||
expect(isValidFilePath({})).to.equal(false);
|
||||
})
|
||||
});
|
||||
|
||||
describe("getFirstParentDirectory()", function() {
|
||||
const getFirstParentDirectory = dirHelpers.getFirstParentDirectory;
|
||||
|
||||
it("should return the first parent directory in a filepath", function() {
|
||||
expect(getFirstParentDirectory("/dir1/foo.txt")).to.equal("dir1/");
|
||||
expect(getFirstParentDirectory("/dir1/dir2/dir3/dir4/foo.txt")).to.equal("dir1/");
|
||||
expect(getFirstParentDirectory("/_dir1/dir2/foo.js")).to.equal("_dir1/");
|
||||
});
|
||||
|
||||
it("should return '/' if there is no first parent directory", function() {
|
||||
expect(getFirstParentDirectory("")).to.equal("/");
|
||||
expect(getFirstParentDirectory(" ")).to.equal("/");
|
||||
expect(getFirstParentDirectory("/")).to.equal("/");
|
||||
expect(getFirstParentDirectory("//")).to.equal("/");
|
||||
expect(getFirstParentDirectory("foo.script")).to.equal("/");
|
||||
expect(getFirstParentDirectory("/foo.txt")).to.equal("/");
|
||||
});
|
||||
});
|
||||
|
||||
describe("getAllParentDirectories()", function() {
|
||||
const getAllParentDirectories = dirHelpers.getAllParentDirectories;
|
||||
|
||||
it("should return all parent directories in a filepath", function() {
|
||||
expect(getAllParentDirectories("/")).to.equal("/");
|
||||
expect(getAllParentDirectories("/home/var/foo.txt")).to.equal("/home/var/");
|
||||
expect(getAllParentDirectories("/home/var/")).to.equal("/home/var/");
|
||||
expect(getAllParentDirectories("/home/var/test/")).to.equal("/home/var/test/");
|
||||
});
|
||||
|
||||
it("should return an empty string if there are no parent directories", function() {
|
||||
expect(getAllParentDirectories("foo.txt")).to.equal("");
|
||||
});
|
||||
});
|
||||
|
||||
describe("isInRootDirectory()", function() {
|
||||
const isInRootDirectory = dirHelpers.isInRootDirectory;
|
||||
|
||||
it("should return true for filepaths that refer to a file in the root directory", function() {
|
||||
expect(isInRootDirectory("a.b")).to.equal(true);
|
||||
expect(isInRootDirectory("foo.txt")).to.equal(true);
|
||||
expect(isInRootDirectory("/foo.txt")).to.equal(true);
|
||||
});
|
||||
|
||||
it("should return false for filepaths that refer to a file that's NOT in the root directory", function() {
|
||||
expect(isInRootDirectory("/dir/foo.txt")).to.equal(false);
|
||||
expect(isInRootDirectory("dir/foo.txt")).to.equal(false);
|
||||
expect(isInRootDirectory("/./foo.js")).to.equal(false);
|
||||
expect(isInRootDirectory("../foo.js")).to.equal(false);
|
||||
expect(isInRootDirectory("/dir1/dir2/dir3/foo.txt")).to.equal(false);
|
||||
});
|
||||
|
||||
it("should return false for invalid inputs (inputs that aren't filepaths)", function() {
|
||||
expect(isInRootDirectory(null)).to.equal(false);
|
||||
expect(isInRootDirectory(undefined)).to.equal(false);
|
||||
expect(isInRootDirectory("")).to.equal(false);
|
||||
expect(isInRootDirectory(" ")).to.equal(false);
|
||||
expect(isInRootDirectory("a")).to.equal(false);
|
||||
expect(isInRootDirectory("/dir")).to.equal(false);
|
||||
expect(isInRootDirectory("/dir/")).to.equal(false);
|
||||
expect(isInRootDirectory("/dir/foo")).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("evaluateDirectoryPath()", function() {
|
||||
const evaluateDirectoryPath = dirHelpers.evaluateDirectoryPath;
|
||||
|
||||
// TODO
|
||||
});
|
||||
|
||||
describe("evaluateFilePath()", function() {
|
||||
const evaluateFilePath = dirHelpers.evaluateFilePath;
|
||||
|
||||
// TODO
|
||||
})
|
||||
});
|
@ -1,3 +1,4 @@
|
||||
export * from "./Netscript/DynamicRamCalculationTests";
|
||||
export * from "./Netscript/StaticRamCalculationTests";
|
||||
export * from "./StockMarketTests";
|
||||
export * from "./Terminal/DirectoryTests";
|
||||
|
@ -14,7 +14,7 @@ export let yesNoBoxOpen: boolean = false;
|
||||
const yesNoBoxContainer: HTMLElement | null = document.getElementById("yes-no-box-container");
|
||||
const yesNoBoxTextElement: HTMLElement | null = document.getElementById("yes-no-box-text");
|
||||
|
||||
export function yesNoBoxHotkeyHandler(e: KeyboardEvent) {
|
||||
function yesNoBoxHotkeyHandler(e: KeyboardEvent) {
|
||||
if (e.keyCode === KEY.ESC) {
|
||||
yesNoBoxClose();
|
||||
} else if (e.keyCode === KEY.ENTER) {
|
||||
|
Loading…
Reference in New Issue
Block a user