Skip to content

Commit

Permalink
Reapply "Adapt code to work with PyTA (#103)"
Browse files Browse the repository at this point in the history
This reverts commit 70d7694.
  • Loading branch information
yoonieaj committed Nov 21, 2024
1 parent 70d7694 commit 5def04b
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 34 deletions.
6 changes: 5 additions & 1 deletion jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,11 @@ const config: Config = {
// preset: undefined,

// Run tests from one or more projects
projects: ["./demo/jest.config.ts", "./memory-viz/jest.config.ts"],
projects: [
"./demo/jest.config.ts",
"./memory-viz/jest.config.ts",
"./webstepper/jest.config.ts",
],

// Use this configuration option to add custom reporters to Jest
// reporters: undefined,
Expand Down
22 changes: 22 additions & 0 deletions webstepper/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased

### ✨ Enhancements

- Launchd an initial prototype!
- Improved UI to indicate when the end of the program is reached.

### 🐛 Bug fixes

### 🚨 Breaking changes

### 🔧 Internal changes

- Added a script for installing the Webstepper build to a specified path.
- Updated to use the window object to serve app data.
1 change: 1 addition & 0 deletions webstepper/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"test-cov": "jest --no-cache --coverage",
"build-dev": "webpack --config webpack.dev.js",
"build": "webpack --config webpack.prod.js",
"build-copy": "webpack --config webpack.prod.js && cp -r dist/*",
"start": "webpack serve --config webpack.dev.js"
},
"repository": {
Expand Down
36 changes: 23 additions & 13 deletions webstepper/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,57 @@ import Header from "./Header";
import { Button, Box, Typography, Stack } from "@mui/material";
import SvgDisplay from "./SvgDisplay";
import CodeDisplay from "./CodeDisplay";
import placeholder from "./placeholder";
import "./css/styles.css";

if (typeof window === "object" && process.env.NODE_ENV !== "production") {
window.svgArray = placeholder.svgArray;
window.codeText = placeholder.codeText;
}

export default function App() {
const [step, setStep] = useState<number>(0);
// TODO: replace this with actual code to display
const codeText = `num = 123
some_string = "Hello, world"
num2 = 321
arr = [some_string, "string 123321"]`;
const limit = codeText.split("\n").length;
const codeText = window.codeText;
const limit = window.svgArray.length;

const handleStep = (newStep: number) => {
setStep(Math.min(Math.max(newStep, 0), limit - 1));
};
const svgPath = `/images/snapshot-${step}.svg`;

return (
<main className="container">
<Header />
<Stack direction="row" spacing={2}>
<Box sx={{ width: "40%" }}>
<h2>Code</h2>
<Typography>Line: {step + 1}</Typography>
<Typography>
Step {step + 1}/{limit}
</Typography>
<Box className="code-display">
<CodeDisplay
text={codeText}
startingLineNumber={Math.max(step - 10, 1)}
highlightLine={step + 1}
startingLineNumber={window.svgArray[0].lineNumber}
highlightLine={window.svgArray[step].lineNumber}
/>
<Box className="button-container">
<Button onClick={() => handleStep(step - 1)}>
<Button
disabled={step === 0}
onClick={() => handleStep(step - 1)}
>
Back
</Button>
<Button onClick={() => handleStep(step + 1)}>
<Button
disabled={step === limit - 1}
onClick={() => handleStep(step + 1)}
>
Next
</Button>
</Box>
</Box>
</Box>
<Box sx={{ width: "60%" }}>
<h2>Memory diagrams</h2>
<SvgDisplay svgPath={svgPath} />
<SvgDisplay step={step} />
</Box>
</Stack>
</main>
Expand Down
11 changes: 6 additions & 5 deletions webstepper/src/SvgDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch";
import "./css/styles.css";

type SvgDisplayPropTypes = {
svgPath: string;
step: number;
};

export default function SvgDisplay(props: SvgDisplayPropTypes) {
Expand All @@ -13,10 +13,11 @@ export default function SvgDisplay(props: SvgDisplayPropTypes) {
useEffect(() => {
const loadAndDrawSvg = async () => {
try {
const response = await fetch(props.svgPath);
const blob = await response.blob();
const svgString = window.svgArray[props.step].svg;
const image = new Image();
image.src = URL.createObjectURL(blob);
let data =
"data:image/svg+xml;base64," + window.btoa(svgString);
image.src = data;
image.onload = () => {
const canvas = canvasRef.current;
const context = canvas.getContext("2d");
Expand All @@ -30,7 +31,7 @@ export default function SvgDisplay(props: SvgDisplayPropTypes) {
}
};
loadAndDrawSvg();
}, [props.svgPath]);
}, [props.step]);

return (
<Paper
Expand Down
36 changes: 21 additions & 15 deletions webstepper/src/__tests__/App.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ global.fetch = jest.fn(() =>

URL.createObjectURL = jest.fn(() => "mock-url");

const getStepString = (): string => {
return screen.getByText(/Step \d+\/\d+/).textContent;
};

const getMaxStep = (): number => {
return Number(getStepString().split("/")[1]);
};

describe("App", () => {
beforeEach(() => {
global.fetch = jest.fn(() =>
Expand All @@ -24,52 +32,50 @@ describe("App", () => {
});

it("renders initial state correctly", async () => {
expect(screen.getByText("Line: 1")).toBeInTheDocument();
expect(screen.getByText(/Step \d+\/\d+/)).toBeInTheDocument();
expect(screen.getByText("Code")).toBeInTheDocument();
expect(screen.getByText("Memory diagrams")).toBeInTheDocument();
await waitFor(() => {
expect(global.fetch).toHaveBeenCalledWith("/images/snapshot-0.svg");
});
});

it("handles next button click correctly", () => {
const maxStep = getMaxStep();
const nextButton = screen.getByText("Next");
fireEvent.click(nextButton);

expect(screen.getByText("Line: 2")).toBeInTheDocument();
expect(global.fetch).toHaveBeenCalledWith("/images/snapshot-1.svg");
expect(screen.getByText(`Step 2/${maxStep}`)).toBeInTheDocument();
});

it("handles back button click correctly", () => {
// First go forward
const maxStep = getMaxStep();
const nextButton = screen.getByText("Next");
fireEvent.click(nextButton);

expect(screen.getByText(`Step 2/${maxStep}`)).toBeInTheDocument();

// Then go back
const backButton = screen.getByText("Back");
fireEvent.click(backButton);

expect(screen.getByText("Line: 1")).toBeInTheDocument();
expect(global.fetch).toHaveBeenCalledWith("/images/snapshot-0.svg");
expect(screen.getByText(`Step 1/${maxStep}`)).toBeInTheDocument();
});

it("prevents going below step 0", () => {
const backButton = screen.getByText("Back");
fireEvent.click(backButton);

expect(screen.getByText("Line: 1")).toBeInTheDocument();
expect(global.fetch).toHaveBeenCalledWith("/images/snapshot-0.svg");
expect(screen.getByText(`Step 1/${getMaxStep()}`)).toBeInTheDocument();
});

it("prevents going above maximum steps", () => {
// The limit is 4 (defined in App.tsx)
const maxStep = getMaxStep();
const nextButton = screen.getByText("Next");
for (let i = 0; i < 5; i++) {
for (let i = 0; i < maxStep; i++) {
fireEvent.click(nextButton);
}

expect(screen.getByText("Line: 4")).toBeInTheDocument();
expect(global.fetch).toHaveBeenCalledWith("/images/snapshot-3.svg");
expect(
screen.getByText(`Step ${maxStep}/${maxStep}`)
).toBeInTheDocument();
});

it("highlights the correct line in code display", async () => {
Expand Down
8 changes: 8 additions & 0 deletions webstepper/src/declarations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,11 @@ declare module "*.svg" {
const value: string;
export default value;
}

declare interface Window {
svgArray: {
lineNumber: number;
svg: string;
}[];
codeText: string;
}
60 changes: 60 additions & 0 deletions webstepper/src/placeholder.js

Large diffs are not rendered by default.

0 comments on commit 5def04b

Please sign in to comment.