From 8d7327361adbdbd60ea374edbc019d987c57b8b1 Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Tue, 13 Feb 2024 06:48:02 -0600 Subject: [PATCH] Move printFormula to Formula.stringify and add tests for it --- src/game/formulas/formulas.ts | 55 ++++++++++++++++++++--------------- src/game/formulas/types.d.ts | 8 ++++- tests/game/formulas.test.ts | 19 ++++++++++-- tests/game/modifiers.test.ts | 6 ++-- 4 files changed, 57 insertions(+), 31 deletions(-) diff --git a/src/game/formulas/formulas.ts b/src/game/formulas/formulas.ts index 7f88d0c..ac1145f 100644 --- a/src/game/formulas/formulas.ts +++ b/src/game/formulas/formulas.ts @@ -56,6 +56,7 @@ export abstract class InternalFormula | undefined; protected readonly internalIntegrateInner: IntegrateFunction | undefined; protected readonly applySubstitution: SubstitutionFunction | undefined; + protected readonly description: string | undefined; protected readonly internalVariables: number; public readonly innermostVariable: ProcessedComputable | undefined; @@ -85,6 +86,7 @@ export abstract class InternalFormula, formulaModifier: (value: InvertibleIntegralFormula) => GenericFormula @@ -1402,28 +1431,6 @@ export function findNonInvertible(formula: GenericFormula): GenericFormula | nul return null; } -/** - * Stringifies a formula so it's more easy to read in the console - * @param formula The formula to print - */ -export function printFormula(formula: FormulaSource): string { - if (formula instanceof InternalFormula) { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - return formula.internalEvaluate == null - ? formula.hasVariable() - ? "x" - : formula.inputs[0] ?? 0 - : // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - formula.internalEvaluate.name + - "(" + - formula.inputs.map(printFormula).join(", ") + - ")"; - } - return format(unref(formula)); -} - /** * Utility for calculating the maximum amount of purchases possible with a given formula and resource. If {@link cumulativeCost} is changed to false, the calculation will be much faster with higher numbers. * @param formula The formula to use for calculating buy max from diff --git a/src/game/formulas/types.d.ts b/src/game/formulas/types.d.ts index 88efd92..cc185a9 100644 --- a/src/game/formulas/types.d.ts +++ b/src/game/formulas/types.d.ts @@ -37,9 +37,13 @@ type SubstitutionFunction = ( ...inputs: T ) => GenericFormula; -type VariableFormulaOptions = { variable: ProcessedComputable }; +type VariableFormulaOptions = { + variable: ProcessedComputable; + description?: string; +}; type ConstantFormulaOptions = { inputs: [FormulaSource]; + description?: string; }; type GeneralFormulaOptions = { inputs: T; @@ -48,6 +52,7 @@ type GeneralFormulaOptions = { integrate?: IntegrateFunction; integrateInner?: IntegrateFunction; applySubstitution?: SubstitutionFunction; + description?: string; }; type FormulaOptions = | VariableFormulaOptions @@ -63,6 +68,7 @@ type InternalFormulaProperties = { internalIntegrateInner?: IntegrateFunction; applySubstitution?: SubstitutionFunction; innermostVariable?: ProcessedComputable; + description?: string; }; type SubstitutionStack = ((value: GenericFormula) => GenericFormula)[] | undefined; diff --git a/tests/game/formulas.test.ts b/tests/game/formulas.test.ts index 98bb82d..b21c2e0 100644 --- a/tests/game/formulas.test.ts +++ b/tests/game/formulas.test.ts @@ -155,7 +155,7 @@ describe("Formula Equality Checking", () => { describe("Formula aliases", () => { function testAliases( aliases: T[], - args: Parameters + args: Parameters<(typeof Formula)[T]> ) { describe(aliases[0], () => { let formula: GenericFormula; @@ -250,7 +250,7 @@ describe("Creating Formulas", () => { function checkFormula( functionName: T, - args: Readonly> + args: Readonly> ) { let formula: GenericFormula; beforeAll(() => { @@ -274,7 +274,7 @@ describe("Creating Formulas", () => { // It's a lot of tests, but I'd rather be exhaustive function testFormulaCall( functionName: T, - args: Readonly> + args: Readonly> ) { if ((functionName === "slog" || functionName === "layeradd") && args[0] === -1) { // These cases in particular take a long time, so skip them @@ -1275,3 +1275,16 @@ describe("Buy Max", () => { }); }); }); + +describe("Stringifies", () => { + test("Nested formula", () => { + const variable = Formula.variable(ref(0)); + expect(variable.add(5).pow(Formula.constant(10)).stringify()).toBe( + "pow(add(x, 5.00), 10.00)" + ); + }); + test("Indeterminate", () => { + expect(Formula.if(10, true, f => f.add(5)).stringify()).toBe("indeterminate"); + expect(Formula.step(10, 5, f => f.add(5)).stringify()).toBe("indeterminate"); + }); +}); diff --git a/tests/game/modifiers.test.ts b/tests/game/modifiers.test.ts index d5e186d..b2f537d 100644 --- a/tests/game/modifiers.test.ts +++ b/tests/game/modifiers.test.ts @@ -1,5 +1,5 @@ import { CoercableComponent, JSXFunction } from "features/feature"; -import Formula, { printFormula } from "game/formulas/formulas"; +import Formula from "game/formulas/formulas"; import { createAdditiveModifier, createExponentialModifier, @@ -52,7 +52,7 @@ function testModifiers< expect(modifier.invert(operation(10, 5))).compare_tolerance(10)); test("getFormula returns the right formula", () => { const value = ref(10); - expect(printFormula(modifier.getFormula(Formula.variable(value)))).toBe( + expect(modifier.getFormula(Formula.variable(value)).stringify()).toBe( `${operation.name}(x, 5.00)` ); }); @@ -156,7 +156,7 @@ describe("Sequential Modifiers", () => { expect(modifier.invert(Decimal.add(10, 5).times(5).pow(5))).compare_tolerance(10)); test("getFormula returns the right formula", () => { const value = ref(10); - expect(printFormula(modifier.getFormula(Formula.variable(value)))).toBe( + expect(modifier.getFormula(Formula.variable(value)).stringify()).toBe( `pow(mul(add(x, 5.00), 5.00), 5.00)` ); });