mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-18 13:43:49 +01:00
Added and Updated Stock Market tests for the new changes
This commit is contained in:
parent
a15041da75
commit
7301946236
14
package-lock.json
generated
14
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "bitburner",
|
||||
"version": "0.46.2",
|
||||
"version": "0.47.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@ -361,6 +361,18 @@
|
||||
"integrity": "sha512-LAQ1d4OPfSJ/BMbI2DuizmYrrkD9JMaTdi2hQTlI53lQ4kRQPyZQRS4CYQ7O66bnBBnP/oYdRxbk++X0xuFU6A==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/chai": {
|
||||
"version": "4.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz",
|
||||
"integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/mocha": {
|
||||
"version": "5.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz",
|
||||
"integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/numeral": {
|
||||
"version": "0.0.25",
|
||||
"resolved": "https://registry.npmjs.org/@types/numeral/-/numeral-0.0.25.tgz",
|
||||
|
@ -45,6 +45,8 @@
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.3.4",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"@types/chai": "^4.1.7",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"babel-loader": "^8.0.5",
|
||||
"beautify-lint": "^1.0.3",
|
||||
"benchmark": "^2.1.1",
|
||||
|
@ -151,6 +151,7 @@ export interface IPlayer {
|
||||
reapplyAllSourceFiles(): void;
|
||||
regenerateHp(amt: number): void;
|
||||
recordMoneySource(amt: number, source: string): void;
|
||||
setMoney(amt: number): void;
|
||||
startBladeburner(p: object): void;
|
||||
startClass(costMult: number, expMult: number, className: string): void;
|
||||
startCorporation(corpName: string, additionalShares?: number): void;
|
||||
|
@ -22,7 +22,7 @@ import { numeralWrapper } from "../ui/numeralFormat";
|
||||
|
||||
import { dialogBoxCreate } from "../../utils/DialogBox";
|
||||
|
||||
interface IProcessOrderRefs {
|
||||
export interface IProcessOrderRefs {
|
||||
rerenderFn: () => void;
|
||||
stockMarket: IStockMarket;
|
||||
symbolToStockMap: IMap<Stock>;
|
||||
@ -49,7 +49,7 @@ export function processOrders(stock: Stock, orderType: OrderTypes, posType: Posi
|
||||
}
|
||||
let stockOrders = orderBook[stock.symbol];
|
||||
if (stockOrders == null || !(stockOrders.constructor === Array)) {
|
||||
console.error(`Invalid Order book for ${stock.symbol} in processOrders()`);
|
||||
console.error(`Invalid Order book for ${stock.symbol} in processOrders(): ${stockOrders}`);
|
||||
stockOrders = [];
|
||||
return;
|
||||
}
|
||||
@ -160,9 +160,6 @@ function executeOrder(order: Order, refs: IProcessOrderRefs) {
|
||||
if (isBuy) {
|
||||
dialogBoxCreate(`Failed to execute ${order.type} for ${stock.symbol} @ ${numeralWrapper.formatMoney(order.price)} (${pos}). ` +
|
||||
`This is most likely because you do not have enough money or the order would exceed the stock's maximum number of shares`);
|
||||
} else {
|
||||
dialogBoxCreate(`Failed to execute ${order.type} for ${stock.symbol} @ ${numeralWrapper.formatMoney(order.price)} (${pos}). ` +
|
||||
`This may be a bug, please report to game developer with details.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,10 +9,10 @@ import { Company } from "../Company/Company";
|
||||
import { Server } from "../Server/Server";
|
||||
|
||||
// Change in second-order forecast due to hacks/grows
|
||||
const forecastForecastChangeFromHack = 0.1;
|
||||
export const forecastForecastChangeFromHack = 0.1;
|
||||
|
||||
// Change in second-order forecast due to company work
|
||||
const forecastForecastChangeFromCompanyWork = 0.001;
|
||||
export const forecastForecastChangeFromCompanyWork = 0.001;
|
||||
|
||||
/**
|
||||
* Potentially decreases a stock's second-order forecast when its corresponding
|
||||
|
@ -33,7 +33,7 @@ import * as ReactDOM from "react-dom";
|
||||
export let StockMarket: IStockMarket | IMap<any> = {}; // Maps full stock name -> Stock object
|
||||
export let SymbolToStockMap: IMap<Stock> = {}; // Maps symbol -> Stock object
|
||||
|
||||
export function placeOrder(stock: Stock, shares: number, price: number, type: OrderTypes, position: PositionTypes, workerScript: WorkerScript | null=null) {
|
||||
export function placeOrder(stock: Stock, shares: number, price: number, type: OrderTypes, position: PositionTypes, workerScript: WorkerScript | null=null): boolean {
|
||||
const tixApi = (workerScript instanceof WorkerScript);
|
||||
if (!(stock instanceof Stock)) {
|
||||
if (tixApi) {
|
||||
@ -85,7 +85,7 @@ interface ICancelOrderParams {
|
||||
stock?: Stock;
|
||||
type?: OrderTypes;
|
||||
}
|
||||
export function cancelOrder(params: ICancelOrderParams, workerScript: WorkerScript | null=null) {
|
||||
export function cancelOrder(params: ICancelOrderParams, workerScript: WorkerScript | null=null): boolean {
|
||||
var tixApi = (workerScript instanceof WorkerScript);
|
||||
if (StockMarket["Orders"] == null) {return false;}
|
||||
if (params.order && params.order instanceof Order) {
|
||||
@ -263,7 +263,11 @@ export function processStockPrices(numCycles=1) {
|
||||
|
||||
let otlkMagChange = stock.otlkMag * av;
|
||||
if (stock.otlkMag < 5) {
|
||||
otlkMagChange *= 10;
|
||||
if (stock.otlkMag <= 1) {
|
||||
otlkMagChange = 1;
|
||||
} else {
|
||||
otlkMagChange *= 10;
|
||||
}
|
||||
}
|
||||
stock.cycleForecast(otlkMagChange);
|
||||
stock.cycleForecastForecast(otlkMagChange / 2);
|
||||
|
@ -2,4 +2,4 @@
|
||||
* How many stock market 'ticks' before a 'cycle' is triggered.
|
||||
* A 'tick' is whenver stock prices update
|
||||
*/
|
||||
export const TicksPerCycle = 70;
|
||||
export const TicksPerCycle = 75;
|
||||
|
@ -1,19 +1,33 @@
|
||||
import { CONSTANTS } from "../src/Constants";
|
||||
import { Player } from "../src/Player";
|
||||
import { IMap } from "../src/types";
|
||||
|
||||
import { Company } from "../src/Company/Company";
|
||||
import { Server } from "../src/Server/Server";
|
||||
|
||||
import {
|
||||
buyStock,
|
||||
sellStock,
|
||||
shortStock,
|
||||
sellShort,
|
||||
} from "../src/StockMarket/BuyingAndSelling";
|
||||
import { IStockMarket } from "../src/StockMarket/IStockMarket";
|
||||
import { Order } from "../src/StockMarket/Order";
|
||||
import { processOrders } from "../src/StockMarket/OrderProcessing";
|
||||
import {
|
||||
forecastForecastChangeFromCompanyWork,
|
||||
forecastForecastChangeFromHack,
|
||||
influenceStockThroughCompanyWork,
|
||||
influenceStockThroughServerGrow,
|
||||
influenceStockThroughServerHack,
|
||||
} from "../src/StockMarket/PlayerInfluencing";
|
||||
import { processOrders, IProcessOrderRefs } from "../src/StockMarket/OrderProcessing";
|
||||
import { Stock , StockForecastInfluenceLimit } from "../src/StockMarket/Stock";
|
||||
import {
|
||||
cancelOrder,
|
||||
deleteStockMarket,
|
||||
initStockMarket,
|
||||
initSymbolToStockMap,
|
||||
loadStockMarket,
|
||||
placeOrder,
|
||||
processStockPrices,
|
||||
StockMarket,
|
||||
SymbolToStockMap,
|
||||
@ -35,7 +49,7 @@ describe("Stock Market Tests", function() {
|
||||
const commission = CONSTANTS.StockMarketCommission;
|
||||
|
||||
// Generic Stock object that can be used by each test
|
||||
let stock;
|
||||
let stock: Stock;
|
||||
const ctorParams = {
|
||||
b: true,
|
||||
initPrice: 10e3,
|
||||
@ -59,13 +73,13 @@ describe("Stock Market Tests", function() {
|
||||
describe("Stock Class", function() {
|
||||
describe("constructor", function() {
|
||||
it("should have default parameters", function() {
|
||||
let defaultStock;
|
||||
let defaultStock: Stock;
|
||||
function construct() {
|
||||
defaultStock = new Stock();
|
||||
}
|
||||
|
||||
expect(construct).to.not.throw();
|
||||
expect(defaultStock.name).to.equal("");
|
||||
expect(defaultStock!.name).to.equal("");
|
||||
});
|
||||
|
||||
it("should properly initialize props from parameters", function() {
|
||||
@ -85,7 +99,7 @@ describe("Stock Market Tests", function() {
|
||||
});
|
||||
|
||||
it ("should properly initialize props from range-values", function() {
|
||||
let stock;
|
||||
let stock: Stock;
|
||||
const params = {
|
||||
b: true,
|
||||
initPrice: {
|
||||
@ -117,10 +131,10 @@ describe("Stock Market Tests", function() {
|
||||
}
|
||||
|
||||
expect(construct).to.not.throw();
|
||||
expect(stock.price).to.be.within(params.initPrice.min, params.initPrice.max);
|
||||
expect(stock.mv).to.be.within(params.mv.min / params.mv.divisor, params.mv.max / params.mv.divisor);
|
||||
expect(stock.spreadPerc).to.be.within(params.spreadPerc.min / params.spreadPerc.divisor, params.spreadPerc.max / params.spreadPerc.divisor);
|
||||
expect(stock.shareTxForMovement).to.be.within(params.shareTxForMovement.min, params.shareTxForMovement.max);
|
||||
expect(stock!.price).to.be.within(params.initPrice.min, params.initPrice.max);
|
||||
expect(stock!.mv).to.be.within(params.mv.min / params.mv.divisor, params.mv.max / params.mv.divisor);
|
||||
expect(stock!.spreadPerc).to.be.within(params.spreadPerc.min / params.spreadPerc.divisor, params.spreadPerc.max / params.spreadPerc.divisor);
|
||||
expect(stock!.shareTxForMovement).to.be.within(params.shareTxForMovement.min, params.shareTxForMovement.max);
|
||||
});
|
||||
|
||||
it("should round the 'totalShare' prop to the nearest 100k", function() {
|
||||
@ -365,7 +379,7 @@ describe("Stock Market Tests", function() {
|
||||
describe("StockMarket object", function() {
|
||||
describe("Initialization", function() {
|
||||
// Keeps track of initialized stocks. Contains their symbols
|
||||
const stocks = [];
|
||||
const stocks: string[]= [];
|
||||
|
||||
before(function() {
|
||||
expect(initStockMarket).to.not.throw();
|
||||
@ -430,7 +444,7 @@ describe("Stock Market Tests", function() {
|
||||
|
||||
it("should trigger a price update when it has enough cycles", function() {
|
||||
// Get the initial prices
|
||||
const initialValues = {};
|
||||
const initialValues: IMap<any> = {};
|
||||
for (const stockName in StockMarket) {
|
||||
const stock = StockMarket[stockName];
|
||||
if (!(stock instanceof Stock)) { continue; }
|
||||
@ -451,7 +465,7 @@ describe("Stock Market Tests", function() {
|
||||
if (!(stock instanceof Stock)) { continue; }
|
||||
expect(initialValues[stock.symbol].price).to.not.equal(stock.price);
|
||||
// expect(initialValues[stock.symbol].otlkMag).to.not.equal(stock.otlkMag);
|
||||
expect(initialValues[stock.symbol]).to.satisfy(function(initValue) {
|
||||
expect(initialValues[stock.symbol]).to.satisfy(function(initValue: any) {
|
||||
if ((initValue.otlkMag !== stock.otlkMag) || (initValue.b !== stock.b)) {
|
||||
return true;
|
||||
} else {
|
||||
@ -483,7 +497,7 @@ describe("Stock Market Tests", function() {
|
||||
describe("Transaction Cost Calculator Functions", function() {
|
||||
describe("getBuyTransactionCost()", function() {
|
||||
it("should fail on invalid 'stock' argument", function() {
|
||||
const res = getBuyTransactionCost({}, 10, PositionTypes.Long);
|
||||
const res = getBuyTransactionCost({} as Stock, 10, PositionTypes.Long);
|
||||
expect(res).to.equal(null);
|
||||
});
|
||||
|
||||
@ -516,7 +530,7 @@ describe("Stock Market Tests", function() {
|
||||
|
||||
describe("getSellTransactionGain()", function() {
|
||||
it("should fail on invalid 'stock' argument", function() {
|
||||
const res = getSellTransactionGain({}, 10, PositionTypes.Long);
|
||||
const res = getSellTransactionGain({} as Stock, 10, PositionTypes.Long);
|
||||
expect(res).to.equal(null);
|
||||
});
|
||||
|
||||
@ -555,11 +569,11 @@ describe("Stock Market Tests", function() {
|
||||
|
||||
describe("Forecast Movement Processor Function", function() {
|
||||
// N = 1 is the original forecast
|
||||
function getNthForecast(origForecast, n) {
|
||||
function getNthForecast(origForecast: number, n: number) {
|
||||
return origForecast - forecastChangePerPriceMovement * (n - 1);
|
||||
}
|
||||
|
||||
function getNthForecastForecast(origForecastForecast, n) {
|
||||
function getNthForecastForecast(origForecastForecast: number, n: number) {
|
||||
if (stock.otlkMagForecast > 50) {
|
||||
const expected = origForecastForecast - (forecastChangePerPriceMovement * (n - 1) * (stock.mv / 100));
|
||||
return expected < 50 ? 50 : expected;
|
||||
@ -576,24 +590,24 @@ describe("Stock Market Tests", function() {
|
||||
it("should do nothing on invalid 'stock' argument", function() {
|
||||
const oldTracker = stock.shareTxUntilMovement;
|
||||
|
||||
processTransactionForecastMovement({}, mvmtShares, PositionTypes.Long);
|
||||
processTransactionForecastMovement({} as Stock, mvmtShares);
|
||||
expect(stock.shareTxUntilMovement).to.equal(oldTracker);
|
||||
});
|
||||
|
||||
it("should do nothing on invalid 'shares' arg", function() {
|
||||
const oldTracker = stock.shareTxUntilMovement;
|
||||
|
||||
processTransactionForecastMovement(stock, NaN, PositionTypes.Long);
|
||||
processTransactionForecastMovement(stock, NaN);
|
||||
expect(stock.shareTxUntilMovement).to.equal(oldTracker);
|
||||
|
||||
processTransactionForecastMovement(stock, -1, PositionTypes.Long);
|
||||
processTransactionForecastMovement(stock, -1);
|
||||
expect(stock.shareTxUntilMovement).to.equal(oldTracker);
|
||||
});
|
||||
|
||||
it("should properly evaluate a LONG transaction that doesn't trigger a forecast movement", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
|
||||
processTransactionForecastMovement(stock, noMvmtShares, PositionTypes.Long);
|
||||
processTransactionForecastMovement(stock, noMvmtShares);
|
||||
expect(stock.otlkMag).to.equal(oldForecast);
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement - noMvmtShares);
|
||||
});
|
||||
@ -601,7 +615,7 @@ describe("Stock Market Tests", function() {
|
||||
it("should properly evaluate a SHORT transaction that doesn't trigger a forecast movement", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
|
||||
processTransactionForecastMovement(stock, noMvmtShares, PositionTypes.Short);
|
||||
processTransactionForecastMovement(stock, noMvmtShares);
|
||||
expect(stock.otlkMag).to.equal(oldForecast);
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement - noMvmtShares);
|
||||
});
|
||||
@ -610,7 +624,7 @@ describe("Stock Market Tests", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
const oldForecastForecast = stock.otlkMagForecast;
|
||||
|
||||
processTransactionForecastMovement(stock, mvmtShares, PositionTypes.Long);
|
||||
processTransactionForecastMovement(stock, mvmtShares);
|
||||
expect(stock.otlkMag).to.equal(getNthForecast(oldForecast, 4));
|
||||
expect(stock.otlkMagForecast).to.equal(getNthForecastForecast(oldForecastForecast, 4));
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement - noMvmtShares);
|
||||
@ -620,7 +634,7 @@ describe("Stock Market Tests", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
const oldForecastForecast = stock.otlkMagForecast;
|
||||
|
||||
processTransactionForecastMovement(stock, mvmtShares, PositionTypes.Short);
|
||||
processTransactionForecastMovement(stock, mvmtShares);
|
||||
expect(stock.otlkMag).to.equal(getNthForecast(oldForecast, 4));
|
||||
expect(stock.otlkMagForecast).to.equal(getNthForecastForecast(oldForecastForecast, 4));
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement - noMvmtShares);
|
||||
@ -630,7 +644,7 @@ describe("Stock Market Tests", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
const oldForecastForecast = stock.otlkMagForecast;
|
||||
|
||||
processTransactionForecastMovement(stock, stock.shareTxForMovement, PositionTypes.Long);
|
||||
processTransactionForecastMovement(stock, stock.shareTxForMovement);
|
||||
expect(stock.otlkMag).to.equal(getNthForecast(oldForecast, 2));
|
||||
expect(stock.otlkMagForecast).to.equal(getNthForecastForecast(oldForecastForecast, 2));
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement);
|
||||
@ -640,9 +654,9 @@ describe("Stock Market Tests", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
const oldForecastForecast = stock.otlkMagForecast;
|
||||
|
||||
processTransactionForecastMovement(stock, Math.round(stock.shareTxForMovement / 2), PositionTypes.Long);
|
||||
processTransactionForecastMovement(stock, Math.round(stock.shareTxForMovement / 2));
|
||||
expect(stock.shareTxUntilMovement).to.be.below(stock.shareTxForMovement);
|
||||
processTransactionForecastMovement(stock, stock.shareTxUntilMovement, PositionTypes.Long);
|
||||
processTransactionForecastMovement(stock, stock.shareTxUntilMovement);
|
||||
expect(stock.otlkMag).to.equal(getNthForecast(oldForecast, 2));
|
||||
expect(stock.otlkMagForecast).to.equal(getNthForecastForecast(oldForecastForecast, 2));
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement);
|
||||
@ -652,7 +666,7 @@ describe("Stock Market Tests", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
const oldForecastForecast = stock.otlkMagForecast;
|
||||
|
||||
processTransactionForecastMovement(stock, 3 * stock.shareTxForMovement, PositionTypes.Long);
|
||||
processTransactionForecastMovement(stock, 3 * stock.shareTxForMovement);
|
||||
expect(stock.otlkMag).to.equal(getNthForecast(oldForecast, 4));
|
||||
expect(stock.otlkMagForecast).to.equal(getNthForecastForecast(oldForecastForecast, 4));
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement);
|
||||
@ -662,7 +676,7 @@ describe("Stock Market Tests", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
const oldForecastForecast = stock.otlkMagForecast;
|
||||
|
||||
processTransactionForecastMovement(stock, stock.shareTxForMovement, PositionTypes.Short);
|
||||
processTransactionForecastMovement(stock, stock.shareTxForMovement);
|
||||
expect(stock.otlkMag).to.equal(getNthForecast(oldForecast, 2));
|
||||
expect(stock.otlkMagForecast).to.equal(getNthForecastForecast(oldForecastForecast, 2));
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement);
|
||||
@ -672,9 +686,9 @@ describe("Stock Market Tests", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
const oldForecastForecast = stock.otlkMagForecast;
|
||||
|
||||
processTransactionForecastMovement(stock, Math.round(stock.shareTxForMovement / 2), PositionTypes.Short);
|
||||
processTransactionForecastMovement(stock, Math.round(stock.shareTxForMovement / 2));
|
||||
expect(stock.shareTxUntilMovement).to.be.below(stock.shareTxForMovement);
|
||||
processTransactionForecastMovement(stock, stock.shareTxUntilMovement, PositionTypes.Short);
|
||||
processTransactionForecastMovement(stock, stock.shareTxUntilMovement);
|
||||
expect(stock.otlkMag).to.equal(getNthForecast(oldForecast, 2));
|
||||
expect(stock.otlkMagForecast).to.equal(getNthForecastForecast(oldForecastForecast, 2));
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement);
|
||||
@ -684,7 +698,7 @@ describe("Stock Market Tests", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
const oldForecastForecast = stock.otlkMagForecast;
|
||||
|
||||
processTransactionForecastMovement(stock, 3 * stock.shareTxForMovement, PositionTypes.Short);
|
||||
processTransactionForecastMovement(stock, 3 * stock.shareTxForMovement);
|
||||
expect(stock.otlkMag).to.equal(getNthForecast(oldForecast, 4));
|
||||
expect(stock.otlkMagForecast).to.equal(getNthForecastForecast(oldForecastForecast, 4));
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement);
|
||||
@ -698,24 +712,24 @@ describe("Stock Market Tests", function() {
|
||||
it("should do nothing on invalid 'stock' argument", function() {
|
||||
const oldTracker = stock.shareTxUntilMovement;
|
||||
|
||||
processTransactionForecastMovement({}, mvmtShares, PositionTypes.Long);
|
||||
processTransactionForecastMovement({} as Stock, mvmtShares);
|
||||
expect(stock.shareTxUntilMovement).to.equal(oldTracker);
|
||||
});
|
||||
|
||||
it("should do nothing on invalid 'shares' arg", function() {
|
||||
const oldTracker = stock.shareTxUntilMovement;
|
||||
|
||||
processTransactionForecastMovement(stock, NaN, PositionTypes.Long);
|
||||
processTransactionForecastMovement(stock, NaN);
|
||||
expect(stock.shareTxUntilMovement).to.equal(oldTracker);
|
||||
|
||||
processTransactionForecastMovement(stock, -1, PositionTypes.Long);
|
||||
processTransactionForecastMovement(stock, -1);
|
||||
expect(stock.shareTxUntilMovement).to.equal(oldTracker);
|
||||
});
|
||||
|
||||
it("should properly evaluate a LONG transaction that doesn't trigger a price movement", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
|
||||
processTransactionForecastMovement(stock, noMvmtShares, PositionTypes.Long);
|
||||
processTransactionForecastMovement(stock, noMvmtShares);
|
||||
expect(stock.otlkMag).to.equal(oldForecast);
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement - noMvmtShares);
|
||||
});
|
||||
@ -723,7 +737,7 @@ describe("Stock Market Tests", function() {
|
||||
it("should properly evaluate a SHORT transaction that doesn't trigger a price movement", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
|
||||
processTransactionForecastMovement(stock, noMvmtShares, PositionTypes.Short);
|
||||
processTransactionForecastMovement(stock, noMvmtShares);
|
||||
expect(stock.otlkMag).to.equal(oldForecast);
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement - noMvmtShares);
|
||||
});
|
||||
@ -731,7 +745,7 @@ describe("Stock Market Tests", function() {
|
||||
it("should properly evaluate LONG transactions that trigger price movements", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
|
||||
processTransactionForecastMovement(stock, mvmtShares, PositionTypes.Long);
|
||||
processTransactionForecastMovement(stock, mvmtShares);
|
||||
expect(stock.otlkMag).to.equal(getNthForecast(oldForecast, 4));
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement - noMvmtShares);
|
||||
});
|
||||
@ -739,7 +753,7 @@ describe("Stock Market Tests", function() {
|
||||
it("should properly evaluate SHORT transactions that trigger price movements", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
|
||||
processTransactionForecastMovement(stock, mvmtShares, PositionTypes.Short);
|
||||
processTransactionForecastMovement(stock, mvmtShares);
|
||||
expect(stock.otlkMag).to.equal(getNthForecast(oldForecast, 4));
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement - noMvmtShares);
|
||||
});
|
||||
@ -747,7 +761,7 @@ describe("Stock Market Tests", function() {
|
||||
it("should properly evaluate LONG transactions of exactly 'shareTxForMovement' shares", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
|
||||
processTransactionForecastMovement(stock, stock.shareTxForMovement, PositionTypes.Long);
|
||||
processTransactionForecastMovement(stock, stock.shareTxForMovement);
|
||||
expect(stock.otlkMag).to.equal(getNthForecast(oldForecast, 2));
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement);
|
||||
});
|
||||
@ -755,9 +769,9 @@ describe("Stock Market Tests", function() {
|
||||
it("should properly evaluate LONG transactions that total to 'shareTxForMovement' shares", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
|
||||
processTransactionForecastMovement(stock, Math.round(stock.shareTxForMovement / 2), PositionTypes.Long);
|
||||
processTransactionForecastMovement(stock, Math.round(stock.shareTxForMovement / 2));
|
||||
expect(stock.shareTxUntilMovement).to.be.below(stock.shareTxForMovement);
|
||||
processTransactionForecastMovement(stock, stock.shareTxUntilMovement, PositionTypes.Long);
|
||||
processTransactionForecastMovement(stock, stock.shareTxUntilMovement);
|
||||
expect(stock.otlkMag).to.equal(getNthForecast(oldForecast, 2));
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement);
|
||||
});
|
||||
@ -765,7 +779,7 @@ describe("Stock Market Tests", function() {
|
||||
it("should properly evaluate LONG transactions that are a multiple of 'shareTxForMovement' shares", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
|
||||
processTransactionForecastMovement(stock, 3 * stock.shareTxForMovement, PositionTypes.Long);
|
||||
processTransactionForecastMovement(stock, 3 * stock.shareTxForMovement);
|
||||
expect(stock.otlkMag).to.equal(getNthForecast(oldForecast, 4));
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement);
|
||||
});
|
||||
@ -773,7 +787,7 @@ describe("Stock Market Tests", function() {
|
||||
it("should properly evaluate SHORT transactions of exactly 'shareTxForMovement' shares", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
|
||||
processTransactionForecastMovement(stock, stock.shareTxForMovement, PositionTypes.Short);
|
||||
processTransactionForecastMovement(stock, stock.shareTxForMovement);
|
||||
expect(stock.otlkMag).to.equal(getNthForecast(oldForecast, 2));
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement);
|
||||
});
|
||||
@ -781,9 +795,9 @@ describe("Stock Market Tests", function() {
|
||||
it("should properly evaluate SHORT transactions that total to 'shareTxForMovement' shares", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
|
||||
processTransactionForecastMovement(stock, Math.round(stock.shareTxForMovement / 2), PositionTypes.Short);
|
||||
processTransactionForecastMovement(stock, Math.round(stock.shareTxForMovement / 2));
|
||||
expect(stock.shareTxUntilMovement).to.be.below(stock.shareTxForMovement);
|
||||
processTransactionForecastMovement(stock, stock.shareTxUntilMovement, PositionTypes.Short);
|
||||
processTransactionForecastMovement(stock, stock.shareTxUntilMovement);
|
||||
expect(stock.otlkMag).to.equal(getNthForecast(oldForecast, 2));
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement);
|
||||
});
|
||||
@ -791,7 +805,7 @@ describe("Stock Market Tests", function() {
|
||||
it("should properly evaluate SHORT transactions that are a multiple of 'shareTxForMovement' shares", function() {
|
||||
const oldForecast = stock.otlkMag;
|
||||
|
||||
processTransactionForecastMovement(stock, 3 * stock.shareTxForMovement, PositionTypes.Short);
|
||||
processTransactionForecastMovement(stock, 3 * stock.shareTxForMovement);
|
||||
expect(stock.otlkMag).to.equal(getNthForecast(oldForecast, 4));
|
||||
expect(stock.shareTxUntilMovement).to.equal(stock.shareTxForMovement);
|
||||
});
|
||||
@ -803,7 +817,7 @@ describe("Stock Market Tests", function() {
|
||||
|
||||
describe("buyStock()", function() {
|
||||
it("should fail for invalid arguments", function() {
|
||||
expect(buyStock({}, 1, null, suppressDialogOpt)).to.equal(false);
|
||||
expect(buyStock({} as Stock, 1, null, suppressDialogOpt)).to.equal(false);
|
||||
expect(buyStock(stock, 0, null, suppressDialogOpt)).to.equal(false);
|
||||
expect(buyStock(stock, -1, null, suppressDialogOpt)).to.equal(false);
|
||||
expect(buyStock(stock, NaN, null, suppressDialogOpt)).to.equal(false);
|
||||
@ -822,7 +836,11 @@ describe("Stock Market Tests", function() {
|
||||
it("should return true and properly update stock properties for successful transactions", function() {
|
||||
const shares = 1e3;
|
||||
const cost = getBuyTransactionCost(stock, shares, PositionTypes.Long);
|
||||
Player.setMoney(cost);
|
||||
if (cost == null) {
|
||||
expect.fail();
|
||||
}
|
||||
|
||||
Player.setMoney(cost!);
|
||||
|
||||
expect(buyStock(stock, shares, null, suppressDialogOpt)).to.equal(true);
|
||||
expect(stock.playerShares).to.equal(shares);
|
||||
@ -833,7 +851,7 @@ describe("Stock Market Tests", function() {
|
||||
|
||||
describe("sellStock()", function() {
|
||||
it("should fail for invalid arguments", function() {
|
||||
expect(sellStock({}, 1, null, suppressDialogOpt)).to.equal(false);
|
||||
expect(sellStock({} as Stock, 1, null, suppressDialogOpt)).to.equal(false);
|
||||
expect(sellStock(stock, 0, null, suppressDialogOpt)).to.equal(false);
|
||||
expect(sellStock(stock, -1, null, suppressDialogOpt)).to.equal(false);
|
||||
expect(sellStock(stock, NaN, null, suppressDialogOpt)).to.equal(false);
|
||||
@ -893,7 +911,7 @@ describe("Stock Market Tests", function() {
|
||||
|
||||
describe("shortStock()", function() {
|
||||
it("should fail for invalid arguments", function() {
|
||||
expect(shortStock({}, 1, null, suppressDialogOpt)).to.equal(false);
|
||||
expect(shortStock({} as Stock, 1, null, suppressDialogOpt)).to.equal(false);
|
||||
expect(shortStock(stock, 0, null, suppressDialogOpt)).to.equal(false);
|
||||
expect(shortStock(stock, -1, null, suppressDialogOpt)).to.equal(false);
|
||||
expect(shortStock(stock, NaN, null, suppressDialogOpt)).to.equal(false);
|
||||
@ -912,7 +930,11 @@ describe("Stock Market Tests", function() {
|
||||
it("should return true and properly update stock properties for successful transactions", function() {
|
||||
const shares = 1e3;
|
||||
const cost = getBuyTransactionCost(stock, shares, PositionTypes.Short);
|
||||
Player.setMoney(cost);
|
||||
if (cost == null) {
|
||||
expect.fail();
|
||||
}
|
||||
|
||||
Player.setMoney(cost!);
|
||||
|
||||
expect(shortStock(stock, shares, null, suppressDialogOpt)).to.equal(true);
|
||||
expect(stock.playerShortShares).to.equal(shares);
|
||||
@ -923,7 +945,7 @@ describe("Stock Market Tests", function() {
|
||||
|
||||
describe("sellShort()", function() {
|
||||
it("should fail for invalid arguments", function() {
|
||||
expect(sellShort({}, 1, null, suppressDialogOpt)).to.equal(false);
|
||||
expect(sellShort({} as Stock, 1, null, suppressDialogOpt)).to.equal(false);
|
||||
expect(sellShort(stock, 0, null, suppressDialogOpt)).to.equal(false);
|
||||
expect(sellShort(stock, -1, null, suppressDialogOpt)).to.equal(false);
|
||||
expect(sellShort(stock, NaN, null, suppressDialogOpt)).to.equal(false);
|
||||
@ -985,13 +1007,13 @@ describe("Stock Market Tests", function() {
|
||||
describe("Order Class", function() {
|
||||
it("should throw on invalid arguments", function() {
|
||||
function invalid1() {
|
||||
return new Order({}, 1, 1, OrderTypes.LimitBuy, PositionTypes.Long);
|
||||
return new Order({} as string, 1, 1, OrderTypes.LimitBuy, PositionTypes.Long);
|
||||
}
|
||||
function invalid2() {
|
||||
return new Order("FOO", "z", 0, OrderTypes.LimitBuy, PositionTypes.Short);
|
||||
return new Order("FOO", "z" as any as number, 0, OrderTypes.LimitBuy, PositionTypes.Short);
|
||||
}
|
||||
function invalid3() {
|
||||
return new Order("FOO", 1, {}, OrderTypes.LimitBuy, PositionTypes.Short);
|
||||
return new Order("FOO", 1, {} as number, OrderTypes.LimitBuy, PositionTypes.Short);
|
||||
}
|
||||
function invalid4() {
|
||||
return new Order("FOO", 1, NaN, OrderTypes.LimitBuy, PositionTypes.Short);
|
||||
@ -1008,19 +1030,281 @@ describe("Stock Market Tests", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("Order Processing", function() {
|
||||
before(function() {
|
||||
describe("Order Placing & Processing", function() {
|
||||
beforeEach(function() {
|
||||
expect(initStockMarket).to.not.throw();
|
||||
expect(initSymbolToStockMap).to.not.throw();
|
||||
});
|
||||
|
||||
describe()
|
||||
describe("executeOrder()", function() {
|
||||
|
||||
// Create an order book for our mock stock
|
||||
StockMarket["Orders"][stock.symbol] = [];
|
||||
});
|
||||
|
||||
describe("placeOrder()", function() {
|
||||
it("should return false when it's called with invalid arguments", function() {
|
||||
const invalid1 = placeOrder({} as Stock, 1, 1, OrderTypes.LimitBuy, PositionTypes.Long);
|
||||
const invalid2 = placeOrder(stock, "foo" as any as number, 2, OrderTypes.LimitBuy, PositionTypes.Long);
|
||||
const invalid3 = placeOrder(stock, 1, "foo" as any as number, OrderTypes.LimitBuy, PositionTypes.Long);
|
||||
|
||||
expect(invalid1).to.equal(false);
|
||||
expect(invalid2).to.equal(false);
|
||||
expect(invalid3).to.equal(false);
|
||||
|
||||
expect(StockMarket["Orders"][stock.symbol]).to.be.empty;
|
||||
});
|
||||
|
||||
it("should return true and update the order book for valid arguments", function() {
|
||||
const res = placeOrder(stock, 1e3, 9e3, OrderTypes.LimitBuy, PositionTypes.Long);
|
||||
expect(res).to.equal(true);
|
||||
|
||||
expect(StockMarket["Orders"][stock.symbol]).to.have.lengthOf(1);
|
||||
const order = StockMarket["Orders"][stock.symbol][0];
|
||||
expect(order).to.be.an.instanceof(Order);
|
||||
expect(order.stockSymbol).to.equal(ctorParams.symbol);
|
||||
expect(order.shares).to.equal(1e3);
|
||||
expect(order.price).to.equal(9e3);
|
||||
expect(order.type).to.equal(OrderTypes.LimitBuy);
|
||||
expect(order.pos).to.equal(PositionTypes.Long);
|
||||
});
|
||||
});
|
||||
|
||||
describe("cancelOrder()", function() {
|
||||
beforeEach(function() {
|
||||
StockMarket["Orders"][stock.symbol] = [];
|
||||
|
||||
const res = placeOrder(stock, 1e3, 9e3, OrderTypes.LimitBuy, PositionTypes.Long);
|
||||
expect(res).to.equal(true);
|
||||
expect(StockMarket["Orders"][stock.symbol]).to.have.lengthOf(1);
|
||||
});
|
||||
|
||||
it("returns true & removes an Order from the order book", function() {
|
||||
const order = StockMarket["Orders"][stock.symbol][0];
|
||||
const res = cancelOrder({ order });
|
||||
expect(res).to.equal(true);
|
||||
expect(StockMarket["Orders"][stock.symbol]).to.have.lengthOf(0);
|
||||
});
|
||||
|
||||
it("should also work when passing in order parameters separately", function() {
|
||||
const res = cancelOrder({
|
||||
stock,
|
||||
shares: 1e3,
|
||||
price: 9e3,
|
||||
type: OrderTypes.LimitBuy,
|
||||
pos: PositionTypes.Long
|
||||
});
|
||||
expect(res).to.equal(true);
|
||||
expect(StockMarket["Orders"][stock.symbol]).to.have.lengthOf(0);
|
||||
});
|
||||
|
||||
it("should return false and do nothing when the specified order doesn't exist", function() {
|
||||
// Same parameters, but its a different object
|
||||
const order = new Order(stock.symbol, 1e3, 9e3, OrderTypes.LimitBuy, PositionTypes.Long);
|
||||
const res = cancelOrder({ order });
|
||||
expect(res).to.equal(false);
|
||||
expect(StockMarket["Orders"][stock.symbol]).to.have.lengthOf(1);
|
||||
|
||||
const res2 = cancelOrder({
|
||||
stock,
|
||||
shares: 999,
|
||||
price: 9e3,
|
||||
type: OrderTypes.LimitBuy,
|
||||
pos: PositionTypes.Long
|
||||
});
|
||||
expect(res2).to.equal(false);
|
||||
expect(StockMarket["Orders"][stock.symbol]).to.have.lengthOf(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("processOrders()", function() {
|
||||
let processOrdersRefs: IProcessOrderRefs;
|
||||
|
||||
beforeEach(function() {
|
||||
expect(initStockMarket).to.not.throw();
|
||||
expect(initSymbolToStockMap).to.not.throw();
|
||||
|
||||
StockMarket[stock.name] = stock;
|
||||
SymbolToStockMap[stock.symbol] = stock;
|
||||
StockMarket["Orders"][stock.symbol] = [];
|
||||
|
||||
stock.playerShares = 1e3;
|
||||
stock.playerShortShares = 1e3;
|
||||
Player.setMoney(100e9);
|
||||
|
||||
processOrdersRefs = {
|
||||
rerenderFn: () => {},
|
||||
stockMarket: StockMarket as IStockMarket,
|
||||
symbolToStockMap: SymbolToStockMap,
|
||||
};
|
||||
});
|
||||
|
||||
function checkThatOrderExists(placeOrderRes?: boolean) {
|
||||
if (typeof placeOrderRes === "boolean") {
|
||||
expect(placeOrderRes).to.equal(true);
|
||||
}
|
||||
expect(StockMarket["Orders"][stock.symbol]).to.have.lengthOf(1);
|
||||
}
|
||||
|
||||
function checkThatOrderExecuted() {
|
||||
expect(StockMarket["Orders"][stock.symbol]).to.have.lengthOf(0);
|
||||
}
|
||||
|
||||
it("should execute LONG Limit Buy orders when price <= order price", function() {
|
||||
const res = placeOrder(stock, 1e3, 9e3, OrderTypes.LimitBuy, PositionTypes.Long);
|
||||
checkThatOrderExists(res);
|
||||
|
||||
stock.changePrice(9e3);
|
||||
processOrders(stock, OrderTypes.LimitBuy, PositionTypes.Long, processOrdersRefs);
|
||||
checkThatOrderExecuted();
|
||||
expect(stock.playerShares).to.equal(2e3);
|
||||
});
|
||||
|
||||
it("should execute SHORT Limit Buy Orders when price >= order price", function() {
|
||||
const res = placeOrder(stock, 1e3, 11e3, OrderTypes.LimitBuy, PositionTypes.Short);
|
||||
checkThatOrderExists(res);
|
||||
|
||||
stock.changePrice(11e3);
|
||||
processOrders(stock, OrderTypes.LimitBuy, PositionTypes.Short, processOrdersRefs);
|
||||
checkThatOrderExecuted();
|
||||
expect(stock.playerShortShares).to.equal(2e3);
|
||||
});
|
||||
|
||||
it("should execute LONG Limit Sell Orders when price >= order price", function() {
|
||||
const res = placeOrder(stock, 1e3, 11e3, OrderTypes.LimitSell, PositionTypes.Long);
|
||||
checkThatOrderExists(res);
|
||||
|
||||
stock.changePrice(11e3);
|
||||
processOrders(stock, OrderTypes.LimitSell, PositionTypes.Long, processOrdersRefs);
|
||||
checkThatOrderExecuted();
|
||||
expect(stock.playerShares).to.equal(0);
|
||||
});
|
||||
|
||||
it("should execute SHORT Limit Sell Orders when price <= order price", function() {
|
||||
const res = placeOrder(stock, 1e3, 9e3, OrderTypes.LimitSell, PositionTypes.Short);
|
||||
checkThatOrderExists(res);
|
||||
|
||||
stock.changePrice(9e3);
|
||||
processOrders(stock, OrderTypes.LimitSell, PositionTypes.Short, processOrdersRefs);
|
||||
checkThatOrderExecuted();
|
||||
expect(stock.playerShortShares).to.equal(0);
|
||||
});
|
||||
|
||||
it("should execute LONG Stop Buy Orders when price >= order price", function() {
|
||||
const res = placeOrder(stock, 1e3, 11e3, OrderTypes.StopBuy, PositionTypes.Long);
|
||||
checkThatOrderExists(res);
|
||||
|
||||
stock.changePrice(11e3);
|
||||
processOrders(stock, OrderTypes.StopBuy, PositionTypes.Long, processOrdersRefs);
|
||||
checkThatOrderExecuted();
|
||||
expect(stock.playerShares).to.equal(2e3);
|
||||
});
|
||||
|
||||
it("should execute SHORT Stop Buy Orders when price <= order price", function() {
|
||||
const res = placeOrder(stock, 1e3, 9e3, OrderTypes.StopBuy, PositionTypes.Short);
|
||||
checkThatOrderExists(res);
|
||||
|
||||
stock.changePrice(9e3);
|
||||
processOrders(stock, OrderTypes.StopBuy, PositionTypes.Short, processOrdersRefs);
|
||||
checkThatOrderExecuted();
|
||||
expect(stock.playerShortShares).to.equal(2e3);
|
||||
});
|
||||
|
||||
it("should execute LONG Stop Sell Orders when price <= order price", function() {
|
||||
const res = placeOrder(stock, 1e3, 9e3, OrderTypes.StopSell, PositionTypes.Long);
|
||||
checkThatOrderExists(res);
|
||||
|
||||
stock.changePrice(9e3);
|
||||
processOrders(stock, OrderTypes.StopSell, PositionTypes.Long, processOrdersRefs);
|
||||
checkThatOrderExecuted();
|
||||
expect(stock.playerShares).to.equal(0);
|
||||
});
|
||||
|
||||
it("should execute SHORT Stop Sell Orders when price >= order price", function() {
|
||||
const res = placeOrder(stock, 1e3, 11e3, OrderTypes.StopSell, PositionTypes.Short);
|
||||
checkThatOrderExists(res);
|
||||
|
||||
stock.changePrice(11e3);
|
||||
processOrders(stock, OrderTypes.StopSell, PositionTypes.Short, processOrdersRefs);
|
||||
checkThatOrderExecuted();
|
||||
expect(stock.playerShortShares).to.equal(0);
|
||||
});
|
||||
|
||||
it("should execute immediately if their conditions are satisfied", function() {
|
||||
placeOrder(stock, 1e3, 11e3, OrderTypes.LimitBuy, PositionTypes.Long);
|
||||
checkThatOrderExecuted();
|
||||
expect(stock.playerShares).to.equal(2e3);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// TODO
|
||||
describe("Player Influencing", function() {
|
||||
// TODO
|
||||
const server = new Server({
|
||||
hostname: "mockserver",
|
||||
moneyAvailable: 1e6,
|
||||
organizationName: "MockStock",
|
||||
});
|
||||
|
||||
const company = new Company({
|
||||
name: "MockStock",
|
||||
info: "",
|
||||
companyPositions: {},
|
||||
expMultiplier: 1,
|
||||
salaryMultiplier: 1,
|
||||
jobStatReqOffset: 1,
|
||||
})
|
||||
|
||||
beforeEach(function() {
|
||||
expect(initStockMarket).to.not.throw();
|
||||
expect(initSymbolToStockMap).to.not.throw();
|
||||
|
||||
StockMarket[stock.name] = stock;
|
||||
});
|
||||
|
||||
describe("influenceStockThroughServerHack()", function() {
|
||||
it("should decrease a stock's second-order forecast when all of its money is hacked", function() {
|
||||
const oldSecondOrderForecast = stock.otlkMagForecast;
|
||||
influenceStockThroughServerHack(server, server.moneyMax);
|
||||
expect(stock.otlkMagForecast).to.equal(oldSecondOrderForecast - forecastForecastChangeFromHack);
|
||||
});
|
||||
|
||||
it("should not decrease the stock's second-order forecast when no money is stolen", function() {
|
||||
const oldSecondOrderForecast = stock.otlkMagForecast;
|
||||
influenceStockThroughServerHack(server, 0);
|
||||
expect(stock.otlkMagForecast).to.equal(oldSecondOrderForecast);
|
||||
});
|
||||
});
|
||||
|
||||
describe("influenceStockThroughServerGrow()", function() {
|
||||
it("should increase a stock's second-order forecast when all of its money is grown", function() {
|
||||
const oldSecondOrderForecast = stock.otlkMagForecast;
|
||||
influenceStockThroughServerGrow(server, server.moneyMax);
|
||||
expect(stock.otlkMagForecast).to.equal(oldSecondOrderForecast + forecastForecastChangeFromHack);
|
||||
});
|
||||
|
||||
it("should not increase the stock's second-order forecast when no money is grown", function() {
|
||||
const oldSecondOrderForecast = stock.otlkMagForecast;
|
||||
influenceStockThroughServerGrow(server, 0);
|
||||
expect(stock.otlkMagForecast).to.equal(oldSecondOrderForecast);
|
||||
});
|
||||
});
|
||||
|
||||
describe("influenceStockThroughCompanyWork()", function() {
|
||||
it("should increase the server's second order forecast", function() {
|
||||
const oldSecondOrderForecast = stock.otlkMagForecast;
|
||||
|
||||
// Use 1e3 for numCycles to force a change
|
||||
// (This may break later if numbers are rebalanced);
|
||||
influenceStockThroughCompanyWork(company, 1, 1e3);
|
||||
expect(stock.otlkMagForecast).to.equal(oldSecondOrderForecast + forecastForecastChangeFromCompanyWork);
|
||||
});
|
||||
|
||||
it("should be affected by performanceMult", function() {
|
||||
const oldSecondOrderForecast = stock.otlkMagForecast;
|
||||
|
||||
// Use 1e3 for numCycles to force a change
|
||||
// (This may break later if numbers are rebalanced);
|
||||
influenceStockThroughCompanyWork(company, 4, 1e3);
|
||||
expect(stock.otlkMagForecast).to.equal(oldSecondOrderForecast + 4 * forecastForecastChangeFromCompanyWork);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user