From 2b5f14cf6979706d394a7699aa00f2b5e9d02bbb Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Mon, 31 Jan 2022 16:37:54 -0500 Subject: [PATCH 01/39] Require Hello World in the document --- src/text.Test.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/text.Test.tsx diff --git a/src/text.Test.tsx b/src/text.Test.tsx new file mode 100644 index 0000000000..b32c330d3f --- /dev/null +++ b/src/text.Test.tsx @@ -0,0 +1,9 @@ +import React from "react"; +import { render, screen } from "@testing-library/react"; +import App from "./App"; + +test("renders the text 'Hello World' somewhere", () => { + render(); + const text = screen.getByText(/Hello World/); + expect(text).toBeInTheDocument(); +}); From a7dee05e0bee0379110c6189433d12482280146a Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Mon, 31 Jan 2022 16:41:17 -0500 Subject: [PATCH 02/39] Rename text.Test.tsx to text.test.tsx --- src/{text.Test.tsx => text.test.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{text.Test.tsx => text.test.tsx} (100%) diff --git a/src/text.Test.tsx b/src/text.test.tsx similarity index 100% rename from src/text.Test.tsx rename to src/text.test.tsx From 3e381f38b1d44afd102eb053a8ba9a48a069434e Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Mon, 31 Jan 2022 16:56:42 -0500 Subject: [PATCH 03/39] Include the task info --- public/tasks/task-first-branch.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 public/tasks/task-first-branch.md diff --git a/public/tasks/task-first-branch.md b/public/tasks/task-first-branch.md new file mode 100644 index 0000000000..94333338a0 --- /dev/null +++ b/public/tasks/task-first-branch.md @@ -0,0 +1,5 @@ +# Task - First Branch + +Version: 0.0.1 + +Pass a short test to have certain text on the page. From e6b1dab1961daf6f03459789cef974bf043501f2 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Thu, 3 Feb 2022 14:10:55 -0500 Subject: [PATCH 04/39] Allow one or more instances of the Hello World text --- src/text.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/text.test.tsx b/src/text.test.tsx index b32c330d3f..f99a063e76 100644 --- a/src/text.test.tsx +++ b/src/text.test.tsx @@ -4,6 +4,6 @@ import App from "./App"; test("renders the text 'Hello World' somewhere", () => { render(); - const text = screen.getByText(/Hello World/); - expect(text).toBeInTheDocument(); + const texts = screen.getAllByText(/Hello World/); + expect(texts.length).toBeGreaterThanOrEqual(1); }); From 7a207345d9e404afd04607811b89bb758de02905 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Sat, 24 Aug 2024 12:52:12 -0400 Subject: [PATCH 05/39] Include json test command here --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index cf6e1bc772..fc2b66a549 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "build": "react-scripts build", "test": "react-scripts test", "test:cov": "react-scripts test --coverage --watchAll", + "test:json": "react-scripts test --json --watchAll=false --outputFile jest-output.json --coverage", "eject": "react-scripts eject", "lint": "eslint ./src --ext .tsx --ext .ts --max-warnings 0", "eslint-output": "eslint-output ./src --ext .tsx --ext .ts --max-warnings 0", From 7fe9ca316fad2e694586e037fe601b85a2584c56 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Mon, 31 Jan 2022 16:37:54 -0500 Subject: [PATCH 06/39] Require Hello World in the document --- src/text.Test.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/text.Test.tsx diff --git a/src/text.Test.tsx b/src/text.Test.tsx new file mode 100644 index 0000000000..b32c330d3f --- /dev/null +++ b/src/text.Test.tsx @@ -0,0 +1,9 @@ +import React from "react"; +import { render, screen } from "@testing-library/react"; +import App from "./App"; + +test("renders the text 'Hello World' somewhere", () => { + render(); + const text = screen.getByText(/Hello World/); + expect(text).toBeInTheDocument(); +}); From b8b8878c873d4faa2fd5f04d656e23d66c7d6cef Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Mon, 31 Jan 2022 16:56:42 -0500 Subject: [PATCH 07/39] Include the task info --- public/tasks/task-first-branch.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 public/tasks/task-first-branch.md diff --git a/public/tasks/task-first-branch.md b/public/tasks/task-first-branch.md new file mode 100644 index 0000000000..94333338a0 --- /dev/null +++ b/public/tasks/task-first-branch.md @@ -0,0 +1,5 @@ +# Task - First Branch + +Version: 0.0.1 + +Pass a short test to have certain text on the page. From fbdebdec2006b01d3976bd9408037baf82eb5e56 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Mon, 31 Jan 2022 16:41:17 -0500 Subject: [PATCH 08/39] Rename text.Test.tsx to text.test.tsx --- src/{text.Test.tsx => text.test.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{text.Test.tsx => text.test.tsx} (100%) diff --git a/src/text.Test.tsx b/src/text.test.tsx similarity index 100% rename from src/text.Test.tsx rename to src/text.test.tsx From 2f0146c22beca5c5ac48603876f0fa8ea2e2e905 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Thu, 3 Feb 2022 14:10:55 -0500 Subject: [PATCH 09/39] Allow one or more instances of the Hello World text --- src/text.test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/text.test.tsx b/src/text.test.tsx index b32c330d3f..f99a063e76 100644 --- a/src/text.test.tsx +++ b/src/text.test.tsx @@ -4,6 +4,6 @@ import App from "./App"; test("renders the text 'Hello World' somewhere", () => { render(); - const text = screen.getByText(/Hello World/); - expect(text).toBeInTheDocument(); + const texts = screen.getAllByText(/Hello World/); + expect(texts.length).toBeGreaterThanOrEqual(1); }); From ac36b32302a8ea2e66b4b954626c8e396e172075 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Sat, 29 Jan 2022 23:59:24 -0500 Subject: [PATCH 10/39] First set of tests --- public/tasks/task-html-css.md | 5 +++++ src/HtmlCss.test.tsx | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 public/tasks/task-html-css.md create mode 100644 src/HtmlCss.test.tsx diff --git a/public/tasks/task-html-css.md b/public/tasks/task-html-css.md new file mode 100644 index 0000000000..ebc0efcba5 --- /dev/null +++ b/public/tasks/task-html-css.md @@ -0,0 +1,5 @@ +# Task - HTML/CSS + +Version: 0.0.1 + +Add in some HTML and CSS, including a fancy looking button. diff --git a/src/HtmlCss.test.tsx b/src/HtmlCss.test.tsx new file mode 100644 index 0000000000..168ce37fde --- /dev/null +++ b/src/HtmlCss.test.tsx @@ -0,0 +1,28 @@ +import React from "react"; +import { render, screen } from "@testing-library/react"; +import App from "./App"; + +describe("Some HTML Elements are added.", () => { + test("There is a header", () => { + render(); + const header = screen.getByRole("heading"); + expect(header).toBeInTheDocument(); + }); +}); + +describe("Some basic CSS is added.", () => { + test("There is a floating red box", () => { + render(); + expect(true); + }); +}); + +describe("Some Bootstrap Elements are added", () => { + test("There is a bootstrap button", () => { + render(); + const button = screen.getByRole("button"); + expect(button).toBeInTheDocument(); + expect(button).toHaveClass("btn"); + expect(button).toHaveClass("btn-primary"); + }); +}); From d04739d1d2ec0c934c0ecf1dc05ac1289063627d Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Sun, 30 Jan 2022 00:24:38 -0500 Subject: [PATCH 11/39] Some logging tests --- src/HtmlCss.test.tsx | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/HtmlCss.test.tsx b/src/HtmlCss.test.tsx index 168ce37fde..bf957616f9 100644 --- a/src/HtmlCss.test.tsx +++ b/src/HtmlCss.test.tsx @@ -1,6 +1,7 @@ import React from "react"; import { render, screen } from "@testing-library/react"; import App from "./App"; +import userEvent from "@testing-library/user-event"; describe("Some HTML Elements are added.", () => { test("There is a header", () => { @@ -18,11 +19,25 @@ describe("Some basic CSS is added.", () => { }); describe("Some Bootstrap Elements are added", () => { - test("There is a bootstrap button", () => { + test("There is one bootstrap button with the text 'Log Hello World'", () => { render(); - const button = screen.getByRole("button"); + const button = screen.getByRole("button", { name: /Log Hello World/i }); expect(button).toBeInTheDocument(); expect(button).toHaveClass("btn"); expect(button).toHaveClass("btn-primary"); }); + + test("Not clicking the bootstrap button does not logs 'Hello World!'", () => { + const consoleSpy = jest.spyOn(console, "log"); + render(); + expect(consoleSpy).not.toHaveBeenCalledWith("Hello World!"); + }); + + test("Clicking the bootstrap button logs 'Hello World!'", () => { + const consoleSpy = jest.spyOn(console, "log"); + render(); + const button = screen.getByRole("button", { name: /Log Hello World/i }); + userEvent.click(button); + expect(consoleSpy).toHaveBeenCalledWith("Hello World!"); + }); }); From b26100f543943eced73fdff33784861243c65386 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Sun, 30 Jan 2022 00:47:43 -0500 Subject: [PATCH 12/39] More html tests --- src/HtmlCss.test.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/HtmlCss.test.tsx b/src/HtmlCss.test.tsx index bf957616f9..676c37f903 100644 --- a/src/HtmlCss.test.tsx +++ b/src/HtmlCss.test.tsx @@ -9,6 +9,20 @@ describe("Some HTML Elements are added.", () => { const header = screen.getByRole("heading"); expect(header).toBeInTheDocument(); }); + + test("There is an image with alt text", () => { + render(); + const image = screen.getByRole("image"); + expect(image).toBeInTheDocument(); + expect(image).toHaveAttribute("alt"); + }); + + test("There is a list with at least three elements", () => { + render(); + const list = screen.getByRole("list"); + expect(list).toBeInTheDocument(); + expect(list.children.length).toBeGreaterThanOrEqual(3); + }); }); describe("Some basic CSS is added.", () => { From 3bf4550a8f042dee28a57c06abec05dfce779519 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Sun, 30 Jan 2022 00:55:24 -0500 Subject: [PATCH 13/39] Fix the image test --- src/HtmlCss.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HtmlCss.test.tsx b/src/HtmlCss.test.tsx index 676c37f903..79b7db2dda 100644 --- a/src/HtmlCss.test.tsx +++ b/src/HtmlCss.test.tsx @@ -12,7 +12,7 @@ describe("Some HTML Elements are added.", () => { test("There is an image with alt text", () => { render(); - const image = screen.getByRole("image"); + const image = screen.getByRole("img"); expect(image).toBeInTheDocument(); expect(image).toHaveAttribute("alt"); }); From 8dff2b64a2efc0b1b49703077965fe5e334eab1a Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Mon, 31 Jan 2022 16:31:58 -0500 Subject: [PATCH 14/39] Updated CSS tests, left a note about additional tests --- src/HtmlCss.test.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/HtmlCss.test.tsx b/src/HtmlCss.test.tsx index 79b7db2dda..379fc8f449 100644 --- a/src/HtmlCss.test.tsx +++ b/src/HtmlCss.test.tsx @@ -30,6 +30,14 @@ describe("Some basic CSS is added.", () => { render(); expect(true); }); + + test("The background color of the header area is different", () => { + render(); + const banner = screen.getByRole("banner"); + expect(banner).not.toHaveStyle({ + "background-color": "rgb(40, 44, 52)" + }); + }); }); describe("Some Bootstrap Elements are added", () => { From b66d4de909f74de4cba160a6fff05b078b9b47cc Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Mon, 31 Jan 2022 16:32:13 -0500 Subject: [PATCH 15/39] See previous commit message --- src/HtmlCss.test.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/HtmlCss.test.tsx b/src/HtmlCss.test.tsx index 379fc8f449..36767ad350 100644 --- a/src/HtmlCss.test.tsx +++ b/src/HtmlCss.test.tsx @@ -26,11 +26,6 @@ describe("Some HTML Elements are added.", () => { }); describe("Some basic CSS is added.", () => { - test("There is a floating red box", () => { - render(); - expect(true); - }); - test("The background color of the header area is different", () => { render(); const banner = screen.getByRole("banner"); @@ -63,3 +58,7 @@ describe("Some Bootstrap Elements are added", () => { expect(consoleSpy).toHaveBeenCalledWith("Hello World!"); }); }); + +/** + * Remember, there are additional tasks described on the page! + */ From 0a24364f67b1ee221ebe175d6c494d5eca6ad7dc Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Sat, 24 Aug 2024 13:10:09 -0400 Subject: [PATCH 16/39] Add in new css test --- src/HtmlCss.test.tsx | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/HtmlCss.test.tsx b/src/HtmlCss.test.tsx index 36767ad350..48b0a6df2d 100644 --- a/src/HtmlCss.test.tsx +++ b/src/HtmlCss.test.tsx @@ -30,7 +30,7 @@ describe("Some basic CSS is added.", () => { render(); const banner = screen.getByRole("banner"); expect(banner).not.toHaveStyle({ - "background-color": "rgb(40, 44, 52)" + "background-color": "rgb(40, 44, 52)", }); }); }); @@ -59,6 +59,25 @@ describe("Some Bootstrap Elements are added", () => { }); }); -/** - * Remember, there are additional tasks described on the page! - */ +describe("Some additional CSS was added", () => { + test("checks if any element has a background color of red", () => { + const { container } = render(); + // Get all elements in the rendered container + const elements = container.querySelectorAll("*"); + + // Check if any element has a background color of red + let foundRedBackground = false; + + elements.forEach((element) => { + const style = getComputedStyle(element); + if ( + style.backgroundColor === "red" || + style.backgroundColor === "rgb(255, 0, 0)" + ) { + foundRedBackground = true; + } + }); + + expect(foundRedBackground).toBe(true); + }); +}); From 4d43d7a5d133522b0a8d92e1cb3d7e4053a81992 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Sat, 24 Aug 2024 13:12:28 -0400 Subject: [PATCH 17/39] Add in points --- src/HtmlCss.test.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/HtmlCss.test.tsx b/src/HtmlCss.test.tsx index 48b0a6df2d..320cb97524 100644 --- a/src/HtmlCss.test.tsx +++ b/src/HtmlCss.test.tsx @@ -4,20 +4,20 @@ import App from "./App"; import userEvent from "@testing-library/user-event"; describe("Some HTML Elements are added.", () => { - test("There is a header", () => { + test("(2 pts) There is a header", () => { render(); const header = screen.getByRole("heading"); expect(header).toBeInTheDocument(); }); - test("There is an image with alt text", () => { + test("(2 pts) There is an image with alt text", () => { render(); const image = screen.getByRole("img"); expect(image).toBeInTheDocument(); expect(image).toHaveAttribute("alt"); }); - test("There is a list with at least three elements", () => { + test("(2 pts) There is a list with at least three elements", () => { render(); const list = screen.getByRole("list"); expect(list).toBeInTheDocument(); @@ -25,7 +25,7 @@ describe("Some HTML Elements are added.", () => { }); }); -describe("Some basic CSS is added.", () => { +describe("(2 pts) Some basic CSS is added.", () => { test("The background color of the header area is different", () => { render(); const banner = screen.getByRole("banner"); @@ -35,7 +35,7 @@ describe("Some basic CSS is added.", () => { }); }); -describe("Some Bootstrap Elements are added", () => { +describe("(2 pts) Some Bootstrap Elements are added", () => { test("There is one bootstrap button with the text 'Log Hello World'", () => { render(); const button = screen.getByRole("button", { name: /Log Hello World/i }); @@ -44,13 +44,13 @@ describe("Some Bootstrap Elements are added", () => { expect(button).toHaveClass("btn-primary"); }); - test("Not clicking the bootstrap button does not logs 'Hello World!'", () => { + test("(2 pts) Not clicking the bootstrap button does not logs 'Hello World!'", () => { const consoleSpy = jest.spyOn(console, "log"); render(); expect(consoleSpy).not.toHaveBeenCalledWith("Hello World!"); }); - test("Clicking the bootstrap button logs 'Hello World!'", () => { + test("(2 pts) Clicking the bootstrap button logs 'Hello World!'", () => { const consoleSpy = jest.spyOn(console, "log"); render(); const button = screen.getByRole("button", { name: /Log Hello World/i }); @@ -60,7 +60,7 @@ describe("Some Bootstrap Elements are added", () => { }); describe("Some additional CSS was added", () => { - test("checks if any element has a background color of red", () => { + test("(2 pts) checks if any element has a background color of red", () => { const { container } = render(); // Get all elements in the rendered container const elements = container.querySelectorAll("*"); From 83c4461f9dbe7d2a66c09eed18959565a302eea2 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Sat, 29 Jan 2022 23:23:45 -0500 Subject: [PATCH 18/39] Basic functions tests and stubs --- public/tasks/task-functions.md | 5 +++ src/functions.test.ts | 59 ++++++++++++++++++++++++++++++++++ src/functions.ts | 19 +++++++++++ 3 files changed, 83 insertions(+) create mode 100644 public/tasks/task-functions.md create mode 100644 src/functions.test.ts create mode 100644 src/functions.ts diff --git a/public/tasks/task-functions.md b/public/tasks/task-functions.md new file mode 100644 index 0000000000..36e7926bb7 --- /dev/null +++ b/public/tasks/task-functions.md @@ -0,0 +1,5 @@ +# Task - Functions + +Version: 0.0.1 + +Implement a bunch of functions that work on primitives. diff --git a/src/functions.test.ts b/src/functions.test.ts new file mode 100644 index 0000000000..e0bef414ea --- /dev/null +++ b/src/functions.test.ts @@ -0,0 +1,59 @@ +import { + add3, + fahrenheitToCelius, + shout, + isQuestion, + convertYesNo +} from "./functions"; + +test("Testing the basic functions", () => { + it("Testing the add3 function", () => { + expect(add3(1, 2, 3)).toBe(6); + expect(add3(9, 7, 4)).toBe(20); + expect(add3(6, -3, 9)).toBe(15); + expect(add3(10, 1, -9)).toBe(11); + expect(add3(-9, -100, -4)).toBe(0); + expect(add3(-1, -1, 1)).toBe(1); + }); + + it("Testing the fahrenheitToCelius function", () => { + expect(fahrenheitToCelius(32)).toBe(0); + expect(fahrenheitToCelius(-40)).toBe(40); + expect(fahrenheitToCelius(-22)).toBe(-30); + expect(fahrenheitToCelius(14)).toBe(-10); + expect(fahrenheitToCelius(68)).toBe(20); + expect(fahrenheitToCelius(86)).toBe(30); + expect(fahrenheitToCelius(212)).toBe(100); + }); + + it("Testing the shout function", () => { + expect(shout("Hello")).toBe("HELLO!"); + expect(shout("What?")).toBe("WHAT?!"); + expect(shout("oHo")).toBe("OHO!"); + expect(shout("AHHHH!!!")).toBe("AHHHH!!!!"); + expect(shout("")).toBe("!"); + expect(shout("Please go outside")).toBe("PLEASE GO OUTSIDE!"); + }); + + it("Testing the isQuestion function", () => { + expect(isQuestion("Is this a question?")).toBe(true); + expect(isQuestion("Who are you?")).toBe(true); + expect(isQuestion("WHAT ARE YOU !?")).toBe(true); + expect(isQuestion("WHAT IS THIS?!")).toBe(false); + expect(isQuestion("OH GOD!")).toBe(false); + expect(isQuestion("Oh nevermind, it's fine.")).toBe(false); + expect(isQuestion("")).toBe(false); + }); + + it("Testing the convertYesNo function", () => { + expect(convertYesNo("yes")).toBe(true); + expect(convertYesNo("YES")).toBe(true); + expect(convertYesNo("NO")).toBe(false); + expect(convertYesNo("no")).toBe(false); + expect(convertYesNo("Apple")).toBe(null); + expect(convertYesNo("Bananas")).toBe(null); + expect(convertYesNo("Nope")).toBe(null); + expect(convertYesNo("Yesterday")).toBe(null); + expect(convertYesNo("Maybe")).toBe(null); + }); +}); diff --git a/src/functions.ts b/src/functions.ts new file mode 100644 index 0000000000..03193e4212 --- /dev/null +++ b/src/functions.ts @@ -0,0 +1,19 @@ +export function fahrenheitToCelius(temperature: number): number { + return 0; +} + +export function add3(first: number, second: number, third: number): number { + return 0; +} + +export function shout(message: string): string { + return ""; +} + +export function isQuestion(message: string): boolean { + return true; +} + +export function convertYesNo(word: string): boolean | null { + return true; +} From a48653022ec3c8b7ce99cf49d98b041e20815420 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Sat, 29 Jan 2022 23:30:17 -0500 Subject: [PATCH 19/39] Fix test organization --- src/functions.test.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/functions.test.ts b/src/functions.test.ts index e0bef414ea..98c926bb6f 100644 --- a/src/functions.test.ts +++ b/src/functions.test.ts @@ -6,8 +6,8 @@ import { convertYesNo } from "./functions"; -test("Testing the basic functions", () => { - it("Testing the add3 function", () => { +describe("Testing the basic functions", () => { + test("Testing the add3 function", () => { expect(add3(1, 2, 3)).toBe(6); expect(add3(9, 7, 4)).toBe(20); expect(add3(6, -3, 9)).toBe(15); @@ -16,7 +16,7 @@ test("Testing the basic functions", () => { expect(add3(-1, -1, 1)).toBe(1); }); - it("Testing the fahrenheitToCelius function", () => { + test("Testing the fahrenheitToCelius function", () => { expect(fahrenheitToCelius(32)).toBe(0); expect(fahrenheitToCelius(-40)).toBe(40); expect(fahrenheitToCelius(-22)).toBe(-30); @@ -26,7 +26,7 @@ test("Testing the basic functions", () => { expect(fahrenheitToCelius(212)).toBe(100); }); - it("Testing the shout function", () => { + test("Testing the shout function", () => { expect(shout("Hello")).toBe("HELLO!"); expect(shout("What?")).toBe("WHAT?!"); expect(shout("oHo")).toBe("OHO!"); @@ -35,7 +35,7 @@ test("Testing the basic functions", () => { expect(shout("Please go outside")).toBe("PLEASE GO OUTSIDE!"); }); - it("Testing the isQuestion function", () => { + test("Testing the isQuestion function", () => { expect(isQuestion("Is this a question?")).toBe(true); expect(isQuestion("Who are you?")).toBe(true); expect(isQuestion("WHAT ARE YOU !?")).toBe(true); @@ -45,7 +45,7 @@ test("Testing the basic functions", () => { expect(isQuestion("")).toBe(false); }); - it("Testing the convertYesNo function", () => { + test("Testing the convertYesNo function", () => { expect(convertYesNo("yes")).toBe(true); expect(convertYesNo("YES")).toBe(true); expect(convertYesNo("NO")).toBe(false); From 9722564e99cecda5d50dd95524c94a76c4cda923 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Sat, 29 Jan 2022 23:39:22 -0500 Subject: [PATCH 20/39] Fix issue in fahrenheit conversion --- src/functions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions.test.ts b/src/functions.test.ts index 98c926bb6f..3eb9f4f3aa 100644 --- a/src/functions.test.ts +++ b/src/functions.test.ts @@ -18,7 +18,7 @@ describe("Testing the basic functions", () => { test("Testing the fahrenheitToCelius function", () => { expect(fahrenheitToCelius(32)).toBe(0); - expect(fahrenheitToCelius(-40)).toBe(40); + expect(fahrenheitToCelius(-40)).toBe(-40); expect(fahrenheitToCelius(-22)).toBe(-30); expect(fahrenheitToCelius(14)).toBe(-10); expect(fahrenheitToCelius(68)).toBe(20); From bd06d5d0e3ed264f7bffb4e8e4811d0efc170255 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Thu, 3 Feb 2022 14:27:08 -0500 Subject: [PATCH 21/39] Move around some of the functions --- src/functions.test.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/functions.test.ts b/src/functions.test.ts index 3eb9f4f3aa..c496ac7e99 100644 --- a/src/functions.test.ts +++ b/src/functions.test.ts @@ -7,15 +7,6 @@ import { } from "./functions"; describe("Testing the basic functions", () => { - test("Testing the add3 function", () => { - expect(add3(1, 2, 3)).toBe(6); - expect(add3(9, 7, 4)).toBe(20); - expect(add3(6, -3, 9)).toBe(15); - expect(add3(10, 1, -9)).toBe(11); - expect(add3(-9, -100, -4)).toBe(0); - expect(add3(-1, -1, 1)).toBe(1); - }); - test("Testing the fahrenheitToCelius function", () => { expect(fahrenheitToCelius(32)).toBe(0); expect(fahrenheitToCelius(-40)).toBe(-40); @@ -26,6 +17,15 @@ describe("Testing the basic functions", () => { expect(fahrenheitToCelius(212)).toBe(100); }); + test("Testing the add3 function", () => { + expect(add3(1, 2, 3)).toBe(6); + expect(add3(9, 7, 4)).toBe(20); + expect(add3(6, -3, 9)).toBe(15); + expect(add3(10, 1, -9)).toBe(11); + expect(add3(-9, -100, -4)).toBe(0); + expect(add3(-1, -1, 1)).toBe(1); + }); + test("Testing the shout function", () => { expect(shout("Hello")).toBe("HELLO!"); expect(shout("What?")).toBe("WHAT?!"); From 4cd1900783f690690229b7c17cf9e81995f52b3a Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Thu, 3 Feb 2022 14:27:18 -0500 Subject: [PATCH 22/39] Explain what the actual functions require you to do --- src/functions.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/functions.ts b/src/functions.ts index 03193e4212..e614c81c0c 100644 --- a/src/functions.ts +++ b/src/functions.ts @@ -1,19 +1,41 @@ +/** + * Consumes a single temperature in Fahrenheit (a number) and converts to Celsius + * using this formula: + * C = (F - 32) * 5/9 + */ export function fahrenheitToCelius(temperature: number): number { return 0; } +/** + * Consumes three numbers and produces their sum. BUT you should only add a number + * if the number is greater than zero. + */ export function add3(first: number, second: number, third: number): number { return 0; } +/** + * Consumes a string and produces the same string in UPPERCASE and with an exclamation + * mark added to the end. + */ export function shout(message: string): string { return ""; } +/** + * Consumes a string (a message) and returns a boolean if the string ends in a question + * mark. Do not use an `if` statement in solving this question. + */ export function isQuestion(message: string): boolean { return true; } +/** + * Consumes a word (a string) and returns either `true`, `false`, or `null`. If the string + * is "yes" (upper or lower case), then return `true`. If the string is "no" (again, either + * upper or lower case), then return `false`. Otherwise, return `null`. + */ export function convertYesNo(word: string): boolean | null { return true; } From cf1d21a31d00c2e8dc8bb7c76f372b3e0adebfbe Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Sat, 24 Aug 2024 13:15:59 -0400 Subject: [PATCH 23/39] Update formatting --- src/functions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/functions.test.ts b/src/functions.test.ts index c496ac7e99..a082bfd61a 100644 --- a/src/functions.test.ts +++ b/src/functions.test.ts @@ -3,7 +3,7 @@ import { fahrenheitToCelius, shout, isQuestion, - convertYesNo + convertYesNo, } from "./functions"; describe("Testing the basic functions", () => { From e11693a366f61cdb442c6f6f5822bd49e2dd604f Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Sat, 24 Aug 2024 13:18:24 -0400 Subject: [PATCH 24/39] Add in points --- src/functions.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/functions.test.ts b/src/functions.test.ts index a082bfd61a..3d921f5d64 100644 --- a/src/functions.test.ts +++ b/src/functions.test.ts @@ -7,7 +7,7 @@ import { } from "./functions"; describe("Testing the basic functions", () => { - test("Testing the fahrenheitToCelius function", () => { + test("(3 pts) Testing the fahrenheitToCelius function", () => { expect(fahrenheitToCelius(32)).toBe(0); expect(fahrenheitToCelius(-40)).toBe(-40); expect(fahrenheitToCelius(-22)).toBe(-30); @@ -17,7 +17,7 @@ describe("Testing the basic functions", () => { expect(fahrenheitToCelius(212)).toBe(100); }); - test("Testing the add3 function", () => { + test("(3 pts) Testing the add3 function", () => { expect(add3(1, 2, 3)).toBe(6); expect(add3(9, 7, 4)).toBe(20); expect(add3(6, -3, 9)).toBe(15); @@ -26,7 +26,7 @@ describe("Testing the basic functions", () => { expect(add3(-1, -1, 1)).toBe(1); }); - test("Testing the shout function", () => { + test("(3 pts) Testing the shout function", () => { expect(shout("Hello")).toBe("HELLO!"); expect(shout("What?")).toBe("WHAT?!"); expect(shout("oHo")).toBe("OHO!"); @@ -35,7 +35,7 @@ describe("Testing the basic functions", () => { expect(shout("Please go outside")).toBe("PLEASE GO OUTSIDE!"); }); - test("Testing the isQuestion function", () => { + test("(3 pts) Testing the isQuestion function", () => { expect(isQuestion("Is this a question?")).toBe(true); expect(isQuestion("Who are you?")).toBe(true); expect(isQuestion("WHAT ARE YOU !?")).toBe(true); @@ -45,7 +45,7 @@ describe("Testing the basic functions", () => { expect(isQuestion("")).toBe(false); }); - test("Testing the convertYesNo function", () => { + test("(3 pts) Testing the convertYesNo function", () => { expect(convertYesNo("yes")).toBe(true); expect(convertYesNo("YES")).toBe(true); expect(convertYesNo("NO")).toBe(false); From 7cc4e3f20e61307e9f22eb466fe21871b3eefbd3 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Tue, 1 Feb 2022 14:51:32 -0500 Subject: [PATCH 25/39] First stab at array problems --- public/tasks/task-arrays.md | 5 +++ src/arrays.test.ts | 12 ++++++ src/arrays.ts | 84 +++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 public/tasks/task-arrays.md create mode 100644 src/arrays.test.ts create mode 100644 src/arrays.ts diff --git a/public/tasks/task-arrays.md b/public/tasks/task-arrays.md new file mode 100644 index 0000000000..c2fbf80f8d --- /dev/null +++ b/public/tasks/task-arrays.md @@ -0,0 +1,5 @@ +# Task - Arrays + +Version: 0.0.1 + +Implement functions that work with arrays immutably. diff --git a/src/arrays.test.ts b/src/arrays.test.ts new file mode 100644 index 0000000000..b812349d2f --- /dev/null +++ b/src/arrays.test.ts @@ -0,0 +1,12 @@ +import { bookEndList } from "./arrays"; + +describe("Testing the array functions", () => { + const NUMBERS_1 = [1, 2, 3]; + + test("Testing the bookEndList function", () => { + // Ensure that the original array was not changed + expect(bookEndList(NUMBERS_1)).not.toBe(NUMBERS_1); + // And that a correct new array was returned + expect(bookEndList(NUMBERS_1)).toEqual([1, 3]); + }); +}); diff --git a/src/arrays.ts b/src/arrays.ts new file mode 100644 index 0000000000..7604b40cdb --- /dev/null +++ b/src/arrays.ts @@ -0,0 +1,84 @@ +/** + * Consume an array of numbers, and return a new array containing + * JUST the first and last number. If there are no elements, return + * an empty array. If there is one element, the resulting list should + * the number twice. + */ +export function bookEndList(numbers: number[]): number[] { + return numbers; +} + +/** + * Consume an array of numbers, and return a new array where each + * number has been tripled (multiplied by 3). + */ +export function tripleNumbers(numbers: number[]): number[] { + return numbers; +} + +/** + * Consume an array of strings and convert them to integers. If + * the number cannot be parsed as an integer, convert it to "?" instead. + */ +export function stringsToIntegers(numbers: string[]): number[] { + return []; +} + +/** + * Consume an array of strings and return them as numbers. Note that + * the strings MAY have "$" symbols at the beginning, in which case + * those should be removed. If the result cannot be parsed as an integer, + * convert it to "?" instead. + */ +// Remember, you can write functions as lambdas too! They work exactly the same. +export const removeDollars = (amounts: string[]): number[] => { + return []; +}; + +/** + * Consume an array of messages and return a new list of the messages. However, any + * string that ends in "!" should be made uppercase. + */ +export const shoutIfExclaiming = (messages: string[]): string[] => { + return []; +}; + +/** + * Consumes an array of words and returns the number of words that are LESS THAN + * 4 letters long. + */ +export function countShortWords(words: string[]): number { + return 0; +} + +/** + * Consumes an array of colors (e.g., 'red', 'purple') and returns true if ALL + * the colors are either 'red', 'blue', or 'green'. If an empty list is given, + * then return true. + */ +export function allRGB(colors: string[]): boolean { + return false; +} + +/** + * Consumes an array of numbers, and produces a string representation of the + * numbers being added together along with their actual sum. + * + * For instance, the array [1, 2, 3] would become "6=1+2+3". + */ +export function makeMath(addends: number[]): string { + return ""; +} + +/** + * Consumes an array of numbers and produces a new array of the same numbers, + * with one difference. After the FIRST negative number, insert the sum of all + * previous numbers in the list. If there are no negative numbers, then append + * 0 to the list. + * + * For instance, the array [1, 9, -5, 7] would become [1, 9, -5, 10, 7] + * And the array [1, 9, 7] would become [1, 9, 0] + */ +export function injectPositive(values: number[]): number[] { + return []; +} From f25333778032fc42866a278af6a3ce871f735150 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Tue, 1 Feb 2022 16:09:10 -0500 Subject: [PATCH 26/39] Add in the rest of the tests --- src/arrays.test.ts | 269 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 265 insertions(+), 4 deletions(-) diff --git a/src/arrays.test.ts b/src/arrays.test.ts index b812349d2f..0881d9fe8a 100644 --- a/src/arrays.test.ts +++ b/src/arrays.test.ts @@ -1,12 +1,273 @@ -import { bookEndList } from "./arrays"; +import { + allRGB, + bookEndList, + countShortWords, + injectPositive, + makeMath, + removeDollars, + shoutIfExclaiming, + stringsToIntegers, + tripleNumbers +} from "./arrays"; describe("Testing the array functions", () => { + ////////////////////////////////// + // bookEndList and tripleNumbers + const NUMBERS_1 = [1, 2, 3]; + const NUMBERS_2 = [100, 300, 200]; + const NUMBERS_3 = [5]; + const NUMBERS_4: number[] = []; + const NUMBERS_5 = [100, 199, 1, -5, 7, 3]; + const NUMBERS_6 = [-100, -200, 100, 200]; + const NUMBERS_7 = [199, 1, 550, 50, 200]; + + // Ensure that none of the arrays were changed mutably + // If you fail these, you aren't using map/filter/reduce/etc. properly! + afterEach(() => { + expect(NUMBERS_1).toEqual([1, 2, 3]); + expect(NUMBERS_2).toEqual([100, 300, 200]); + expect(NUMBERS_3).toEqual([5]); + expect(NUMBERS_4).toEqual([]); + expect(NUMBERS_5).toEqual([100, 199, 1, -5, 7, 3]); + expect(NUMBERS_6).toEqual([-100, -200, 100, 200]); + expect(NUMBERS_7).toEqual([199, 1, 550, 50, 200]); + }); test("Testing the bookEndList function", () => { - // Ensure that the original array was not changed - expect(bookEndList(NUMBERS_1)).not.toBe(NUMBERS_1); - // And that a correct new array was returned expect(bookEndList(NUMBERS_1)).toEqual([1, 3]); + expect(bookEndList(NUMBERS_2)).toEqual([100, 200]); + expect(bookEndList(NUMBERS_3)).toEqual([5, 5]); + expect(bookEndList(NUMBERS_4)).toEqual([]); + expect(bookEndList(NUMBERS_5)).toEqual([100, 3]); + expect(bookEndList(NUMBERS_6)).toEqual([-100, 200]); + }); + + test("Testing the tripleNumbers function", () => { + expect(tripleNumbers(NUMBERS_1)).toEqual([3, 6, 9]); + expect(tripleNumbers(NUMBERS_2)).toEqual([300, 900, 600]); + expect(tripleNumbers(NUMBERS_3)).toEqual([15]); + expect(tripleNumbers(NUMBERS_4)).toEqual([]); + expect(tripleNumbers(NUMBERS_5)).toEqual([300, 597, 3, -15, 21, 9]); + expect(tripleNumbers(NUMBERS_6)).toEqual([-300, -600, 300, 600]); + }); + + ////////////////////////////////// + // stringsToIntegers + + const VALUES_1 = ["1", "2", "3"]; + const VALUES_2 = ["100", "200", "300"]; + const VALUES_3 = ["5"]; + const VALUES_4: string[] = []; + const VALUES_5 = ["100", "?", "27", "$44"]; + const VALUES_6 = ["-1", "0", "1", "*1"]; + const VALUES_7 = ["apple", "banana", "cactus"]; + + // Ensure that none of the arrays were changed mutably + // If you fail these, you aren't using map/filter/reduce/etc. properly! + afterEach(() => { + expect(VALUES_1).toEqual(["1", "2", "3"]); + expect(VALUES_2).toEqual(["100", "200", "300"]); + expect(VALUES_3).toEqual(["5"]); + expect(VALUES_4).toEqual([]); + expect(VALUES_5).toEqual(["100", "?", "27", "$44"]); + expect(VALUES_6).toEqual(["-1", "0", "1", "*1"]); + expect(VALUES_7).toEqual(["apple", "banana", "cactus"]); + }); + + test("Testing the stringsToIntegers function", () => { + expect(stringsToIntegers(VALUES_1)).toEqual([1, 2, 3]); + expect(stringsToIntegers(VALUES_2)).toEqual([100, 200, 300]); + expect(stringsToIntegers(VALUES_3)).toEqual([5]); + expect(stringsToIntegers(VALUES_4)).toEqual([]); + expect(stringsToIntegers(VALUES_5)).toEqual([100, 0, 27, 0]); + expect(stringsToIntegers(VALUES_6)).toEqual([-1, 0, 1, 0]); + expect(stringsToIntegers(VALUES_7)).toEqual([0, 0, 0]); + }); + + ////////////////////////////////// + // removeDollars + + const AMOUNTS_1 = ["$1", "$2", "$3"]; + const AMOUNTS_2 = ["$100", "$200", "$300", "$400"]; + const AMOUNTS_3 = ["$5"]; + const AMOUNTS_4 = ["$"]; + const AMOUNTS_5 = ["100", "200", "$300", "$400"]; + const AMOUNTS_6: string[] = []; + const AMOUNTS_7 = ["100", "???", "7", "$233", "", "$"]; + const AMOUNTS_8 = ["$one", "two", "$three"]; + + // Ensure that none of the arrays were changed mutably + // If you fail these, you aren't using map/filter/reduce/etc. properly! + afterEach(() => { + expect(AMOUNTS_1).toEqual(["$1", "$2", "$3"]); + expect(AMOUNTS_2).toEqual(["$100", "$200", "$300", "$400"]); + expect(AMOUNTS_3).toEqual(["$5"]); + expect(AMOUNTS_4).toEqual(["$"]); + expect(AMOUNTS_5).toEqual(["100", "200", "$300", "$400"]); + expect(AMOUNTS_6).toEqual([]); + expect(AMOUNTS_7).toEqual(["100", "???", "7", "$233", "", "$"]); + expect(AMOUNTS_8).toEqual(["$one", "two", "$three"]); + }); + + test("Testing the removeDollars function", () => { + expect(removeDollars(AMOUNTS_1)).toEqual([1, 2, 3]); + expect(removeDollars(AMOUNTS_2)).toEqual([100, 200, 300, 400]); + expect(removeDollars(AMOUNTS_3)).toEqual([5]); + expect(removeDollars(AMOUNTS_4)).toEqual([0]); + expect(removeDollars(AMOUNTS_5)).toEqual([100, 200, 300, 400]); + expect(removeDollars(AMOUNTS_6)).toEqual([]); + expect(removeDollars(AMOUNTS_7)).toEqual([100, 0, 7, 233, 0, 0]); + expect(removeDollars(AMOUNTS_8)).toEqual([0, 0, 0]); + }); + + ////////////////////////////////// + // shoutIfExclaiming + + const MESSAGE_1 = ["Hello", "you", "are", "great!"]; + const MESSAGE_2 = ["oho!", "Oho!", "oHo!", "oHO!", "OHO!"]; + const MESSAGE_3 = ["Wait?", "What?", "Lo", "How?", "High!"]; + const MESSAGE_4 = ["??????"]; + const MESSAGE_5: string[] = ["This one is very long!"]; + const MESSAGE_6 = ["No", "Caps", "here.", "Right?"]; + + // Ensure that none of the arrays were changed mutably + // If you fail these, you aren't using map/filter/reduce/etc. properly! + afterEach(() => { + expect(MESSAGE_1).toEqual(["Hello", "you", "are", "great!"]); + expect(MESSAGE_2).toEqual(["oho!", "Oho!", "oHo!", "oHO!", "OHO!"]); + expect(MESSAGE_3).toEqual(["Wait?", "What?", "Lo", "How?", "High!"]); + expect(MESSAGE_4).toEqual(["??????"]); + expect(MESSAGE_5).toEqual(["This one is very long!"]); + expect(MESSAGE_6).toEqual(["No", "Caps", "here.", "Right?"]); + }); + + test("Testing the shoutIfExclaiming function", () => { + expect(shoutIfExclaiming(MESSAGE_1)).toEqual([ + "Hello", + "you", + "are", + "GREAT!" + ]); + expect(shoutIfExclaiming(MESSAGE_2)).toEqual([ + "OHO!", + "OHO!", + "OHO!", + "OHO!", + "OHO!" + ]); + expect(shoutIfExclaiming(MESSAGE_3)).toEqual(["Lo", "HIGH!"]); + expect(shoutIfExclaiming(MESSAGE_4)).toEqual([]); + expect(shoutIfExclaiming(MESSAGE_5)).toEqual([ + "THIS ONE IS VERY LONG!" + ]); + expect(shoutIfExclaiming(MESSAGE_6)).toEqual(["No", "Caps", "here."]); + }); + + ////////////////////////////////// + // countShortWords + + const WORDS_1 = ["the", "cat", "in", "the", "hat"]; + const WORDS_2 = ["one", "two", "three", "four", "five", "six", "seven"]; + const WORDS_3 = ["alpha", "beta", "gamma"]; + const WORDS_4 = ["Longest", "Words", "Possible"]; + const WORDS_5: string[] = []; + const WORDS_6 = ["", "", "", ""]; + + // Ensure that none of the arrays were changed mutably + // If you fail these, you aren't using map/filter/reduce/etc. properly! + afterEach(() => { + expect(WORDS_1).toEqual(["the", "cat", "in", "the", "hat"]); + expect(WORDS_2).toEqual([ + "one", + "two", + "three", + "four", + "five", + "six", + "seven" + ]); + expect(WORDS_3).toEqual(["alpha", "beta", "gamma"]); + expect(WORDS_4).toEqual(["Longest", "Words", "Possible"]); + expect(WORDS_5).toEqual([]); + expect(WORDS_6).toEqual(["", "", "", ""]); + }); + + test("Testing the countShortWords function", () => { + expect(countShortWords(WORDS_1)).toEqual(5); + expect(countShortWords(WORDS_2)).toEqual(3); + expect(countShortWords(WORDS_3)).toEqual(0); + expect(countShortWords(WORDS_4)).toEqual(0); + expect(countShortWords(WORDS_5)).toEqual(0); + expect(countShortWords(WORDS_6)).toEqual(4); + }); + + ////////////////////////////////// + // allRGB + + const COLORS_1 = ["red", "green", "blue"]; + const COLORS_2 = ["red", "red", "red"]; + const COLORS_3 = ["red", "red", "blue", "blue", "green", "red"]; + const COLORS_4 = ["purple", "orange", "violet"]; + const COLORS_5 = ["red", "blue", "yellow"]; + const COLORS_6 = ["green"]; + const COLORS_7 = ["red"]; + const COLORS_8 = ["kabluey"]; + const COLORS_9: string[] = []; + + // Ensure that none of the arrays were changed mutably + // If you fail these, you aren't using map/filter/reduce/etc. properly! + afterEach(() => { + expect(COLORS_1).toEqual(["red", "green", "blue"]); + expect(COLORS_2).toEqual(["red", "red", "red"]); + expect(COLORS_3).toEqual([ + "red", + "red", + "blue", + "blue", + "green", + "red" + ]); + expect(COLORS_4).toEqual(["purple", "orange", "violet"]); + expect(COLORS_5).toEqual(["red", "blue", "yellow"]); + expect(COLORS_6).toEqual(["green"]); + expect(COLORS_7).toEqual(["red"]); + expect(COLORS_8).toEqual(["kabluey"]); + expect(COLORS_9).toEqual([]); + }); + + test("Testing the allRGB function", () => { + expect(allRGB(COLORS_1)).toEqual(true); + expect(allRGB(COLORS_2)).toEqual(true); + expect(allRGB(COLORS_3)).toEqual(true); + expect(allRGB(COLORS_4)).toEqual(false); + expect(allRGB(COLORS_5)).toEqual(false); + expect(allRGB(COLORS_6)).toEqual(true); + expect(allRGB(COLORS_7)).toEqual(true); + expect(allRGB(COLORS_8)).toEqual(false); + expect(allRGB(COLORS_9)).toEqual(true); + }); + + ////////////////////////////////// + // makeMath + + test("Testing the makeMath function", () => { + expect(makeMath(NUMBERS_1)).toEqual("6=1+2+3"); + expect(makeMath(NUMBERS_2)).toEqual("600=100+300+200"); + expect(makeMath(NUMBERS_3)).toEqual("5=5"); + expect(makeMath(NUMBERS_4)).toEqual("0=0"); + expect(makeMath(NUMBERS_7)).toEqual("1000=199+1+550+50+200"); + }); + + ////////////////////////////////// + // injectPositive + test("Testing the tripleNumbers function", () => { + expect(injectPositive(NUMBERS_1)).toEqual([1, 2, 3, 6]); + expect(injectPositive(NUMBERS_2)).toEqual([100, 300, 200, 600]); + expect(injectPositive(NUMBERS_3)).toEqual([5, 5]); + expect(injectPositive(NUMBERS_4)).toEqual([0]); + expect(injectPositive(NUMBERS_5)).toEqual([100, 199, 1, -5, 300, 7, 3]); + expect(injectPositive(NUMBERS_6)).toEqual([-100, 0, -200, 100, 200]); + expect(injectPositive(NUMBERS_7)).toEqual([199, 1, 550, 50, 200, 1000]); }); }); From b8777b1873553a2e2780b67fd504486b9d16bd92 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Tue, 1 Feb 2022 16:09:25 -0500 Subject: [PATCH 27/39] Fix question text --- src/arrays.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/arrays.ts b/src/arrays.ts index 7604b40cdb..4a2ffe8e5b 100644 --- a/src/arrays.ts +++ b/src/arrays.ts @@ -18,7 +18,7 @@ export function tripleNumbers(numbers: number[]): number[] { /** * Consume an array of strings and convert them to integers. If - * the number cannot be parsed as an integer, convert it to "?" instead. + * the number cannot be parsed as an integer, convert it to 0 instead. */ export function stringsToIntegers(numbers: string[]): number[] { return []; @@ -28,7 +28,7 @@ export function stringsToIntegers(numbers: string[]): number[] { * Consume an array of strings and return them as numbers. Note that * the strings MAY have "$" symbols at the beginning, in which case * those should be removed. If the result cannot be parsed as an integer, - * convert it to "?" instead. + * convert it to 0 instead. */ // Remember, you can write functions as lambdas too! They work exactly the same. export const removeDollars = (amounts: string[]): number[] => { @@ -37,7 +37,8 @@ export const removeDollars = (amounts: string[]): number[] => { /** * Consume an array of messages and return a new list of the messages. However, any - * string that ends in "!" should be made uppercase. + * string that ends in "!" should be made uppercase. Also, remove any strings that end + * in question marks ("?"). */ export const shoutIfExclaiming = (messages: string[]): string[] => { return []; @@ -65,6 +66,7 @@ export function allRGB(colors: string[]): boolean { * numbers being added together along with their actual sum. * * For instance, the array [1, 2, 3] would become "6=1+2+3". + * And the array [] would become "0=0". */ export function makeMath(addends: number[]): string { return ""; @@ -74,10 +76,10 @@ export function makeMath(addends: number[]): string { * Consumes an array of numbers and produces a new array of the same numbers, * with one difference. After the FIRST negative number, insert the sum of all * previous numbers in the list. If there are no negative numbers, then append - * 0 to the list. + * the sum to the list. * * For instance, the array [1, 9, -5, 7] would become [1, 9, -5, 10, 7] - * And the array [1, 9, 7] would become [1, 9, 0] + * And the array [1, 9, 7] would become [1, 9, 7, 17] */ export function injectPositive(values: number[]): number[] { return []; From f87771e7d8058f6c4fc6d8c6d036953f65b3a775 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Fri, 11 Feb 2022 14:24:17 -0500 Subject: [PATCH 28/39] Update arrays.test.ts --- src/arrays.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arrays.test.ts b/src/arrays.test.ts index 0881d9fe8a..3652078efa 100644 --- a/src/arrays.test.ts +++ b/src/arrays.test.ts @@ -261,7 +261,7 @@ describe("Testing the array functions", () => { ////////////////////////////////// // injectPositive - test("Testing the tripleNumbers function", () => { + test("Testing the injectPositive function", () => { expect(injectPositive(NUMBERS_1)).toEqual([1, 2, 3, 6]); expect(injectPositive(NUMBERS_2)).toEqual([100, 300, 200, 600]); expect(injectPositive(NUMBERS_3)).toEqual([5, 5]); From f0d316b36ae394d502e75849b5532b76ffdf7c68 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Sat, 24 Aug 2024 13:21:13 -0400 Subject: [PATCH 29/39] Add in points --- src/arrays.test.ts | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/arrays.test.ts b/src/arrays.test.ts index 3652078efa..c2847517bd 100644 --- a/src/arrays.test.ts +++ b/src/arrays.test.ts @@ -7,7 +7,7 @@ import { removeDollars, shoutIfExclaiming, stringsToIntegers, - tripleNumbers + tripleNumbers, } from "./arrays"; describe("Testing the array functions", () => { @@ -34,7 +34,7 @@ describe("Testing the array functions", () => { expect(NUMBERS_7).toEqual([199, 1, 550, 50, 200]); }); - test("Testing the bookEndList function", () => { + test("(3 pts) Testing the bookEndList function", () => { expect(bookEndList(NUMBERS_1)).toEqual([1, 3]); expect(bookEndList(NUMBERS_2)).toEqual([100, 200]); expect(bookEndList(NUMBERS_3)).toEqual([5, 5]); @@ -43,7 +43,7 @@ describe("Testing the array functions", () => { expect(bookEndList(NUMBERS_6)).toEqual([-100, 200]); }); - test("Testing the tripleNumbers function", () => { + test("(3 pts) Testing the tripleNumbers function", () => { expect(tripleNumbers(NUMBERS_1)).toEqual([3, 6, 9]); expect(tripleNumbers(NUMBERS_2)).toEqual([300, 900, 600]); expect(tripleNumbers(NUMBERS_3)).toEqual([15]); @@ -75,7 +75,7 @@ describe("Testing the array functions", () => { expect(VALUES_7).toEqual(["apple", "banana", "cactus"]); }); - test("Testing the stringsToIntegers function", () => { + test("(3 pts) Testing the stringsToIntegers function", () => { expect(stringsToIntegers(VALUES_1)).toEqual([1, 2, 3]); expect(stringsToIntegers(VALUES_2)).toEqual([100, 200, 300]); expect(stringsToIntegers(VALUES_3)).toEqual([5]); @@ -110,7 +110,7 @@ describe("Testing the array functions", () => { expect(AMOUNTS_8).toEqual(["$one", "two", "$three"]); }); - test("Testing the removeDollars function", () => { + test("(3 pts) Testing the removeDollars function", () => { expect(removeDollars(AMOUNTS_1)).toEqual([1, 2, 3]); expect(removeDollars(AMOUNTS_2)).toEqual([100, 200, 300, 400]); expect(removeDollars(AMOUNTS_3)).toEqual([5]); @@ -142,24 +142,24 @@ describe("Testing the array functions", () => { expect(MESSAGE_6).toEqual(["No", "Caps", "here.", "Right?"]); }); - test("Testing the shoutIfExclaiming function", () => { + test("(3 pts) Testing the shoutIfExclaiming function", () => { expect(shoutIfExclaiming(MESSAGE_1)).toEqual([ "Hello", "you", "are", - "GREAT!" + "GREAT!", ]); expect(shoutIfExclaiming(MESSAGE_2)).toEqual([ "OHO!", "OHO!", "OHO!", "OHO!", - "OHO!" + "OHO!", ]); expect(shoutIfExclaiming(MESSAGE_3)).toEqual(["Lo", "HIGH!"]); expect(shoutIfExclaiming(MESSAGE_4)).toEqual([]); expect(shoutIfExclaiming(MESSAGE_5)).toEqual([ - "THIS ONE IS VERY LONG!" + "THIS ONE IS VERY LONG!", ]); expect(shoutIfExclaiming(MESSAGE_6)).toEqual(["No", "Caps", "here."]); }); @@ -185,7 +185,7 @@ describe("Testing the array functions", () => { "four", "five", "six", - "seven" + "seven", ]); expect(WORDS_3).toEqual(["alpha", "beta", "gamma"]); expect(WORDS_4).toEqual(["Longest", "Words", "Possible"]); @@ -193,7 +193,7 @@ describe("Testing the array functions", () => { expect(WORDS_6).toEqual(["", "", "", ""]); }); - test("Testing the countShortWords function", () => { + test("(3 pts) Testing the countShortWords function", () => { expect(countShortWords(WORDS_1)).toEqual(5); expect(countShortWords(WORDS_2)).toEqual(3); expect(countShortWords(WORDS_3)).toEqual(0); @@ -226,7 +226,7 @@ describe("Testing the array functions", () => { "blue", "blue", "green", - "red" + "red", ]); expect(COLORS_4).toEqual(["purple", "orange", "violet"]); expect(COLORS_5).toEqual(["red", "blue", "yellow"]); @@ -236,7 +236,7 @@ describe("Testing the array functions", () => { expect(COLORS_9).toEqual([]); }); - test("Testing the allRGB function", () => { + test("(3 pts) Testing the allRGB function", () => { expect(allRGB(COLORS_1)).toEqual(true); expect(allRGB(COLORS_2)).toEqual(true); expect(allRGB(COLORS_3)).toEqual(true); @@ -251,7 +251,7 @@ describe("Testing the array functions", () => { ////////////////////////////////// // makeMath - test("Testing the makeMath function", () => { + test("(3 pts) Testing the makeMath function", () => { expect(makeMath(NUMBERS_1)).toEqual("6=1+2+3"); expect(makeMath(NUMBERS_2)).toEqual("600=100+300+200"); expect(makeMath(NUMBERS_3)).toEqual("5=5"); @@ -261,7 +261,7 @@ describe("Testing the array functions", () => { ////////////////////////////////// // injectPositive - test("Testing the injectPositive function", () => { + test("(3 pts) Testing the injectPositive function", () => { expect(injectPositive(NUMBERS_1)).toEqual([1, 2, 3, 6]); expect(injectPositive(NUMBERS_2)).toEqual([100, 300, 200, 600]); expect(injectPositive(NUMBERS_3)).toEqual([5, 5]); From c2e556dece7ea7737c13bdd355ef3ebcee121e70 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Wed, 2 Feb 2022 13:12:40 -0500 Subject: [PATCH 30/39] First stab at questions --- public/tasks/task-objects.md | 5 + src/data/questions.json | 79 ++++++++++ src/objects.test.ts | 295 +++++++++++++++++++++++++++++++++++ src/objects.ts | 141 +++++++++++++++++ 4 files changed, 520 insertions(+) create mode 100644 public/tasks/task-objects.md create mode 100644 src/data/questions.json create mode 100644 src/objects.test.ts create mode 100644 src/objects.ts diff --git a/public/tasks/task-objects.md b/public/tasks/task-objects.md new file mode 100644 index 0000000000..480889da0d --- /dev/null +++ b/public/tasks/task-objects.md @@ -0,0 +1,5 @@ +# Task - Objects + +Version: 0.0.1 + +Implement functions that work with objects immutably. diff --git a/src/data/questions.json b/src/data/questions.json new file mode 100644 index 0000000000..3b19537526 --- /dev/null +++ b/src/data/questions.json @@ -0,0 +1,79 @@ +{ + "BLANK_QUESTIONS": [ + { + "id": 1, + "name": "Question 1", + "body": "", + "type": "multiple_choice_question", + "options": [], + "expected": "", + "points": 1, + "published": false + }, + { + "id": 47, + "name": "My New Question", + "body": "", + "type": "multiple_choice_question", + "options": [], + "expected": "", + "points": 1, + "published": false + }, + { + "id": 2, + "name": "Question 2", + "body": "", + "type": "short_answer_question", + "options": [], + "expected": "", + "points": 1, + "published": false + } + ], + "SIMPLE_QUESTIONS": [ + { + "id": 1, + "name": "Addition", + "body": "What is 2+2?", + "type": "short_answer_question", + "options": [], + "expected": "4", + "points": 1, + "published": true + }, + { + "id": 2, + "name": "Letters", + "body": "What is the last letter of the English alphabet?", + "type": "short_answer_question", + "options": [], + "expected": "Z", + "points": 1, + "published": false + }, + { + "id": 5, + "name": "Colors", + "body": "Which of these is a color?", + "type": "multiple_choice_question", + "options": ["red", "apple", "firetruck"], + "expected": "red", + "points": 1, + "published": true + }, + { + "id": 9, + "name": "Shapes", + "body": "What shape can you make with one line?", + "type": "multiple_choice_question", + "options": ["square", "triangle", "circle"], + "expected": "circle", + "points": 2, + "published": false + } + ], + "SIMPLE_QUESTIONS_2": [], + "EMPTY_QUESTIONS": [], + "TRIVIA_QUESTIONS": [] +} diff --git a/src/objects.test.ts b/src/objects.test.ts new file mode 100644 index 0000000000..bcff7ab176 --- /dev/null +++ b/src/objects.test.ts @@ -0,0 +1,295 @@ +import { + makeBlankQuestion, + isCorrect, + Question, + isValid, + toShortForm, + toMarkdown, + duplicateQuestion, + renameQuestion, + publishQuestion, + addOption, + mergeQuestion +} from "./objects"; +import testQuestionData from "./data/questions.json"; +import backupQuestionData from "./data/questions.json"; + +//////////////////////////////////////////// +// Setting up the test data + +const { BLANK_QUESTIONS, SIMPLE_QUESTIONS }: Record = + // Typecast the test data that we imported to be a record matching + // strings to the question list + testQuestionData as Record; + +// We have backup versions of the data to make sure all changes are immutable +const { + BLANK_QUESTIONS: BACKUP_BLANK_QUESTIONS, + SIMPLE_QUESTIONS: BACKUP_SIMPLE_QUESTIONS +}: Record = backupQuestionData as Record< + string, + Question[] +>; + +// Unpack the list of simple questions into convenient constants +const [ADDITION_QUESTION, LETTER_QUESTION, COLOR_QUESTION, SHAPE_QUESTION] = + SIMPLE_QUESTIONS; +const [ + BACKUP_ADDITION_QUESTION, + BACKUP_LETTER_QUESTION, + BACKUP_COLOR_QUESTION, + BACKUP_SHAPE_QUESTION +] = BACKUP_SIMPLE_QUESTIONS; + +//////////////////////////////////////////// +// Actual tests + +describe("Testing the object functions", () => { + ////////////////////////////////// + // makeBlankQuestion + + test("Testing the makeBlankQuestion function", () => { + expect( + makeBlankQuestion(1, "Question 1", "multiple_choice_question") + ).toEqual(BLANK_QUESTIONS[0]); + expect( + makeBlankQuestion(47, "My New Question", "multiple_choice_question") + ).toEqual(BLANK_QUESTIONS[1]); + expect( + makeBlankQuestion(2, "Question 2", "short_answer_question") + ).toEqual(BLANK_QUESTIONS[2]); + }); + + /////////////////////////////////// + // isCorrect + test("Testing the isCorrect function", () => { + expect(isCorrect(ADDITION_QUESTION, "4")).toEqual(true); + expect(isCorrect(ADDITION_QUESTION, "2")).toEqual(false); + expect(isCorrect(ADDITION_QUESTION, " 4\n")).toEqual(true); + expect(isCorrect(LETTER_QUESTION, "Z")).toEqual(true); + expect(isCorrect(LETTER_QUESTION, "z")).toEqual(true); + expect(isCorrect(LETTER_QUESTION, "4")).toEqual(false); + expect(isCorrect(LETTER_QUESTION, "0")).toEqual(false); + expect(isCorrect(LETTER_QUESTION, "zed")).toEqual(false); + expect(isCorrect(COLOR_QUESTION, "red")).toEqual(true); + expect(isCorrect(COLOR_QUESTION, "apple")).toEqual(false); + expect(isCorrect(COLOR_QUESTION, "firetruck")).toEqual(false); + expect(isCorrect(SHAPE_QUESTION, "square")).toEqual(false); + expect(isCorrect(SHAPE_QUESTION, "triangle")).toEqual(false); + expect(isCorrect(SHAPE_QUESTION, "circle")).toEqual(true); + }); + + /////////////////////////////////// + // isValid + test("Testing the isValid function", () => { + expect(isValid(ADDITION_QUESTION, "4")).toEqual(true); + expect(isValid(ADDITION_QUESTION, "2")).toEqual(true); + expect(isValid(ADDITION_QUESTION, " 4\n")).toEqual(true); + expect(isValid(LETTER_QUESTION, "Z")).toEqual(true); + expect(isValid(LETTER_QUESTION, "z")).toEqual(true); + expect(isValid(LETTER_QUESTION, "4")).toEqual(true); + expect(isValid(LETTER_QUESTION, "0")).toEqual(true); + expect(isValid(LETTER_QUESTION, "zed")).toEqual(true); + expect(isValid(COLOR_QUESTION, "red")).toEqual(true); + expect(isValid(COLOR_QUESTION, "apple")).toEqual(true); + expect(isValid(COLOR_QUESTION, "firetruck")).toEqual(true); + expect(isValid(COLOR_QUESTION, "RED")).toEqual(false); + expect(isValid(COLOR_QUESTION, "orange")).toEqual(false); + expect(isValid(SHAPE_QUESTION, "square")).toEqual(true); + expect(isValid(SHAPE_QUESTION, "triangle")).toEqual(true); + expect(isValid(SHAPE_QUESTION, "circle")).toEqual(true); + expect(isValid(SHAPE_QUESTION, "circle ")).toEqual(false); + expect(isValid(SHAPE_QUESTION, "rhombus")).toEqual(false); + }); + + /////////////////////////////////// + // toShortForm + test("Testing the toShortForm function", () => { + expect(toShortForm(ADDITION_QUESTION)).toEqual("1: Addition"); + expect(toShortForm(LETTER_QUESTION)).toEqual("2: Letters"); + expect(toShortForm(COLOR_QUESTION)).toEqual("5: Colors"); + expect(toShortForm(SHAPE_QUESTION)).toEqual("9: Shapes"); + expect(toShortForm(BLANK_QUESTIONS[1])).toEqual("47: My New Que"); + }); + + /////////////////////////////////// + // toMarkdown + test("Testing the toMarkdown function", () => { + expect(toMarkdown(ADDITION_QUESTION)).toEqual(`# Addition +What is 2+2?`); + expect(toMarkdown(LETTER_QUESTION)).toEqual(`# Letters +What is the last letter of the English alphabet?`); + expect(toMarkdown(COLOR_QUESTION)).toEqual(`# Colors +Which of these is a color? +- red +- apple +- firetruck`); + expect(toMarkdown(SHAPE_QUESTION)).toEqual(`# Shapes +What shape can you make with one line? +- square +- triangle +- circle`); + }); + + afterEach(() => { + expect(ADDITION_QUESTION).toEqual(BACKUP_ADDITION_QUESTION); + expect(LETTER_QUESTION).toEqual(BACKUP_LETTER_QUESTION); + expect(SHAPE_QUESTION).toEqual(BACKUP_SHAPE_QUESTION); + expect(COLOR_QUESTION).toEqual(BACKUP_COLOR_QUESTION); + expect(BLANK_QUESTIONS).toEqual(BACKUP_BLANK_QUESTIONS); + }); + + /////////////////////////////////// + // renameQuestion + test("Testing the renameQuestion function", () => { + expect( + renameQuestion(ADDITION_QUESTION, "My Addition Question") + ).toEqual({ + id: 1, + name: "My Addition Question", + body: "What is 2+2?", + type: "short_answer_question", + options: [], + expected: "4", + points: 1, + published: true + }); + expect( + renameQuestion(SHAPE_QUESTION, "I COMPLETELY CHANGED THIS NAME") + ).toEqual({ + id: 9, + name: "I COMPLETELY CHANGED THIS NAME", + body: "What shape can you make with one line?", + type: "multiple_choice_question", + options: ["square", "triangle", "circle"], + expected: "circle", + points: 2, + published: false + }); + }); + + /////////////////////////////////// + // publishQuestion + test("Testing the publishQuestion function", () => { + expect(publishQuestion(ADDITION_QUESTION)).toEqual({ + id: 1, + name: "Addition", + body: "What is 2+2?", + type: "short_answer_question", + options: [], + expected: "4", + points: 1, + published: false + }); + expect(publishQuestion(LETTER_QUESTION)).toEqual({ + id: 2, + name: "Letters", + body: "What is the last letter of the English alphabet?", + type: "short_answer_question", + options: [], + expected: "Z", + points: 1, + published: true + }); + expect(publishQuestion(publishQuestion(ADDITION_QUESTION))).toEqual({ + id: 1, + name: "Addition", + body: "What is 2+2?", + type: "short_answer_question", + options: [], + expected: "4", + points: 1, + published: true + }); + }); + + /////////////////////////////////// + // duplicateQuestion + test("Testing the duplicateQuestion function", () => { + expect(duplicateQuestion(9, ADDITION_QUESTION)).toEqual({ + id: 9, + name: "Copy of Addition", + body: "What is 2+2?", + type: "short_answer_question", + options: [], + expected: "4", + points: 1, + published: false + }); + expect(duplicateQuestion(55, LETTER_QUESTION)).toEqual({ + id: 55, + name: "Copy of Letters", + body: "What is the last letter of the English alphabet?", + type: "short_answer_question", + options: [], + expected: "Z", + points: 1, + published: false + }); + }); + + /////////////////////////////////// + // addOption + test("Testing the addOption function", () => { + expect(addOption(SHAPE_QUESTION, "heptagon")).toEqual({ + id: 9, + name: "Shapes", + body: "What shape can you make with one line?", + type: "multiple_choice_question", + options: ["square", "triangle", "circle", "heptagon"], + expected: "circle", + points: 2, + published: false + }); + expect(addOption(COLOR_QUESTION, "squiggles")).toEqual({ + id: 5, + name: "Colors", + body: "Which of these is a color?", + type: "multiple_choice_question", + options: ["red", "apple", "firetruck", "squiggles"], + expected: "red", + points: 1, + published: true + }); + }); + + /////////////////////////////////// + // mergeQuestion + test("Testing the mergeQuestion function", () => { + expect( + mergeQuestion( + 192, + "More Points Addition", + ADDITION_QUESTION, + SHAPE_QUESTION + ) + ).toEqual({ + id: 192, + name: "More Points Addition", + body: "What is 2+2?", + type: "short_answer_question", + options: [], + expected: "4", + points: 2, + published: false + }); + + expect( + mergeQuestion( + 99, + "Less Points Shape", + SHAPE_QUESTION, + ADDITION_QUESTION + ) + ).toEqual({ + id: 99, + name: "Less Points Shape", + body: "What shape can you make with one line?", + type: "multiple_choice_question", + options: ["square", "triangle", "circle"], + expected: "circle", + points: 1, + published: false + }); + }); +}); diff --git a/src/objects.ts b/src/objects.ts new file mode 100644 index 0000000000..d03dd473e3 --- /dev/null +++ b/src/objects.ts @@ -0,0 +1,141 @@ +/** QuestionType influences how a question is asked and what kinds of answers are possible */ +export type QuestionType = "multiple_choice_question" | "short_answer_question"; + +export interface Question { + /** A unique identifier for the question */ + id: number; + /** The human-friendly title of the question */ + name: string; + /** The instructions and content of the Question */ + body: string; + /** The kind of Question; influences how the user answers and what options are displayed */ + type: QuestionType; + /** The possible answers for a Question (for Multiple Choice questions) */ + options: string[]; + /** The actually correct answer expected */ + expected: string; + /** How many points this question is worth, roughly indicating its importance and difficulty */ + points: number; + /** Whether or not this question is ready to display to students */ + published: boolean; +} + +/** + * Create a new blank question with the given `id`, `name`, and `type. The `body` and + * `expected` should be empty strings, the `options` should be an empty list, the `points` + * should default to 1, and `published` should default to false. + */ +export function makeBlankQuestion( + id: number, + name: string, + type: QuestionType +): Question { + return {}; +} + +/** + * Consumes a question and a potential `answer`, and returns whether or not + * the `answer` is correct. You should check that the `answer` is equal to + * the `expected`, ignoring capitalization and trimming any whitespace. + * + * HINT: Look up the `trim` and `toLowerCase` functions. + */ +export function isCorrect(question: Question, answer: string): boolean { + return false; +} + +/** + * Consumes a question and a potential `answer`, and returns whether or not + * the `answer` is valid (but not necessarily correct). For a `short_answer_question`, + * any answer is valid. But for a `multiple_choice_question`, the `answer` must + * be exactly one of the options. + */ +export function isValid(question: Question, answer: string): boolean { + return false; +} + +/** + * Consumes a question and produces a string representation combining the + * `id` and first 10 characters of the `name`. The two strings should be + * separated by ": ". So for example, the question with id 9 and the + * name "My First Question" would become "9: My First Q". + */ +export function toShortForm(question: Question): string { + return ""; +} + +/** + * Consumes a question and returns a formatted string representation as follows: + * - The first line should be a hash sign, a space, and then the `name` + * - The second line should be the `body` + * - If the question is a `multiple_choice_question`, then the following lines + * need to show each option on its line, preceded by a dash and space. + * + * The example below might help, but don't include the border! + * ----------Example------------- + * |# Name | + * |The body goes here! | + * |- Option 1 | + * |- Option 2 | + * |- Option 3 | + * ------------------------------ + * Check the unit tests for more examples of what this looks like! + */ +export function toMarkdown(question: Question): string { + return ""; +} + +/** + * Return a new version of the given question, except the name should now be + * `newName`. + */ +export function renameQuestion(question: Question, newName: string): Question { + return question; +} + +/** + * Return a new version of the given question, except the `published` field + * should be inverted. If the question was not published, now it should be + * published; if it was published, now it should be not published. + */ +export function publishQuestion(question: Question): Question { + return question; +} + +/** + * Create a new question based on the old question, copying over its `body`, `type`, + * `options`, `expected`, and `points` without changes. The `name` should be copied + * over as "Copy of ORIGINAL NAME" (e.g., so "Question 1" would become "Copy of Question 1"). + * The `published` field should be reset to false. + */ +export function duplicateQuestion(id: number, oldQuestion: Question): Question { + return oldQuestion; +} + +/** + * Return a new version of the given question, with the `newOption` added to + * the list of existing `options`. Remember that the new Question MUST have + * its own separate copy of the `options` list, rather than the same reference + * to the original question's list! + * Check out the subsection about "Nested Fields" for more information. + */ +export function addOption(question: Question, newOption: string): Question { + return question; +} + +/** + * Consumes an id, name, and two questions, and produces a new question. + * The new question will use the `body`, `type`, `options`, and `expected` of the + * `contentQuestion`. The second question will provide the `points`. + * The `published` status should be set to false. + * Notice that the second Question is provided as just an object with a `points` + * field; but the function call would be the same as if it were a `Question` type! + */ +export function mergeQuestion( + id: number, + name: string, + contentQuestion: Question, + { points }: { points: number } +): Question { + return contentQuestion; +} From 406ffb2b572cb14e885af2a2fddc8e9cc42c97dd Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Sun, 6 Feb 2022 18:33:46 -0500 Subject: [PATCH 31/39] Move Question interface to separate file --- src/interfaces/question.ts | 21 +++++++++++++++++++++ src/objects.test.ts | 2 +- src/objects.ts | 22 +--------------------- 3 files changed, 23 insertions(+), 22 deletions(-) create mode 100644 src/interfaces/question.ts diff --git a/src/interfaces/question.ts b/src/interfaces/question.ts new file mode 100644 index 0000000000..a39431565e --- /dev/null +++ b/src/interfaces/question.ts @@ -0,0 +1,21 @@ +/** QuestionType influences how a question is asked and what kinds of answers are possible */ +export type QuestionType = "multiple_choice_question" | "short_answer_question"; + +export interface Question { + /** A unique identifier for the question */ + id: number; + /** The human-friendly title of the question */ + name: string; + /** The instructions and content of the Question */ + body: string; + /** The kind of Question; influences how the user answers and what options are displayed */ + type: QuestionType; + /** The possible answers for a Question (for Multiple Choice questions) */ + options: string[]; + /** The actually correct answer expected */ + expected: string; + /** How many points this question is worth, roughly indicating its importance and difficulty */ + points: number; + /** Whether or not this question is ready to display to students */ + published: boolean; +} diff --git a/src/objects.test.ts b/src/objects.test.ts index bcff7ab176..a9c76a334e 100644 --- a/src/objects.test.ts +++ b/src/objects.test.ts @@ -1,7 +1,7 @@ +import { Question } from "./interfaces/question"; import { makeBlankQuestion, isCorrect, - Question, isValid, toShortForm, toMarkdown, diff --git a/src/objects.ts b/src/objects.ts index d03dd473e3..3fd2072e5e 100644 --- a/src/objects.ts +++ b/src/objects.ts @@ -1,24 +1,4 @@ -/** QuestionType influences how a question is asked and what kinds of answers are possible */ -export type QuestionType = "multiple_choice_question" | "short_answer_question"; - -export interface Question { - /** A unique identifier for the question */ - id: number; - /** The human-friendly title of the question */ - name: string; - /** The instructions and content of the Question */ - body: string; - /** The kind of Question; influences how the user answers and what options are displayed */ - type: QuestionType; - /** The possible answers for a Question (for Multiple Choice questions) */ - options: string[]; - /** The actually correct answer expected */ - expected: string; - /** How many points this question is worth, roughly indicating its importance and difficulty */ - points: number; - /** Whether or not this question is ready to display to students */ - published: boolean; -} +import { Question, QuestionType } from "./interfaces/question"; /** * Create a new blank question with the given `id`, `name`, and `type. The `body` and From 9b9adb6f2ccbd1113a09cb8e13186d6d4f829928 Mon Sep 17 00:00:00 2001 From: Austin Cory Bart Date: Sat, 24 Aug 2024 13:27:44 -0400 Subject: [PATCH 32/39] Fix formatting --- src/objects.test.ts | 70 ++++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/src/objects.test.ts b/src/objects.test.ts index a9c76a334e..4d3117405d 100644 --- a/src/objects.test.ts +++ b/src/objects.test.ts @@ -9,7 +9,7 @@ import { renameQuestion, publishQuestion, addOption, - mergeQuestion + mergeQuestion, } from "./objects"; import testQuestionData from "./data/questions.json"; import backupQuestionData from "./data/questions.json"; @@ -25,7 +25,7 @@ const { BLANK_QUESTIONS, SIMPLE_QUESTIONS }: Record = // We have backup versions of the data to make sure all changes are immutable const { BLANK_QUESTIONS: BACKUP_BLANK_QUESTIONS, - SIMPLE_QUESTIONS: BACKUP_SIMPLE_QUESTIONS + SIMPLE_QUESTIONS: BACKUP_SIMPLE_QUESTIONS, }: Record = backupQuestionData as Record< string, Question[] @@ -38,7 +38,7 @@ const [ BACKUP_ADDITION_QUESTION, BACKUP_LETTER_QUESTION, BACKUP_COLOR_QUESTION, - BACKUP_SHAPE_QUESTION + BACKUP_SHAPE_QUESTION, ] = BACKUP_SIMPLE_QUESTIONS; //////////////////////////////////////////// @@ -48,21 +48,25 @@ describe("Testing the object functions", () => { ////////////////////////////////// // makeBlankQuestion - test("Testing the makeBlankQuestion function", () => { + test("(3 pts) Testing the makeBlankQuestion function", () => { expect( - makeBlankQuestion(1, "Question 1", "multiple_choice_question") + makeBlankQuestion(1, "Question 1", "multiple_choice_question"), ).toEqual(BLANK_QUESTIONS[0]); expect( - makeBlankQuestion(47, "My New Question", "multiple_choice_question") + makeBlankQuestion( + 47, + "My New Question", + "multiple_choice_question", + ), ).toEqual(BLANK_QUESTIONS[1]); expect( - makeBlankQuestion(2, "Question 2", "short_answer_question") + makeBlankQuestion(2, "Question 2", "short_answer_question"), ).toEqual(BLANK_QUESTIONS[2]); }); /////////////////////////////////// // isCorrect - test("Testing the isCorrect function", () => { + test("(3 pts) Testing the isCorrect function", () => { expect(isCorrect(ADDITION_QUESTION, "4")).toEqual(true); expect(isCorrect(ADDITION_QUESTION, "2")).toEqual(false); expect(isCorrect(ADDITION_QUESTION, " 4\n")).toEqual(true); @@ -81,7 +85,7 @@ describe("Testing the object functions", () => { /////////////////////////////////// // isValid - test("Testing the isValid function", () => { + test("(3 pts) Testing the isValid function", () => { expect(isValid(ADDITION_QUESTION, "4")).toEqual(true); expect(isValid(ADDITION_QUESTION, "2")).toEqual(true); expect(isValid(ADDITION_QUESTION, " 4\n")).toEqual(true); @@ -104,7 +108,7 @@ describe("Testing the object functions", () => { /////////////////////////////////// // toShortForm - test("Testing the toShortForm function", () => { + test("(3 pts) Testing the toShortForm function", () => { expect(toShortForm(ADDITION_QUESTION)).toEqual("1: Addition"); expect(toShortForm(LETTER_QUESTION)).toEqual("2: Letters"); expect(toShortForm(COLOR_QUESTION)).toEqual("5: Colors"); @@ -114,7 +118,7 @@ describe("Testing the object functions", () => { /////////////////////////////////// // toMarkdown - test("Testing the toMarkdown function", () => { + test("(3 pts) Testing the toMarkdown function", () => { expect(toMarkdown(ADDITION_QUESTION)).toEqual(`# Addition What is 2+2?`); expect(toMarkdown(LETTER_QUESTION)).toEqual(`# Letters @@ -141,9 +145,9 @@ What shape can you make with one line? /////////////////////////////////// // renameQuestion - test("Testing the renameQuestion function", () => { + test("(3 pts) Testing the renameQuestion function", () => { expect( - renameQuestion(ADDITION_QUESTION, "My Addition Question") + renameQuestion(ADDITION_QUESTION, "My Addition Question"), ).toEqual({ id: 1, name: "My Addition Question", @@ -152,10 +156,10 @@ What shape can you make with one line? options: [], expected: "4", points: 1, - published: true + published: true, }); expect( - renameQuestion(SHAPE_QUESTION, "I COMPLETELY CHANGED THIS NAME") + renameQuestion(SHAPE_QUESTION, "I COMPLETELY CHANGED THIS NAME"), ).toEqual({ id: 9, name: "I COMPLETELY CHANGED THIS NAME", @@ -164,13 +168,13 @@ What shape can you make with one line? options: ["square", "triangle", "circle"], expected: "circle", points: 2, - published: false + published: false, }); }); /////////////////////////////////// // publishQuestion - test("Testing the publishQuestion function", () => { + test("(3 pts) Testing the publishQuestion function", () => { expect(publishQuestion(ADDITION_QUESTION)).toEqual({ id: 1, name: "Addition", @@ -179,7 +183,7 @@ What shape can you make with one line? options: [], expected: "4", points: 1, - published: false + published: false, }); expect(publishQuestion(LETTER_QUESTION)).toEqual({ id: 2, @@ -189,7 +193,7 @@ What shape can you make with one line? options: [], expected: "Z", points: 1, - published: true + published: true, }); expect(publishQuestion(publishQuestion(ADDITION_QUESTION))).toEqual({ id: 1, @@ -199,13 +203,13 @@ What shape can you make with one line? options: [], expected: "4", points: 1, - published: true + published: true, }); }); /////////////////////////////////// // duplicateQuestion - test("Testing the duplicateQuestion function", () => { + test("(3 pts) Testing the duplicateQuestion function", () => { expect(duplicateQuestion(9, ADDITION_QUESTION)).toEqual({ id: 9, name: "Copy of Addition", @@ -214,7 +218,7 @@ What shape can you make with one line? options: [], expected: "4", points: 1, - published: false + published: false, }); expect(duplicateQuestion(55, LETTER_QUESTION)).toEqual({ id: 55, @@ -224,13 +228,13 @@ What shape can you make with one line? options: [], expected: "Z", points: 1, - published: false + published: false, }); }); /////////////////////////////////// // addOption - test("Testing the addOption function", () => { + test("(3 pts) Testing the addOption function", () => { expect(addOption(SHAPE_QUESTION, "heptagon")).toEqual({ id: 9, name: "Shapes", @@ -239,7 +243,7 @@ What shape can you make with one line? options: ["square", "triangle", "circle", "heptagon"], expected: "circle", points: 2, - published: false + published: false, }); expect(addOption(COLOR_QUESTION, "squiggles")).toEqual({ id: 5, @@ -249,20 +253,20 @@ What shape can you make with one line? options: ["red", "apple", "firetruck", "squiggles"], expected: "red", points: 1, - published: true + published: true, }); }); /////////////////////////////////// // mergeQuestion - test("Testing the mergeQuestion function", () => { + test("(3 pts) Testing the mergeQuestion function", () => { expect( mergeQuestion( 192, "More Points Addition", ADDITION_QUESTION, - SHAPE_QUESTION - ) + SHAPE_QUESTION, + ), ).toEqual({ id: 192, name: "More Points Addition", @@ -271,7 +275,7 @@ What shape can you make with one line? options: [], expected: "4", points: 2, - published: false + published: false, }); expect( @@ -279,8 +283,8 @@ What shape can you make with one line? 99, "Less Points Shape", SHAPE_QUESTION, - ADDITION_QUESTION - ) + ADDITION_QUESTION, + ), ).toEqual({ id: 99, name: "Less Points Shape", @@ -289,7 +293,7 @@ What shape can you make with one line? options: ["square", "triangle", "circle"], expected: "circle", points: 1, - published: false + published: false, }); }); }); From 985879800de62cdb2bb06c43fc2afc13c72d76ec Mon Sep 17 00:00:00 2001 From: Daniel La Mastra Date: Wed, 4 Feb 2026 15:08:08 -0500 Subject: [PATCH 33/39] Added name to App --- src/App.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/App.tsx b/src/App.tsx index b77558eaac..533135ce58 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,7 +5,9 @@ function App(): React.JSX.Element { return (
- UD CISC275 with React Hooks and TypeScript + UD CISC275 with React Hooks and TypeScript +
+ Daniel La Mastra

Edit src/App.tsx and save. This page will From f86050cbf28c599ed9d8542c519ad3aaa3f2c400 Mon Sep 17 00:00:00 2001 From: Daniel La Mastra Date: Fri, 6 Feb 2026 12:30:06 -0500 Subject: [PATCH 34/39] Added Hello World --- package-lock.json | 123 +++++++++++++++++++++------------------------- src/App.tsx | 2 + 2 files changed, 59 insertions(+), 66 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8c3779f487..1e6922997e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2153,7 +2153,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" @@ -2166,7 +2166,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -3273,7 +3273,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" @@ -3436,7 +3436,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -3454,7 +3454,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -3470,7 +3470,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -3487,7 +3487,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -3500,14 +3500,14 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@jest/types/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -3517,7 +3517,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -3909,7 +3909,7 @@ "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@sinonjs/commons": { @@ -4222,7 +4222,6 @@ "version": "10.4.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.10.4", @@ -4242,7 +4241,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -4258,7 +4256,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -4275,7 +4272,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -4288,14 +4284,12 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, "license": "MIT" }, "node_modules/@testing-library/dom/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4305,7 +4299,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -4470,35 +4463,34 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@types/aria-query": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", - "dev": true, "license": "MIT" }, "node_modules/@types/babel__core": { @@ -4911,7 +4903,7 @@ "version": "17.0.33", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@types/yargs-parser": "*" @@ -5508,7 +5500,7 @@ "version": "8.3.3", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "acorn": "^8.11.0" @@ -7210,7 +7202,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/cross-spawn": { @@ -7947,7 +7939,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -13021,7 +13013,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -13031,7 +13023,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -13949,7 +13941,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -13959,7 +13951,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -13994,7 +13986,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -14010,7 +14002,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -14027,7 +14019,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -14040,14 +14032,14 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/jest-resolve/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -14057,7 +14049,7 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", @@ -14075,7 +14067,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -14518,7 +14510,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -14536,7 +14528,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -14552,7 +14544,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -14569,7 +14561,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -14582,14 +14574,14 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/jest-util/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -14599,7 +14591,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -14612,7 +14604,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -14630,7 +14622,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -14646,7 +14638,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -14659,7 +14651,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -14676,7 +14668,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -14689,14 +14681,14 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/jest-validate/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -14706,7 +14698,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -14721,7 +14713,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -14734,14 +14726,14 @@ "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/jest-validate/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -14850,7 +14842,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -14866,7 +14858,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -14876,7 +14868,7 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -15368,7 +15360,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", - "dev": true, "license": "MIT", "bin": { "lz-string": "bin/bin.js" @@ -15402,7 +15393,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/makeerror": { @@ -20668,7 +20659,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=10" @@ -22588,7 +22579,7 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -22632,7 +22623,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/tsconfig-paths": { @@ -23056,7 +23047,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/v8-to-istanbul": { @@ -24118,7 +24109,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" diff --git a/src/App.tsx b/src/App.tsx index 533135ce58..3717fc06cd 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,6 +8,8 @@ function App(): React.JSX.Element { UD CISC275 with React Hooks and TypeScript
Daniel La Mastra +
+ Hello World

Edit src/App.tsx and save. This page will From b588794e4505f9b3bb1291aeeba1b3ce7020fdbe Mon Sep 17 00:00:00 2001 From: Daniel La Mastra Date: Mon, 9 Feb 2026 17:53:14 -0500 Subject: [PATCH 35/39] All tests for Task 3 are passing. --- src/App.css | 6 +++--- src/App.tsx | 34 +++++++++++++++++++++++++++++++++- src/images/oldman.jpg | Bin 0 -> 78544 bytes src/images/simpsons.jpg | Bin 0 -> 39496 bytes 4 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 src/images/oldman.jpg create mode 100644 src/images/simpsons.jpg diff --git a/src/App.css b/src/App.css index ad32fac073..47ba977f56 100644 --- a/src/App.css +++ b/src/App.css @@ -15,18 +15,18 @@ .App-header { width: 100%; - background-color: #282c34; + background-color: rgb(255, 0, 0); min-height: 40vh; display: flex; flex-direction: column; align-items: center; justify-content: center; font-size: calc(10px + 2vmin); - color: white; + color: rgb(0, 0, 0); } .App-link { - color: #61dafb; + color: #020000; } @keyframes App-logo-spin { diff --git a/src/App.tsx b/src/App.tsx index 3717fc06cd..da605048cb 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,20 +1,52 @@ import React from "react"; +import { Button } from "react-bootstrap"; +import simpsons from "./images/simpsons.jpg"; +import { Container } from 'react-bootstrap'; +import { Row } from 'react-bootstrap'; +import { Col } from 'react-bootstrap'; import "./App.css"; function App(): React.JSX.Element { return (

- UD CISC275 with React Hooks and TypeScript +

This is a header.

+ UD CISC275 with React Hooks and TypeScript
Daniel La Mastra
Hello World + Old man yells at clouds. + This is colored text. +
    +
  • First thing
  • +
  • Another thing
  • +
  • A third item
  • +

+ Edit src/App.tsx and save. This page will automatically reload.

+
+ + + First column. + + Second column. + You can put whatever you want in here, and it will be on the right side. + Maybe try adding an image? + + + +
); } diff --git a/src/images/oldman.jpg b/src/images/oldman.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dbdf90460236ed1fcfdda5c0e5325f7b1ea3c15a GIT binary patch literal 78544 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

U@FmMg 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�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 A+W-In literal 0 HcmV?d00001 From 42271a99a198c194b29916c83008fe3d29878626 Mon Sep 17 00:00:00 2001 From: Daniel La Mastra Date: Mon, 16 Feb 2026 17:26:07 -0500 Subject: [PATCH 36/39] All tests are passing. --- package-lock.json | 378 +++++++++++++++++++++++++++++++--------------- package.json | 6 +- src/App.tsx | 38 +++-- src/functions.ts | 28 +++- 4 files changed, 307 insertions(+), 143 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1e6922997e..4aa4fe2134 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,9 +26,9 @@ "@testing-library/react": "^16.0.0", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^8.2.0", - "@typescript-eslint/parser": "^8.2.0", - "eslint": "^8.57.0", + "@typescript-eslint/eslint-plugin": "^8.55.0", + "@typescript-eslint/parser": "^8.55.0", + "eslint": "^8.57.1", "eslint-config-prettier": "^9.1.0", "eslint-output": "^3.0.1", "eslint-plugin-prettier": "^5.2.1", @@ -2460,24 +2460,27 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -2556,22 +2559,22 @@ } }, "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "deprecated": "Use @eslint/config-array instead", "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", + "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" }, @@ -2580,9 +2583,9 @@ } }, "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -4916,21 +4919,20 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.2.0.tgz", - "integrity": "sha512-02tJIs655em7fvt9gps/+4k4OsKULYGtLBPJfOsmOq1+3cdClYiF0+d6mHu6qDnTcg88wJBkcPLpQhq7FyDz0A==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.55.0.tgz", + "integrity": "sha512-1y/MVSz0NglV1ijHC8OT49mPJ4qhPYjiK08YUQVbIOyu+5k862LKUHFkpKHWu//zmr7hDR2rhwUm6gnCGNmGBQ==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.2.0", - "@typescript-eslint/type-utils": "8.2.0", - "@typescript-eslint/utils": "8.2.0", - "@typescript-eslint/visitor-keys": "8.2.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.55.0", + "@typescript-eslint/type-utils": "8.55.0", + "@typescript-eslint/utils": "8.55.0", + "@typescript-eslint/visitor-keys": "8.55.0", + "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.4.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4940,13 +4942,32 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", - "eslint": "^8.57.0 || ^9.0.0" + "@typescript-eslint/parser": "^8.55.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ts-api-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "typescript": ">=4.8.4" } }, "node_modules/@typescript-eslint/experimental-utils": { @@ -5103,17 +5124,17 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.2.0.tgz", - "integrity": "sha512-j3Di+o0lHgPrb7FxL3fdEy6LJ/j2NE8u+AP/5cQ9SKb+JLH6V6UHDqJ+e0hXBkHP1wn1YDFjYCS9LBQsZDlDEg==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.55.0.tgz", + "integrity": "sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.2.0", - "@typescript-eslint/types": "8.2.0", - "@typescript-eslint/typescript-estree": "8.2.0", - "@typescript-eslint/visitor-keys": "8.2.0", - "debug": "^4.3.4" + "@typescript-eslint/scope-manager": "8.55.0", + "@typescript-eslint/types": "8.55.0", + "@typescript-eslint/typescript-estree": "8.55.0", + "@typescript-eslint/visitor-keys": "8.55.0", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5123,23 +5144,41 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.55.0.tgz", + "integrity": "sha512-zRcVVPFUYWa3kNnjaZGXSu3xkKV1zXy8M4nO/pElzQhFweb7PPtluDLQtKArEOGmjXoRjnUZ29NjOiF0eCDkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.55.0", + "@typescript-eslint/types": "^8.55.0", + "debug": "^4.4.3" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.2.0.tgz", - "integrity": "sha512-OFn80B38yD6WwpoHU2Tz/fTz7CgFqInllBoC3WP+/jLbTb4gGPTy9HBSTsbDWkMdN55XlVU0mMDYAtgvlUspGw==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.55.0.tgz", + "integrity": "sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.2.0", - "@typescript-eslint/visitor-keys": "8.2.0" + "@typescript-eslint/types": "8.55.0", + "@typescript-eslint/visitor-keys": "8.55.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5149,17 +5188,35 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.55.0.tgz", + "integrity": "sha512-1R9cXqY7RQd7WuqSN47PK9EDpgFUK3VqdmbYrvWJZYDd0cavROGn+74ktWBlmJ13NXUQKlZ/iAEQHI/V0kKe0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.2.0.tgz", - "integrity": "sha512-g1CfXGFMQdT5S+0PSO0fvGXUaiSkl73U1n9LTK5aRAFnPlJ8dLKkXr4AaLFvPedW8lVDoMgLLE3JN98ZZfsj0w==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.55.0.tgz", + "integrity": "sha512-x1iH2unH4qAt6I37I2CGlsNs+B9WGxurP2uyZLRz6UJoZWDBx9cJL1xVN/FiOmHEONEg6RIufdvyT0TEYIgC5g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.2.0", - "@typescript-eslint/utils": "8.2.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" + "@typescript-eslint/types": "8.55.0", + "@typescript-eslint/typescript-estree": "8.55.0", + "@typescript-eslint/utils": "8.55.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5168,16 +5225,28 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/ts-api-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" } }, "node_modules/@typescript-eslint/types": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.2.0.tgz", - "integrity": "sha512-6a9QSK396YqmiBKPkJtxsgZZZVjYQ6wQ/TlI0C65z7vInaETuC6HAHD98AGLC8DyIPqHytvNuS8bBVvNLKyqvQ==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.55.0.tgz", + "integrity": "sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==", "dev": true, "license": "MIT", "engines": { @@ -5189,20 +5258,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.2.0.tgz", - "integrity": "sha512-kiG4EDUT4dImplOsbh47B1QnNmXSoUqOjWDvCJw/o8LgfD0yr7k2uy54D5Wm0j4t71Ge1NkynGhpWdS0dEIAUA==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.55.0.tgz", + "integrity": "sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.2.0", - "@typescript-eslint/visitor-keys": "8.2.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" + "@typescript-eslint/project-service": "8.55.0", + "@typescript-eslint/tsconfig-utils": "8.55.0", + "@typescript-eslint/types": "8.55.0", + "@typescript-eslint/visitor-keys": "8.55.0", + "debug": "^4.4.3", + "minimatch": "^9.0.5", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5211,16 +5281,14 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { @@ -5230,17 +5298,30 @@ "node": ">=10" } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/ts-api-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, "node_modules/@typescript-eslint/utils": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.2.0.tgz", - "integrity": "sha512-O46eaYKDlV3TvAVDNcoDzd5N550ckSe8G4phko++OCSC1dYIb9LTc3HDGYdWqWIAT5qDUKphO6sd9RrpIJJPfg==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.55.0.tgz", + "integrity": "sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.2.0", - "@typescript-eslint/types": "8.2.0", - "@typescript-eslint/typescript-estree": "8.2.0" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.55.0", + "@typescript-eslint/types": "8.55.0", + "@typescript-eslint/typescript-estree": "8.55.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5250,18 +5331,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.2.0.tgz", - "integrity": "sha512-sbgsPMW9yLvS7IhCi8IpuK1oBmtbWUNP+hBdwl/I9nzqVsszGnNGti5r9dUtF5RLivHUFFIdRvLiTsPhzSyJ3Q==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.55.0.tgz", + "integrity": "sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.2.0", - "eslint-visitor-keys": "^3.4.3" + "@typescript-eslint/types": "8.55.0", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5271,6 +5353,19 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -7706,12 +7801,12 @@ } }, "node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -8487,16 +8582,17 @@ } }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -15598,9 +15694,9 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/multicast-dns": { @@ -21051,12 +21147,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -22402,6 +22492,54 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "license": "MIT" }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", diff --git a/package.json b/package.json index fc2b66a549..e7232e3a6b 100644 --- a/package.json +++ b/package.json @@ -51,9 +51,9 @@ "@testing-library/react": "^16.0.0", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^8.2.0", - "@typescript-eslint/parser": "^8.2.0", - "eslint": "^8.57.0", + "@typescript-eslint/eslint-plugin": "^8.55.0", + "@typescript-eslint/parser": "^8.55.0", + "eslint": "^8.57.1", "eslint-config-prettier": "^9.1.0", "eslint-output": "^3.0.1", "eslint-plugin-prettier": "^5.2.1", diff --git a/src/App.tsx b/src/App.tsx index da605048cb..71eaeb58f8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,9 +1,9 @@ import React from "react"; import { Button } from "react-bootstrap"; import simpsons from "./images/simpsons.jpg"; -import { Container } from 'react-bootstrap'; -import { Row } from 'react-bootstrap'; -import { Col } from 'react-bootstrap'; +import { Container } from "react-bootstrap"; +import { Row } from "react-bootstrap"; +import { Col } from "react-bootstrap"; import "./App.css"; function App(): React.JSX.Element { @@ -17,7 +17,7 @@ function App(): React.JSX.Element {
Hello World Old man yells at clouds. - This is colored text. + This is colored text.

  • First thing
  • Another thing
  • @@ -36,17 +36,25 @@ function App(): React.JSX.Element { automatically reload.

    - - - First column. - - Second column. - You can put whatever you want in here, and it will be on the right side. - Maybe try adding an image? - - - -
    + + + + First column. + + + Second column. You can put whatever you want in + here, and it will be on the right side. Maybe try + adding an image? + + + +
); } diff --git a/src/functions.ts b/src/functions.ts index e614c81c0c..e18eed1b33 100644 --- a/src/functions.ts +++ b/src/functions.ts @@ -4,7 +4,7 @@ * C = (F - 32) * 5/9 */ export function fahrenheitToCelius(temperature: number): number { - return 0; + return (temperature - 32) * (5 / 9); } /** @@ -12,7 +12,16 @@ export function fahrenheitToCelius(temperature: number): number { * if the number is greater than zero. */ export function add3(first: number, second: number, third: number): number { - return 0; + if (first <= 0) { + first = 0; + } + if (second <= 0) { + second = 0; + } + if (third <= 0) { + third = 0; + } + return first + second + third; } /** @@ -20,7 +29,7 @@ export function add3(first: number, second: number, third: number): number { * mark added to the end. */ export function shout(message: string): string { - return ""; + return message.toUpperCase() + "!"; } /** @@ -28,7 +37,9 @@ export function shout(message: string): string { * mark. Do not use an `if` statement in solving this question. */ export function isQuestion(message: string): boolean { - return true; + let lastChar: string = message[message.length - 1]; + let _question: boolean = lastChar === "?" ? true : false; + return _question; } /** @@ -37,5 +48,12 @@ export function isQuestion(message: string): boolean { * upper or lower case), then return `false`. Otherwise, return `null`. */ export function convertYesNo(word: string): boolean | null { - return true; + word = word.toLowerCase(); + if (word === "yes") { + return true; + } + if (word === "no") { + return false; + } + return null; } From 97c9af2a8017fe3b8bc656dedbbd2042b128b7a5 Mon Sep 17 00:00:00 2001 From: Daniel La Mastra Date: Sun, 22 Feb 2026 19:23:38 -0500 Subject: [PATCH 37/39] Passing all tests. No loops, no mutation of the original array(s) --- src/arrays.ts | 85 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 6 deletions(-) diff --git a/src/arrays.ts b/src/arrays.ts index 4a2ffe8e5b..406f19d8c5 100644 --- a/src/arrays.ts +++ b/src/arrays.ts @@ -5,6 +5,18 @@ * the number twice. */ export function bookEndList(numbers: number[]): number[] { + if (numbers.length === 0) { + return numbers; + } + if (numbers.length === 1) { + return [numbers[0], numbers[0]]; + } else { + numbers = numbers.filter( + (_number: number): boolean => + _number === numbers[0] || + _number === numbers[numbers.length - 1], + ); + } return numbers; } @@ -13,6 +25,9 @@ export function bookEndList(numbers: number[]): number[] { * number has been tripled (multiplied by 3). */ export function tripleNumbers(numbers: number[]): number[] { + numbers = numbers.map((_number: number): number => + _number ? 3 * _number : _number, + ); return numbers; } @@ -21,7 +36,11 @@ export function tripleNumbers(numbers: number[]): number[] { * the number cannot be parsed as an integer, convert it to 0 instead. */ export function stringsToIntegers(numbers: string[]): number[] { - return []; + let _numbers = numbers.map((str: string): number => parseInt(str)); + _numbers = _numbers.map((num: number): number => + Number.isNaN(num) ? (num = 0) : num, + ); + return _numbers; } /** @@ -32,7 +51,14 @@ export function stringsToIntegers(numbers: string[]): number[] { */ // Remember, you can write functions as lambdas too! They work exactly the same. export const removeDollars = (amounts: string[]): number[] => { - return []; + let _Numbers = amounts.map((str: string): string => + str[0] === "$" ? str.replace("$", "") : str, + ); + let _numbers = _Numbers.map((str: string): number => parseInt(str)); + _numbers = _numbers.map((num: number): number => + Number.isNaN(num) ? (num = 0) : num, + ); + return _numbers; }; /** @@ -41,7 +67,13 @@ export const removeDollars = (amounts: string[]): number[] => { * in question marks ("?"). */ export const shoutIfExclaiming = (messages: string[]): string[] => { - return []; + let _messages = messages.map((str: string): string => + str[str.length - 1] === "!" ? str.toUpperCase() : str, + ); + _messages = _messages.filter( + (str: string): boolean => str[str.length - 1] !== "?", + ); + return _messages; }; /** @@ -49,7 +81,10 @@ export const shoutIfExclaiming = (messages: string[]): string[] => { * 4 letters long. */ export function countShortWords(words: string[]): number { - return 0; + let shortWords: number = 0; + words = words.filter((str: string): boolean => str.length < 4); + shortWords = words.length; + return shortWords; } /** @@ -58,6 +93,15 @@ export function countShortWords(words: string[]): number { * then return true. */ export function allRGB(colors: string[]): boolean { + if (colors.length === 0) { + return true; + } + let isRGB = colors.map((str: string): boolean => + str === "red" || str === "blue" || str === "green" ? true : false, + ); + if (isRGB.every((t) => t)) { + return true; + } return false; } @@ -69,7 +113,24 @@ export function allRGB(colors: string[]): boolean { * And the array [] would become "0=0". */ export function makeMath(addends: number[]): string { - return ""; + if (addends.length === 0) { + return "0=0"; + } + let sum: number = addends.reduce((a, b) => { + return a + b; + }, 0); + let _arr: string = addends.toString(); + let arr: string = _arr.split(",").join("+"); + /* + let arr = addends.map((num: number): string => + addends[addends.length - 1] ? `${num} +` : `${num}`, + ); + arr = arr.map((str: string): string => + str.includes(",") ? str.replaceAll(",", "") : str, + ); + */ + let stringSum: string = sum.toString(); + return stringSum + "=" + arr; } /** @@ -82,5 +143,17 @@ export function makeMath(addends: number[]): string { * And the array [1, 9, 7] would become [1, 9, 7, 17] */ export function injectPositive(values: number[]): number[] { - return []; + let firstNegative: number = values.findIndex((v) => v < 0); + if (firstNegative === -1) { + let sum: number = values.reduce((acc, v) => acc + v, 0); + return [...values, sum]; + } + let sum: number = values + .slice(0, firstNegative) + .reduce((acc, v) => acc + v, 0); + return [ + ...values.slice(0, firstNegative + 1), + sum, + ...values.slice(firstNegative + 1), + ]; } From 14b80e415766daec750a8b716cfe1c3757243b78 Mon Sep 17 00:00:00 2001 From: Daniel La Mastra Date: Mon, 2 Mar 2026 17:07:41 -0500 Subject: [PATCH 38/39] All tests are passing. --- src/objects.ts | 76 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 10 deletions(-) diff --git a/src/objects.ts b/src/objects.ts index 3fd2072e5e..f1f88abf60 100644 --- a/src/objects.ts +++ b/src/objects.ts @@ -8,9 +8,18 @@ import { Question, QuestionType } from "./interfaces/question"; export function makeBlankQuestion( id: number, name: string, - type: QuestionType + type: QuestionType, ): Question { - return {}; + return { + id, + name, + type, + body: "", + expected: "", + options: [], + points: 1, + published: false, + }; } /** @@ -21,6 +30,10 @@ export function makeBlankQuestion( * HINT: Look up the `trim` and `toLowerCase` functions. */ export function isCorrect(question: Question, answer: string): boolean { + answer = answer.toLowerCase().trim(); + if (answer === question.expected.toLowerCase().trim()) { + return true; + } return false; } @@ -31,6 +44,11 @@ export function isCorrect(question: Question, answer: string): boolean { * be exactly one of the options. */ export function isValid(question: Question, answer: string): boolean { + if (answer && question.type === "short_answer_question") { + return true; + } else if (question.options.includes(answer)) { + return true; + } return false; } @@ -41,7 +59,11 @@ export function isValid(question: Question, answer: string): boolean { * name "My First Question" would become "9: My First Q". */ export function toShortForm(question: Question): string { - return ""; + let _id: string = question.id.toString() + ": "; + let short_form: string[] = question.name.split(""); + let short_name: string[] = short_form.slice(0, 10); + let name: string = short_name.join(""); + return _id + name; } /** @@ -62,7 +84,24 @@ export function toShortForm(question: Question): string { * Check the unit tests for more examples of what this looks like! */ export function toMarkdown(question: Question): string { - return ""; + if (question.type === "short_answer_question") { + return "# " + `${question.name}` + "\n" + `${question.body}`; + } + return ( + "# " + + `${question.name}` + + "\n" + + `${question.body}` + + "\n" + + "- " + + `${question.options[0]}` + + "\n" + + "- " + + `${question.options[1]}` + + "\n" + + "- " + + `${question.options[2]}` + ); } /** @@ -70,7 +109,8 @@ export function toMarkdown(question: Question): string { * `newName`. */ export function renameQuestion(question: Question, newName: string): Question { - return question; + //question.name = newName; + return { ...question, name: newName }; //instructions imply that I should not mutate. } /** @@ -79,7 +119,7 @@ export function renameQuestion(question: Question, newName: string): Question { * published; if it was published, now it should be not published. */ export function publishQuestion(question: Question): Question { - return question; + return { ...question, published: !question.published }; } /** @@ -89,7 +129,12 @@ export function publishQuestion(question: Question): Question { * The `published` field should be reset to false. */ export function duplicateQuestion(id: number, oldQuestion: Question): Question { - return oldQuestion; + return { + ...oldQuestion, + id: id, + name: `Copy of ${oldQuestion.name}`, + published: false, + }; } /** @@ -100,7 +145,9 @@ export function duplicateQuestion(id: number, oldQuestion: Question): Question { * Check out the subsection about "Nested Fields" for more information. */ export function addOption(question: Question, newOption: string): Question { - return question; + /*let newQuestion: Question = { ...question }; + newQuestion.options.push(newOption);*/ + return { ...question, options: [...question.options, newOption] }; } /** @@ -115,7 +162,16 @@ export function mergeQuestion( id: number, name: string, contentQuestion: Question, - { points }: { points: number } + { points }: { points: number }, ): Question { - return contentQuestion; + return { + id: id, + name: name, + body: contentQuestion.body, + type: contentQuestion.type, + options: contentQuestion.options, + expected: contentQuestion.expected, + points: points, + published: false, + }; } From 4783fcf44a4d288c4330f60c2340714f4388cb51 Mon Sep 17 00:00:00 2001 From: Daniel La Mastra Date: Mon, 2 Mar 2026 17:33:47 -0500 Subject: [PATCH 39/39] Slightly changed my work for the very last problem. Changed line 172 to avoid mutating the data. I believe this is the MORE correct solution. --- src/objects.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objects.ts b/src/objects.ts index f1f88abf60..e6bb1ae83f 100644 --- a/src/objects.ts +++ b/src/objects.ts @@ -169,7 +169,7 @@ export function mergeQuestion( name: name, body: contentQuestion.body, type: contentQuestion.type, - options: contentQuestion.options, + options: [...contentQuestion.options], //avoid mutating the data. expected: contentQuestion.expected, points: points, published: false,