mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-29 19:13:49 +01:00
Merge pull request #4190 from Snarling/testFixes
TESTS: Fixed tests for PRs and converted tests to TS.
This commit is contained in:
commit
c4571efdbf
16
package-lock.json
generated
16
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "bitburner",
|
||||
"version": "1.7.0",
|
||||
"version": "2.1.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "bitburner",
|
||||
"version": "1.7.0",
|
||||
"version": "2.1.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "SEE LICENSE IN license.txt",
|
||||
"dependencies": {
|
||||
@ -6074,9 +6074,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001328",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001328.tgz",
|
||||
"integrity": "sha512-Ue55jHkR/s4r00FLNiX+hGMMuwml/QGqqzVeMQ5thUewznU2EdULFvI3JR7JJid6OrjJNfFvHY2G2dIjmRaDDQ==",
|
||||
"version": "1.0.30001414",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001414.tgz",
|
||||
"integrity": "sha512-t55jfSaWjCdocnFdKQoO+d2ct9C59UZg4dY3OnUlSZ447r8pUtIKdp0hpAzrGFultmTC+Us+KpKi4GZl/LXlFg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@ -26801,9 +26801,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30001328",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001328.tgz",
|
||||
"integrity": "sha512-Ue55jHkR/s4r00FLNiX+hGMMuwml/QGqqzVeMQ5thUewznU2EdULFvI3JR7JJid6OrjJNfFvHY2G2dIjmRaDDQ=="
|
||||
"version": "1.0.30001414",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001414.tgz",
|
||||
"integrity": "sha512-t55jfSaWjCdocnFdKQoO+d2ct9C59UZg4dY3OnUlSZ447r8pUtIKdp0hpAzrGFultmTC+Us+KpKi4GZl/LXlFg=="
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
import { BitNodeMultipliers, IBitNodeMultipliers } from "./BitNodeMultipliers";
|
||||
import { Player } from "../Player";
|
||||
import { BitNodeMultipliers, IBitNodeMultipliers } from "./BitNodeMultipliers";
|
||||
import { IMap } from "../types";
|
||||
import { FactionNames } from "../Faction/data/FactionNames";
|
||||
import { CityName } from "../Locations/data/CityNames";
|
||||
@ -30,7 +30,7 @@ class BitNode {
|
||||
}
|
||||
|
||||
export const BitNodes: IMap<BitNode> = {};
|
||||
|
||||
export function initBitNodes() {
|
||||
BitNodes["BitNode1"] = new BitNode(
|
||||
1,
|
||||
0,
|
||||
@ -46,8 +46,8 @@ BitNodes["BitNode1"] = new BitNode(
|
||||
<br />
|
||||
<br />
|
||||
Destroying this BitNode will give you Source-File 1, or if you already have this Source-File it will upgrade its
|
||||
level up to a maximum of 3. This Source-File lets the player start with 32GB of RAM on his/her home computer when
|
||||
entering a new BitNode, and also increases all of the player's multipliers by:
|
||||
level up to a maximum of 3. This Source-File lets the player start with 32GB of RAM on his/her home computer
|
||||
when entering a new BitNode, and also increases all of the player's multipliers by:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: 16%
|
||||
@ -68,13 +68,14 @@ BitNodes["BitNode2"] = new BitNode(
|
||||
From the shadows, they rose.
|
||||
<br />
|
||||
<br />
|
||||
Organized crime groups quickly filled the void of power left behind from the collapse of Western government in the
|
||||
2050s. As society and civilization broke down, people quickly succumbed to the innate human impulse of evil and
|
||||
savagery. The organized crime factions quickly rose to the top of the modern world.
|
||||
Organized crime groups quickly filled the void of power left behind from the collapse of Western government in
|
||||
the 2050s. As society and civilization broke down, people quickly succumbed to the innate human impulse of evil
|
||||
and savagery. The organized crime factions quickly rose to the top of the modern world.
|
||||
<br />
|
||||
<br />
|
||||
Certain Factions ({FactionNames.SlumSnakes}, {FactionNames.Tetrads}, {FactionNames.TheSyndicate},{" "}
|
||||
{FactionNames.TheDarkArmy}, {FactionNames.SpeakersForTheDead}, {FactionNames.NiteSec}, {FactionNames.TheBlackHand}
|
||||
{FactionNames.TheDarkArmy}, {FactionNames.SpeakersForTheDead}, {FactionNames.NiteSec},{" "}
|
||||
{FactionNames.TheBlackHand}
|
||||
) give the player the ability to form and manage their own gangs. These gangs will earn the player money and
|
||||
reputation with the corresponding Faction
|
||||
<br />
|
||||
@ -82,8 +83,9 @@ BitNodes["BitNode2"] = new BitNode(
|
||||
<br />
|
||||
<br />
|
||||
Destroying this BitNode will give you Source-File 2, or if you already have this Source-File it will upgrade its
|
||||
level up to a maximum of 3. This Source-File allows you to form gangs in other BitNodes once your karma decreases
|
||||
to a certain value. It also increases the player's crime success rate, crime money, and charisma multipliers by:
|
||||
level up to a maximum of 3. This Source-File allows you to form gangs in other BitNodes once your karma
|
||||
decreases to a certain value. It also increases the player's crime success rate, crime money, and charisma
|
||||
multipliers by:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: 24%
|
||||
@ -105,18 +107,18 @@ BitNodes["BitNode3"] = new BitNode(
|
||||
<br />
|
||||
<br />
|
||||
Sometime in the early 21st century economic and political globalization turned the world into a corporatocracy,
|
||||
and it never looked back. Now, the privileged elite will happily bankrupt their own countrymen, decimate their own
|
||||
community, and evict their neighbors from houses in their desperate bid to increase their wealth.
|
||||
and it never looked back. Now, the privileged elite will happily bankrupt their own countrymen, decimate their
|
||||
own community, and evict their neighbors from houses in their desperate bid to increase their wealth.
|
||||
<br />
|
||||
<br />
|
||||
In this BitNode you can create and manage your own corporation. Running a successful corporation has the potential
|
||||
of generating massive profits.
|
||||
In this BitNode you can create and manage your own corporation. Running a successful corporation has the
|
||||
potential of generating massive profits.
|
||||
<br />
|
||||
<br />
|
||||
Destroying this BitNode will give you Source-File 3, or if you already have this Source-File it will upgrade its
|
||||
level up to a maximum of 3. This Source-File lets you create corporations on other BitNodes (although some
|
||||
BitNodes will disable this mechanic) and level 3 permanently unlocks the full API. This Source-File also increases
|
||||
your charisma and company salary multipliers by:
|
||||
BitNodes will disable this mechanic) and level 3 permanently unlocks the full API. This Source-File also
|
||||
increases your charisma and company salary multipliers by:
|
||||
<br />
|
||||
Level 1: 8%
|
||||
<br />
|
||||
@ -138,13 +140,13 @@ BitNodes["BitNode4"] = new BitNode(
|
||||
<br />
|
||||
<br />
|
||||
In this BitNode you will gain access to a new set of Netscript Functions known as Singularity Functions. These
|
||||
functions allow you to control most aspects of the game through scripts, including working for factions/companies,
|
||||
purchasing/installing Augmentations, and creating programs.
|
||||
functions allow you to control most aspects of the game through scripts, including working for
|
||||
factions/companies, purchasing/installing Augmentations, and creating programs.
|
||||
<br />
|
||||
<br />
|
||||
Destroying this BitNode will give you Source-File 4, or if you already have this Source-File it will upgrade its
|
||||
level up to a maximum of 3. This Source-File lets you access and use the Singularity Functions in other BitNodes.
|
||||
Each level of this Source-File reduces the RAM cost of singularity functions:
|
||||
level up to a maximum of 3. This Source-File lets you access and use the Singularity Functions in other
|
||||
BitNodes. Each level of this Source-File reduces the RAM cost of singularity functions:
|
||||
<br />
|
||||
Level 1: 16x
|
||||
<br />
|
||||
@ -161,16 +163,16 @@ BitNodes["BitNode5"] = new BitNode(
|
||||
"Posthuman",
|
||||
(
|
||||
<>
|
||||
They said it couldn't be done. They said the human brain, along with its consciousness and intelligence, couldn't
|
||||
be replicated. They said the complexity of the brain results from unpredictable, nonlinear interactions that
|
||||
couldn't be modeled by 1's and 0's. They were wrong.
|
||||
They said it couldn't be done. They said the human brain, along with its consciousness and intelligence,
|
||||
couldn't be replicated. They said the complexity of the brain results from unpredictable, nonlinear interactions
|
||||
that couldn't be modeled by 1's and 0's. They were wrong.
|
||||
<br />
|
||||
<br />
|
||||
Destroying this BitNode will give you Source-File 5, or if you already have this Source-File it will upgrade its
|
||||
level up to a maximum of 3. This Source-File grants you a special new stat called Intelligence. Intelligence is
|
||||
unique because it is permanent and persistent (it never gets reset back to 1). However gaining Intelligence
|
||||
experience is much slower than other stats. Higher Intelligence levels will boost your production for many actions
|
||||
in the game. <br />
|
||||
experience is much slower than other stats. Higher Intelligence levels will boost your production for many
|
||||
actions in the game. <br />
|
||||
<br />
|
||||
In addition, this Source-File will unlock the getBitNodeMultipliers() Netscript function and let you start with
|
||||
Formulas.exe, and will also raise all of your hacking-related multipliers by:
|
||||
@ -223,11 +225,11 @@ BitNodes["BitNode7"] = new BitNode(
|
||||
"More human than humans",
|
||||
(
|
||||
<>
|
||||
In the middle of the 21st century, you were doing cutting-edge work at {FactionNames.OmniTekIncorporated} as part
|
||||
of the AI design team for advanced synthetic androids, or Synthoids for short. You helped achieve a major
|
||||
technological breakthrough in the sixth generation of the company's Synthoid design, called MK-VI, by developing a
|
||||
hyperintelligent AI. Many argue that this was the first sentient AI ever created. This resulted in Synthoid models
|
||||
that were stronger, faster, and more intelligent than the humans that had created them.
|
||||
In the middle of the 21st century, you were doing cutting-edge work at {FactionNames.OmniTekIncorporated} as
|
||||
part of the AI design team for advanced synthetic androids, or Synthoids for short. You helped achieve a major
|
||||
technological breakthrough in the sixth generation of the company's Synthoid design, called MK-VI, by developing
|
||||
a hyperintelligent AI. Many argue that this was the first sentient AI ever created. This resulted in Synthoid
|
||||
models that were stronger, faster, and more intelligent than the humans that had created them.
|
||||
<br />
|
||||
<br />
|
||||
In this BitNode you will be able to access the {FactionNames.Bladeburners} API, which allows you to access{" "}
|
||||
@ -235,9 +237,9 @@ BitNodes["BitNode7"] = new BitNode(
|
||||
<br />
|
||||
<br />
|
||||
Destroying this BitNode will give you Source-File 7, or if you already have this Source-File it will upgrade its
|
||||
level up to a maximum of 3. This Source-File allows you to access the {FactionNames.Bladeburners} Netscript API in
|
||||
other BitNodes. In addition, this Source-File will increase all of your {FactionNames.Bladeburners} multipliers
|
||||
by:
|
||||
level up to a maximum of 3. This Source-File allows you to access the {FactionNames.Bladeburners} Netscript API
|
||||
in other BitNodes. In addition, this Source-File will increase all of your {FactionNames.Bladeburners}{" "}
|
||||
multipliers by:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: 8%
|
||||
@ -302,8 +304,8 @@ BitNodes["BitNode9"] = new BitNode(
|
||||
quickly abandoned the project and dissociated themselves from it.
|
||||
<br />
|
||||
<br />
|
||||
This BitNode unlocks the Hacknet Server, an upgraded version of the Hacknet Node. Hacknet Servers generate hashes,
|
||||
which can be spent on a variety of different upgrades.
|
||||
This BitNode unlocks the Hacknet Server, an upgraded version of the Hacknet Node. Hacknet Servers generate
|
||||
hashes, which can be spent on a variety of different upgrades.
|
||||
<br />
|
||||
<br />
|
||||
Destroying this BitNode will give you Source-File 9, or if you already have this Source-File it will upgrade its
|
||||
@ -339,7 +341,7 @@ BitNodes["BitNode10"] = new BitNode(
|
||||
(
|
||||
<>
|
||||
In 2084, VitaLife unveiled to the world the Persona Core, a technology that allowed people to digitize their
|
||||
consciousness. Their consciousness could then be transferred into Synthoids or other bodies by trasmitting the
|
||||
consciousness. Their consciousness could then be transferred into Synthoids or other bodies by transmitting the
|
||||
digitized data. Human bodies became nothing more than 'sleeves' for the human consciousness. Mankind had finally
|
||||
achieved immortality - at least for those that could afford it.
|
||||
<br />
|
||||
@ -356,9 +358,9 @@ BitNodes["BitNode10"] = new BitNode(
|
||||
Grafting technology allows you to graft Augmentations, which is an alternative way of installing Augmentations.
|
||||
<br />
|
||||
<br />
|
||||
Destroying this BitNode will give you Source-File 10, or if you already have this Source-File it will upgrade its
|
||||
level up to a maximum of 3. This Source-File unlocks Sleeve technology, and the Grafting API in other BitNodes.
|
||||
Each level of this Source-File also grants you a Duplicate Sleeve
|
||||
Destroying this BitNode will give you Source-File 10, or if you already have this Source-File it will upgrade
|
||||
its level up to a maximum of 3. This Source-File unlocks Sleeve technology, and the Grafting API in other
|
||||
BitNodes. Each level of this Source-File also grants you a Duplicate Sleeve
|
||||
</>
|
||||
),
|
||||
);
|
||||
@ -371,20 +373,20 @@ BitNodes["BitNode11"] = new BitNode(
|
||||
<>
|
||||
The 2050s was defined by the massive amounts of violent civil unrest and anarchic rebellion that rose all around
|
||||
the world. It was this period of disorder that eventually lead to the governmental reformation of many global
|
||||
superpowers, most notably the USA and China. But just as the world was slowly beginning to recover from these dark
|
||||
times, financial catastrophe hit.
|
||||
superpowers, most notably the USA and China. But just as the world was slowly beginning to recover from these
|
||||
dark times, financial catastrophe hit.
|
||||
<br />
|
||||
<br />
|
||||
In many countries, the high cost of trying to deal with the civil disorder bankrupted the governments. In all of
|
||||
this chaos and confusion, hackers were able to steal billions of dollars from the world's largest electronic
|
||||
banks, prompting an international banking crisis as governments were unable to bail out insolvent banks. Now, the
|
||||
world is slowly crumbling in the middle of the biggest economic crisis of all time.
|
||||
banks, prompting an international banking crisis as governments were unable to bail out insolvent banks. Now,
|
||||
the world is slowly crumbling in the middle of the biggest economic crisis of all time.
|
||||
<br />
|
||||
<br />
|
||||
Destroying this BitNode will give you Source-File 11, or if you already have this Source-File it will upgrade its
|
||||
level up to a maximum of 3. This Source-File makes it so that company favor increases BOTH the player's salary and
|
||||
reputation gain rate at that company by 1% per favor (rather than just the reputation gain). This Source-File also
|
||||
increases the player's company salary and reputation gain multipliers by:
|
||||
Destroying this BitNode will give you Source-File 11, or if you already have this Source-File it will upgrade
|
||||
its level up to a maximum of 3. This Source-File makes it so that company favor increases BOTH the player's
|
||||
salary and reputation gain rate at that company by 1% per favor (rather than just the reputation gain). This
|
||||
Source-File also increases the player's company salary and reputation gain multipliers by:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: 32%
|
||||
@ -437,8 +439,8 @@ BitNodes["BitNode13"] = new BitNode(
|
||||
other. Find her in {CityName.Chongqing} and gain her trust.
|
||||
<br />
|
||||
<br />
|
||||
Destroying this BitNode will give you Source-File 13, or if you already have this Source-File it will upgrade its
|
||||
level up to a maximum of 3. This Source-File lets the {FactionNames.ChurchOfTheMachineGod} appear in other
|
||||
Destroying this BitNode will give you Source-File 13, or if you already have this Source-File it will upgrade
|
||||
its level up to a maximum of 3. This Source-File lets the {FactionNames.ChurchOfTheMachineGod} appear in other
|
||||
BitNodes.
|
||||
<br />
|
||||
<br />
|
||||
@ -446,6 +448,7 @@ BitNodes["BitNode13"] = new BitNode(
|
||||
</>
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
export const defaultMultipliers: IBitNodeMultipliers = {
|
||||
HackingLevelMultiplier: 1,
|
||||
|
@ -1,9 +1,13 @@
|
||||
import React from "react";
|
||||
import { SourceFile } from "./SourceFile";
|
||||
import { IMap } from "../types";
|
||||
import { initBitNodes, initBitNodeMultipliers } from "../BitNode/BitNode";
|
||||
|
||||
export const SourceFiles: IMap<SourceFile> = {};
|
||||
|
||||
/** Engine initializer for SourceFiles, BitNodes, and BitNodeMultipliers. Run once at engine load. */
|
||||
export function initSourceFiles() {
|
||||
initBitNodes();
|
||||
initBitNodeMultipliers();
|
||||
SourceFiles["SourceFile1"] = new SourceFile(
|
||||
1,
|
||||
(
|
||||
@ -24,8 +28,8 @@ SourceFiles["SourceFile2"] = new SourceFile(
|
||||
2,
|
||||
(
|
||||
<>
|
||||
This Source-File allows you to form gangs in other BitNodes once your karma decreases to a certain value. It also
|
||||
increases the player's crime success rate, crime money, and charisma multipliers by:
|
||||
This Source-File allows you to form gangs in other BitNodes once your karma decreases to a certain value. It
|
||||
also increases the player's crime success rate, crime money, and charisma multipliers by:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: 24%
|
||||
@ -41,8 +45,8 @@ SourceFiles["SourceFile3"] = new SourceFile(
|
||||
(
|
||||
<>
|
||||
This Source-File lets you create corporations on other BitNodes (although some BitNodes will disable this
|
||||
mechanic) and level 3 permanently unlocks the full API. This Source-File also increases your charisma and company
|
||||
salary multipliers by:
|
||||
mechanic) and level 3 permanently unlocks the full API. This Source-File also increases your charisma and
|
||||
company salary multipliers by:
|
||||
<br />
|
||||
Level 1: 8%
|
||||
<br />
|
||||
@ -71,10 +75,10 @@ SourceFiles["SourceFile5"] = new SourceFile(
|
||||
5,
|
||||
(
|
||||
<>
|
||||
This Source-File grants a special new stat called Intelligence. Intelligence is unique because it is permanent and
|
||||
persistent (it never gets reset back to 1). However, gaining Intelligence experience is much slower than other
|
||||
stats. Higher Intelligence levels will boost your production for many actions in the game. In addition, this
|
||||
Source-File will unlock:
|
||||
This Source-File grants a special new stat called Intelligence. Intelligence is unique because it is permanent
|
||||
and persistent (it never gets reset back to 1). However, gaining Intelligence experience is much slower than
|
||||
other stats. Higher Intelligence levels will boost your production for many actions in the game. In addition,
|
||||
this Source-File will unlock:
|
||||
<br />
|
||||
<ul>
|
||||
<li>
|
||||
@ -184,8 +188,8 @@ SourceFiles["SourceFile10"] = new SourceFile(
|
||||
10,
|
||||
(
|
||||
<>
|
||||
This Source-File unlocks Sleeve technology, and the Grafting API in other BitNodes. Each level of this Source-File
|
||||
also grants you a Duplicate Sleeve
|
||||
This Source-File unlocks Sleeve technology, and the Grafting API in other BitNodes. Each level of this
|
||||
Source-File also grants you a Duplicate Sleeve
|
||||
</>
|
||||
),
|
||||
);
|
||||
@ -194,8 +198,8 @@ SourceFiles["SourceFile11"] = new SourceFile(
|
||||
(
|
||||
<>
|
||||
This Source-File makes it so that company favor increases BOTH the player's salary and reputation gain rate at
|
||||
that company by 1% per favor (rather than just the reputation gain). This Source-File also increases the player's
|
||||
company salary and reputation gain multipliers by:
|
||||
that company by 1% per favor (rather than just the reputation gain). This Source-File also increases the
|
||||
player's company salary and reputation gain multipliers by:
|
||||
<br />
|
||||
<br />
|
||||
Level 1: 32%
|
||||
@ -224,3 +228,4 @@ SourceFiles["SourceFile13"] = new SourceFile(
|
||||
13,
|
||||
<>Each level of this Source-File increases the size of Stanek's Gift.</>,
|
||||
);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
import { convertTimeMsToTimeElapsedString } from "./utils/StringHelperFunctions";
|
||||
import { initAugmentations } from "./Augmentation/AugmentationHelpers";
|
||||
import { AugmentationNames } from "./Augmentation/data/AugmentationNames";
|
||||
import { initBitNodeMultipliers } from "./BitNode/BitNode";
|
||||
import { initSourceFiles } from "./SourceFile/SourceFiles";
|
||||
import { initDarkWebItems } from "./DarkWeb/DarkWebItems";
|
||||
import { generateRandomContract } from "./CodingContractGenerator";
|
||||
import { initCompanies } from "./Company/Companies";
|
||||
@ -230,8 +230,7 @@ const Engine: {
|
||||
|
||||
if (loadGame(saveString)) {
|
||||
ThemeEvents.emit();
|
||||
|
||||
initBitNodeMultipliers();
|
||||
initSourceFiles();
|
||||
initDarkWebItems();
|
||||
initAugmentations(); // Also calls Player.reapplyAllAugmentations()
|
||||
Player.reapplyAllSourceFiles();
|
||||
@ -370,7 +369,7 @@ const Engine: {
|
||||
);
|
||||
} else {
|
||||
// No save found, start new game
|
||||
initBitNodeMultipliers();
|
||||
initSourceFiles();
|
||||
initDarkWebItems();
|
||||
Engine.start(); // Run main game loop and Scripts loop
|
||||
Player.init();
|
||||
|
@ -38,9 +38,9 @@ class NumeralFormatter {
|
||||
return true;
|
||||
}
|
||||
|
||||
format(n: number, format: string): string {
|
||||
// numeraljs doesnt properly format numbers that are too big or too small
|
||||
if (Math.abs(n) < 1e-6) {
|
||||
format(n: number | string, format?: string): string {
|
||||
// numeral.js doesn't properly format numbers that are too big or too small
|
||||
if (Math.abs(n as number) < 1e-6) {
|
||||
n = 0;
|
||||
}
|
||||
const answer = numeral(n).format(format);
|
||||
@ -50,19 +50,19 @@ class NumeralFormatter {
|
||||
return answer;
|
||||
}
|
||||
|
||||
formatBigNumber(n: number): string {
|
||||
formatBigNumber(n: number | string): string {
|
||||
return this.format(n, "0.000a");
|
||||
}
|
||||
|
||||
// TODO: leverage numeral.js to do it. This function also implies you can
|
||||
// use this format in some text field but you can't. ( "1t" will parse but
|
||||
// "1s" will not)
|
||||
formatReallyBigNumber(n: number, decimalPlaces = 3): string {
|
||||
const nAbs = Math.abs(n);
|
||||
formatReallyBigNumber(n: number | string, decimalPlaces = 3): string {
|
||||
const nAbs = Math.abs(n as number);
|
||||
if (n === Infinity) return "∞";
|
||||
for (let i = 0; i < extraFormats.length; i++) {
|
||||
if (extraFormats[i] < nAbs && nAbs <= extraFormats[i] * 1000) {
|
||||
return this.format(n / extraFormats[i], "0." + "0".repeat(decimalPlaces)) + extraNotations[i];
|
||||
return this.format((n as number) / extraFormats[i], "0." + "0".repeat(decimalPlaces)) + extraNotations[i];
|
||||
}
|
||||
}
|
||||
if (nAbs < 1000) {
|
||||
@ -118,7 +118,7 @@ class NumeralFormatter {
|
||||
return this.format(n * gigaMultiplier.standard, "0.00b");
|
||||
}
|
||||
|
||||
formatPercentage(n: number, decimalPlaces = 2): string {
|
||||
formatPercentage(n: number | string, decimalPlaces = 2): string {
|
||||
const formatter: string = "0." + "0".repeat(decimalPlaces) + "%";
|
||||
return this.format(n, formatter);
|
||||
}
|
||||
|
@ -1,27 +1,22 @@
|
||||
import { Player } from "../../../src/Player";
|
||||
import { NetscriptFunctions } from "../../../src/NetscriptFunctions";
|
||||
import { getRamCost, RamCostConstants } from "../../../src/Netscript/RamCostGenerator";
|
||||
import { Environment } from "../../../src/Netscript/Environment";
|
||||
import { RunningScript } from "../../../src/Script/RunningScript";
|
||||
import { Script } from "../../../src/Script/Script";
|
||||
|
||||
jest.mock(`!!raw-loader!../NetscriptDefinitions.d.ts`, () => "", {
|
||||
virtual: true,
|
||||
});
|
||||
|
||||
const ScriptBaseCost = RamCostConstants.ScriptBaseRamCost;
|
||||
import { WorkerScript } from "../../../src/Netscript/WorkerScript";
|
||||
|
||||
describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
|
||||
const ScriptBaseCost = RamCostConstants.ScriptBaseRamCost;
|
||||
// Creates a mock RunningScript object
|
||||
/**
|
||||
*
|
||||
* @param {string} code
|
||||
* @returns
|
||||
*/
|
||||
async function createRunningScript(code) {
|
||||
function createRunningScript(code: string) {
|
||||
const script = new Script();
|
||||
script.code = code;
|
||||
await script.updateRamUsage(Player, []);
|
||||
script.updateRamUsage([]);
|
||||
|
||||
const runningScript = new RunningScript(script);
|
||||
|
||||
@ -34,7 +29,7 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
|
||||
* @param {number} val
|
||||
* @param {number} expected
|
||||
*/
|
||||
function testEquality(val, expected) {
|
||||
function testEquality(val: number, expected: number) {
|
||||
expect(val).toBeGreaterThanOrEqual(expected - 100 * Number.EPSILON);
|
||||
expect(val).toBeLessThanOrEqual(expected + 100 * Number.EPSILON);
|
||||
}
|
||||
@ -46,7 +41,10 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
|
||||
* @param {(...args: unknown[]) => unknown} fn
|
||||
* @param {unknown[]} args
|
||||
*/
|
||||
function runPotentiallyAsyncFunction(fn, ...args) {
|
||||
function runPotentiallyAsyncFunction(
|
||||
fn: (...args: (string | number | boolean)[]) => unknown,
|
||||
...args: (string | number | boolean)[]
|
||||
) {
|
||||
const res = fn(...args);
|
||||
if (res instanceof Promise) {
|
||||
res.catch(() => undefined);
|
||||
@ -61,43 +59,39 @@ 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 testNonzeroDynamicRamCost(fnDesc, ...args) {
|
||||
async function testNonzeroDynamicRamCost(fnDesc: string[], ...args: (string | number | boolean)[]) {
|
||||
if (!Array.isArray(fnDesc)) {
|
||||
throw new Error("Non-array passed to testNonzeroDynamicRamCost()");
|
||||
}
|
||||
const expected = getRamCost(Player, ...fnDesc);
|
||||
const expected = getRamCost(...fnDesc);
|
||||
expect(expected).toBeGreaterThan(0);
|
||||
|
||||
const code = `${fnDesc.join(".")}();`;
|
||||
|
||||
const runningScript = await createRunningScript(code);
|
||||
const runningScript = createRunningScript(code);
|
||||
|
||||
// We don't need a real WorkerScript
|
||||
const workerScript = {
|
||||
args: args,
|
||||
code: code,
|
||||
delay: null,
|
||||
dynamicLoadedFns: {},
|
||||
dynamicRamUsage: RamCostConstants.ScriptBaseRamCost,
|
||||
env: new Environment(null),
|
||||
env: new Environment(),
|
||||
ramUsage: runningScript.ramUsage,
|
||||
scriptRef: runningScript,
|
||||
};
|
||||
workerScript.env.vars = NetscriptFunctions(workerScript);
|
||||
workerScript.env.vars = NetscriptFunctions(workerScript as WorkerScript);
|
||||
|
||||
// Run the function through the workerscript's args
|
||||
const scope = workerScript.env.vars;
|
||||
let curr = scope[fnDesc[0]];
|
||||
for (let i = 1; i < fnDesc.length; ++i) {
|
||||
if (curr == null) {
|
||||
throw new Error(`Invalid function specified: [${fnDesc}]`);
|
||||
}
|
||||
|
||||
if (typeof curr === "function") {
|
||||
break;
|
||||
}
|
||||
|
||||
curr = curr[fnDesc[i]];
|
||||
const curr = fnDesc.reduce((prev, curr) => {
|
||||
try {
|
||||
return prev[curr];
|
||||
} catch {
|
||||
throw new Error(`Invalid function: [${fnDesc}]`);
|
||||
}
|
||||
}, scope as any);
|
||||
|
||||
if (typeof curr === "function") {
|
||||
// We use a try/catch because the function will probably fail since the game isn't
|
||||
@ -126,17 +120,17 @@ 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, skipRun = false) {
|
||||
async function testZeroDynamicRamCost(fnDesc: string[], skipRun = false) {
|
||||
if (!Array.isArray(fnDesc)) {
|
||||
throw new Error("Non-array passed to testZeroDynamicRamCost()");
|
||||
}
|
||||
const expected = getRamCost(Player, ...fnDesc);
|
||||
const expected = getRamCost(...fnDesc);
|
||||
expect(expected).toEqual(0);
|
||||
if (skipRun) return;
|
||||
|
||||
const code = `${fnDesc.join(".")}();`;
|
||||
|
||||
const runningScript = await createRunningScript(code);
|
||||
const runningScript = createRunningScript(code);
|
||||
|
||||
// We don't need a real WorkerScript
|
||||
const workerScript = {
|
||||
@ -144,26 +138,21 @@ describe("Netscript Dynamic RAM Calculation/Generation Tests", function () {
|
||||
code: code,
|
||||
dynamicLoadedFns: {},
|
||||
dynamicRamUsage: RamCostConstants.ScriptBaseRamCost,
|
||||
env: new Environment(null),
|
||||
env: new Environment(),
|
||||
ramUsage: runningScript.ramUsage,
|
||||
scriptRef: runningScript,
|
||||
};
|
||||
workerScript.env.vars = NetscriptFunctions(workerScript);
|
||||
workerScript.env.vars = NetscriptFunctions(workerScript as unknown as WorkerScript);
|
||||
|
||||
// Run the function through the workerscript's args
|
||||
const scope = workerScript.env.vars;
|
||||
let curr = scope[fnDesc[0]];
|
||||
for (let i = 1; i < fnDesc.length; ++i) {
|
||||
if (curr == null) {
|
||||
throw new Error(`Invalid function specified: [${fnDesc}]`);
|
||||
}
|
||||
|
||||
if (typeof curr === "function") {
|
||||
break;
|
||||
}
|
||||
|
||||
curr = curr[fnDesc[i]];
|
||||
const curr = fnDesc.reduce((prev, curr) => {
|
||||
try {
|
||||
return prev[curr];
|
||||
} catch {
|
||||
throw new Error(`Invalid function: [${fnDesc}]`);
|
||||
}
|
||||
}, scope as any);
|
||||
|
||||
if (typeof curr === "function") {
|
||||
// We use a try/catch because the function will probably fail since the game isn't
|
52
test/jest/Netscript/StaticRamCalculation.test.js → test/jest/Netscript/StaticRamCalculation.test.ts
52
test/jest/Netscript/StaticRamCalculation.test.js → test/jest/Netscript/StaticRamCalculation.test.ts
@ -2,10 +2,6 @@ import { Player } from "../../../src/Player";
|
||||
import { getRamCost, RamCostConstants } from "../../../src/Netscript/RamCostGenerator";
|
||||
import { calculateRamUsage } from "../../../src/Script/RamCalculations";
|
||||
|
||||
jest.mock(`!!raw-loader!../NetscriptDefinitions.d.ts`, () => "", {
|
||||
virtual: true,
|
||||
});
|
||||
|
||||
const ScriptBaseCost = RamCostConstants.ScriptBaseRamCost;
|
||||
const HacknetNamespaceCost = RamCostConstants.ScriptHacknetNodesRamCost;
|
||||
|
||||
@ -16,7 +12,7 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () {
|
||||
* @param {number} val
|
||||
* @param {number} expected
|
||||
*/
|
||||
function testEquality(val, expected) {
|
||||
function testEquality(val: number, expected: number) {
|
||||
expect(val).toBeGreaterThanOrEqual(expected - 100 * Number.EPSILON);
|
||||
expect(val).toBeLessThanOrEqual(expected + 100 * Number.EPSILON);
|
||||
}
|
||||
@ -29,17 +25,17 @@ describe("Netscript Static 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 expectNonZeroRamCost(fnDesc) {
|
||||
const expected = getRamCost(Player, ...fnDesc);
|
||||
async function expectNonZeroRamCost(fnDesc: string[]) {
|
||||
const expected = getRamCost(...fnDesc);
|
||||
expect(expected).toBeGreaterThan(0);
|
||||
|
||||
const code = fnDesc.join(".") + "(); ";
|
||||
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
testEquality(calculated, expected + ScriptBaseCost);
|
||||
|
||||
const multipleCallsCode = code.repeat(3);
|
||||
const multipleCallsCalculated = (await calculateRamUsage(Player, multipleCallsCode, [])).cost;
|
||||
const multipleCallsCalculated = calculateRamUsage(multipleCallsCode, []).cost;
|
||||
expect(multipleCallsCalculated).toEqual(calculated);
|
||||
}
|
||||
|
||||
@ -51,27 +47,21 @@ describe("Netscript Static 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 expectZeroRamCost(fnDesc) {
|
||||
const expected = getRamCost(Player, ...fnDesc);
|
||||
async function expectZeroRamCost(fnDesc: string[]) {
|
||||
const expected = getRamCost(...fnDesc);
|
||||
expect(expected).toEqual(0);
|
||||
|
||||
const code = fnDesc.join(".") + "(); ";
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
testEquality(calculated, ScriptBaseCost);
|
||||
|
||||
const multipleCallsCalculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const multipleCallsCalculated = calculateRamUsage(code, []).cost;
|
||||
expect(multipleCallsCalculated).toEqual(ScriptBaseCost);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Player} player
|
||||
* @param {number} cost
|
||||
* @returns
|
||||
*/
|
||||
function SF4Cost(player, cost) {
|
||||
if (player.bitNodeN === 4) return cost;
|
||||
const sf4 = player.sourceFileLvl(4);
|
||||
function SF4Cost(cost: number) {
|
||||
if (Player.bitNodeN === 4) return cost;
|
||||
const sf4 = Player.sourceFileLvl(4);
|
||||
if (sf4 <= 1) return cost * 16;
|
||||
if (sf4 === 2) return cost * 4;
|
||||
return cost;
|
||||
@ -86,16 +76,16 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () {
|
||||
* including the namespace(s). e.g. ["gang", "getMemberNames"]
|
||||
* @param {number} cost - expected cost
|
||||
*/
|
||||
async function expectSpecificRamCost(fnDesc, cost) {
|
||||
const expected = getRamCost(Player, ...fnDesc);
|
||||
expect(expected).toEqual(SF4Cost(Player, cost));
|
||||
async function expectSpecificRamCost(fnDesc: string[], cost: number) {
|
||||
const expected = getRamCost(...fnDesc);
|
||||
expect(expected).toEqual(SF4Cost(cost));
|
||||
|
||||
const code = fnDesc.join(".") + "(); ";
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
testEquality(calculated, ScriptBaseCost + SF4Cost(Player, cost));
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
testEquality(calculated, ScriptBaseCost + SF4Cost(cost));
|
||||
|
||||
const multipleCallsCalculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
expect(multipleCallsCalculated).toEqual(ScriptBaseCost + SF4Cost(Player, cost));
|
||||
const multipleCallsCalculated = calculateRamUsage(code, []).cost;
|
||||
expect(multipleCallsCalculated).toEqual(ScriptBaseCost + SF4Cost(cost));
|
||||
}
|
||||
|
||||
describe("Basic Functions", function () {
|
||||
@ -535,7 +525,7 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () {
|
||||
];
|
||||
it("should have zero RAM cost for all functions", function () {
|
||||
for (const fn of apiFunctions) {
|
||||
expect(getRamCost(Player, "hacknet", fn)).toEqual(0);
|
||||
expect(getRamCost("hacknet", fn)).toEqual(0);
|
||||
}
|
||||
});
|
||||
|
||||
@ -545,7 +535,7 @@ describe("Netscript Static RAM Calculation/Generation Tests", function () {
|
||||
code += "hacknet." + fn + "(); ";
|
||||
}
|
||||
|
||||
const calculated = await calculateRamUsage(Player, code, []);
|
||||
const calculated = calculateRamUsage(code, []);
|
||||
testEquality(calculated.cost, ScriptBaseCost + HacknetNamespaceCost);
|
||||
});
|
||||
});
|
@ -1,14 +1,7 @@
|
||||
// Player is needed for calculating costs like Singularity functions, that depend on acquired source files
|
||||
import { Player } from "../../../src/Player";
|
||||
|
||||
import { RamCostConstants } from "../../../src/Netscript/RamCostGenerator";
|
||||
import { calculateRamUsage } from "../../../src/Script/RamCalculations";
|
||||
import { Script } from "../../../src/Script/Script";
|
||||
|
||||
jest.mock(`!!raw-loader!../NetscriptDefinitions.d.ts`, () => "", {
|
||||
virtual: true,
|
||||
});
|
||||
|
||||
const ScriptBaseCost = RamCostConstants.ScriptBaseRamCost;
|
||||
const HackCost = 0.1;
|
||||
const GrowCost = 0.15;
|
||||
@ -17,13 +10,8 @@ const HacknetCost = 4;
|
||||
const CorpCost = 1024 - ScriptBaseCost;
|
||||
|
||||
describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
// Tests numeric equality, allowing for floating point imprecision - and includes script base cost
|
||||
/**
|
||||
*
|
||||
* @param {number} val
|
||||
* @param {number} expected
|
||||
*/
|
||||
function expectCost(val, expected) {
|
||||
/** Tests numeric equality, allowing for floating point imprecision - and includes script base cost */
|
||||
function expectCost(val: number, expected: number) {
|
||||
const expectedWithBase = expected + ScriptBaseCost;
|
||||
expect(val).toBeGreaterThanOrEqual(expectedWithBase - 100 * Number.EPSILON);
|
||||
expect(val).toBeLessThanOrEqual(expectedWithBase + 100 * Number.EPSILON);
|
||||
@ -34,7 +22,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
const code = `
|
||||
export async function main(ns) { }
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
expectCost(calculated, 0);
|
||||
});
|
||||
|
||||
@ -44,7 +32,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
ns.print("Slum snakes r00l!");
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
expectCost(calculated, 0);
|
||||
});
|
||||
|
||||
@ -54,7 +42,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
await ns.hack("joesguns");
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
expectCost(calculated, HackCost);
|
||||
});
|
||||
|
||||
@ -64,7 +52,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
await X.hack("joesguns");
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
expectCost(calculated, HackCost);
|
||||
});
|
||||
|
||||
@ -75,7 +63,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
await ns.hack("joesguns");
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
expectCost(calculated, HackCost);
|
||||
});
|
||||
|
||||
@ -86,7 +74,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
await ns.grow("joesguns");
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
expectCost(calculated, HackCost + GrowCost);
|
||||
});
|
||||
|
||||
@ -99,7 +87,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
await ns.hack("joesguns");
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
expectCost(calculated, HackCost);
|
||||
});
|
||||
|
||||
@ -114,7 +102,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
async doHacking() { await this.ns.hack("joesguns"); }
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
expectCost(calculated, HackCost);
|
||||
});
|
||||
|
||||
@ -129,7 +117,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
async doHacking() { await this.#ns.hack("joesguns"); }
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
expectCost(calculated, HackCost);
|
||||
});
|
||||
});
|
||||
@ -142,7 +130,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
}
|
||||
function get() { return 0; }
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
expectCost(calculated, 0);
|
||||
});
|
||||
|
||||
@ -153,7 +141,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
}
|
||||
function purchaseNode() { return 0; }
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
// Works at present, because the parser checks the namespace only, not the function name
|
||||
expectCost(calculated, 0);
|
||||
});
|
||||
@ -166,7 +154,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
}
|
||||
function getTask() { return 0; }
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
expectCost(calculated, 0);
|
||||
});
|
||||
});
|
||||
@ -178,7 +166,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
ns.hacknet.purchaseNode(0);
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
expectCost(calculated, HacknetCost);
|
||||
});
|
||||
|
||||
@ -188,7 +176,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
ns.corporation.getCorporation();
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
expectCost(calculated, CorpCost);
|
||||
});
|
||||
|
||||
@ -199,7 +187,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
ns.hacknet.purchaseNode(0);
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
expectCost(calculated, CorpCost + HacknetCost);
|
||||
});
|
||||
|
||||
@ -209,7 +197,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
ns.sleeve.getTask(3);
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [])).cost;
|
||||
const calculated = calculateRamUsage(code, []).cost;
|
||||
expectCost(calculated, SleeveGetTaskCost);
|
||||
});
|
||||
});
|
||||
@ -219,7 +207,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
const libCode = `
|
||||
export function dummy() { return 0; }
|
||||
`;
|
||||
const lib = new Script(Player, "libTest.js", libCode, []);
|
||||
const lib = new Script("libTest.js", libCode);
|
||||
|
||||
const code = `
|
||||
import { dummy } from "libTest";
|
||||
@ -227,7 +215,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
dummy();
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [lib])).cost;
|
||||
const calculated = calculateRamUsage(code, [lib]).cost;
|
||||
expectCost(calculated, 0);
|
||||
});
|
||||
|
||||
@ -235,7 +223,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
const libCode = `
|
||||
export async function doHack(ns) { return await ns.hack("joesguns"); }
|
||||
`;
|
||||
const lib = new Script(Player, "libTest.js", libCode, []);
|
||||
const lib = new Script("libTest.js", libCode);
|
||||
|
||||
const code = `
|
||||
import { doHack } from "libTest";
|
||||
@ -243,7 +231,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
await doHack(ns);
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [lib])).cost;
|
||||
const calculated = calculateRamUsage(code, [lib]).cost;
|
||||
expectCost(calculated, HackCost);
|
||||
});
|
||||
|
||||
@ -252,7 +240,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
export async function doHack(ns) { return await ns.hack("joesguns"); }
|
||||
export async function doGrow(ns) { return await ns.grow("joesguns"); }
|
||||
`;
|
||||
const lib = new Script(Player, "libTest.js", libCode, []);
|
||||
const lib = new Script("libTest.js", libCode);
|
||||
|
||||
const code = `
|
||||
import { doHack } from "libTest";
|
||||
@ -260,7 +248,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
await doHack(ns);
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [lib])).cost;
|
||||
const calculated = calculateRamUsage(code, [lib]).cost;
|
||||
expectCost(calculated, HackCost);
|
||||
});
|
||||
|
||||
@ -269,7 +257,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
export async function doHack(ns) { return await ns.hack("joesguns"); }
|
||||
export async function doGrow(ns) { return await ns.grow("joesguns"); }
|
||||
`;
|
||||
const lib = new Script(Player, "libTest.js", libCode, []);
|
||||
const lib = new Script("libTest.js", libCode);
|
||||
|
||||
const code = `
|
||||
import * as test from "libTest";
|
||||
@ -277,7 +265,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
await test.doHack(ns);
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [lib])).cost;
|
||||
const calculated = calculateRamUsage(code, [lib]).cost;
|
||||
expectCost(calculated, HackCost + GrowCost);
|
||||
});
|
||||
|
||||
@ -291,7 +279,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
async doGrow() { return await this.ns.grow("joesguns"); }
|
||||
}
|
||||
`;
|
||||
const lib = new Script(Player, "libTest.js", libCode, []);
|
||||
const lib = new Script("libTest.js", libCode);
|
||||
|
||||
const code = `
|
||||
import * as test from "libTest";
|
||||
@ -299,7 +287,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
await test.doHack(ns);
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [lib])).cost;
|
||||
const calculated = calculateRamUsage(code, [lib]).cost;
|
||||
expectCost(calculated, HackCost);
|
||||
});
|
||||
|
||||
@ -314,7 +302,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
return Grower;
|
||||
}
|
||||
`;
|
||||
const lib = new Script(Player, "libTest.js", libCode, []);
|
||||
const lib = new Script("libTest.js", libCode);
|
||||
|
||||
const code = `
|
||||
import { createClass } from "libTest";
|
||||
@ -325,7 +313,7 @@ describe("Parsing NetScript code to work out static RAM costs", function () {
|
||||
await growerInstance.doGrow();
|
||||
}
|
||||
`;
|
||||
const calculated = (await calculateRamUsage(Player, code, [lib])).cost;
|
||||
const calculated = calculateRamUsage(code, [lib]).cost;
|
||||
expectCost(calculated, GrowCost);
|
||||
});
|
||||
});
|
@ -1,9 +1,4 @@
|
||||
import { Script } from "../../../src/Script/Script";
|
||||
import { Player } from "../../../src/Player";
|
||||
|
||||
jest.mock(`!!raw-loader!../NetscriptDefinitions.d.ts`, () => "", {
|
||||
virtual: true,
|
||||
});
|
||||
|
||||
const code = `/** @param {NS} ns */
|
||||
export async function main(ns) {
|
||||
@ -14,9 +9,8 @@ describe("Validate Save Script Works", function () {
|
||||
it("Save", function () {
|
||||
const server = "home";
|
||||
const filename = "test.js";
|
||||
const player = Player;
|
||||
const script = new Script();
|
||||
script.saveScript(player, filename, code, server, []);
|
||||
script.saveScript(filename, code, server, []);
|
||||
|
||||
expect(script.filename).toEqual(filename);
|
||||
expect(script.code).toEqual(code);
|
||||
|
@ -224,10 +224,10 @@ describe("Terminal Directory Tests", function () {
|
||||
});
|
||||
|
||||
it("should return false for invalid arguments", function () {
|
||||
expect(isValidFilePath(null)).toEqual(false);
|
||||
expect(isValidFilePath()).toEqual(false);
|
||||
expect(isValidFilePath(5)).toEqual(false);
|
||||
expect(isValidFilePath({})).toEqual(false);
|
||||
expect(isValidFilePath(null as unknown as string)).toEqual(false);
|
||||
expect(isValidFilePath(undefined as unknown as string)).toEqual(false);
|
||||
expect(isValidFilePath(5 as unknown as string)).toEqual(false);
|
||||
expect(isValidFilePath({} as unknown as string)).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
@ -283,8 +283,8 @@ describe("Terminal Directory Tests", function () {
|
||||
});
|
||||
|
||||
it("should return false for invalid inputs (inputs that aren't filepaths)", function () {
|
||||
expect(isInRootDirectory(null)).toEqual(false);
|
||||
expect(isInRootDirectory(undefined)).toEqual(false);
|
||||
expect(isInRootDirectory(null as unknown as string)).toEqual(false);
|
||||
expect(isInRootDirectory(undefined as unknown as string)).toEqual(false);
|
||||
expect(isInRootDirectory("")).toEqual(false);
|
||||
expect(isInRootDirectory(" ")).toEqual(false);
|
||||
expect(isInRootDirectory("a")).toEqual(false);
|
@ -1,4 +1,3 @@
|
||||
import { CityName } from "./../../../src/Locations/data/CityNames";
|
||||
/* eslint-disable no-await-in-loop */
|
||||
|
||||
import { Player } from "../../../src/Player";
|
||||
@ -7,10 +6,7 @@ import { Server } from "../../../src/Server/Server";
|
||||
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,
|
||||
});
|
||||
import { initDarkWebItems } from "../../../src/DarkWeb/DarkWebItems";
|
||||
|
||||
describe("determineAllPossibilitiesForTabCompletion", function () {
|
||||
let closeServer: Server;
|
||||
@ -18,6 +14,7 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
|
||||
|
||||
beforeEach(() => {
|
||||
prestigeAllServers();
|
||||
initDarkWebItems();
|
||||
Player.init();
|
||||
|
||||
closeServer = new Server({
|
||||
@ -36,7 +33,7 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
|
||||
hackDifficulty: 1,
|
||||
moneyAvailable: 70000,
|
||||
numOpenPortsRequired: 0,
|
||||
organizationName: CityName.Aevum,
|
||||
organizationName: LocationName.Sector12JoesGuns,
|
||||
requiredHackingSkill: 1,
|
||||
serverGrowth: 3000,
|
||||
});
|
||||
@ -49,12 +46,12 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
|
||||
});
|
||||
|
||||
it("completes the connect command", async () => {
|
||||
const options = await determineAllPossibilitiesForTabCompletion(Player, "connect ", 0);
|
||||
const options = await determineAllPossibilitiesForTabCompletion("connect ", 0);
|
||||
expect(options).toEqual(["near"]);
|
||||
});
|
||||
|
||||
it("completes the buy command", async () => {
|
||||
const options = await determineAllPossibilitiesForTabCompletion(Player, "buy ", 0);
|
||||
const options = await determineAllPossibilitiesForTabCompletion("buy ", 0);
|
||||
expect(options.sort()).toEqual(
|
||||
[
|
||||
"BruteSSH.exe",
|
||||
@ -74,43 +71,43 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
|
||||
it("completes the scp command", async () => {
|
||||
Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark");
|
||||
Player.getHomeComputer().messages.push("af.lit");
|
||||
Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "oh hai mark");
|
||||
const options1 = await determineAllPossibilitiesForTabCompletion(Player, "scp ", 0);
|
||||
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
|
||||
const options1 = await determineAllPossibilitiesForTabCompletion("scp ", 0);
|
||||
expect(options1).toEqual(["/www/script.js", "af.lit", "note.txt", "www/"]);
|
||||
|
||||
const options2 = await determineAllPossibilitiesForTabCompletion(Player, "scp note.txt ", 1);
|
||||
const options2 = await determineAllPossibilitiesForTabCompletion("scp note.txt ", 1);
|
||||
expect(options2).toEqual(["home", "near", "far"]);
|
||||
});
|
||||
|
||||
it("completes the kill, tail, mem, and check commands", async () => {
|
||||
Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "oh hai mark");
|
||||
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
|
||||
for (const command of ["kill", "tail", "mem", "check"]) {
|
||||
const options = await determineAllPossibilitiesForTabCompletion(Player, `${command} `, 0);
|
||||
const options = await determineAllPossibilitiesForTabCompletion(`${command} `, 0);
|
||||
expect(options).toEqual(["/www/script.js", "www/"]);
|
||||
}
|
||||
});
|
||||
|
||||
it("completes the nano commands", async () => {
|
||||
Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "oh hai mark");
|
||||
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
|
||||
Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark");
|
||||
const options = await determineAllPossibilitiesForTabCompletion(Player, "nano ", 0);
|
||||
const options = await determineAllPossibilitiesForTabCompletion("nano ", 0);
|
||||
expect(options).toEqual(["/www/script.js", "note.txt", "www/"]);
|
||||
});
|
||||
|
||||
it("completes the rm command", async () => {
|
||||
Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark");
|
||||
Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "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");
|
||||
const options = await determineAllPossibilitiesForTabCompletion(Player, "rm ", 0);
|
||||
const options = await determineAllPossibilitiesForTabCompletion("rm ", 0);
|
||||
expect(options).toEqual(["/www/script.js", "NUKE.exe", "af.lit", "note.txt", "linklist.cct", "www/"]);
|
||||
});
|
||||
|
||||
it("completes the run command", async () => {
|
||||
Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "oh hai mark");
|
||||
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
|
||||
Player.getHomeComputer().contracts.push(new CodingContract("linklist.cct"));
|
||||
const options = await determineAllPossibilitiesForTabCompletion(Player, "run ", 0);
|
||||
const options = await determineAllPossibilitiesForTabCompletion("run ", 0);
|
||||
expect(options).toEqual(["/www/script.js", "NUKE.exe", "linklist.cct", "www/"]);
|
||||
});
|
||||
|
||||
@ -118,36 +115,36 @@ describe("determineAllPossibilitiesForTabCompletion", function () {
|
||||
Player.getHomeComputer().writeToTextFile("/www/note.txt", "oh hai mark");
|
||||
Player.getHomeComputer().messages.push("asl.msg");
|
||||
Player.getHomeComputer().messages.push("af.lit");
|
||||
const options = await determineAllPossibilitiesForTabCompletion(Player, "cat ", 0);
|
||||
const options = await determineAllPossibilitiesForTabCompletion("cat ", 0);
|
||||
expect(options).toEqual(["asl.msg", "af.lit", "/www/note.txt", "www/"]);
|
||||
});
|
||||
|
||||
it("completes the download and mv commands", async () => {
|
||||
Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "oh hai mark");
|
||||
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
|
||||
Player.getHomeComputer().writeToTextFile("note.txt", "oh hai mark");
|
||||
for (const command of ["download", "mv"]) {
|
||||
const options = await determineAllPossibilitiesForTabCompletion(Player, `${command} `, 0);
|
||||
const options = await determineAllPossibilitiesForTabCompletion(`${command} `, 0);
|
||||
expect(options).toEqual(["/www/script.js", "note.txt", "www/"]);
|
||||
}
|
||||
});
|
||||
|
||||
it("completes the cd command", async () => {
|
||||
Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "oh hai mark");
|
||||
const options = await determineAllPossibilitiesForTabCompletion(Player, "cd ", 0);
|
||||
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
|
||||
const options = await determineAllPossibilitiesForTabCompletion("cd ", 0);
|
||||
expect(options).toEqual(["www/"]);
|
||||
});
|
||||
|
||||
it("completes the ls and cd commands", async () => {
|
||||
Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "oh hai mark");
|
||||
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
|
||||
for (const command of ["ls", "cd"]) {
|
||||
const options = await determineAllPossibilitiesForTabCompletion(Player, `${command} `, 0);
|
||||
const options = await determineAllPossibilitiesForTabCompletion(`${command} `, 0);
|
||||
expect(options).toEqual(["www/"]);
|
||||
}
|
||||
});
|
||||
|
||||
it("completes commands starting with ./", async () => {
|
||||
Player.getHomeComputer().writeToScriptFile(Player, "/www/script.js", "oh hai mark");
|
||||
const options = await determineAllPossibilitiesForTabCompletion(Player, "run ./", 0);
|
||||
Player.getHomeComputer().writeToScriptFile("/www/script.js", "oh hai mark");
|
||||
const options = await determineAllPossibilitiesForTabCompletion("run ./", 0);
|
||||
expect(options).toEqual([".//www/script.js", "NUKE.exe", "./www/"]);
|
||||
});
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { numeralWrapper } from "../../../src/ui/numeralFormat";
|
||||
|
||||
let decimalFormat = "0.[000000]";
|
||||
const decimalFormat = "0.[000000]";
|
||||
|
||||
describe("Numeral formatting for positive numbers", () => {
|
||||
test("should not format too small numbers", () => {
|
||||
@ -241,6 +241,8 @@ describe("Finding the number furthest away from 0", () => {
|
||||
expect(numeralWrapper.largestAbsoluteNumber(789123, -123456, -456789)).toEqual(789123);
|
||||
});
|
||||
test("Should return 0 for invalid input", () => {
|
||||
expect(numeralWrapper.largestAbsoluteNumber("abc", undefined, null)).toEqual(0);
|
||||
expect(
|
||||
numeralWrapper.largestAbsoluteNumber("abc" as unknown as number, undefined, null as unknown as number),
|
||||
).toEqual(0);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user