chore: now actually runs tests
This commit is contained in:
@@ -140,7 +140,7 @@ function VisualProgrammingUI() {
|
||||
}
|
||||
|
||||
// currently outputs the prepared program to the console
|
||||
function runProgramm() {
|
||||
function runProgram() {
|
||||
const phases = graphReducer();
|
||||
const program = {phases}
|
||||
console.log(JSON.stringify(program, null, 2));
|
||||
@@ -183,11 +183,11 @@ function VisProgPage() {
|
||||
const [showSimpleProgram, setShowSimpleProgram] = useState(false);
|
||||
const setProgramState = useProgramStore((state) => state.setProgramState);
|
||||
|
||||
const runProgram = () => {
|
||||
const onClick = () => {
|
||||
const phases = graphReducer(); // reduce graph
|
||||
setProgramState({ phases }); // <-- save to store
|
||||
setShowSimpleProgram(true); // show SimpleProgram
|
||||
runProgramm(); // send to backend if needed
|
||||
runProgram(); // send to backend if needed
|
||||
};
|
||||
|
||||
if (showSimpleProgram) {
|
||||
@@ -204,7 +204,7 @@ function VisProgPage() {
|
||||
return (
|
||||
<>
|
||||
<VisualProgrammingUI/>
|
||||
<button onClick={runProgram}>run program</button>
|
||||
<button onClick={onClick}>run program</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
176
test/pages/simpleProgram/SimpleProgram.test.tsx
Normal file
176
test/pages/simpleProgram/SimpleProgram.test.tsx
Normal file
@@ -0,0 +1,176 @@
|
||||
import { render, screen, fireEvent } from "@testing-library/react";
|
||||
import SimpleProgram from "../../../src/pages/SimpleProgram/SimpleProgram";
|
||||
import useProgramStore from "../../../src/utils/programStore";
|
||||
|
||||
/**
|
||||
* Helper to preload the program store before rendering.
|
||||
*/
|
||||
function loadProgram(phases: Record<string, unknown>[]) {
|
||||
useProgramStore.getState().setProgramState({ phases });
|
||||
}
|
||||
|
||||
describe("SimpleProgram", () => {
|
||||
beforeEach(() => {
|
||||
loadProgram([]);
|
||||
});
|
||||
|
||||
test("shows empty state when no program is loaded", () => {
|
||||
render(<SimpleProgram />);
|
||||
expect(screen.getByText("No program loaded.")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("renders first phase content", () => {
|
||||
loadProgram([
|
||||
{
|
||||
id: "phase-1",
|
||||
norms: [{ id: "n1", norm: "Be polite" }],
|
||||
goals: [{ id: "g1", description: "Finish task", achieved: true }],
|
||||
triggers: [{ id: "t1", label: "Keyword trigger" }],
|
||||
},
|
||||
]);
|
||||
|
||||
render(<SimpleProgram />);
|
||||
|
||||
expect(screen.getByText("Phase 1 / 1")).toBeInTheDocument();
|
||||
expect(screen.getByText("Be polite")).toBeInTheDocument();
|
||||
expect(screen.getByText("Finish task")).toBeInTheDocument();
|
||||
expect(screen.getByText("Keyword trigger")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("renders empty messages when phase has no data", () => {
|
||||
loadProgram([
|
||||
{
|
||||
id: "phase-1",
|
||||
norms: [],
|
||||
goals: [],
|
||||
triggers: [],
|
||||
},
|
||||
]);
|
||||
|
||||
render(<SimpleProgram />);
|
||||
|
||||
expect(screen.getAllByText("No norms defined.").length).toBeGreaterThanOrEqual(1);
|
||||
expect(screen.getAllByText("No goals defined.").length).toBeGreaterThanOrEqual(1);
|
||||
expect(screen.getAllByText("No triggers defined.").length).toBeGreaterThanOrEqual(1);
|
||||
expect(
|
||||
screen.getByText("No conditional norms defined.")
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("allows navigating between phases", () => {
|
||||
loadProgram([
|
||||
{
|
||||
id: "phase-1",
|
||||
norms: [],
|
||||
goals: [],
|
||||
triggers: [],
|
||||
},
|
||||
{
|
||||
id: "phase-2",
|
||||
norms: [{ id: "n2", norm: "Be careful" }],
|
||||
goals: [],
|
||||
triggers: [],
|
||||
},
|
||||
]);
|
||||
|
||||
render(<SimpleProgram />);
|
||||
|
||||
expect(screen.getByText("Phase 1 / 2")).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByText("Next ▶"));
|
||||
|
||||
expect(screen.getByText("Phase 2 / 2")).toBeInTheDocument();
|
||||
expect(screen.getByText("Be careful")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("prev button is disabled on first phase", () => {
|
||||
loadProgram([{ id: "phase-1", norms: [], goals: [], triggers: [] }]);
|
||||
|
||||
render(<SimpleProgram />);
|
||||
expect(screen.getByText("◀ Prev")).toBeDisabled();
|
||||
});
|
||||
|
||||
test("next button is disabled on last phase", () => {
|
||||
loadProgram([{ id: "phase-1", norms: [], goals: [], triggers: [] }]);
|
||||
|
||||
render(<SimpleProgram />);
|
||||
expect(screen.getByText("Next ▶")).toBeDisabled();
|
||||
});
|
||||
|
||||
test("prev and next buttons enable/disable correctly when navigating", () => {
|
||||
loadProgram([
|
||||
{ id: "p1", norms: [], goals: [], triggers: [] },
|
||||
{ id: "p2", norms: [], goals: [], triggers: [] },
|
||||
]);
|
||||
|
||||
render(<SimpleProgram />);
|
||||
|
||||
const prev = screen.getByText("◀ Prev");
|
||||
const next = screen.getByText("Next ▶");
|
||||
|
||||
expect(prev).toBeDisabled();
|
||||
expect(next).not.toBeDisabled();
|
||||
|
||||
fireEvent.click(next);
|
||||
|
||||
expect(prev).not.toBeDisabled();
|
||||
expect(next).toBeDisabled();
|
||||
});
|
||||
|
||||
test("renders achieved and unachieved goals with correct icons", () => {
|
||||
loadProgram([
|
||||
{
|
||||
id: "phase-1",
|
||||
norms: [],
|
||||
goals: [
|
||||
{ id: "g1", description: "Done goal", achieved: true },
|
||||
{ id: "g2", description: "Failed goal", achieved: false },
|
||||
],
|
||||
triggers: [],
|
||||
},
|
||||
]);
|
||||
|
||||
render(<SimpleProgram />);
|
||||
|
||||
expect(screen.getByText("✔")).toBeInTheDocument();
|
||||
expect(screen.getByText("✖")).toBeInTheDocument();
|
||||
expect(screen.getByText("Done goal")).toBeInTheDocument();
|
||||
expect(screen.getByText("Failed goal")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("renders fallback labels when optional fields are missing", () => {
|
||||
loadProgram([
|
||||
{
|
||||
id: "phase-1",
|
||||
norms: [{}],
|
||||
goals: [{}],
|
||||
triggers: [{}],
|
||||
},
|
||||
]);
|
||||
|
||||
render(<SimpleProgram />);
|
||||
|
||||
expect(screen.getByText("Unnamed norm")).toBeInTheDocument();
|
||||
expect(screen.getByText("Unnamed goal")).toBeInTheDocument();
|
||||
expect(screen.getByText("Unnamed trigger")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("does not crash when navigating beyond boundaries", () => {
|
||||
loadProgram([
|
||||
{ id: "p1", norms: [], goals: [], triggers: [] },
|
||||
{ id: "p2", norms: [], goals: [], triggers: [] },
|
||||
]);
|
||||
|
||||
render(<SimpleProgram />);
|
||||
|
||||
fireEvent.click(screen.getByText("Next ▶"));
|
||||
fireEvent.click(screen.getByText("Next ▶"));
|
||||
|
||||
expect(screen.getByText("Phase 2 / 2")).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByText("◀ Prev"));
|
||||
fireEvent.click(screen.getByText("◀ Prev"));
|
||||
|
||||
expect(screen.getByText("Phase 1 / 2")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -1,83 +0,0 @@
|
||||
import { render, screen, fireEvent } from "@testing-library/react";
|
||||
import SimpleProgram from "../../../src/pages/SimpleProgram/SimpleProgram";
|
||||
import useProgramStore from "../../../src/utils/programStore";
|
||||
|
||||
/**
|
||||
* Helper to preload the program store before rendering.
|
||||
*/
|
||||
function loadProgram(phases: Record<string, unknown>[]) {
|
||||
useProgramStore.getState().setProgramState({ phases });
|
||||
}
|
||||
|
||||
describe("SimpleProgram", () => {
|
||||
beforeEach(() => {
|
||||
loadProgram([]);
|
||||
});
|
||||
|
||||
test("shows empty state when no program is loaded", () => {
|
||||
render(<SimpleProgram />);
|
||||
expect(screen.getByText("No program loaded.")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("renders first phase content", () => {
|
||||
loadProgram([
|
||||
{
|
||||
id: "phase-1",
|
||||
norms: [{ id: "n1", norm: "Be polite" }],
|
||||
goals: [{ id: "g1", description: "Finish task", achieved: true }],
|
||||
triggers: [{ id: "t1", label: "Keyword trigger" }],
|
||||
},
|
||||
]);
|
||||
|
||||
render(<SimpleProgram />);
|
||||
|
||||
expect(screen.getByText("Phase 1 / 1")).toBeInTheDocument();
|
||||
expect(screen.getByText("Be polite")).toBeInTheDocument();
|
||||
expect(screen.getByText("Finish task")).toBeInTheDocument();
|
||||
expect(screen.getByText("Keyword trigger")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("allows navigating between phases", () => {
|
||||
loadProgram([
|
||||
{
|
||||
id: "phase-1",
|
||||
norms: [],
|
||||
goals: [],
|
||||
triggers: [],
|
||||
},
|
||||
{
|
||||
id: "phase-2",
|
||||
norms: [{ id: "n2", norm: "Be careful" }],
|
||||
goals: [],
|
||||
triggers: [],
|
||||
},
|
||||
]);
|
||||
|
||||
render(<SimpleProgram />);
|
||||
|
||||
expect(screen.getByText("Phase 1 / 2")).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByText("Next ▶"));
|
||||
|
||||
expect(screen.getByText("Phase 2 / 2")).toBeInTheDocument();
|
||||
expect(screen.getByText("Be careful")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test("prev button is disabled on first phase", () => {
|
||||
loadProgram([
|
||||
{ id: "phase-1", norms: [], goals: [], triggers: [] },
|
||||
]);
|
||||
|
||||
render(<SimpleProgram />);
|
||||
expect(screen.getByText("◀ Prev")).toBeDisabled();
|
||||
});
|
||||
|
||||
test("next button is disabled on last phase", () => {
|
||||
loadProgram([
|
||||
{ id: "phase-1", norms: [], goals: [], triggers: [] },
|
||||
]);
|
||||
|
||||
render(<SimpleProgram />);
|
||||
expect(screen.getByText("Next ▶")).toBeDisabled();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user