Skip to content

Commit

Permalink
0.10.10 - Fix bugs and add tests (#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
charredUtensil authored Dec 8, 2024
1 parent 03a00d5 commit ceec805
Show file tree
Hide file tree
Showing 11 changed files with 266 additions and 37 deletions.
15 changes: 15 additions & 0 deletions bin/presubmit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#! /usr/bin/env bash

echo "Presubmit: Running Prettier...";
prettier --write src || exit 1;

echo "Presubmit: Running ESLint...";
eslint --fix src --max-warnings=0 || exit 1;

echo "Presubmit: Building...";
react-scripts build || exit 1;

echo "Presubmit: Running all tests...";
react-scripts test --all --watchAll=false --coverage || exit 1;

echo "Presubmit succeeded. Remember to commit any changes."
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "groundhog",
"version": "0.10.9",
"version": "0.10.10",
"homepage": "https://charredutensil.github.io/groundhog",
"private": true,
"dependencies": {
Expand All @@ -23,11 +23,12 @@
"test": "react-scripts test",
"predeploy": "react-scripts build",
"deploy": "gh-pages -d build",
"presubmit": "prettier --write src && eslint --fix src --max-warnings=0 && react-scripts build && react-scripts test --all",
"presubmit": "bin/presubmit.sh",
"eject": "react-scripts eject",
"gen": "tsx bin/groundhog-gen",
"architect-stats": "tsx bin/architect-stats",
"lore-dump": "tsx bin/lore-dump"
"lore-dump": "tsx bin/lore-dump",
"update-goldens": "UPDATE_GOLDENS=1 react-scripts test --all --watchAll=false"
},
"eslintConfig": {
"extends": [
Expand Down
172 changes: 171 additions & 1 deletion src/core/architects/utils/script.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { sanitizeString } from "./script";
import goldenTest from "../../test_utils/golden";
import { PreprogrammedCavern } from "../../transformers/04_ephemera/03_preprogram";
import { mkScriptBuilder, mkVars, sanitizeString } from "./script";

describe("escapeString", () => {
it("handles the empty string", () => {
Expand All @@ -23,3 +25,171 @@ describe("escapeString", () => {
);
});
});

describe("ScriptBuilder", () => {
const cavern = {} as PreprogrammedCavern;

it("declares variables", () => {
const sb = mkScriptBuilder(cavern);
sb.declareArrow("arw");
sb.declareBuilding("bld");
sb.declareCreature("cr");
sb.declareInt("num", 42);
sb.declareString("str", "Message!");
expect(sb.build()).toEqual(`\
arrow arw
building bld
creature cr
int num=42
string str="Message!"`);
});

it("declares an event", () => {
const sb = mkScriptBuilder(cavern);
sb.event("foo", "crystals+=1;");
expect(sb.build()).toEqual(`\
foo::;
crystals+=1;
`);
});

it("declares a simple if trigger", () => {
const sb = mkScriptBuilder(cavern);
sb.if("crystals>10", "crystals-=5;");
expect(sb.build()).toEqual("if(crystals>10)[crystals-=5]");
});

it("declares a simple when trigger", () => {
const sb = mkScriptBuilder(cavern);
sb.when("crystals>50", "crystals-=1;");
expect(sb.build()).toEqual("when(crystals>50)[crystals-=1]");
});

it("creates an anonymous event chain to handle multiple statements", () => {
const sb = mkScriptBuilder(cavern);
sb.if("crystals>10", "wait:5;", "crystals-=5;");
expect(sb.build()).toEqual(`\
if(crystals>10)[t0]
t0::;
wait:5;
crystals-=5;
`);
});

it("creates an anonymous event chain to handle repeated triggers", () => {
const sb = mkScriptBuilder(cavern);
sb.when("ore>50", "ore-=20;");
sb.when("ore>50", "crystals+=1;");
expect(sb.build()).toEqual(`\
when(ore>50)[tw0]
tw0::;
ore-=20;
crystals+=1;
`);
});

it("creates anonymous event chains to handle repeated triggers with multiple statements", () => {
const sb = mkScriptBuilder(cavern);
sb.when("ore>50", "ore-=20;");
sb.when("ore>50", "wait:5;", "crystals+=1;");
sb.when("ore>50", "wait:10;", "crystals+=1;");
expect(sb.build()).toEqual(`\
when(ore>50)[tw2]
tw2::;
ore-=20;
t0;
t1;
t0::;
wait:5;
crystals+=1;
t1::;
wait:10;
crystals+=1;
`);
});

it("handles if and when triggers on the same condition 1", () => {
const sb = mkScriptBuilder(cavern);
sb.if("ore>50", "msg:msgFirstAlchemy;");
sb.when("ore>50", "ore-=20;", "wait:5;", "crystals+=1;");
expect(sb.build()).toEqual(`\
int tf0=0
if(tf0>0)[msg:msgFirstAlchemy]
when(ore>50)[tw2]
tw2::;
tf0=1;
t1;
t1::;
ore-=20;
wait:5;
crystals+=1;
`);
});

it("handles if and when triggers on the same condition 2", () => {
const sb = mkScriptBuilder(cavern);
sb.if("ore>50", "shake:1;", "msg:msgFirstAlchemy;");
sb.when("ore>50", "ore-=20;");
expect(sb.build()).toEqual(`\
int tf0=0
if(tf0>0)[t1]
t1::;
shake:1;
msg:msgFirstAlchemy;
when(ore>50)[tw2]
tw2::;
tf0=1;
ore-=20;
`);
});

goldenTest("fizzbuzz", () => {
// This code is bad but idk - it's more about testing the builder.

const sb = mkScriptBuilder(cavern);
const v = mkVars("fbz", [
"n",
"lock",
"m",
"three",
"five",
"msgFizz",
"msgBuzz",
"msgFizzBuzz",
]);
sb.declareInt(v.n, 0);
sb.declareInt(v.m, 0);
sb.declareInt(v.lock, 0);
sb.declareInt(v.three, 0);
sb.declareInt(v.five, 0);

sb.when("enter:1,1", `${v.lock}+=1;`);
sb.when(
`${v.lock}==1`,

`pan:${v.three},${v.five};`,

`${v.n}+=1;`,
`${v.m}=0;`,

`${v.three}+=1;`,
`((${v.three}==3))${v.m}=1;`,
`((${v.three}>=3))${v.three}-=3;`,

`${v.five}+=1;`,
`((${v.five}==5))${v.m}+=2;`,
`((${v.five}>=5))${v.five}-=5;`,

`((${v.m}==1))msg:${sb.declareString(v.msgFizz, "Fizz")};`,
`((${v.m}==2))msg:${sb.declareString(v.msgBuzz, "Buzz")};`,
`((${v.m}==3))msg:${sb.declareString(v.msgFizzBuzz, "Fizz Buzz")};`,

`${v.lock}=0;`,
);
return sb.build();
});
});
39 changes: 29 additions & 10 deletions src/core/architects/utils/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ export type ScriptBuilder = {
};

type Trigger = {
kind: "if" | "when";
condition: string;
bodies: `${string};`[];
ifs: `${string};`[];
whens: `${string};`[];
};

type BuildableScriptBuilder = ScriptBuilder & { build(): string };
Expand Down Expand Up @@ -148,20 +148,39 @@ export function mkScriptBuilder(
}
const tx: Trigger | undefined = triggers.byCondition[condition];
if (tx) {
if (tx.kind !== kind) {
throw new Error(
`Attempted to redefine trigger \`${tx.kind}(${condition})\` as a \`${kind}\` trigger`,
);
}
triggers.byCondition[condition].bodies.push(body);
triggers.byCondition[condition][`${kind}s`].push(body);
return;
}
const t: Trigger = { kind, condition, bodies: [body] };
const t: Trigger =
kind === "if"
? { condition, ifs: [body], whens: [] }
: { condition, ifs: [], whens: [body] };
triggers.inOrder.push(t);
triggers.byCondition[condition] = t;
}

function buildTrigger({ kind, condition, bodies }: Trigger) {
function buildTrigger({ condition, ifs, whens }: Trigger) {
if (ifs.length && whens.length) {
// If there are both ifs and whens, need to trigger them separately.
const v = `tf${uid++}`;
return [
`int ${v}=0`,
buildTriggerHelper("if", `${v}>0`, ifs),
buildTriggerHelper("when", condition, [`${v}=1;`, ...whens]),
].join("\n");
} else if (ifs.length) {
return buildTriggerHelper("if", condition, ifs);
} else if (whens.length) {
return buildTriggerHelper("when", condition, whens);
}
return "";
}

function buildTriggerHelper(
kind: "if" | "when",
condition: Trigger["condition"],
bodies: `${string};`[],
) {
const calls: `${string};`[] = [];
const extra: string[] = [];
bodies.forEach((body) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const updateGoldenFile = async (filePath: string, actual: string) => {
};

const goldenTest = async (name: string, fn: () => string) => {
const filePath = path.resolve(__dirname, `${GOLDEN_DIR}/${name}.dat`);
const filePath = path.resolve(__dirname, GOLDEN_DIR, name);
test(name, async () => {
const actual = fn();
if (process.env[UPDATE_GOLDENS]) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
comments{
Cavern generated by groundHog [VERSION]
https://github.com/charredUtensil/groundhog
initialContext: {}
initialContext = {}
}
info{
rowcount:14
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
comments{
Cavern generated by groundHog [VERSION]
https://github.com/charredUtensil/groundhog
initialContext: {}
initialContext = {}
}
info{
rowcount:14
Expand Down
24 changes: 24 additions & 0 deletions src/core/test_utils/goldens/fizzbuzz
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
int fbz_n=0
int fbz_m=0
int fbz_lock=0
int fbz_three=0
int fbz_five=0
string fbz_msgFizz="Fizz"
string fbz_msgBuzz="Buzz"
string fbz_msgFizzBuzz="Fizz Buzz"
when(enter:1,1)[fbz_lock+=1]
when(fbz_lock==1)[t0]
t0::;
pan:fbz_three,fbz_five;
fbz_n+=1;
fbz_m=0;
fbz_three+=1;
((fbz_three==3))fbz_m=1;
((fbz_three>=3))fbz_three-=3;
fbz_five+=1;
((fbz_five==5))fbz_m+=2;
((fbz_five>=5))fbz_five-=5;
((fbz_m==1))msg:fbz_msgFizz;
((fbz_m==2))msg:fbz_msgBuzz;
((fbz_m==3))msg:fbz_msgFizzBuzz;
fbz_lock=0;
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
comments{
Cavern generated by groundHog [VERSION]
https://github.com/charredUtensil/groundhog
initialContext: {}
initialContext = {}
}
info{
rowcount:6
Expand Down
Loading

0 comments on commit ceec805

Please sign in to comment.