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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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 3660252c2f3f53f262fadb91e8d14d0eeffa6cd2 Mon Sep 17 00:00:00 2001
From: Austin Cory Bart
Date: Wed, 2 Feb 2022 13:12:40 -0500
Subject: [PATCH 33/81] 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 09d3d4f104a2cacab2641271c5c6cab55424efd1 Mon Sep 17 00:00:00 2001
From: Austin Cory Bart
Date: Sun, 6 Feb 2022 18:33:46 -0500
Subject: [PATCH 34/81] 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 9a2402444e847b2c05ce0c9a6887534a249d7c46 Mon Sep 17 00:00:00 2001
From: Austin Cory Bart
Date: Tue, 8 Feb 2022 00:36:21 -0500
Subject: [PATCH 35/81] Create answer interface
---
src/interfaces/answer.ts | 13 +++++++++++++
1 file changed, 13 insertions(+)
create mode 100644 src/interfaces/answer.ts
diff --git a/src/interfaces/answer.ts b/src/interfaces/answer.ts
new file mode 100644
index 0000000000..743ee8dff9
--- /dev/null
+++ b/src/interfaces/answer.ts
@@ -0,0 +1,13 @@
+/***
+ * A representation of a students' answer in a quizzing game
+ */
+export interface Answer {
+ /** The ID of the question being answered. */
+ questionId: number;
+ /** The text that the student entered for their answer. */
+ text: string;
+ /** Whether or not the student has submitted this answer. */
+ submitted: boolean;
+ /** Whether or not the students' answer matched the expected. */
+ correct: boolean;
+}
From 879fe177e356794eedf9f893fe0e865e49f36eb7 Mon Sep 17 00:00:00 2001
From: Austin Cory Bart
Date: Tue, 8 Feb 2022 00:36:37 -0500
Subject: [PATCH 36/81] First stab at nested tasks
---
src/nested.test.ts | 57 +++++++++++++++
src/nested.ts | 178 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 235 insertions(+)
create mode 100644 src/nested.test.ts
create mode 100644 src/nested.ts
diff --git a/src/nested.test.ts b/src/nested.test.ts
new file mode 100644
index 0000000000..1e3ff24b5c
--- /dev/null
+++ b/src/nested.test.ts
@@ -0,0 +1,57 @@
+import { Question } from "./interfaces/question";
+import { getPublishedQuestions } from "./nested";
+import testQuestionData from "./data/questions.json";
+import backupQuestionData from "./data/questions.json";
+
+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[]
+>;
+
+////////////////////////////////////////////
+// Actual tests
+
+describe("Testing the Question[] functions", () => {
+ //////////////////////////////////
+ // getPublishedQuestions
+
+ test("Testing the getPublishedQuestions function", () => {
+ expect(getPublishedQuestions(BLANK_QUESTIONS)).toEqual([]);
+ expect(getPublishedQuestions(SIMPLE_QUESTIONS)).toEqual([
+ {
+ id: 1,
+ name: "Addition",
+ body: "What is 2+2?",
+ type: "short_answer_question",
+ options: [],
+ expected: "4",
+ points: 1,
+ published: true
+ },
+ {
+ 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
+ }
+ ]);
+ });
+
+ afterEach(() => {
+ expect(BLANK_QUESTIONS).toEqual(BACKUP_BLANK_QUESTIONS);
+ expect(SIMPLE_QUESTIONS).toEqual(BACKUP_SIMPLE_QUESTIONS);
+ });
+});
diff --git a/src/nested.ts b/src/nested.ts
new file mode 100644
index 0000000000..b9fb13f3cf
--- /dev/null
+++ b/src/nested.ts
@@ -0,0 +1,178 @@
+import { Answer } from "./interfaces/answer";
+import { Question, QuestionType } from "./interfaces/question";
+
+/**
+ * Consumes an array of questions and returns a new array with only the questions
+ * that are `published`.
+ */
+export function getPublishedQuestions(questions: Question[]): Question[] {
+ return [];
+}
+
+/**
+ * Consumes an array of questions and returns a new array of only the questions that are
+ * considered "non-empty". An empty question has an empty string for its `body` and
+ * `expected`, and an empty array for its `options`.
+ */
+export function getNonEmptyQuestions(questions: Question[]): Question[] {
+ return [];
+}
+
+/***
+ * Consumes an array of questions and returns the question with the given `id`. If the
+ * question is not found, return `null` instead.
+ */
+export function findQuestion(
+ questions: Question[],
+ id: number
+): Question | null {
+ return null;
+}
+
+/**
+ * Consumes an array of questions and returns a new array that does not contain the question
+ * with the given `id`.
+ */
+export function removeQuestion(questions: Question[], id: number): Question[] {
+ return [];
+}
+
+/***
+ * Consumes an array of questions and returns a new array containing just the names of the
+ * questions, as an array.
+ */
+export function getNames(questions: Question[]): string[] {
+ return [];
+}
+
+/***
+ * Consumes an array of questions and returns the sum total of all their points added together.
+ */
+export function sumPoints(questions: Question[]): number {
+ return 0;
+}
+
+/***
+ * Consumes an array of questions and returns the sum total of the PUBLISHED questions.
+ */
+export function sumPublishedPoints(questions: Question[]): number {
+ return 0;
+}
+
+/***
+ * Consumes an array of questions, and produces a Comma-Separated Value (CSV) string representation.
+ * A CSV is a type of file frequently used to share tabular data; we will use a single string
+ * to represent the entire file. The first line of the file is the headers "id", "name", "options",
+ * "points", and "published". The following line contains the value for each question, separated by
+ * commas. For the `options` field, use the NUMBER of options.
+ *
+ * Here is an example of what this will look like (do not include the border).
+ *`
+id,name,options,points,published
+1,Addition,0,1,true
+2,Letters,0,1,false
+5,Colors,3,1,true
+9,Shapes,3,2,false
+` *
+ * Check the unit tests for more examples!
+ */
+export function toCSV(questions: Question[]): string {
+ return "";
+}
+
+/**
+ * Consumes an array of Questions and produces a corresponding array of
+ * Answers. Each Question gets its own Answer, copying over the `id` as the `questionId`,
+ * making the `text` an empty string, and using false for both `submitted` and `correct`.
+ */
+export function makeAnswers(questions: Question[]): Answer[] {
+ return [];
+}
+
+/***
+ * Consumes an array of Questions and produces a new array of questions, where
+ * each question is now published, regardless of its previous published status.
+ */
+export function publishAll(questions: Question[]): Question[] {
+ return [];
+}
+
+/***
+ * Consumes an array of Questions and produces whether or not all the questions
+ * are the same type. They can be any type, as long as they are all the SAME type.
+ */
+export function sameType(questions: Question[]): boolean {
+ return false;
+}
+
+/***
+ * Consumes an array of Questions and produces a new array of the same Questions,
+ * except that a blank question has been added onto the end. Reuse the `makeBlankQuestion`
+ * you defined in the `objects.ts` file.
+ */
+export function addNewQuestion(
+ questions: Question[],
+ id: number,
+ name: string,
+ type: QuestionType
+): Question[] {
+ return [];
+}
+
+/***
+ * Consumes an array of Questions and produces a new array of Questions, where all
+ * the Questions are the same EXCEPT for the one with the given `targetId`. That
+ * Question should be the same EXCEPT that its name should now be `newName`.
+ */
+export function renameQuestionById(
+ questions: Question[],
+ targetId: number,
+ newName: string
+): Question[] {
+ return [];
+}
+
+/***
+ * Consumes an array of Questions and produces a new array of Questions, where all
+ * the Questions are the same EXCEPT for the one with the given `targetId`. That
+ * Question should be the same EXCEPT that its `type` should now be the `newQuestionType`
+ * AND if the `newQuestionType` is no longer "multiple_choice_question" than the `options`
+ * must be set to an empty list.
+ */
+export function changeQuestionTypeById(
+ questions: Question[],
+ targetId: number,
+ newQuestionType: QuestionType
+): Question[] {
+ return [];
+}
+
+/**
+ * Consumes an array of Questions and produces a new array of Questions, where all
+ * the Questions are the same EXCEPT for the one with the given `targetId`. That
+ * Question should be the same EXCEPT that its `option` array should have a new element.
+ * If the `targetOptionIndex` is -1, the `newOption` should be added to the end of the list.
+ * Otherwise, it should *replace* the existing element at the `targetOptionIndex`.
+ */
+export function editOption(
+ questions: Question[],
+ targetId: number,
+ targetOptionIndex: number,
+ newOption: string
+) {
+ return [];
+}
+
+/***
+ * Consumes an array of questions, and produces a new array based on the original array.
+ * The only difference is that the question with id `targetId` should now be duplicated, with
+ * the duplicate inserted directly after the original question. Use the `duplicateQuestion`
+ * function you defined previously; the `newId` is the parameter to use for the duplicate's ID.
+ */
+export function duplicateQuestionInArray(
+ questions: Question[],
+ targetId: number,
+ newId: number
+): Question[] {
+ return [];
+}
From 4d29d2132a060f7f91420d71eea4e80ab72e7727 Mon Sep 17 00:00:00 2001
From: Austin Cory Bart
Date: Wed, 9 Feb 2022 13:20:35 -0500
Subject: [PATCH 37/81] Document Question interface
---
src/interfaces/question.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/interfaces/question.ts b/src/interfaces/question.ts
index a39431565e..5def48f2f7 100644
--- a/src/interfaces/question.ts
+++ b/src/interfaces/question.ts
@@ -1,6 +1,7 @@
/** QuestionType influences how a question is asked and what kinds of answers are possible */
export type QuestionType = "multiple_choice_question" | "short_answer_question";
+/** A representation of a Question in a quizzing application */
export interface Question {
/** A unique identifier for the question */
id: number;
From d71d9fcc94831dc1aea8d2aa847feeadeed6b9c4 Mon Sep 17 00:00:00 2001
From: Austin Cory Bart
Date: Wed, 9 Feb 2022 13:20:46 -0500
Subject: [PATCH 38/81] Expand questions test data
---
src/data/questions.json | 147 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 144 insertions(+), 3 deletions(-)
diff --git a/src/data/questions.json b/src/data/questions.json
index 3b19537526..0411f30afe 100644
--- a/src/data/questions.json
+++ b/src/data/questions.json
@@ -73,7 +73,148 @@
"published": false
}
],
- "SIMPLE_QUESTIONS_2": [],
- "EMPTY_QUESTIONS": [],
- "TRIVIA_QUESTIONS": []
+ "TRIVIA_QUESTIONS": [
+ {
+ "id": 1,
+ "name": "Mascot",
+ "body": "What is the name of the UD Mascot?",
+ "type": "multiple_choice_question",
+ "options": ["Bluey", "YoUDee", "Charles the Wonder Dog"],
+ "expected": "YoUDee",
+ "points": 7,
+ "published": false
+ },
+ {
+ "id": 2,
+ "name": "Motto",
+ "body": "What is the University of Delaware's motto?",
+ "type": "multiple_choice_question",
+ "options": [
+ "Knowledge is the light of the mind",
+ "Just U Do it",
+ "Nothing, what's the motto with you?"
+ ],
+ "expected": "Knowledge is the light of the mind",
+ "points": 3,
+ "published": false
+ },
+ {
+ "id": 3,
+ "name": "Goats",
+ "body": "How many goats are there usually on the Green?",
+ "type": "multiple_choice_question",
+ "options": [
+ "Zero, why would there be goats on the green?",
+ "18420",
+ "Two"
+ ],
+ "expected": "Two",
+ "points": 10,
+ "published": false
+ }
+ ],
+ "EMPTY_QUESTIONS": [
+ {
+ "id": 1,
+ "name": "Empty 1",
+ "body": "This question is not empty, right?",
+ "type": "multiple_choice_question",
+ "options": ["correct", "it is", "not"],
+ "expected": "correct",
+ "points": 5,
+ "published": true
+ },
+ {
+ "id": 2,
+ "name": "Empty 2",
+ "body": "",
+ "type": "multiple_choice_question",
+ "options": ["this", "one", "is", "not", "empty", "either"],
+ "expected": "one",
+ "points": 5,
+ "published": true
+ },
+ {
+ "id": 3,
+ "name": "Empty 3",
+ "body": "This questions is not empty either!",
+ "type": "short_answer_question",
+ "options": [],
+ "expected": "",
+ "points": 5,
+ "published": true
+ },
+ {
+ "id": 4,
+ "name": "Empty 4",
+ "body": "",
+ "type": "short_answer_question",
+ "options": [],
+ "expected": "Even this one is not empty",
+ "points": 5,
+ "published": true
+ },
+ {
+ "id": 5,
+ "name": "Empty 5 (Actual)",
+ "body": "",
+ "type": "short_answer_question",
+ "options": [],
+ "expected": "",
+ "points": 5,
+ "published": false
+ }
+ ],
+ "SIMPLE_QUESTIONS_2": [
+ {
+ "id": 478,
+ "name": "Students",
+ "body": "How many students are taking CISC275 this semester?",
+ "type": "short_answer_question",
+ "options": [],
+ "expected": "90",
+ "points": 53,
+ "published": true
+ },
+ {
+ "id": 1937,
+ "name": "Importance",
+ "body": "On a scale of 1 to 10, how important is this quiz for them?",
+ "type": "short_answer_question",
+ "options": [],
+ "expected": "10",
+ "points": 47,
+ "published": true
+ },
+ {
+ "id": 479,
+ "name": "Sentience",
+ "body": "Is it technically possible for this quiz to become sentient?",
+ "type": "short_answer_question",
+ "options": [],
+ "expected": "Yes",
+ "points": 40,
+ "published": true
+ },
+ {
+ "id": 777,
+ "name": "Danger",
+ "body": "If this quiz became sentient, would it pose a danger to others?",
+ "type": "short_answer_question",
+ "options": [],
+ "expected": "Yes",
+ "points": 60,
+ "published": true
+ },
+ {
+ "id": 1937,
+ "name": "Listening",
+ "body": "Is this quiz listening to us right now?",
+ "type": "short_answer_question",
+ "options": [],
+ "expected": "Yes",
+ "points": 100,
+ "published": true
+ }
+ ]
}
From c955718b2a52fe88f0f3b27b00b8fcb74e8be0ca Mon Sep 17 00:00:00 2001
From: Austin Cory Bart
Date: Wed, 9 Feb 2022 13:21:43 -0500
Subject: [PATCH 39/81] Add a little hint for a tough one
---
src/nested.ts | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/nested.ts b/src/nested.ts
index b9fb13f3cf..7934ec1741 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -153,6 +153,9 @@ export function changeQuestionTypeById(
* Question should be the same EXCEPT that its `option` array should have a new element.
* If the `targetOptionIndex` is -1, the `newOption` should be added to the end of the list.
* Otherwise, it should *replace* the existing element at the `targetOptionIndex`.
+ *
+ * Remember, if a function starts getting too complicated, think about how a helper function
+ * can make it simpler! Break down complicated tasks into little pieces.
*/
export function editOption(
questions: Question[],
From c574699cc746d22d95223bfc85d2e0cb8d5843e8 Mon Sep 17 00:00:00 2001
From: Austin Cory Bart
Date: Wed, 9 Feb 2022 13:22:01 -0500
Subject: [PATCH 40/81] Nested tests (phew)
---
src/nested.test.ts | 1187 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 1184 insertions(+), 3 deletions(-)
diff --git a/src/nested.test.ts b/src/nested.test.ts
index 1e3ff24b5c..3d2b75406d 100644
--- a/src/nested.test.ts
+++ b/src/nested.test.ts
@@ -1,9 +1,32 @@
import { Question } from "./interfaces/question";
-import { getPublishedQuestions } from "./nested";
+import {
+ getPublishedQuestions,
+ getNonEmptyQuestions,
+ findQuestion,
+ removeQuestion,
+ getNames,
+ sumPoints,
+ sumPublishedPoints,
+ toCSV,
+ makeAnswers,
+ publishAll,
+ sameType,
+ addNewQuestion,
+ renameQuestionById,
+ changeQuestionTypeById,
+ editOption,
+ duplicateQuestionInArray
+} from "./nested";
import testQuestionData from "./data/questions.json";
import backupQuestionData from "./data/questions.json";
-const { BLANK_QUESTIONS, SIMPLE_QUESTIONS }: Record =
+const {
+ BLANK_QUESTIONS,
+ SIMPLE_QUESTIONS,
+ TRIVIA_QUESTIONS,
+ EMPTY_QUESTIONS,
+ SIMPLE_QUESTIONS_2
+}: Record =
// Typecast the test data that we imported to be a record matching
// strings to the question list
testQuestionData as Record;
@@ -11,12 +34,41 @@ 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,
+ TRIVIA_QUESTIONS: BACKUP_TRIVIA_QUESTIONS,
+ EMPTY_QUESTIONS: BACKUP_EMPTY_QUESTIONS,
+ SIMPLE_QUESTIONS_2: BACKUP_SIMPLE_QUESTIONS_2
}: Record = backupQuestionData as Record<
string,
Question[]
>;
+const NEW_BLANK_QUESTION = {
+ id: 142,
+ name: "A new question",
+ body: "",
+ type: "short_answer_question",
+ options: [],
+ expected: "",
+ points: 1,
+ published: false
+};
+
+const NEW_TRIVIA_QUESTION = {
+ id: 449,
+ name: "Colors",
+ body: "",
+ type: "multiple_choice_question",
+ options: [],
+ expected: "",
+ /*body: "The official colors of UD are Blue and ...?",
+ type: "multiple_choice_question",
+ options: ["Black, like my soul", "Blue again, we're tricky.", "#FFD200"],
+ expected: "#FFD200",*/
+ points: 1,
+ published: false
+};
+
////////////////////////////////////////////
// Actual tests
@@ -48,10 +100,1139 @@ describe("Testing the Question[] functions", () => {
published: true
}
]);
+ expect(getPublishedQuestions(TRIVIA_QUESTIONS)).toEqual([]);
+ expect(getPublishedQuestions(SIMPLE_QUESTIONS_2)).toEqual(
+ BACKUP_SIMPLE_QUESTIONS_2
+ );
+ expect(getPublishedQuestions(EMPTY_QUESTIONS)).toEqual([
+ {
+ id: 1,
+ name: "Empty 1",
+ body: "This question is not empty, right?",
+ type: "multiple_choice_question",
+ options: ["correct", "it is", "not"],
+ expected: "correct",
+ points: 5,
+ published: true
+ },
+ {
+ id: 2,
+ name: "Empty 2",
+ body: "",
+ type: "multiple_choice_question",
+ options: ["this", "one", "is", "not", "empty", "either"],
+ expected: "one",
+ points: 5,
+ published: true
+ },
+ {
+ id: 3,
+ name: "Empty 3",
+ body: "This questions is not empty either!",
+ type: "short_answer_question",
+ options: [],
+ expected: "",
+ points: 5,
+ published: true
+ },
+ {
+ id: 4,
+ name: "Empty 4",
+ body: "",
+ type: "short_answer_question",
+ options: [],
+ expected: "Even this one is not empty",
+ points: 5,
+ published: true
+ }
+ ]);
+ });
+
+ test("Testing the getNonEmptyQuestions functions", () => {
+ expect(getNonEmptyQuestions(BLANK_QUESTIONS)).toEqual([]);
+ expect(getNonEmptyQuestions(SIMPLE_QUESTIONS)).toEqual(
+ BACKUP_SIMPLE_QUESTIONS
+ );
+ expect(getNonEmptyQuestions(TRIVIA_QUESTIONS)).toEqual(
+ BACKUP_TRIVIA_QUESTIONS
+ );
+ expect(getNonEmptyQuestions(SIMPLE_QUESTIONS_2)).toEqual(
+ BACKUP_SIMPLE_QUESTIONS_2
+ );
+ expect(getNonEmptyQuestions(EMPTY_QUESTIONS)).toEqual([
+ {
+ id: 1,
+ name: "Empty 1",
+ body: "This question is not empty, right?",
+ type: "multiple_choice_question",
+ options: ["correct", "it is", "not"],
+ expected: "correct",
+ points: 5,
+ published: true
+ },
+ {
+ id: 2,
+ name: "Empty 2",
+ body: "",
+ type: "multiple_choice_question",
+ options: ["this", "one", "is", "not", "empty", "either"],
+ expected: "one",
+ points: 5,
+ published: true
+ },
+ {
+ id: 3,
+ name: "Empty 3",
+ body: "This questions is not empty either!",
+ type: "short_answer_question",
+ options: [],
+ expected: "",
+ points: 5,
+ published: true
+ },
+ {
+ id: 4,
+ name: "Empty 4",
+ body: "",
+ type: "short_answer_question",
+ options: [],
+ expected: "Even this one is not empty",
+ points: 5,
+ published: true
+ }
+ ]);
+ });
+
+ test("Testing the findQuestion function", () => {
+ expect(findQuestion(BLANK_QUESTIONS, 1)).toEqual(BLANK_QUESTIONS[0]);
+ expect(findQuestion(BLANK_QUESTIONS, 47)).toEqual(BLANK_QUESTIONS[1]);
+ expect(findQuestion(BLANK_QUESTIONS, 2)).toEqual(BLANK_QUESTIONS[2]);
+ expect(findQuestion(BLANK_QUESTIONS, 3)).toEqual(null);
+ expect(findQuestion(SIMPLE_QUESTIONS, 1)).toEqual(SIMPLE_QUESTIONS[0]);
+ expect(findQuestion(SIMPLE_QUESTIONS, 2)).toEqual(SIMPLE_QUESTIONS[1]);
+ expect(findQuestion(SIMPLE_QUESTIONS, 5)).toEqual(SIMPLE_QUESTIONS[2]);
+ expect(findQuestion(SIMPLE_QUESTIONS, 9)).toEqual(SIMPLE_QUESTIONS[3]);
+ expect(findQuestion(SIMPLE_QUESTIONS, 6)).toEqual(null);
+ expect(findQuestion(SIMPLE_QUESTIONS_2, 478)).toEqual(
+ SIMPLE_QUESTIONS_2[0]
+ );
+ expect(findQuestion([], 0)).toEqual(null);
+ });
+
+ test("Testing the removeQuestion", () => {
+ expect(removeQuestion(BLANK_QUESTIONS, 1)).toEqual([
+ {
+ 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
+ }
+ ]);
+ expect(removeQuestion(BLANK_QUESTIONS, 47)).toEqual([
+ {
+ id: 1,
+ name: "Question 1",
+ 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
+ }
+ ]);
+ expect(removeQuestion(BLANK_QUESTIONS, 2)).toEqual([
+ {
+ 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
+ }
+ ]);
+ expect(removeQuestion(SIMPLE_QUESTIONS, 9)).toEqual([
+ {
+ 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
+ }
+ ]);
+ expect(removeQuestion(SIMPLE_QUESTIONS, 5)).toEqual([
+ {
+ 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: 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
+ }
+ ]);
+ });
+
+ test("Testing the getNames function", () => {
+ expect(getNames(BLANK_QUESTIONS)).toEqual([
+ "Question 1",
+ "My New Question",
+ "Question 2"
+ ]);
+ expect(getNames(SIMPLE_QUESTIONS)).toEqual([
+ "Addition",
+ "Letters",
+ "Colors",
+ "Shapes"
+ ]);
+ expect(getNames(TRIVIA_QUESTIONS)).toEqual([
+ "Mascot",
+ "Motto",
+ "Goats"
+ ]);
+ expect(getNames(SIMPLE_QUESTIONS_2)).toEqual([
+ "Students",
+ "Importance",
+ "Sentience",
+ "Danger",
+ "Listening"
+ ]);
+ expect(getNames(EMPTY_QUESTIONS)).toEqual([
+ "Empty 1",
+ "Empty 2",
+ "Empty 3",
+ "Empty 4",
+ "Empty 5 (Actual)"
+ ]);
+ });
+
+ test("Testing the sumPoints function", () => {
+ expect(sumPoints(BLANK_QUESTIONS)).toEqual(3);
+ expect(sumPoints(SIMPLE_QUESTIONS)).toEqual(5);
+ expect(sumPoints(TRIVIA_QUESTIONS)).toEqual(20);
+ expect(sumPoints(EMPTY_QUESTIONS)).toEqual(25);
+ expect(sumPoints(SIMPLE_QUESTIONS_2)).toEqual(300);
+ });
+
+ test("Testing the sumPublishedPoints function", () => {
+ expect(sumPublishedPoints(BLANK_QUESTIONS)).toEqual(0);
+ expect(sumPublishedPoints(SIMPLE_QUESTIONS)).toEqual(2);
+ expect(sumPublishedPoints(TRIVIA_QUESTIONS)).toEqual(0);
+ expect(sumPublishedPoints(EMPTY_QUESTIONS)).toEqual(20);
+ expect(sumPublishedPoints(SIMPLE_QUESTIONS_2)).toEqual(300);
+ });
+
+ test("Testing the toCSV function", () => {
+ expect(toCSV(BLANK_QUESTIONS)).toEqual(`id,name,options,points,published
+1,Question 1,0,1,false
+47,My New Question,0,1,false
+2,Question 2,0,1,false`);
+ expect(toCSV(SIMPLE_QUESTIONS))
+ .toEqual(`id,name,options,points,published
+1,Addition,0,1,true
+2,Letters,0,1,false
+5,Colors,3,1,true
+9,Shapes,3,2,false`);
+ expect(toCSV(TRIVIA_QUESTIONS))
+ .toEqual(`id,name,options,points,published
+1,Mascot,3,7,false
+2,Motto,3,3,false
+3,Goats,3,10,false`);
+ expect(toCSV(EMPTY_QUESTIONS)).toEqual(`id,name,options,points,published
+1,Empty 1,3,5,true
+2,Empty 2,6,5,true
+3,Empty 3,0,5,true
+4,Empty 4,0,5,true
+5,Empty 5 (Actual),0,5,false`);
+ expect(toCSV(SIMPLE_QUESTIONS_2))
+ .toEqual(`id,name,options,points,published
+478,Students,0,53,true
+1937,Importance,0,47,true
+479,Sentience,0,40,true
+777,Danger,0,60,true
+1937,Listening,0,100,true`);
+ });
+
+ test("Testing the makeAnswers function", () => {
+ expect(makeAnswers(BLANK_QUESTIONS)).toEqual([
+ { questionId: 1, correct: false, text: "", submitted: false },
+ { questionId: 47, correct: false, text: "", submitted: false },
+ { questionId: 2, correct: false, text: "", submitted: false }
+ ]);
+ expect(makeAnswers(SIMPLE_QUESTIONS)).toEqual([
+ { questionId: 1, correct: false, text: "", submitted: false },
+ { questionId: 2, correct: false, text: "", submitted: false },
+ { questionId: 5, correct: false, text: "", submitted: false },
+ { questionId: 9, correct: false, text: "", submitted: false }
+ ]);
+ expect(makeAnswers(TRIVIA_QUESTIONS)).toEqual([
+ { questionId: 1, correct: false, text: "", submitted: false },
+ { questionId: 2, correct: false, text: "", submitted: false },
+ { questionId: 3, correct: false, text: "", submitted: false }
+ ]);
+ expect(makeAnswers(SIMPLE_QUESTIONS_2)).toEqual([
+ { questionId: 478, correct: false, text: "", submitted: false },
+ { questionId: 1937, correct: false, text: "", submitted: false },
+ { questionId: 479, correct: false, text: "", submitted: false },
+ { questionId: 777, correct: false, text: "", submitted: false },
+ { questionId: 1937, correct: false, text: "", submitted: false }
+ ]);
+ expect(makeAnswers(EMPTY_QUESTIONS)).toEqual([
+ { questionId: 1, correct: false, text: "", submitted: false },
+ { questionId: 2, correct: false, text: "", submitted: false },
+ { questionId: 3, correct: false, text: "", submitted: false },
+ { questionId: 4, correct: false, text: "", submitted: false },
+ { questionId: 5, correct: false, text: "", submitted: false }
+ ]);
+ });
+
+ test("Testing the publishAll function", () => {
+ expect(publishAll(BLANK_QUESTIONS)).toEqual([
+ {
+ id: 1,
+ name: "Question 1",
+ body: "",
+ type: "multiple_choice_question",
+ options: [],
+ expected: "",
+ points: 1,
+ published: true
+ },
+ {
+ id: 47,
+ name: "My New Question",
+ body: "",
+ type: "multiple_choice_question",
+ options: [],
+ expected: "",
+ points: 1,
+ published: true
+ },
+ {
+ id: 2,
+ name: "Question 2",
+ body: "",
+ type: "short_answer_question",
+ options: [],
+ expected: "",
+ points: 1,
+ published: true
+ }
+ ]);
+ expect(publishAll(SIMPLE_QUESTIONS)).toEqual([
+ {
+ 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: true
+ },
+ {
+ 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: true
+ }
+ ]);
+ expect(publishAll(TRIVIA_QUESTIONS)).toEqual([
+ {
+ id: 1,
+ name: "Mascot",
+ body: "What is the name of the UD Mascot?",
+ type: "multiple_choice_question",
+ options: ["Bluey", "YoUDee", "Charles the Wonder Dog"],
+ expected: "YoUDee",
+ points: 7,
+ published: true
+ },
+ {
+ id: 2,
+ name: "Motto",
+ body: "What is the University of Delaware's motto?",
+ type: "multiple_choice_question",
+ options: [
+ "Knowledge is the light of the mind",
+ "Just U Do it",
+ "Nothing, what's the motto with you?"
+ ],
+ expected: "Knowledge is the light of the mind",
+ points: 3,
+ published: true
+ },
+ {
+ id: 3,
+ name: "Goats",
+ body: "How many goats are there usually on the Green?",
+ type: "multiple_choice_question",
+ options: [
+ "Zero, why would there be goats on the green?",
+ "18420",
+ "Two"
+ ],
+ expected: "Two",
+ points: 10,
+ published: true
+ }
+ ]);
+ expect(publishAll(EMPTY_QUESTIONS)).toEqual([
+ {
+ id: 1,
+ name: "Empty 1",
+ body: "This question is not empty, right?",
+ type: "multiple_choice_question",
+ options: ["correct", "it is", "not"],
+ expected: "correct",
+ points: 5,
+ published: true
+ },
+ {
+ id: 2,
+ name: "Empty 2",
+ body: "",
+ type: "multiple_choice_question",
+ options: ["this", "one", "is", "not", "empty", "either"],
+ expected: "one",
+ points: 5,
+ published: true
+ },
+ {
+ id: 3,
+ name: "Empty 3",
+ body: "This questions is not empty either!",
+ type: "short_answer_question",
+ options: [],
+ expected: "",
+ points: 5,
+ published: true
+ },
+ {
+ id: 4,
+ name: "Empty 4",
+ body: "",
+ type: "short_answer_question",
+ options: [],
+ expected: "Even this one is not empty",
+ points: 5,
+ published: true
+ },
+ {
+ id: 5,
+ name: "Empty 5 (Actual)",
+ body: "",
+ type: "short_answer_question",
+ options: [],
+ expected: "",
+ points: 5,
+ published: true
+ }
+ ]);
+ expect(publishAll(SIMPLE_QUESTIONS_2)).toEqual(SIMPLE_QUESTIONS_2);
+ });
+
+ test("Testing the sameType function", () => {
+ expect(sameType([])).toEqual(true);
+ expect(sameType(BLANK_QUESTIONS)).toEqual(false);
+ expect(sameType(SIMPLE_QUESTIONS)).toEqual(false);
+ expect(sameType(TRIVIA_QUESTIONS)).toEqual(true);
+ expect(sameType(EMPTY_QUESTIONS)).toEqual(false);
+ expect(sameType(SIMPLE_QUESTIONS_2)).toEqual(true);
+ });
+
+ test("Testing the addNewQuestion function", () => {
+ expect(
+ addNewQuestion([], 142, "A new question", "short_answer_question")
+ ).toEqual([NEW_BLANK_QUESTION]);
+ expect(
+ addNewQuestion(
+ BLANK_QUESTIONS,
+ 142,
+ "A new question",
+ "short_answer_question"
+ )
+ ).toEqual([...BLANK_QUESTIONS, NEW_BLANK_QUESTION]);
+ expect(
+ addNewQuestion(
+ TRIVIA_QUESTIONS,
+ 449,
+ "Colors",
+ "multiple_choice_question"
+ )
+ ).toEqual([...TRIVIA_QUESTIONS, NEW_TRIVIA_QUESTION]);
+ });
+
+ test("Testing the renameQuestionById function", () => {
+ expect(renameQuestionById(BLANK_QUESTIONS, 1, "New Name")).toEqual([
+ {
+ id: 1,
+ name: "New Name",
+ 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
+ }
+ ]);
+ expect(renameQuestionById(BLANK_QUESTIONS, 47, "Another Name")).toEqual(
+ [
+ {
+ id: 1,
+ name: "Question 1",
+ body: "",
+ type: "multiple_choice_question",
+ options: [],
+ expected: "",
+ points: 1,
+ published: false
+ },
+ {
+ id: 47,
+ name: "Another Name",
+ 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
+ }
+ ]
+ );
+ expect(renameQuestionById(SIMPLE_QUESTIONS, 5, "Colours")).toEqual([
+ {
+ 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: "Colours",
+ 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
+ }
+ ]);
+ });
+
+ test("Test the changeQuestionTypeById function", () => {
+ expect(
+ changeQuestionTypeById(
+ BLANK_QUESTIONS,
+ 1,
+ "multiple_choice_question"
+ )
+ ).toEqual(BLANK_QUESTIONS);
+ expect(
+ changeQuestionTypeById(BLANK_QUESTIONS, 1, "short_answer_question")
+ ).toEqual([
+ {
+ id: 1,
+ name: "Question 1",
+ body: "",
+ type: "short_answer_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
+ }
+ ]);
+ expect(
+ changeQuestionTypeById(BLANK_QUESTIONS, 47, "short_answer_question")
+ ).toEqual([
+ {
+ id: 1,
+ name: "Question 1",
+ body: "",
+ type: "multiple_choice_question",
+ options: [],
+ expected: "",
+ points: 1,
+ published: false
+ },
+ {
+ id: 47,
+ name: "My New Question",
+ body: "",
+ type: "short_answer_question",
+ options: [],
+ expected: "",
+ points: 1,
+ published: false
+ },
+ {
+ id: 2,
+ name: "Question 2",
+ body: "",
+ type: "short_answer_question",
+ options: [],
+ expected: "",
+ points: 1,
+ published: false
+ }
+ ]);
+ expect(
+ changeQuestionTypeById(TRIVIA_QUESTIONS, 3, "short_answer_question")
+ ).toEqual([
+ {
+ id: 1,
+ name: "Mascot",
+ body: "What is the name of the UD Mascot?",
+ type: "multiple_choice_question",
+ options: ["Bluey", "YoUDee", "Charles the Wonder Dog"],
+ expected: "YoUDee",
+ points: 7,
+ published: false
+ },
+ {
+ id: 2,
+ name: "Motto",
+ body: "What is the University of Delaware's motto?",
+ type: "multiple_choice_question",
+ options: [
+ "Knowledge is the light of the mind",
+ "Just U Do it",
+ "Nothing, what's the motto with you?"
+ ],
+ expected: "Knowledge is the light of the mind",
+ points: 3,
+ published: false
+ },
+ {
+ id: 3,
+ name: "Goats",
+ body: "How many goats are there usually on the Green?",
+ type: "short_answer_question",
+ options: [],
+ expected: "Two",
+ points: 10,
+ published: false
+ }
+ ]);
+ });
+
+ test("Testing the addEditQuestionOption function", () => {
+ expect(editOption(BLANK_QUESTIONS, 1, -1, "NEW OPTION")).toEqual([
+ {
+ id: 1,
+ name: "Question 1",
+ body: "",
+ type: "multiple_choice_question",
+ options: ["NEW OPTION"],
+ 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
+ }
+ ]);
+ expect(editOption(BLANK_QUESTIONS, 47, -1, "Another option")).toEqual([
+ {
+ 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: ["Another option"],
+ expected: "",
+ points: 1,
+ published: false
+ },
+ {
+ id: 2,
+ name: "Question 2",
+ body: "",
+ type: "short_answer_question",
+ options: [],
+ expected: "",
+ points: 1,
+ published: false
+ }
+ ]);
+ expect(editOption(SIMPLE_QUESTIONS, 5, -1, "newspaper")).toEqual([
+ {
+ 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", "newspaper"],
+ 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
+ }
+ ]);
+ expect(editOption(SIMPLE_QUESTIONS, 5, 0, "newspaper")).toEqual([
+ {
+ 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: ["newspaper", "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
+ }
+ ]);
+
+ expect(editOption(SIMPLE_QUESTIONS, 5, 2, "newspaper")).toEqual([
+ {
+ 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", "newspaper"],
+ 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
+ }
+ ]);
+ });
+
+ test("Testing the duplicateQuestionInArray function", () => {
+ expect(duplicateQuestionInArray(BLANK_QUESTIONS, 1, 27)).toEqual([
+ {
+ id: 1,
+ name: "Question 1",
+ body: "",
+ type: "multiple_choice_question",
+ options: [],
+ expected: "",
+ points: 1,
+ published: false
+ },
+ {
+ id: 27,
+ name: "Copy of 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
+ }
+ ]);
+ expect(duplicateQuestionInArray(BLANK_QUESTIONS, 47, 19)).toEqual([
+ {
+ 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: 19,
+ name: "Copy of 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
+ }
+ ]);
+ expect(duplicateQuestionInArray(TRIVIA_QUESTIONS, 3, 111)).toEqual([
+ {
+ id: 1,
+ name: "Mascot",
+ body: "What is the name of the UD Mascot?",
+ type: "multiple_choice_question",
+ options: ["Bluey", "YoUDee", "Charles the Wonder Dog"],
+ expected: "YoUDee",
+ points: 7,
+ published: false
+ },
+ {
+ id: 2,
+ name: "Motto",
+ body: "What is the University of Delaware's motto?",
+ type: "multiple_choice_question",
+ options: [
+ "Knowledge is the light of the mind",
+ "Just U Do it",
+ "Nothing, what's the motto with you?"
+ ],
+ expected: "Knowledge is the light of the mind",
+ points: 3,
+ published: false
+ },
+ {
+ id: 3,
+ name: "Goats",
+ body: "How many goats are there usually on the Green?",
+ type: "multiple_choice_question",
+ options: [
+ "Zero, why would there be goats on the green?",
+ "18420",
+ "Two"
+ ],
+ expected: "Two",
+ points: 10,
+ published: false
+ },
+ {
+ id: 111,
+ name: "Copy of Goats",
+ body: "How many goats are there usually on the Green?",
+ type: "multiple_choice_question",
+ options: [
+ "Zero, why would there be goats on the green?",
+ "18420",
+ "Two"
+ ],
+ expected: "Two",
+ points: 10,
+ published: false
+ }
+ ]);
});
afterEach(() => {
expect(BLANK_QUESTIONS).toEqual(BACKUP_BLANK_QUESTIONS);
expect(SIMPLE_QUESTIONS).toEqual(BACKUP_SIMPLE_QUESTIONS);
+ expect(TRIVIA_QUESTIONS).toEqual(BACKUP_TRIVIA_QUESTIONS);
+ expect(SIMPLE_QUESTIONS_2).toEqual(BACKUP_SIMPLE_QUESTIONS_2);
+ expect(EMPTY_QUESTIONS).toEqual(BACKUP_EMPTY_QUESTIONS);
});
});
From a368ad06a9847e4cb04fc2d544ff49997db54e90 Mon Sep 17 00:00:00 2001
From: Austin Cory Bart
Date: Sat, 19 Feb 2022 13:52:24 -0500
Subject: [PATCH 41/81] Forgot the task record!
---
public/tasks/task-nested.md | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 public/tasks/task-nested.md
diff --git a/public/tasks/task-nested.md b/public/tasks/task-nested.md
new file mode 100644
index 0000000000..6d29f9369f
--- /dev/null
+++ b/public/tasks/task-nested.md
@@ -0,0 +1,5 @@
+# Task - Nested
+
+Version: 0.0.1
+
+Implement functions that work with nested arrays and objects immutably.
From 304184e9c70c1ed35eff2a7e522c3e71d9204d17 Mon Sep 17 00:00:00 2001
From: Austin Cory Bart
Date: Tue, 1 Mar 2022 16:38:02 -0500
Subject: [PATCH 42/81] Fix typo in editOption test, and missing return type
for editOption
---
src/nested.test.ts | 2 +-
src/nested.ts | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/nested.test.ts b/src/nested.test.ts
index 3d2b75406d..572a7a028d 100644
--- a/src/nested.test.ts
+++ b/src/nested.test.ts
@@ -893,7 +893,7 @@ describe("Testing the Question[] functions", () => {
]);
});
- test("Testing the addEditQuestionOption function", () => {
+ test("Testing the editOption function", () => {
expect(editOption(BLANK_QUESTIONS, 1, -1, "NEW OPTION")).toEqual([
{
id: 1,
diff --git a/src/nested.ts b/src/nested.ts
index 7934ec1741..562b6ca0df 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -162,7 +162,7 @@ export function editOption(
targetId: number,
targetOptionIndex: number,
newOption: string
-) {
+): Question[] {
return [];
}
From 1b76b8050daddd7c26e8cb372b2ad710974a66be Mon Sep 17 00:00:00 2001
From: Austin Cory Bart
Date: Sat, 24 Aug 2024 13:33:40 -0400
Subject: [PATCH 43/81] Fix formatting
---
src/nested.test.ts | 338 +++++++++++++++++++++++----------------------
1 file changed, 173 insertions(+), 165 deletions(-)
diff --git a/src/nested.test.ts b/src/nested.test.ts
index 572a7a028d..7f52bfdf94 100644
--- a/src/nested.test.ts
+++ b/src/nested.test.ts
@@ -15,7 +15,7 @@ import {
renameQuestionById,
changeQuestionTypeById,
editOption,
- duplicateQuestionInArray
+ duplicateQuestionInArray,
} from "./nested";
import testQuestionData from "./data/questions.json";
import backupQuestionData from "./data/questions.json";
@@ -25,7 +25,7 @@ const {
SIMPLE_QUESTIONS,
TRIVIA_QUESTIONS,
EMPTY_QUESTIONS,
- SIMPLE_QUESTIONS_2
+ SIMPLE_QUESTIONS_2,
}: Record =
// Typecast the test data that we imported to be a record matching
// strings to the question list
@@ -37,7 +37,7 @@ const {
SIMPLE_QUESTIONS: BACKUP_SIMPLE_QUESTIONS,
TRIVIA_QUESTIONS: BACKUP_TRIVIA_QUESTIONS,
EMPTY_QUESTIONS: BACKUP_EMPTY_QUESTIONS,
- SIMPLE_QUESTIONS_2: BACKUP_SIMPLE_QUESTIONS_2
+ SIMPLE_QUESTIONS_2: BACKUP_SIMPLE_QUESTIONS_2,
}: Record = backupQuestionData as Record<
string,
Question[]
@@ -51,7 +51,7 @@ const NEW_BLANK_QUESTION = {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
};
const NEW_TRIVIA_QUESTION = {
@@ -66,7 +66,7 @@ const NEW_TRIVIA_QUESTION = {
options: ["Black, like my soul", "Blue again, we're tricky.", "#FFD200"],
expected: "#FFD200",*/
points: 1,
- published: false
+ published: false,
};
////////////////////////////////////////////
@@ -76,7 +76,7 @@ describe("Testing the Question[] functions", () => {
//////////////////////////////////
// getPublishedQuestions
- test("Testing the getPublishedQuestions function", () => {
+ test("(3 pts) Testing the getPublishedQuestions function", () => {
expect(getPublishedQuestions(BLANK_QUESTIONS)).toEqual([]);
expect(getPublishedQuestions(SIMPLE_QUESTIONS)).toEqual([
{
@@ -87,7 +87,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "4",
points: 1,
- published: true
+ published: true,
},
{
id: 5,
@@ -97,12 +97,12 @@ describe("Testing the Question[] functions", () => {
options: ["red", "apple", "firetruck"],
expected: "red",
points: 1,
- published: true
- }
+ published: true,
+ },
]);
expect(getPublishedQuestions(TRIVIA_QUESTIONS)).toEqual([]);
expect(getPublishedQuestions(SIMPLE_QUESTIONS_2)).toEqual(
- BACKUP_SIMPLE_QUESTIONS_2
+ BACKUP_SIMPLE_QUESTIONS_2,
);
expect(getPublishedQuestions(EMPTY_QUESTIONS)).toEqual([
{
@@ -113,7 +113,7 @@ describe("Testing the Question[] functions", () => {
options: ["correct", "it is", "not"],
expected: "correct",
points: 5,
- published: true
+ published: true,
},
{
id: 2,
@@ -123,7 +123,7 @@ describe("Testing the Question[] functions", () => {
options: ["this", "one", "is", "not", "empty", "either"],
expected: "one",
points: 5,
- published: true
+ published: true,
},
{
id: 3,
@@ -133,7 +133,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 5,
- published: true
+ published: true,
},
{
id: 4,
@@ -143,21 +143,21 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "Even this one is not empty",
points: 5,
- published: true
- }
+ published: true,
+ },
]);
});
- test("Testing the getNonEmptyQuestions functions", () => {
+ test("(3 pts) Testing the getNonEmptyQuestions functions", () => {
expect(getNonEmptyQuestions(BLANK_QUESTIONS)).toEqual([]);
expect(getNonEmptyQuestions(SIMPLE_QUESTIONS)).toEqual(
- BACKUP_SIMPLE_QUESTIONS
+ BACKUP_SIMPLE_QUESTIONS,
);
expect(getNonEmptyQuestions(TRIVIA_QUESTIONS)).toEqual(
- BACKUP_TRIVIA_QUESTIONS
+ BACKUP_TRIVIA_QUESTIONS,
);
expect(getNonEmptyQuestions(SIMPLE_QUESTIONS_2)).toEqual(
- BACKUP_SIMPLE_QUESTIONS_2
+ BACKUP_SIMPLE_QUESTIONS_2,
);
expect(getNonEmptyQuestions(EMPTY_QUESTIONS)).toEqual([
{
@@ -168,7 +168,7 @@ describe("Testing the Question[] functions", () => {
options: ["correct", "it is", "not"],
expected: "correct",
points: 5,
- published: true
+ published: true,
},
{
id: 2,
@@ -178,7 +178,7 @@ describe("Testing the Question[] functions", () => {
options: ["this", "one", "is", "not", "empty", "either"],
expected: "one",
points: 5,
- published: true
+ published: true,
},
{
id: 3,
@@ -188,7 +188,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 5,
- published: true
+ published: true,
},
{
id: 4,
@@ -198,12 +198,12 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "Even this one is not empty",
points: 5,
- published: true
- }
+ published: true,
+ },
]);
});
- test("Testing the findQuestion function", () => {
+ test("(3 pts) Testing the findQuestion function", () => {
expect(findQuestion(BLANK_QUESTIONS, 1)).toEqual(BLANK_QUESTIONS[0]);
expect(findQuestion(BLANK_QUESTIONS, 47)).toEqual(BLANK_QUESTIONS[1]);
expect(findQuestion(BLANK_QUESTIONS, 2)).toEqual(BLANK_QUESTIONS[2]);
@@ -214,12 +214,12 @@ describe("Testing the Question[] functions", () => {
expect(findQuestion(SIMPLE_QUESTIONS, 9)).toEqual(SIMPLE_QUESTIONS[3]);
expect(findQuestion(SIMPLE_QUESTIONS, 6)).toEqual(null);
expect(findQuestion(SIMPLE_QUESTIONS_2, 478)).toEqual(
- SIMPLE_QUESTIONS_2[0]
+ SIMPLE_QUESTIONS_2[0],
);
expect(findQuestion([], 0)).toEqual(null);
});
- test("Testing the removeQuestion", () => {
+ test("(3 pts) Testing the removeQuestion", () => {
expect(removeQuestion(BLANK_QUESTIONS, 1)).toEqual([
{
id: 47,
@@ -229,7 +229,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 2,
@@ -239,8 +239,8 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
- }
+ published: false,
+ },
]);
expect(removeQuestion(BLANK_QUESTIONS, 47)).toEqual([
{
@@ -251,7 +251,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 2,
@@ -261,8 +261,8 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
- }
+ published: false,
+ },
]);
expect(removeQuestion(BLANK_QUESTIONS, 2)).toEqual([
{
@@ -273,7 +273,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 47,
@@ -283,8 +283,8 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
- }
+ published: false,
+ },
]);
expect(removeQuestion(SIMPLE_QUESTIONS, 9)).toEqual([
{
@@ -295,7 +295,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "4",
points: 1,
- published: true
+ published: true,
},
{
id: 2,
@@ -305,7 +305,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "Z",
points: 1,
- published: false
+ published: false,
},
{
id: 5,
@@ -315,8 +315,8 @@ describe("Testing the Question[] functions", () => {
options: ["red", "apple", "firetruck"],
expected: "red",
points: 1,
- published: true
- }
+ published: true,
+ },
]);
expect(removeQuestion(SIMPLE_QUESTIONS, 5)).toEqual([
{
@@ -327,7 +327,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "4",
points: 1,
- published: true
+ published: true,
},
{
id: 2,
@@ -337,7 +337,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "Z",
points: 1,
- published: false
+ published: false,
},
{
id: 9,
@@ -347,45 +347,45 @@ describe("Testing the Question[] functions", () => {
options: ["square", "triangle", "circle"],
expected: "circle",
points: 2,
- published: false
- }
+ published: false,
+ },
]);
});
- test("Testing the getNames function", () => {
+ test("(3 pts) Testing the getNames function", () => {
expect(getNames(BLANK_QUESTIONS)).toEqual([
"Question 1",
"My New Question",
- "Question 2"
+ "Question 2",
]);
expect(getNames(SIMPLE_QUESTIONS)).toEqual([
"Addition",
"Letters",
"Colors",
- "Shapes"
+ "Shapes",
]);
expect(getNames(TRIVIA_QUESTIONS)).toEqual([
"Mascot",
"Motto",
- "Goats"
+ "Goats",
]);
expect(getNames(SIMPLE_QUESTIONS_2)).toEqual([
"Students",
"Importance",
"Sentience",
"Danger",
- "Listening"
+ "Listening",
]);
expect(getNames(EMPTY_QUESTIONS)).toEqual([
"Empty 1",
"Empty 2",
"Empty 3",
"Empty 4",
- "Empty 5 (Actual)"
+ "Empty 5 (Actual)",
]);
});
- test("Testing the sumPoints function", () => {
+ test("(3 pts) Testing the sumPoints function", () => {
expect(sumPoints(BLANK_QUESTIONS)).toEqual(3);
expect(sumPoints(SIMPLE_QUESTIONS)).toEqual(5);
expect(sumPoints(TRIVIA_QUESTIONS)).toEqual(20);
@@ -393,7 +393,7 @@ describe("Testing the Question[] functions", () => {
expect(sumPoints(SIMPLE_QUESTIONS_2)).toEqual(300);
});
- test("Testing the sumPublishedPoints function", () => {
+ test("(3 pts) Testing the sumPublishedPoints function", () => {
expect(sumPublishedPoints(BLANK_QUESTIONS)).toEqual(0);
expect(sumPublishedPoints(SIMPLE_QUESTIONS)).toEqual(2);
expect(sumPublishedPoints(TRIVIA_QUESTIONS)).toEqual(0);
@@ -401,7 +401,7 @@ describe("Testing the Question[] functions", () => {
expect(sumPublishedPoints(SIMPLE_QUESTIONS_2)).toEqual(300);
});
- test("Testing the toCSV function", () => {
+ test("(3 pts) Testing the toCSV function", () => {
expect(toCSV(BLANK_QUESTIONS)).toEqual(`id,name,options,points,published
1,Question 1,0,1,false
47,My New Question,0,1,false
@@ -432,40 +432,40 @@ describe("Testing the Question[] functions", () => {
1937,Listening,0,100,true`);
});
- test("Testing the makeAnswers function", () => {
+ test("(3 pts) Testing the makeAnswers function", () => {
expect(makeAnswers(BLANK_QUESTIONS)).toEqual([
{ questionId: 1, correct: false, text: "", submitted: false },
{ questionId: 47, correct: false, text: "", submitted: false },
- { questionId: 2, correct: false, text: "", submitted: false }
+ { questionId: 2, correct: false, text: "", submitted: false },
]);
expect(makeAnswers(SIMPLE_QUESTIONS)).toEqual([
{ questionId: 1, correct: false, text: "", submitted: false },
{ questionId: 2, correct: false, text: "", submitted: false },
{ questionId: 5, correct: false, text: "", submitted: false },
- { questionId: 9, correct: false, text: "", submitted: false }
+ { questionId: 9, correct: false, text: "", submitted: false },
]);
expect(makeAnswers(TRIVIA_QUESTIONS)).toEqual([
{ questionId: 1, correct: false, text: "", submitted: false },
{ questionId: 2, correct: false, text: "", submitted: false },
- { questionId: 3, correct: false, text: "", submitted: false }
+ { questionId: 3, correct: false, text: "", submitted: false },
]);
expect(makeAnswers(SIMPLE_QUESTIONS_2)).toEqual([
{ questionId: 478, correct: false, text: "", submitted: false },
{ questionId: 1937, correct: false, text: "", submitted: false },
{ questionId: 479, correct: false, text: "", submitted: false },
{ questionId: 777, correct: false, text: "", submitted: false },
- { questionId: 1937, correct: false, text: "", submitted: false }
+ { questionId: 1937, correct: false, text: "", submitted: false },
]);
expect(makeAnswers(EMPTY_QUESTIONS)).toEqual([
{ questionId: 1, correct: false, text: "", submitted: false },
{ questionId: 2, correct: false, text: "", submitted: false },
{ questionId: 3, correct: false, text: "", submitted: false },
{ questionId: 4, correct: false, text: "", submitted: false },
- { questionId: 5, correct: false, text: "", submitted: false }
+ { questionId: 5, correct: false, text: "", submitted: false },
]);
});
- test("Testing the publishAll function", () => {
+ test("(3 pts) Testing the publishAll function", () => {
expect(publishAll(BLANK_QUESTIONS)).toEqual([
{
id: 1,
@@ -475,7 +475,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: true
+ published: true,
},
{
id: 47,
@@ -485,7 +485,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: true
+ published: true,
},
{
id: 2,
@@ -495,8 +495,8 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: true
- }
+ published: true,
+ },
]);
expect(publishAll(SIMPLE_QUESTIONS)).toEqual([
{
@@ -507,7 +507,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "4",
points: 1,
- published: true
+ published: true,
},
{
id: 2,
@@ -517,7 +517,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "Z",
points: 1,
- published: true
+ published: true,
},
{
id: 5,
@@ -527,7 +527,7 @@ describe("Testing the Question[] functions", () => {
options: ["red", "apple", "firetruck"],
expected: "red",
points: 1,
- published: true
+ published: true,
},
{
id: 9,
@@ -537,8 +537,8 @@ describe("Testing the Question[] functions", () => {
options: ["square", "triangle", "circle"],
expected: "circle",
points: 2,
- published: true
- }
+ published: true,
+ },
]);
expect(publishAll(TRIVIA_QUESTIONS)).toEqual([
{
@@ -549,7 +549,7 @@ describe("Testing the Question[] functions", () => {
options: ["Bluey", "YoUDee", "Charles the Wonder Dog"],
expected: "YoUDee",
points: 7,
- published: true
+ published: true,
},
{
id: 2,
@@ -559,11 +559,11 @@ describe("Testing the Question[] functions", () => {
options: [
"Knowledge is the light of the mind",
"Just U Do it",
- "Nothing, what's the motto with you?"
+ "Nothing, what's the motto with you?",
],
expected: "Knowledge is the light of the mind",
points: 3,
- published: true
+ published: true,
},
{
id: 3,
@@ -573,12 +573,12 @@ describe("Testing the Question[] functions", () => {
options: [
"Zero, why would there be goats on the green?",
"18420",
- "Two"
+ "Two",
],
expected: "Two",
points: 10,
- published: true
- }
+ published: true,
+ },
]);
expect(publishAll(EMPTY_QUESTIONS)).toEqual([
{
@@ -589,7 +589,7 @@ describe("Testing the Question[] functions", () => {
options: ["correct", "it is", "not"],
expected: "correct",
points: 5,
- published: true
+ published: true,
},
{
id: 2,
@@ -599,7 +599,7 @@ describe("Testing the Question[] functions", () => {
options: ["this", "one", "is", "not", "empty", "either"],
expected: "one",
points: 5,
- published: true
+ published: true,
},
{
id: 3,
@@ -609,7 +609,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 5,
- published: true
+ published: true,
},
{
id: 4,
@@ -619,7 +619,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "Even this one is not empty",
points: 5,
- published: true
+ published: true,
},
{
id: 5,
@@ -629,13 +629,13 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 5,
- published: true
- }
+ published: true,
+ },
]);
expect(publishAll(SIMPLE_QUESTIONS_2)).toEqual(SIMPLE_QUESTIONS_2);
});
- test("Testing the sameType function", () => {
+ test("(3 pts) Testing the sameType function", () => {
expect(sameType([])).toEqual(true);
expect(sameType(BLANK_QUESTIONS)).toEqual(false);
expect(sameType(SIMPLE_QUESTIONS)).toEqual(false);
@@ -644,29 +644,29 @@ describe("Testing the Question[] functions", () => {
expect(sameType(SIMPLE_QUESTIONS_2)).toEqual(true);
});
- test("Testing the addNewQuestion function", () => {
+ test("(3 pts) Testing the addNewQuestion function", () => {
expect(
- addNewQuestion([], 142, "A new question", "short_answer_question")
+ addNewQuestion([], 142, "A new question", "short_answer_question"),
).toEqual([NEW_BLANK_QUESTION]);
expect(
addNewQuestion(
BLANK_QUESTIONS,
142,
"A new question",
- "short_answer_question"
- )
+ "short_answer_question",
+ ),
).toEqual([...BLANK_QUESTIONS, NEW_BLANK_QUESTION]);
expect(
addNewQuestion(
TRIVIA_QUESTIONS,
449,
"Colors",
- "multiple_choice_question"
- )
+ "multiple_choice_question",
+ ),
).toEqual([...TRIVIA_QUESTIONS, NEW_TRIVIA_QUESTION]);
});
- test("Testing the renameQuestionById function", () => {
+ test("(3 pts) Testing the renameQuestionById function", () => {
expect(renameQuestionById(BLANK_QUESTIONS, 1, "New Name")).toEqual([
{
id: 1,
@@ -676,7 +676,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 47,
@@ -686,7 +686,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 2,
@@ -696,8 +696,8 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
- }
+ published: false,
+ },
]);
expect(renameQuestionById(BLANK_QUESTIONS, 47, "Another Name")).toEqual(
[
@@ -709,7 +709,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 47,
@@ -719,7 +719,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 2,
@@ -729,9 +729,9 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
- }
- ]
+ published: false,
+ },
+ ],
);
expect(renameQuestionById(SIMPLE_QUESTIONS, 5, "Colours")).toEqual([
{
@@ -742,7 +742,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "4",
points: 1,
- published: true
+ published: true,
},
{
id: 2,
@@ -752,7 +752,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "Z",
points: 1,
- published: false
+ published: false,
},
{
id: 5,
@@ -762,7 +762,7 @@ describe("Testing the Question[] functions", () => {
options: ["red", "apple", "firetruck"],
expected: "red",
points: 1,
- published: true
+ published: true,
},
{
id: 9,
@@ -772,21 +772,21 @@ describe("Testing the Question[] functions", () => {
options: ["square", "triangle", "circle"],
expected: "circle",
points: 2,
- published: false
- }
+ published: false,
+ },
]);
});
- test("Test the changeQuestionTypeById function", () => {
+ test("(3 pts) Test the changeQuestionTypeById function", () => {
expect(
changeQuestionTypeById(
BLANK_QUESTIONS,
1,
- "multiple_choice_question"
- )
+ "multiple_choice_question",
+ ),
).toEqual(BLANK_QUESTIONS);
expect(
- changeQuestionTypeById(BLANK_QUESTIONS, 1, "short_answer_question")
+ changeQuestionTypeById(BLANK_QUESTIONS, 1, "short_answer_question"),
).toEqual([
{
id: 1,
@@ -796,7 +796,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 47,
@@ -806,7 +806,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 2,
@@ -816,11 +816,15 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
- }
+ published: false,
+ },
]);
expect(
- changeQuestionTypeById(BLANK_QUESTIONS, 47, "short_answer_question")
+ changeQuestionTypeById(
+ BLANK_QUESTIONS,
+ 47,
+ "short_answer_question",
+ ),
).toEqual([
{
id: 1,
@@ -830,7 +834,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 47,
@@ -840,7 +844,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 2,
@@ -850,11 +854,15 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
- }
+ published: false,
+ },
]);
expect(
- changeQuestionTypeById(TRIVIA_QUESTIONS, 3, "short_answer_question")
+ changeQuestionTypeById(
+ TRIVIA_QUESTIONS,
+ 3,
+ "short_answer_question",
+ ),
).toEqual([
{
id: 1,
@@ -864,7 +872,7 @@ describe("Testing the Question[] functions", () => {
options: ["Bluey", "YoUDee", "Charles the Wonder Dog"],
expected: "YoUDee",
points: 7,
- published: false
+ published: false,
},
{
id: 2,
@@ -874,11 +882,11 @@ describe("Testing the Question[] functions", () => {
options: [
"Knowledge is the light of the mind",
"Just U Do it",
- "Nothing, what's the motto with you?"
+ "Nothing, what's the motto with you?",
],
expected: "Knowledge is the light of the mind",
points: 3,
- published: false
+ published: false,
},
{
id: 3,
@@ -888,12 +896,12 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "Two",
points: 10,
- published: false
- }
+ published: false,
+ },
]);
});
- test("Testing the editOption function", () => {
+ test("(3 pts) Testing the editOption function", () => {
expect(editOption(BLANK_QUESTIONS, 1, -1, "NEW OPTION")).toEqual([
{
id: 1,
@@ -903,7 +911,7 @@ describe("Testing the Question[] functions", () => {
options: ["NEW OPTION"],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 47,
@@ -913,7 +921,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 2,
@@ -923,8 +931,8 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
- }
+ published: false,
+ },
]);
expect(editOption(BLANK_QUESTIONS, 47, -1, "Another option")).toEqual([
{
@@ -935,7 +943,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 47,
@@ -945,7 +953,7 @@ describe("Testing the Question[] functions", () => {
options: ["Another option"],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 2,
@@ -955,8 +963,8 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
- }
+ published: false,
+ },
]);
expect(editOption(SIMPLE_QUESTIONS, 5, -1, "newspaper")).toEqual([
{
@@ -967,7 +975,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "4",
points: 1,
- published: true
+ published: true,
},
{
id: 2,
@@ -977,7 +985,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "Z",
points: 1,
- published: false
+ published: false,
},
{
id: 5,
@@ -987,7 +995,7 @@ describe("Testing the Question[] functions", () => {
options: ["red", "apple", "firetruck", "newspaper"],
expected: "red",
points: 1,
- published: true
+ published: true,
},
{
id: 9,
@@ -997,8 +1005,8 @@ describe("Testing the Question[] functions", () => {
options: ["square", "triangle", "circle"],
expected: "circle",
points: 2,
- published: false
- }
+ published: false,
+ },
]);
expect(editOption(SIMPLE_QUESTIONS, 5, 0, "newspaper")).toEqual([
{
@@ -1009,7 +1017,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "4",
points: 1,
- published: true
+ published: true,
},
{
id: 2,
@@ -1019,7 +1027,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "Z",
points: 1,
- published: false
+ published: false,
},
{
id: 5,
@@ -1029,7 +1037,7 @@ describe("Testing the Question[] functions", () => {
options: ["newspaper", "apple", "firetruck"],
expected: "red",
points: 1,
- published: true
+ published: true,
},
{
id: 9,
@@ -1039,8 +1047,8 @@ describe("Testing the Question[] functions", () => {
options: ["square", "triangle", "circle"],
expected: "circle",
points: 2,
- published: false
- }
+ published: false,
+ },
]);
expect(editOption(SIMPLE_QUESTIONS, 5, 2, "newspaper")).toEqual([
@@ -1052,7 +1060,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "4",
points: 1,
- published: true
+ published: true,
},
{
id: 2,
@@ -1062,7 +1070,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "Z",
points: 1,
- published: false
+ published: false,
},
{
id: 5,
@@ -1072,7 +1080,7 @@ describe("Testing the Question[] functions", () => {
options: ["red", "apple", "newspaper"],
expected: "red",
points: 1,
- published: true
+ published: true,
},
{
id: 9,
@@ -1082,12 +1090,12 @@ describe("Testing the Question[] functions", () => {
options: ["square", "triangle", "circle"],
expected: "circle",
points: 2,
- published: false
- }
+ published: false,
+ },
]);
});
- test("Testing the duplicateQuestionInArray function", () => {
+ test("(3 pts) Testing the duplicateQuestionInArray function", () => {
expect(duplicateQuestionInArray(BLANK_QUESTIONS, 1, 27)).toEqual([
{
id: 1,
@@ -1097,7 +1105,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 27,
@@ -1107,7 +1115,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 47,
@@ -1117,7 +1125,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 2,
@@ -1127,8 +1135,8 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
- }
+ published: false,
+ },
]);
expect(duplicateQuestionInArray(BLANK_QUESTIONS, 47, 19)).toEqual([
{
@@ -1139,7 +1147,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 47,
@@ -1149,7 +1157,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 19,
@@ -1159,7 +1167,7 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
+ published: false,
},
{
id: 2,
@@ -1169,8 +1177,8 @@ describe("Testing the Question[] functions", () => {
options: [],
expected: "",
points: 1,
- published: false
- }
+ published: false,
+ },
]);
expect(duplicateQuestionInArray(TRIVIA_QUESTIONS, 3, 111)).toEqual([
{
@@ -1181,7 +1189,7 @@ describe("Testing the Question[] functions", () => {
options: ["Bluey", "YoUDee", "Charles the Wonder Dog"],
expected: "YoUDee",
points: 7,
- published: false
+ published: false,
},
{
id: 2,
@@ -1191,11 +1199,11 @@ describe("Testing the Question[] functions", () => {
options: [
"Knowledge is the light of the mind",
"Just U Do it",
- "Nothing, what's the motto with you?"
+ "Nothing, what's the motto with you?",
],
expected: "Knowledge is the light of the mind",
points: 3,
- published: false
+ published: false,
},
{
id: 3,
@@ -1205,11 +1213,11 @@ describe("Testing the Question[] functions", () => {
options: [
"Zero, why would there be goats on the green?",
"18420",
- "Two"
+ "Two",
],
expected: "Two",
points: 10,
- published: false
+ published: false,
},
{
id: 111,
@@ -1219,12 +1227,12 @@ describe("Testing the Question[] functions", () => {
options: [
"Zero, why would there be goats on the green?",
"18420",
- "Two"
+ "Two",
],
expected: "Two",
points: 10,
- published: false
- }
+ published: false,
+ },
]);
});
From 017584a64838253637158c4c2a6d0e261c035c84 Mon Sep 17 00:00:00 2001
From: Jacob Donn
Date: Tue, 3 Feb 2026 09:57:39 -0500
Subject: [PATCH 44/81] Added name to App
---
src/App.tsx | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/App.tsx b/src/App.tsx
index b77558eaac..bae62d13cb 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -5,7 +5,8 @@ function App(): React.JSX.Element {
return (
- UD CISC275 with React Hooks and TypeScript
+ UD CISC275 with React Hooks and TypeScript. Jacob says Hello
+ world!
Edit src/App.tsx and save. This page will
From 7272459e46bec8dd3e00f02f8cf5cbe04cc7edfd Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Thu, 5 Feb 2026 10:29:40 -0500
Subject: [PATCH 45/81] Passed all tests
---
package-lock.json | 123 +++++++++++++++++++++-------------------------
src/App.tsx | 4 +-
2 files changed, 59 insertions(+), 68 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 bae62d13cb..f9632b13aa 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -5,8 +5,8 @@ function App(): React.JSX.Element {
return (
- UD CISC275 with React Hooks and TypeScript. Jacob says Hello
- world!
+ UD CISC275 with React Hooks and TypeScript. Jacob Donn. Hello
+ World
Edit src/App.tsx and save. This page will
From bd6f679a40fafa6f6aafd4bef4681046c40eb4fd Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Tue, 10 Feb 2026 09:55:50 -0500
Subject: [PATCH 46/81] Finish adding header & image
---
src/App.tsx | 7 +++++++
src/images/budgies.jpg | Bin 0 -> 34074 bytes
2 files changed, 7 insertions(+)
create mode 100644 src/images/budgies.jpg
diff --git a/src/App.tsx b/src/App.tsx
index f9632b13aa..05350ef5c0 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,5 +1,10 @@
import React from "react";
import "./App.css";
+import budgies from "./images/budgies.jpg";
+
+export function Header(): React.JSX.Element {
+ return This is my header ;
+}
function App(): React.JSX.Element {
return (
@@ -12,6 +17,8 @@ function App(): React.JSX.Element {
Edit src/App.tsx and save. This page will
automatically reload.
+
This is a header!
+
);
}
diff --git a/src/images/budgies.jpg b/src/images/budgies.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..904e239135fe6ebb0beccf28791fc295ded4a645
GIT binary patch
literal 34074
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%0A%=}iRhcCc@}
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
literal 0
HcmV?d00001
From 255fdc6ac02332bb2f13cfb73fb11c8c93ca6488 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Tue, 10 Feb 2026 10:00:23 -0500
Subject: [PATCH 47/81] Finish adding (unordered) list
---
src/App.tsx | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/src/App.tsx b/src/App.tsx
index 05350ef5c0..27cc5747f6 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -17,8 +17,19 @@ function App(): React.JSX.Element {
Edit src/App.tsx and save. This page will
automatically reload.
+
This is a header!
+
+
+
+ My go-to Dominos order:
+
+ Pepperoni
+ Sausage
+ Green peppers
+
+
);
}
From b20f96641d8ac277f1bc24d57d51720ff263a59c Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Tue, 10 Feb 2026 10:11:50 -0500
Subject: [PATCH 48/81] Finish adding "Hello World" logger button
---
src/App.tsx | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/App.tsx b/src/App.tsx
index 27cc5747f6..a7fe42ac11 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,6 +1,7 @@
import React from "react";
import "./App.css";
import budgies from "./images/budgies.jpg";
+import { Button } from "react-bootstrap";
export function Header(): React.JSX.Element {
return This is my header ;
@@ -19,9 +20,7 @@ function App(): React.JSX.Element {
This is a header!
-
-
My go-to Dominos order:
@@ -30,6 +29,15 @@ function App(): React.JSX.Element {
Green peppers
+
+ {
+ console.log("Hello World!");
+ }}
+ >
+ Log Hello World
+
+
);
}
From 2720ca4f45e4d260601111aa01aea6336e05aa65 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Tue, 10 Feb 2026 10:39:56 -0500
Subject: [PATCH 49/81] Finish all tests
---
src/App.css | 4 ++--
src/App.tsx | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/App.css b/src/App.css
index ad32fac073..bce3b2b3c0 100644
--- a/src/App.css
+++ b/src/App.css
@@ -15,14 +15,14 @@
.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(255, 255, 255);
}
.App-link {
diff --git a/src/App.tsx b/src/App.tsx
index a7fe42ac11..120223acf5 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -10,7 +10,7 @@ export function Header(): React.JSX.Element {
function App(): React.JSX.Element {
return (
-
+
UD CISC275 with React Hooks and TypeScript. Jacob Donn. Hello
World
From e5bfcf80542bf268c2f1cea495ea2e50dfd8ab98 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Wed, 11 Feb 2026 13:10:06 -0500
Subject: [PATCH 50/81] Finish first func
---
src/functions.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/functions.ts b/src/functions.ts
index e614c81c0c..ddaa3af7b2 100644
--- a/src/functions.ts
+++ b/src/functions.ts
@@ -4,7 +4,8 @@
* C = (F - 32) * 5/9
*/
export function fahrenheitToCelius(temperature: number): number {
- return 0;
+ let celsiusTemp = (temperature - 32) * (5 / 9);
+ return celsiusTemp;
}
/**
From dbf54332e0610cc470bdf3b34e814a601334cc63 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Wed, 11 Feb 2026 13:11:37 -0500
Subject: [PATCH 51/81] Finish second func
---
src/functions.ts | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/functions.ts b/src/functions.ts
index ddaa3af7b2..375c2405be 100644
--- a/src/functions.ts
+++ b/src/functions.ts
@@ -13,7 +13,18 @@ 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;
+ let sum = 0;
+ if (first > 0) {
+ sum += first;
+ }
+ if (second > 0) {
+ sum += second;
+ }
+ if (third > 0) {
+ sum += third;
+ }
+
+ return sum;
}
/**
From 40ad4321d99a1e3e969abb69ae694f1da896d573 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Wed, 11 Feb 2026 13:13:44 -0500
Subject: [PATCH 52/81] Finish third func
---
src/functions.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/functions.ts b/src/functions.ts
index 375c2405be..3714b0fe97 100644
--- a/src/functions.ts
+++ b/src/functions.ts
@@ -32,7 +32,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() + "!";
}
/**
From 1e40289eb54b544efedde2316963edec94b37a28 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Wed, 11 Feb 2026 13:17:26 -0500
Subject: [PATCH 53/81] Finish fourth func
---
src/functions.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/functions.ts b/src/functions.ts
index 3714b0fe97..e99c4570de 100644
--- a/src/functions.ts
+++ b/src/functions.ts
@@ -40,7 +40,7 @@ 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;
+ return message.slice(-1) === "?";
}
/**
From e55ad1812f50683e908417ab5da184129c550eb6 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Wed, 11 Feb 2026 13:18:42 -0500
Subject: [PATCH 54/81] Finish 5th func
---
src/functions.ts | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/functions.ts b/src/functions.ts
index e99c4570de..9acfb261f6 100644
--- a/src/functions.ts
+++ b/src/functions.ts
@@ -49,5 +49,11 @@ 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;
+ if (word === "yes" || word === "YES") {
+ return true;
+ } else if (word === "no" || word === "NO") {
+ return false;
+ }
+
+ return null;
}
From 026542958f838d52b300e7f0c7debb4319ea836e Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Thu, 19 Feb 2026 12:54:00 -0500
Subject: [PATCH 55/81] Finish all array funcs
---
src/arrays.ts | 81 +++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 72 insertions(+), 9 deletions(-)
diff --git a/src/arrays.ts b/src/arrays.ts
index 4a2ffe8e5b..2636138546 100644
--- a/src/arrays.ts
+++ b/src/arrays.ts
@@ -1,3 +1,5 @@
+//import { cursorTo } from "readline";
+
/**
* Consume an array of numbers, and return a new array containing
* JUST the first and last number. If there are no elements, return
@@ -5,7 +7,14 @@
* the number twice.
*/
export function bookEndList(numbers: number[]): number[] {
- return numbers;
+ if (numbers.length === 0) {
+ return [];
+ } else if (numbers.length === 1) {
+ return [...numbers, ...numbers];
+ } else {
+ const firstLast: number[] = [numbers[0], numbers[numbers.length - 1]];
+ return firstLast;
+ }
}
/**
@@ -13,7 +22,8 @@ export function bookEndList(numbers: number[]): number[] {
* number has been tripled (multiplied by 3).
*/
export function tripleNumbers(numbers: number[]): number[] {
- return numbers;
+ const tripled: number[] = numbers.map((num: number): number => num * 3);
+ return tripled;
}
/**
@@ -21,7 +31,10 @@ 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 [];
+ const ints: number[] = numbers.map((num: string): number =>
+ !isNaN(+num) ? +num : 0,
+ );
+ return ints;
}
/**
@@ -32,7 +45,10 @@ 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 [];
+ const justNums: number[] = amounts.map((amount: string): number =>
+ +amount.replace("$", "") ? +amount.replace("$", "") : 0,
+ );
+ return justNums;
};
/**
@@ -41,7 +57,12 @@ export const removeDollars = (amounts: string[]): number[] => {
* in question marks ("?").
*/
export const shoutIfExclaiming = (messages: string[]): string[] => {
- return [];
+ const newMessages: string[] = messages
+ .map((message: string): string =>
+ message.slice(-1) === "!" ? message.toUpperCase() : message,
+ )
+ .filter((message: string): boolean => message.slice(-1) !== "?");
+ return newMessages;
};
/**
@@ -49,7 +70,10 @@ export const shoutIfExclaiming = (messages: string[]): string[] => {
* 4 letters long.
*/
export function countShortWords(words: string[]): number {
- return 0;
+ const shortWords: string[] = words.filter(
+ (word: string): boolean => word.length < 4,
+ );
+ return shortWords.length;
}
/**
@@ -58,7 +82,13 @@ export function countShortWords(words: string[]): number {
* then return true.
*/
export function allRGB(colors: string[]): boolean {
- return false;
+ if (colors.length === 0) {
+ return true;
+ }
+ return colors.every(
+ (color: string): boolean =>
+ color === "red" || color === "blue" || color === "green",
+ );
}
/**
@@ -69,7 +99,16 @@ 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";
+ }
+
+ const sum = addends.reduce(
+ (total: number, curr: number): number => (total += curr),
+ 0,
+ );
+ const additionString: string = addends.join("+");
+ return sum + "=" + additionString;
}
/**
@@ -81,6 +120,30 @@ export function makeMath(addends: number[]): string {
* 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, 7, 17]
*/
+
export function injectPositive(values: number[]): number[] {
- return [];
+ const firstNeg: number | undefined = values.find(
+ (num: number): boolean => num < 0,
+ );
+
+ if (firstNeg === undefined) {
+ const sum = values.reduce(
+ (total: number, curr: number): number => total + curr,
+ 0,
+ );
+ return [...values, sum];
+ }
+
+ const firstNegIndex = values.findIndex((num: number): boolean => num < 0);
+ const valuesUpToNeg = values.slice(0, firstNegIndex);
+ const sumBeforeNeg = valuesUpToNeg.reduce(
+ (total: number, num: number): number => total + num,
+ 0,
+ );
+ const finalArr: number[] = [
+ ...values.slice(0, firstNegIndex + 1),
+ sumBeforeNeg,
+ ...values.slice(firstNegIndex + 1),
+ ];
+ return finalArr;
}
From 4d5511a5ef2792f01bd734dc4339e2958c1cf7b5 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Sun, 22 Feb 2026 11:46:03 -0500
Subject: [PATCH 56/81] Finish makeBlankQuestion
---
src/objects.ts | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/objects.ts b/src/objects.ts
index 3fd2072e5e..e2e467a374 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: id,
+ name: name,
+ type: type,
+ body: "",
+ expected: "",
+ options: [],
+ points: 1,
+ published: false,
+ };
}
/**
@@ -115,7 +124,7 @@ export function mergeQuestion(
id: number,
name: string,
contentQuestion: Question,
- { points }: { points: number }
+ { points }: { points: number },
): Question {
return contentQuestion;
}
From b2fb1d05747b3dc9110fe6a0ad5fcdc0ba0d5811 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Sun, 22 Feb 2026 11:50:44 -0500
Subject: [PATCH 57/81] Finish isCorrect()
---
src/objects.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/objects.ts b/src/objects.ts
index e2e467a374..695d0ca370 100644
--- a/src/objects.ts
+++ b/src/objects.ts
@@ -30,7 +30,7 @@ export function makeBlankQuestion(
* HINT: Look up the `trim` and `toLowerCase` functions.
*/
export function isCorrect(question: Question, answer: string): boolean {
- return false;
+ return question.expected.toLowerCase() === answer.toLowerCase().trim();
}
/**
From 553433f005d002286a6d6a31a3c67cf72aefe1e3 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Sun, 22 Feb 2026 13:44:27 -0500
Subject: [PATCH 58/81] Finish toShortForm()
---
src/objects.ts | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/objects.ts b/src/objects.ts
index 695d0ca370..1a352a12b9 100644
--- a/src/objects.ts
+++ b/src/objects.ts
@@ -40,7 +40,11 @@ export function isCorrect(question: Question, answer: string): boolean {
* be exactly one of the options.
*/
export function isValid(question: Question, answer: string): boolean {
- return false;
+ if (question.type === "multiple_choice_question") {
+ return question.expected === answer;
+ }
+
+ return answer != "";
}
/**
@@ -50,7 +54,7 @@ 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 "";
+ return `${question.id}: ${question.name.slice(0, 10)}`;
}
/**
From 917c88598c699ed7b4470211ffb086335e368d97 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Sun, 22 Feb 2026 13:48:39 -0500
Subject: [PATCH 59/81] Finish renameQuestion()
---
src/objects.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/objects.ts b/src/objects.ts
index 1a352a12b9..4f4f1dd9c6 100644
--- a/src/objects.ts
+++ b/src/objects.ts
@@ -83,7 +83,8 @@ export function toMarkdown(question: Question): string {
* `newName`.
*/
export function renameQuestion(question: Question, newName: string): Question {
- return question;
+ const newQuestion: Question = { ...question, name: newName };
+ return newQuestion;
}
/**
From 3dbc6f18ffee883cf5ceac8e7f18f5a16871e294 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Sun, 22 Feb 2026 13:51:50 -0500
Subject: [PATCH 60/81] Finish publishQuestion()
---
src/objects.ts | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/objects.ts b/src/objects.ts
index 4f4f1dd9c6..8ed3a7f271 100644
--- a/src/objects.ts
+++ b/src/objects.ts
@@ -93,7 +93,13 @@ 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;
+ if (question.published) {
+ const newQuestion = { ...question, published: false };
+ return newQuestion;
+ }
+
+ const newQuestion = { ...question, published: true };
+ return newQuestion;
}
/**
From 1c80284f1345716fce712c5b00cda50509801306 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Sun, 22 Feb 2026 14:03:25 -0500
Subject: [PATCH 61/81] Finish duplicateQuestion()
---
src/objects.ts | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/objects.ts b/src/objects.ts
index 8ed3a7f271..11957c1f8c 100644
--- a/src/objects.ts
+++ b/src/objects.ts
@@ -109,7 +109,13 @@ export function publishQuestion(question: Question): Question {
* The `published` field should be reset to false.
*/
export function duplicateQuestion(id: number, oldQuestion: Question): Question {
- return oldQuestion;
+ const newQuestion = {
+ ...oldQuestion,
+ id: id,
+ published: false,
+ name: `Copy of ${oldQuestion.name}`,
+ };
+ return newQuestion;
}
/**
From d8d09752cb79a5ebe0c82bbd10449f3bfe3afea0 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Sun, 22 Feb 2026 14:12:57 -0500
Subject: [PATCH 62/81] Finish addOption()
---
src/objects.ts | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/objects.ts b/src/objects.ts
index 11957c1f8c..84a1770d32 100644
--- a/src/objects.ts
+++ b/src/objects.ts
@@ -126,7 +126,11 @@ 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;
+ const newQuestion = {
+ ...question,
+ options: [...question.options, newOption],
+ };
+ return newQuestion;
}
/**
From 907117cbc541ace73573373c67713ebd9c2bd1d4 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Sun, 22 Feb 2026 17:14:28 -0500
Subject: [PATCH 63/81] Finish isValid()
---
src/objects.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/objects.ts b/src/objects.ts
index 84a1770d32..f88b41c144 100644
--- a/src/objects.ts
+++ b/src/objects.ts
@@ -41,7 +41,7 @@ export function isCorrect(question: Question, answer: string): boolean {
*/
export function isValid(question: Question, answer: string): boolean {
if (question.type === "multiple_choice_question") {
- return question.expected === answer;
+ return question.options.includes(answer);
}
return answer != "";
From 1ba4c3a2b2f31d1580e5ede9c418a30215605af4 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Sun, 22 Feb 2026 17:19:39 -0500
Subject: [PATCH 64/81] Finish toMarkdown()
---
src/objects.ts | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/objects.ts b/src/objects.ts
index f88b41c144..bc0f36aa5c 100644
--- a/src/objects.ts
+++ b/src/objects.ts
@@ -75,7 +75,11 @@ 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]}`;
}
/**
From e7461aef030cf771ca7d8135e215708efca195a9 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Sun, 22 Feb 2026 17:26:38 -0500
Subject: [PATCH 65/81] Finish mergeQuestion
---
src/objects.ts | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/objects.ts b/src/objects.ts
index bc0f36aa5c..3f94c14cb2 100644
--- a/src/objects.ts
+++ b/src/objects.ts
@@ -151,5 +151,12 @@ export function mergeQuestion(
contentQuestion: Question,
{ points }: { points: number },
): Question {
- return contentQuestion;
+ const mergedQuestion = {
+ ...contentQuestion,
+ id: id,
+ name: name,
+ published: false,
+ points: { points }.points,
+ };
+ return mergedQuestion;
}
From 293ef5fb891d4796a06f9282d60f9ac2e1219658 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Tue, 24 Feb 2026 21:27:10 -0500
Subject: [PATCH 66/81] Finish getPublishedQuestions()
---
src/nested.ts | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/nested.ts b/src/nested.ts
index 562b6ca0df..c0b5018ae5 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -6,7 +6,9 @@ import { Question, QuestionType } from "./interfaces/question";
* that are `published`.
*/
export function getPublishedQuestions(questions: Question[]): Question[] {
- return [];
+ return questions.filter(
+ (question: Question): boolean => question.published,
+ );
}
/**
@@ -14,9 +16,7 @@ export function getPublishedQuestions(questions: Question[]): Question[] {
* considered "non-empty". An empty question has an empty string for its `body` and
* `expected`, and an empty array for its `options`.
*/
-export function getNonEmptyQuestions(questions: Question[]): Question[] {
- return [];
-}
+export function getNonEmptyQuestions(questions: Question[]): Question[] {}
/***
* Consumes an array of questions and returns the question with the given `id`. If the
@@ -24,7 +24,7 @@ export function getNonEmptyQuestions(questions: Question[]): Question[] {
*/
export function findQuestion(
questions: Question[],
- id: number
+ id: number,
): Question | null {
return null;
}
@@ -114,7 +114,7 @@ export function addNewQuestion(
questions: Question[],
id: number,
name: string,
- type: QuestionType
+ type: QuestionType,
): Question[] {
return [];
}
@@ -127,7 +127,7 @@ export function addNewQuestion(
export function renameQuestionById(
questions: Question[],
targetId: number,
- newName: string
+ newName: string,
): Question[] {
return [];
}
@@ -142,7 +142,7 @@ export function renameQuestionById(
export function changeQuestionTypeById(
questions: Question[],
targetId: number,
- newQuestionType: QuestionType
+ newQuestionType: QuestionType,
): Question[] {
return [];
}
@@ -161,7 +161,7 @@ export function editOption(
questions: Question[],
targetId: number,
targetOptionIndex: number,
- newOption: string
+ newOption: string,
): Question[] {
return [];
}
@@ -175,7 +175,7 @@ export function editOption(
export function duplicateQuestionInArray(
questions: Question[],
targetId: number,
- newId: number
+ newId: number,
): Question[] {
return [];
}
From e82e13b486fb8624d6b13a192f413eda463b960f Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Tue, 24 Feb 2026 21:29:52 -0500
Subject: [PATCH 67/81] Finish getNonEmptyQuestions
---
src/nested.ts | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/nested.ts b/src/nested.ts
index c0b5018ae5..4fedd00835 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -16,7 +16,16 @@ export function getPublishedQuestions(questions: Question[]): Question[] {
* considered "non-empty". An empty question has an empty string for its `body` and
* `expected`, and an empty array for its `options`.
*/
-export function getNonEmptyQuestions(questions: Question[]): Question[] {}
+export function getNonEmptyQuestions(questions: Question[]): Question[] {
+ return questions.filter(
+ (question: Question): boolean =>
+ !(
+ question.expected === "" &&
+ question.body === "" &&
+ question.options.length === 0
+ ),
+ );
+}
/***
* Consumes an array of questions and returns the question with the given `id`. If the
From 159b7c9a2feae9155576cdaa249851dc419df68c Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Tue, 24 Feb 2026 21:31:27 -0500
Subject: [PATCH 68/81] Finish findQuestion()
---
src/nested.ts | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/nested.ts b/src/nested.ts
index 4fedd00835..927b0285a0 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -35,7 +35,13 @@ export function findQuestion(
questions: Question[],
id: number,
): Question | null {
- return null;
+ const foundQuestion = questions.find(
+ (question: Question): boolean => question.id === id,
+ );
+ if (foundQuestion === undefined) {
+ return null;
+ }
+ return foundQuestion;
}
/**
From f064245067c7bc4fc48880e7bb0cf90da96b16d5 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Tue, 24 Feb 2026 21:33:49 -0500
Subject: [PATCH 69/81] Finish removeQuestion()
---
src/nested.ts | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/nested.ts b/src/nested.ts
index 927b0285a0..f896791977 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -49,7 +49,9 @@ export function findQuestion(
* with the given `id`.
*/
export function removeQuestion(questions: Question[], id: number): Question[] {
- return [];
+ return questions.filter(
+ (question: Question): boolean => question.id !== id,
+ );
}
/***
From 700d14d2f7aced5536d8ee14f7c1d76763361132 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Tue, 24 Feb 2026 21:35:10 -0500
Subject: [PATCH 70/81] Finish getNames()
---
src/nested.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/nested.ts b/src/nested.ts
index f896791977..e89ec03c24 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -59,7 +59,7 @@ export function removeQuestion(questions: Question[], id: number): Question[] {
* questions, as an array.
*/
export function getNames(questions: Question[]): string[] {
- return [];
+ return questions.map((question: Question): string => question.name);
}
/***
From a5db038ba50e9db3e2c26bc2250f427fc8dc7e2f Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Tue, 24 Feb 2026 21:54:16 -0500
Subject: [PATCH 71/81] Finish sumPoints()
---
src/nested.ts | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/nested.ts b/src/nested.ts
index e89ec03c24..a6a38ccd77 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -66,7 +66,10 @@ export function getNames(questions: Question[]): string[] {
* Consumes an array of questions and returns the sum total of all their points added together.
*/
export function sumPoints(questions: Question[]): number {
- return 0;
+ return questions.reduce(
+ (total: number, curr: Question) => total + curr.points,
+ 0,
+ );
}
/***
From 05e2a930ff56789a2876ae70f748cce82d9b2fee Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Tue, 24 Feb 2026 22:07:19 -0500
Subject: [PATCH 72/81] Finish sumPublishedPoints()
---
src/nested.ts | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/nested.ts b/src/nested.ts
index a6a38ccd77..87d68c933f 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -76,7 +76,9 @@ export function sumPoints(questions: Question[]): number {
* Consumes an array of questions and returns the sum total of the PUBLISHED questions.
*/
export function sumPublishedPoints(questions: Question[]): number {
- return 0;
+ return questions
+ .filter((question: Question): boolean => question.published)
+ .reduce((total: number, curr: Question) => total + curr.points, 0);
}
/***
From a8b1bfb7f15150ec2fbf2d0a6bf2f68a72471d49 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Wed, 25 Feb 2026 20:45:48 -0500
Subject: [PATCH 73/81] Finish makeAnswers()
---
src/nested.ts | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/nested.ts b/src/nested.ts
index 87d68c933f..4413d289b6 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -99,7 +99,7 @@ id,name,options,points,published
* Check the unit tests for more examples!
*/
export function toCSV(questions: Question[]): string {
- return "";
+ const finalStr: string = "id,name,options,points,published\n";
}
/**
@@ -108,7 +108,14 @@ export function toCSV(questions: Question[]): string {
* making the `text` an empty string, and using false for both `submitted` and `correct`.
*/
export function makeAnswers(questions: Question[]): Answer[] {
- return [];
+ return questions.map(
+ (question: Question): Answer => ({
+ questionId: question.id,
+ text: "",
+ submitted: false,
+ correct: false,
+ }),
+ );
}
/***
From 2f65e820ac78c94233603600fd18e6debd50ecd7 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Wed, 25 Feb 2026 20:48:32 -0500
Subject: [PATCH 74/81] Finish publishAll()
---
src/nested.ts | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/nested.ts b/src/nested.ts
index 4413d289b6..575011522c 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -123,7 +123,9 @@ export function makeAnswers(questions: Question[]): Answer[] {
* each question is now published, regardless of its previous published status.
*/
export function publishAll(questions: Question[]): Question[] {
- return [];
+ return questions.map(
+ (question: Question): Question => ({ ...question, published: true }),
+ );
}
/***
From 93cf6088ca78d2ad5b4a53f430f83cd4c99b75a2 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Wed, 25 Feb 2026 20:49:34 -0500
Subject: [PATCH 75/81] Finish sameType()
---
src/nested.ts | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/nested.ts b/src/nested.ts
index 575011522c..6687e238b2 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -133,7 +133,9 @@ export function publishAll(questions: Question[]): Question[] {
* are the same type. They can be any type, as long as they are all the SAME type.
*/
export function sameType(questions: Question[]): boolean {
- return false;
+ return questions.every(
+ (question: Question): boolean => question.type === questions[0].type,
+ );
}
/***
From 8b2fdf25497792f28d43c17d3e6f63293af27d80 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Wed, 25 Feb 2026 20:52:42 -0500
Subject: [PATCH 76/81] Finish addNewQuestion()
---
src/nested.ts | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/nested.ts b/src/nested.ts
index 6687e238b2..93ad44dda1 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -1,5 +1,6 @@
import { Answer } from "./interfaces/answer";
import { Question, QuestionType } from "./interfaces/question";
+import { makeBlankQuestion } from "./objects";
/**
* Consumes an array of questions and returns a new array with only the questions
@@ -149,7 +150,8 @@ export function addNewQuestion(
name: string,
type: QuestionType,
): Question[] {
- return [];
+ const newQuestion: Question = makeBlankQuestion(id, name, type);
+ return [...questions, newQuestion];
}
/***
From 4040f179d6f49fa9354cb2ca1e4b5eaeae5d52d8 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Wed, 25 Feb 2026 21:40:57 -0500
Subject: [PATCH 77/81] Finish renameQuestionById()
---
src/nested.ts | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/nested.ts b/src/nested.ts
index 93ad44dda1..c450e5f1e7 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -164,7 +164,14 @@ export function renameQuestionById(
targetId: number,
newName: string,
): Question[] {
- return [];
+ const targetIndex: number = questions.findIndex(
+ (question: Question): boolean => question.id === targetId,
+ );
+ const questionsCopy: Question[] = questions.map(
+ (question: Question): Question => ({ ...question }),
+ );
+ questionsCopy[targetIndex].name = newName;
+ return questionsCopy;
}
/***
From 253897e228c212e792638989200fbe28a8baf0a9 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Wed, 25 Feb 2026 21:47:11 -0500
Subject: [PATCH 78/81] Finish changeQuestionTypeById()
---
src/nested.ts | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/nested.ts b/src/nested.ts
index c450e5f1e7..7923f7efc8 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -186,7 +186,18 @@ export function changeQuestionTypeById(
targetId: number,
newQuestionType: QuestionType,
): Question[] {
- return [];
+ const targetIndex: number = questions.findIndex(
+ (question: Question): boolean => question.id === targetId,
+ );
+ const questionsCopy: Question[] = questions.map(
+ (question: Question): Question => ({ ...question }),
+ );
+ questionsCopy[targetIndex].options =
+ newQuestionType === "short_answer_question" ?
+ []
+ : questionsCopy[targetIndex].options;
+ questionsCopy[targetIndex].type = newQuestionType;
+ return questionsCopy;
}
/**
From cd21d81be9736edd8f4cde1c63d5ef8e3156a6e1 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Fri, 27 Feb 2026 15:40:54 -0500
Subject: [PATCH 79/81] Finish duplicateQuestionInArray()
---
src/nested.ts | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/src/nested.ts b/src/nested.ts
index 7923f7efc8..21a5682cb2 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -1,6 +1,6 @@
import { Answer } from "./interfaces/answer";
import { Question, QuestionType } from "./interfaces/question";
-import { makeBlankQuestion } from "./objects";
+import { makeBlankQuestion, duplicateQuestion } from "./objects";
/**
* Consumes an array of questions and returns a new array with only the questions
@@ -216,7 +216,9 @@ export function editOption(
targetOptionIndex: number,
newOption: string,
): Question[] {
- return [];
+ const targetQuestion = questions.find(
+ (question: Question): boolean => question.id === targetId,
+ );
}
/***
@@ -230,5 +232,17 @@ export function duplicateQuestionInArray(
targetId: number,
newId: number,
): Question[] {
- return [];
+ const targetQuestion: Question | undefined = questions.find(
+ (question: Question): boolean => question.id === targetId,
+ );
+ const duplicatequestion: Question = duplicateQuestion(
+ newId,
+ targetQuestion!,
+ );
+ const origQuestionIndex: number = questions.findIndex(
+ (question: Question): boolean => question.id === targetId,
+ );
+ const newArr = [...questions];
+ newArr.splice(origQuestionIndex + 1, 0, duplicatequestion);
+ return newArr;
}
From 3991aea0f9c659d4a047fea333ddbd822db21f6f Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Sat, 28 Feb 2026 20:54:52 -0500
Subject: [PATCH 80/81] Finish editOption()
---
src/nested.ts | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/src/nested.ts b/src/nested.ts
index 21a5682cb2..5decb9132b 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -219,6 +219,34 @@ export function editOption(
const targetQuestion = questions.find(
(question: Question): boolean => question.id === targetId,
);
+
+ // if (targetOptionIndex === -1) {
+ // targetQuestion!.options = [...targetQuestion!.options, newOption];
+ // } else {
+ // targetQuestion!.options.splice(targetOptionIndex, 1, newOption);
+ // }
+
+ // return questions.map(
+ // (question: Question): Question =>
+ // question.id === targetId ? targetQuestion! : question,
+ // );
+
+ let targetQuestionOptions: string[] = [];
+ if (targetOptionIndex === -1) {
+ targetQuestionOptions = [...targetQuestion!.options, newOption];
+ } else {
+ targetQuestionOptions = [...targetQuestion!.options];
+ targetQuestionOptions.splice(targetOptionIndex, 1, newOption);
+ }
+
+ const newOptionQuestion: Question = {
+ ...targetQuestion!,
+ options: targetQuestionOptions,
+ };
+ return questions.map(
+ (question: Question): Question =>
+ question.id === targetId ? newOptionQuestion : question,
+ );
}
/***
@@ -242,6 +270,7 @@ export function duplicateQuestionInArray(
const origQuestionIndex: number = questions.findIndex(
(question: Question): boolean => question.id === targetId,
);
+
const newArr = [...questions];
newArr.splice(origQuestionIndex + 1, 0, duplicatequestion);
return newArr;
From 9a7d427c529a2b8ff88b7a39cbc86afe717e6ca7 Mon Sep 17 00:00:00 2001
From: jacobdonn
Date: Sat, 28 Feb 2026 21:23:53 -0500
Subject: [PATCH 81/81] Finish toCSV()
---
src/nested.ts | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/src/nested.ts b/src/nested.ts
index 5decb9132b..7811e3fcc5 100644
--- a/src/nested.ts
+++ b/src/nested.ts
@@ -100,7 +100,14 @@ id,name,options,points,published
* Check the unit tests for more examples!
*/
export function toCSV(questions: Question[]): string {
- const finalStr: string = "id,name,options,points,published\n";
+ const top: string = "id,name,options,points,published\n";
+ const data: string[] = questions.map(
+ (question: Question): string =>
+ `${question.id},${question.name},${question.options.length},${question.points},${question.published}\n`,
+ );
+
+ const final: string[] = [top, ...data];
+ return final.join("").slice(0, -1);
}
/**
@@ -220,17 +227,6 @@ export function editOption(
(question: Question): boolean => question.id === targetId,
);
- // if (targetOptionIndex === -1) {
- // targetQuestion!.options = [...targetQuestion!.options, newOption];
- // } else {
- // targetQuestion!.options.splice(targetOptionIndex, 1, newOption);
- // }
-
- // return questions.map(
- // (question: Question): Question =>
- // question.id === targetId ? targetQuestion! : question,
- // );
-
let targetQuestionOptions: string[] = [];
if (targetOptionIndex === -1) {
targetQuestionOptions = [...targetQuestion!.options, newOption];