Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ function App(): JSX.Element {
</Row>
</Container>
<hr></hr>
<DoubleHalf></DoubleHalf>
<hr></hr>
<ChooseTeam></ChooseTeam>
<hr></hr>
Expand Down
15 changes: 1 addition & 14 deletions src/bad-components/ChooseTeam.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,7 @@ const PEOPLE = [
];

export function ChooseTeam(): JSX.Element {
const [allOptions] = useState<string[]>(PEOPLE);
const [team, setTeam] = useState<string[]>([]);

function chooseMember(newMember: string) {
if (!team.includes(newMember)) {
setTeam([...team, newMember]);
}
}

function clearTeam() {
setTeam([]);
}

return (
Expand All @@ -32,10 +22,7 @@ export function ChooseTeam(): JSX.Element {
{allOptions.map((option: string) => (
<div key={option} style={{ marginBottom: "4px" }}>
Add{" "}
<Button
onClick={() => chooseMember(option)}
size="sm"
>

{option}
</Button>
</div>
Expand Down
21 changes: 21 additions & 0 deletions src/bad-components/ColoredBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ const DEFAULT_COLOR_INDEX = 0;
function ChangeColor(): JSX.Element {
const [colorIndex, setColorIndex] = useState<number>(DEFAULT_COLOR_INDEX);

return (
<Button onClick={() => setColorIndex((1 + colorIndex) % COLORS.length)}>
Next Color
</Button>
);
}

function ColorPreview(): JSX.Element {
const handleNextColorClick = () => {
setColorIndex((colorIndex + 1) % COLORS.length);
};
Expand All @@ -21,7 +29,11 @@ function ColorPreview({ colorIndex }: { colorIndex: number }) {
style={{
width: "50px",
height: "50px",

backgroundColor: COLORS[DEFAULT_COLOR_INDEX],

backgroundColor: COLORS[colorIndex],

display: "inline-block",
verticalAlign: "bottom",
marginLeft: "5px"
Expand All @@ -31,6 +43,15 @@ function ColorPreview({ colorIndex }: { colorIndex: number }) {
}

export function ColoredBox(): JSX.Element {

return (
<div>
<h3>Colored Box</h3>
<span>The current color is: {COLORS[DEFAULT_COLOR_INDEX]}</span>
<div>
<ChangeColor></ChangeColor>
<ColorPreview></ColorPreview>

const [colorIndex] = useState<number>(DEFAULT_COLOR_INDEX);

return (
Expand Down
18 changes: 18 additions & 0 deletions src/bad-components/DoubleHalf.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
import React, { useState } from "react";
import { Button } from "react-bootstrap";

import { dhValue, setDhValue } from "./DoubleHalfState";

function Doubler(): JSX.Element {
return <Button onClick={() => setDhValue(2 * dhValue)}>Double</Button>;
}

function Halver(): JSX.Element {
return <Button onClick={() => setDhValue(0.5 * dhValue)}>Halve</Button>;
}

export function DoubleHalf(): JSX.Element {


export const [dhValue, setDhValue] = useState<number>(10);

export function DoubleHalf(): JSX.Element {
Expand All @@ -18,8 +31,13 @@ export function DoubleHalf(): JSX.Element {
<div>
The current value is: <span>{dhValue}</span>
</div>

<Doubler></Doubler>
<Halver></Halver>

<Button onClick={handleDoubleClick}>Double</Button>
<Button onClick={handleHalfClick}>Half</Button>

</div>
);
}
18 changes: 18 additions & 0 deletions src/bad-components/ShoveBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ function ShoveBoxButton({
position: number;
setPosition: (newPosition: number) => void;
}) {

return (
<Button onClick={() => setPosition(4 + position)}>Shove the Box</Button>
);
}

function MoveableBox(): JSX.Element {
const [position, setPosition] = useState<number>(10);
const handleShoveClick = () => {
setPosition(position + 4);
};
Expand All @@ -16,6 +24,7 @@ function ShoveBoxButton({
}

function MoveableBox({ position }: { position: number }) {

return (
<div
data-testid="moveable-box"
Expand All @@ -33,12 +42,21 @@ function MoveableBox({ position }: { position: number }) {
}

export function ShoveBox(): JSX.Element {
const box = MoveableBox();
// Initialize the position state
const [position, setPosition] = useState<number>(10);

return (
<div>
<h3>Shove Box</h3>
{/* <span>The box is at: {box.position}</span>
<div>
<ShoveBoxButton
position={box.position}
setPosition={box.setPosition}
></ShoveBoxButton>
{box}
</div> */}
{}
<MoveableBox position={position} />
<ShoveBoxButton position={position} setPosition={setPosition} />
Expand Down
35 changes: 35 additions & 0 deletions src/form-components/ChangeColor.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from "react";
import { render, screen } from "@testing-library/react";
import { ChangeColor } from "./ChangeColor";

describe("ChangeColor Component tests", () => {
beforeEach(() => render(<ChangeColor />));
test("There are at least 8 radio buttons and the colored box", () => {
const radios = screen.getAllByRole("radio");
expect(radios.length).toBeGreaterThanOrEqual(8);
expect(screen.getByTestId("colored-box")).toBeInTheDocument();
});
test("Switching the color switches the displayed color.", () => {
const radios: HTMLInputElement[] = screen.getAllByRole("radio");
// Switch to first
radios[0].click();
let coloredBox = screen.getByTestId("colored-box");
expect(coloredBox).toHaveTextContent(radios[0].value);
expect(coloredBox).toHaveStyle({ backgroundColor: radios[0].value });
// Switch to third
radios[2].click();
coloredBox = screen.getByTestId("colored-box");
expect(coloredBox).toHaveTextContent(radios[2].value);
expect(coloredBox).toHaveStyle({ backgroundColor: radios[2].value });
// Switch to 8th
radios[7].click();
coloredBox = screen.getByTestId("colored-box");
expect(coloredBox).toHaveTextContent(radios[7].value);
expect(coloredBox).toHaveStyle({ backgroundColor: radios[7].value });
// Switch back to first
radios[0].click();
coloredBox = screen.getByTestId("colored-box");
expect(coloredBox).toHaveTextContent(radios[0].value);
expect(coloredBox).toHaveStyle({ backgroundColor: radios[0].value });
});
});
51 changes: 51 additions & 0 deletions src/form-components/ChangeColor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React, { useState } from "react";

export function ChangeColor(): JSX.Element {
const [selectedColor, setSelectedColor] = useState("");
const colors = [
"red",
"blue",
"green",
"yellow",
"purple",
"orange",
"pink",
"brown"
];
const handleColorChange = (event: {
target: { value: React.SetStateAction<string> };
}) => {
setSelectedColor(event.target.value);
};

return (
<div>
<h1>Change Color</h1>
<div>
{colors.map((color, index) => (
<label key={index}>
<input
type="radio"
value={color}
checked={selectedColor === color}
onChange={handleColorChange}
style={{ display: "inline" }}
/>
{color}
</label>
))}
</div>
<div
data-testid="colored-box"
style={{
backgroundColor: selectedColor,
color: "white",
padding: "10px",
marginTop: "10px"
}}
>
{selectedColor || "Select a color"}
</div>
</div>
);
}
45 changes: 45 additions & 0 deletions src/form-components/CheckAnswer.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from "react";
import { render, screen } from "@testing-library/react";
import { CheckAnswer } from "./CheckAnswer";
import userEvent from "@testing-library/user-event";

describe("CheckAnswer Component tests", () => {
test("There is an input box", () => {
render(<CheckAnswer expectedAnswer="42" />);
const inputBox = screen.getByRole("textbox");
expect(inputBox).toBeInTheDocument();
});
test("The answer is originally incorrect.", () => {
render(<CheckAnswer expectedAnswer="42" />);
expect(screen.getByText(/❌/i)).toBeInTheDocument();
expect(screen.queryByText(/✔️/i)).not.toBeInTheDocument();
});
test("Entering the right answer makes it correct.", () => {
render(<CheckAnswer expectedAnswer="42" />);
const inputBox = screen.getByRole("textbox");
userEvent.type(inputBox, "42");
expect(screen.getByText(/✔️/i)).toBeInTheDocument();
expect(screen.queryByText(/❌/i)).not.toBeInTheDocument();
});
test("Entering the wrong answer makes it incorrect.", () => {
render(<CheckAnswer expectedAnswer="42" />);
const inputBox = screen.getByRole("textbox");
userEvent.type(inputBox, "43");
expect(screen.getByText(/❌/i)).toBeInTheDocument();
expect(screen.queryByText(/✔️/i)).not.toBeInTheDocument();
});
test("Entering a different right answer makes it correct.", () => {
render(<CheckAnswer expectedAnswer="Hello" />);
const inputBox = screen.getByRole("textbox");
userEvent.type(inputBox, "Hello");
expect(screen.getByText(/✔️/i)).toBeInTheDocument();
expect(screen.queryByText(/❌/i)).not.toBeInTheDocument();
});
test("Entering a different wrong answer still makes it incorrect.", () => {
render(<CheckAnswer expectedAnswer="Hello" />);
const inputBox = screen.getByRole("textbox");
userEvent.type(inputBox, "42");
expect(screen.getByText(/❌/i)).toBeInTheDocument();
expect(screen.queryByText(/✔️/i)).not.toBeInTheDocument();
});
});
26 changes: 26 additions & 0 deletions src/form-components/CheckAnswer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { useState } from "react";

export function CheckAnswer({
expectedAnswer
}: {
expectedAnswer: string;
}): JSX.Element {
const [userAnswer, setUserAnswer] = useState("");
const handleInputChange = (event: {
target: { value: React.SetStateAction<string> };
}) => {
setUserAnswer(event.target.value);
};

return (
<div>
<label>Enter your answer: </label>
<input
type="text"
value={userAnswer}
onChange={handleInputChange}
/>
{userAnswer === expectedAnswer ? <span>✔️</span> : <span>❌</span>}
</div>
);
}
48 changes: 48 additions & 0 deletions src/form-components/EditMode.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from "react";
import { render, screen } from "@testing-library/react";
import { EditMode } from "./EditMode";
import userEvent from "@testing-library/user-event";

describe("EditMode Component tests", () => {
beforeEach(() => render(<EditMode />));
test("There is one checkbox and no textboxes", () => {
const switchButton = screen.getByRole("checkbox");
expect(switchButton).toBeInTheDocument();
expect(switchButton.parentElement).toHaveClass("form-switch");
expect(screen.queryByRole("textbox")).not.toBeInTheDocument();
});
test("Initial text should be 'Your Name is a student'.", () => {
expect(screen.getByText(/Your Name is a student/i)).toBeInTheDocument();
});
test("Can switch into Edit Mode", () => {
const switchButton = screen.getByRole("checkbox");
switchButton.click();
expect(screen.getByRole("textbox")).toBeInTheDocument();
expect(screen.getAllByRole("checkbox")).toHaveLength(2);
});
test("Editing the name and student status changes the text", () => {
const switchButton = screen.getByRole("checkbox");
switchButton.click();
const nameBox = screen.getByRole("textbox");
userEvent.type(nameBox, "Ada Lovelace");
const studentBox = screen.getByRole("checkbox", { name: /student/i });
studentBox.click();
switchButton.click();
expect(
screen.getByText(/Ada Lovelace is not a student/i)
).toBeInTheDocument();
});
test("Different name, click student box twice changes the text", () => {
const switchButton = screen.getByRole("checkbox");
switchButton.click();
const nameBox = screen.getByRole("textbox");
userEvent.type(nameBox, "Alan Turing");
const studentBox = screen.getByRole("checkbox", { name: /student/i });
studentBox.click();
studentBox.click();
switchButton.click();
expect(
screen.getByText(/Alan Turing is a student/i)
).toBeInTheDocument();
});
});
Loading