From 70717d6476dc0831811f8539db94d20b5299a048 Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Tue, 21 Jan 2025 14:25:05 -0800 Subject: [PATCH 01/12] add test cases and implementations for system getters --- ...UnoptimizedInMemoryRepositoryTests.test.ts | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts diff --git a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts new file mode 100644 index 0000000..6a7a50f --- /dev/null +++ b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts @@ -0,0 +1,61 @@ +import { beforeEach, describe, expect, test } from "@jest/globals"; +import { UnoptimizedInMemoryRepository } from "../../src/repositories/UnoptimizedInMemoryRepository"; + +// For repositories created in the future, reuse core testing +// logic from here and differentiate setup (e.g. creating mocks) +// Do this by creating a function which takes a GetterRepository +// or GetterSetterRepository instance + +describe("UnoptimizedInMemoryRepository", () => { + let repository: UnoptimizedInMemoryRepository; + + beforeEach(() => { + repository = new UnoptimizedInMemoryRepository(); + }); + + describe("getSystems", () => { + test("gets the systems stored in the repository", async () => { + const mockSystems = [ + { id: "1", name: "System A" }, + { id: "2", name: "System B" }, + ]; + await repository.addOrUpdateSystem(mockSystems[0]); + await repository.addOrUpdateSystem(mockSystems[1]); + + const result = await repository.getSystems(); + + expect(result).toEqual(mockSystems); + }); + + test("gets an empty list if there are no systems stored", async () => { + const result = await repository.getSystems(); + + expect(result).toEqual([]); + }); + }); + + describe("getSystemById", () => { + test("gets a system by the ID if it exists", async () => { + const mockSystems = [ + { id: "1", name: "System A" }, + { id: "2", name: "System B" }, + { id: "3", name: "System C" }, + ]; + for (const system of mockSystems) { + await repository.addOrUpdateSystem(system); + } + + const result = await repository.getSystemById("2"); + + expect(result).toEqual(mockSystems[1]); // Ensure it retrieves the correct system + }); + + test("returns null if the system doesn't exist", async () => { + const result = await repository.getSystemById("nonexistent-id"); + + expect(result).toBeNull(); + }); + }); + + +}); \ No newline at end of file From 0d9d935a9e65b4c27749b9a2fc9faa35130f371a Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Tue, 21 Jan 2025 14:27:18 -0800 Subject: [PATCH 02/12] add rest of tests (mostly generated) --- ...UnoptimizedInMemoryRepositoryTests.test.ts | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts index 6a7a50f..aa92546 100644 --- a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts +++ b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts @@ -6,6 +6,9 @@ import { UnoptimizedInMemoryRepository } from "../../src/repositories/Unoptimize // Do this by creating a function which takes a GetterRepository // or GetterSetterRepository instance +// Full disclosure: most of this was generated by ChatGPT +// https://chatgpt.com/share/67901f14-c4ac-800d-8bcd-d2e622c522bf + describe("UnoptimizedInMemoryRepository", () => { let repository: UnoptimizedInMemoryRepository; @@ -57,5 +60,84 @@ describe("UnoptimizedInMemoryRepository", () => { }); }); + describe("getStopsBySystemId", () => { + test("gets stops by system ID", async () => { + const mockStops = [ + { id: "1", name: "Stop A", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }, + { id: "2", name: "Stop B", systemId: "sys1", coordinates: { latitude: 15, longitude: 25 } }, + { id: "3", name: "Stop C", systemId: "sys2", coordinates: { latitude: 30, longitude: 40 } }, + ]; + for (const stop of mockStops) { + await repository.addOrUpdateStop(stop); + } + const result = await repository.getStopsBySystemId("sys1"); + expect(result).toEqual(mockStops.filter((stop) => stop.systemId === "sys1")); + }); + + test("returns an empty list if there are no stops for the given system ID", async () => { + const result = await repository.getStopsBySystemId("nonexistent-system"); + expect(result).toEqual([]); + }); + }); + + describe("getShuttleById", () => { + test("gets a shuttle by ID if it exists", async () => { + const mockShuttles = [ + { id: "1", name: "Shuttle A", routeId: "r1", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }, + { id: "2", name: "Shuttle B", routeId: "r2", systemId: "sys1", coordinates: { latitude: 15, longitude: 25 } }, + ]; + for (const shuttle of mockShuttles) { + await repository.addOrUpdateShuttle(shuttle); + } + + const result = await repository.getShuttleById("2"); + expect(result).toEqual(mockShuttles[1]); + }); + + test("returns null if the shuttle doesn't exist", async () => { + const result = await repository.getShuttleById("nonexistent-id"); + expect(result).toBeNull(); + }); + }); + + describe("getEtasForStopId", () => { + test("gets ETAs for a specific stop ID", async () => { + const mockEtas = [ + { shuttleId: "s1", stopId: "st1", secondsRemaining: 120 }, + { shuttleId: "s2", stopId: "st1", secondsRemaining: 180 }, + { shuttleId: "s3", stopId: "st2", secondsRemaining: 240 }, + ]; + for (const eta of mockEtas) { + await repository.addOrUpdateEta(eta); + } + + const result = await repository.getEtasForStopId("st1"); + expect(result).toEqual(mockEtas.filter((eta) => eta.stopId === "st1")); + }); + + test("returns an empty list if there are no ETAs for the stop ID", async () => { + const result = await repository.getEtasForStopId("nonexistent-stop"); + expect(result).toEqual([]); + }); + }); + + describe("getOrderedStopByRouteAndStopId", () => { + test("gets an ordered stop by route ID and stop ID", async () => { + const mockOrderedStop = { + routeId: "r1", + stopId: "st1", + position: 1, + }; + await repository.addOrUpdateOrderedStop(mockOrderedStop); + + const result = await repository.getOrderedStopByRouteAndStopId("r1", "st1"); + expect(result).toEqual(mockOrderedStop); + }); + + test("returns null if no ordered stop matches the given route ID and stop ID", async () => { + const result = await repository.getOrderedStopByRouteAndStopId("nonexistent-route", "nonexistent-stop"); + expect(result).toBeNull(); + }); + }); }); \ No newline at end of file From 8f66b9ddfbb64220fdad243efe84f39ff29d6f01 Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Tue, 21 Jan 2025 14:37:21 -0800 Subject: [PATCH 03/12] add missing tests according to coverage report --- ...UnoptimizedInMemoryRepositoryTests.test.ts | 172 +++++++++++++++++- 1 file changed, 171 insertions(+), 1 deletion(-) diff --git a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts index aa92546..0f0a804 100644 --- a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts +++ b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts @@ -7,7 +7,7 @@ import { UnoptimizedInMemoryRepository } from "../../src/repositories/Unoptimize // or GetterSetterRepository instance // Full disclosure: most of this was generated by ChatGPT -// https://chatgpt.com/share/67901f14-c4ac-800d-8bcd-d2e622c522bf +// https://chatgpt.com/share/67902072-3adc-800d-bd22-06f7b3e6f4a4 describe("UnoptimizedInMemoryRepository", () => { let repository: UnoptimizedInMemoryRepository; @@ -81,6 +81,98 @@ describe("UnoptimizedInMemoryRepository", () => { }); }); + describe("getStopById", () => { + test("gets a stop by ID if it exists", async () => { + const mockStop = { id: "st1", name: "Stop A", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }; + await repository.addOrUpdateStop(mockStop); + + const result = await repository.getStopById("st1"); + expect(result).toEqual(mockStop); + }); + + test("returns null if the stop does not exist", async () => { + const result = await repository.getStopById("nonexistent-stop"); + expect(result).toBeNull(); + }); + }); + + describe("getRoutesBySystemId", () => { + test("gets all routes for a specific system ID", async () => { + const mockRoutes = [ + { id: "r1", name: "Route 1", color: "red", systemId: "sys1", polylineCoordinates: [] }, + { id: "r2", name: "Route 2", color: "blue", systemId: "sys1", polylineCoordinates: [] }, + { id: "r3", name: "Route 3", color: "green", systemId: "sys2", polylineCoordinates: [] }, + ]; + for (const route of mockRoutes) { + await repository.addOrUpdateRoute(route); + } + + const result = await repository.getRoutesBySystemId("sys1"); + expect(result).toEqual(mockRoutes.filter((route) => route.systemId === "sys1")); + }); + + test("returns an empty list if there are no routes for the system ID", async () => { + const result = await repository.getRoutesBySystemId("nonexistent-system"); + expect(result).toEqual([]); + }); + }); + + describe("getRouteById", () => { + test("gets a route by ID if it exists", async () => { + const mockRoute = { id: "r1", name: "Route 1", color: "red", systemId: "sys1", polylineCoordinates: [] }; + await repository.addOrUpdateRoute(mockRoute); + + const result = await repository.getRouteById("r1"); + expect(result).toEqual(mockRoute); + }); + + test("returns null if the route does not exist", async () => { + const result = await repository.getRouteById("nonexistent-route"); + expect(result).toBeNull(); + }); + }); + describe("getShuttlesBySystemId", () => { + test("gets all shuttles for a specific system ID", async () => { + const mockShuttles = [ + { id: "sh1", name: "Shuttle A", routeId: "r1", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }, + { id: "sh2", name: "Shuttle B", routeId: "r2", systemId: "sys1", coordinates: { latitude: 15, longitude: 25 } }, + { id: "sh3", name: "Shuttle C", routeId: "r3", systemId: "sys2", coordinates: { latitude: 30, longitude: 40 } }, + ]; + for (const shuttle of mockShuttles) { + await repository.addOrUpdateShuttle(shuttle); + } + + const result = await repository.getShuttlesBySystemId("sys1"); + expect(result).toEqual(mockShuttles.filter((sh) => sh.systemId === "sys1")); + }); + + test("returns an empty list if there are no shuttles for the system ID", async () => { + const result = await repository.getShuttlesBySystemId("nonexistent-system"); + expect(result).toEqual([]); + }); + }); + + describe("getShuttlesByRouteId", () => { + test("gets all shuttles for a specific route ID", async () => { + const mockShuttles = [ + { id: "sh1", name: "Shuttle A", routeId: "r1", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }, + { id: "sh2", name: "Shuttle B", routeId: "r1", systemId: "sys1", coordinates: { latitude: 15, longitude: 25 } }, + { id: "sh3", name: "Shuttle C", routeId: "r2", systemId: "sys2", coordinates: { latitude: 30, longitude: 40 } }, + ]; + for (const shuttle of mockShuttles) { + await repository.addOrUpdateShuttle(shuttle); + } + + const result = await repository.getShuttlesByRouteId("r1"); + expect(result).toEqual(mockShuttles.filter((sh) => sh.routeId === "r1")); + }); + + test("returns an empty list if there are no shuttles for the route ID", async () => { + const result = await repository.getShuttlesByRouteId("nonexistent-route"); + expect(result).toEqual([]); + }); + }); + describe("getShuttleById", () => { test("gets a shuttle by ID if it exists", async () => { const mockShuttles = [ @@ -101,6 +193,27 @@ describe("UnoptimizedInMemoryRepository", () => { }); }); + describe("getEtasForShuttleId", () => { + test("gets ETAs for a specific shuttle ID", async () => { + const mockEtas = [ + { shuttleId: "sh1", stopId: "st1", secondsRemaining: 120 }, + { shuttleId: "sh1", stopId: "st2", secondsRemaining: 180 }, + { shuttleId: "sh2", stopId: "st3", secondsRemaining: 240 }, + ]; + for (const eta of mockEtas) { + await repository.addOrUpdateEta(eta); + } + + const result = await repository.getEtasForShuttleId("sh1"); + expect(result).toEqual(mockEtas.filter((eta) => eta.shuttleId === "sh1")); + }); + + test("returns an empty list if there are no ETAs for the shuttle ID", async () => { + const result = await repository.getEtasForShuttleId("nonexistent-shuttle"); + expect(result).toEqual([]); + }); + }); + describe("getEtasForStopId", () => { test("gets ETAs for a specific stop ID", async () => { const mockEtas = [ @@ -122,6 +235,21 @@ describe("UnoptimizedInMemoryRepository", () => { }); }); + describe("getEtaForShuttleAndStopId", () => { + test("gets a single ETA for a specific shuttle and stop ID", async () => { + const mockEta = { shuttleId: "sh1", stopId: "st1", secondsRemaining: 120 }; + await repository.addOrUpdateEta(mockEta); + + const result = await repository.getEtaForShuttleAndStopId("sh1", "st1"); + expect(result).toEqual(mockEta); + }); + + test("returns null if no ETA matches the shuttle and stop ID", async () => { + const result = await repository.getEtaForShuttleAndStopId("nonexistent-shuttle", "nonexistent-stop"); + expect(result).toBeNull(); + }); + }); + describe("getOrderedStopByRouteAndStopId", () => { test("gets an ordered stop by route ID and stop ID", async () => { const mockOrderedStop = { @@ -140,4 +268,46 @@ describe("UnoptimizedInMemoryRepository", () => { expect(result).toBeNull(); }); }); + + describe("getOrderedStopsByStopId", () => { + test("gets all ordered stops for a specific stop ID", async () => { + const mockOrderedStops = [ + { stopId: "st1", routeId: "r1", position: 1 }, + { stopId: "st1", routeId: "r2", position: 2 }, + { stopId: "st2", routeId: "r3", position: 3 }, + ]; + for (const orderedStop of mockOrderedStops) { + await repository.addOrUpdateOrderedStop(orderedStop); + } + + const result = await repository.getOrderedStopsByStopId("st1"); + expect(result).toEqual(mockOrderedStops.filter((os) => os.stopId === "st1")); + }); + + test("returns an empty list if there are no ordered stops for the stop ID", async () => { + const result = await repository.getOrderedStopsByStopId("nonexistent-stop"); + expect(result).toEqual([]); + }); + }); + + describe("getOrderedStopsByRouteId", () => { + test("gets all ordered stops for a specific route ID", async () => { + const mockOrderedStops = [ + { stopId: "st1", routeId: "r1", position: 1 }, + { stopId: "st2", routeId: "r1", position: 2 }, + { stopId: "st3", routeId: "r2", position: 3 }, + ]; + for (const orderedStop of mockOrderedStops) { + await repository.addOrUpdateOrderedStop(orderedStop); + } + + const result = await repository.getOrderedStopsByRouteId("r1"); + expect(result).toEqual(mockOrderedStops.filter((os) => os.routeId === "r1")); + }); + + test("returns an empty list if there are no ordered stops for the route ID", async () => { + const result = await repository.getOrderedStopsByRouteId("nonexistent-route"); + expect(result).toEqual([]); + }); + }); }); \ No newline at end of file From 736d348133900407fea7793365639027e4ff666f Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Tue, 21 Jan 2025 14:50:48 -0800 Subject: [PATCH 04/12] add addOrUpdate tests for UnoptimizedInMemoryRepository --- ...UnoptimizedInMemoryRepositoryTests.test.ts | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts index 0f0a804..4a70771 100644 --- a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts +++ b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts @@ -310,4 +310,160 @@ describe("UnoptimizedInMemoryRepository", () => { expect(result).toEqual([]); }); }); + + describe("addOrUpdateSystem", () => { + test("adds a new system if nonexistent", async () => { + const newSystem = { id: "sys1", name: "System A", millisecondsSinceEpoch: 1620000000000 }; + + await repository.addOrUpdateSystem(newSystem); + + const result = await repository.getSystems(); + expect(result).toEqual([newSystem]); + }); + + test("updates an existing system if it exists", async () => { + const existingSystem = { id: "sys1", name: "System A", millisecondsSinceEpoch: 1620000000000 }; + const updatedSystem = { id: "sys1", name: "Updated System A", millisecondsSinceEpoch: 1625000000000 }; + + await repository.addOrUpdateSystem(existingSystem); + await repository.addOrUpdateSystem(updatedSystem); + + const result = await repository.getSystems(); + expect(result).toEqual([updatedSystem]); + }); + }); + + describe("addOrUpdateRoute", () => { + test("adds a new route if nonexistent", async () => { + const newRoute = { id: "route1", name: "Route 1", color: "red", systemId: "sys1", polylineCoordinates: [] }; + + await repository.addOrUpdateRoute(newRoute); + + const result = await repository.getRoutesBySystemId("sys1"); + expect(result).toEqual([newRoute]); + }); + + test("updates an existing route if it exists", async () => { + const existingRoute = { id: "route1", name: "Route 1", color: "red", systemId: "sys1", polylineCoordinates: [] }; + const updatedRoute = { id: "route1", name: "Updated Route 1", color: "blue", systemId: "sys1", polylineCoordinates: [] }; + + await repository.addOrUpdateRoute(existingRoute); + await repository.addOrUpdateRoute(updatedRoute); + + const result = await repository.getRoutesBySystemId("sys1"); + expect(result).toEqual([updatedRoute]); + }); + }); + + describe("addOrUpdateShuttle", () => { + test("adds a new shuttle if nonexistent", async () => { + const newShuttle = { id: "shuttle1", name: "Shuttle A", coordinates: { latitude: 10, longitude: 20 }, routeId: "route1", systemId: "sys1" }; + + await repository.addOrUpdateShuttle(newShuttle); + + const result = await repository.getShuttlesBySystemId("sys1"); + expect(result).toEqual([newShuttle]); + }); + + test("updates an existing shuttle if it exists", async () => { + const existingShuttle = { id: "shuttle1", name: "Shuttle A", coordinates: { latitude: 10, longitude: 20 }, routeId: "route1", systemId: "sys1" }; + const updatedShuttle = { id: "shuttle1", name: "Updated Shuttle A", coordinates: { latitude: 30, longitude: 40 }, routeId: "route1", systemId: "sys1" }; + + await repository.addOrUpdateShuttle(existingShuttle); + await repository.addOrUpdateShuttle(updatedShuttle); + + const result = await repository.getShuttlesBySystemId("sys1"); + expect(result).toEqual([updatedShuttle]); + }); + }); + + describe("addOrUpdateStop", () => { + test("adds a new stop if nonexistent", async () => { + const newStop = { id: "stop1", name: "Stop A", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }; + + await repository.addOrUpdateStop(newStop); + + const result = await repository.getStopsBySystemId("sys1"); + expect(result).toEqual([newStop]); + }); + + test("updates an existing stop if it exists", async () => { + const existingStop = { id: "stop1", name: "Stop A", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }; + const updatedStop = { id: "stop1", name: "Updated Stop A", systemId: "sys1", coordinates: { latitude: 30, longitude: 40 } }; + + await repository.addOrUpdateStop(existingStop); + await repository.addOrUpdateStop(updatedStop); + + const result = await repository.getStopsBySystemId("sys1"); + expect(result).toEqual([updatedStop]); + }); + }); + + describe("addOrUpdateOrderedStop", () => { + test("adds a new ordered stop if nonexistent", async () => { + const newOrderedStop = { routeId: "route1", stopId: "stop1", position: 1 }; + + await repository.addOrUpdateOrderedStop(newOrderedStop); + + const result = await repository.getOrderedStopsByRouteId("route1"); + expect(result).toEqual([newOrderedStop]); + }); + + test("updates an existing ordered stop if it exists", async () => { + const existingOrderedStop = { routeId: "route1", stopId: "stop1", position: 1 }; + const updatedOrderedStop = { routeId: "route1", stopId: "stop1", position: 2 }; + + await repository.addOrUpdateOrderedStop(existingOrderedStop); + await repository.addOrUpdateOrderedStop(updatedOrderedStop); + + const result = await repository.getOrderedStopsByRouteId("route1"); + expect(result).toEqual([updatedOrderedStop]); + }); + }); + + describe("addOrUpdateEta", () => { + test("adds a new ETA if nonexistent", async () => { + const newEta = { shuttleId: "shuttle1", stopId: "stop1", secondsRemaining: 120 }; + + await repository.addOrUpdateEta(newEta); + + const result = await repository.getEtasForShuttleId("shuttle1"); + expect(result).toEqual([newEta]); + }); + + test("updates an existing ETA if it exists", async () => { + const existingEta = { shuttleId: "shuttle1", stopId: "stop1", secondsRemaining: 120 }; + const updatedEta = { shuttleId: "shuttle1", stopId: "stop1", secondsRemaining: 60 }; + + await repository.addOrUpdateEta(existingEta); + await repository.addOrUpdateEta(updatedEta); + + const result = await repository.getEtasForShuttleId("shuttle1"); + expect(result).toEqual([updatedEta]); + }); + }); + + describe("clearSystemData", () => { + + }); + + describe("clearShuttleData", () => { + + }); + + describe("clearEtaData", () => { + + }); + + describe("clearOrderedStopData", () => { + + }); + + describe("clearRouteData", () => { + + }); + + describe("clearStopData", () => { + + }); }); \ No newline at end of file From bfd4c40a10f60cf6f8a7b50f1984977f351337d2 Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Tue, 21 Jan 2025 15:01:21 -0800 Subject: [PATCH 05/12] add remaining tests for 100% test coverage --- ...UnoptimizedInMemoryRepositoryTests.test.ts | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts index 4a70771..a997b7c 100644 --- a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts +++ b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts @@ -444,26 +444,101 @@ describe("UnoptimizedInMemoryRepository", () => { }); describe("clearSystemData", () => { + test("clears all systems from the repository", async () => { + const system1 = { id: "sys1", name: "System A" }; + const system2 = { id: "sys2", name: "System B" }; + await repository.addOrUpdateSystem(system1); + await repository.addOrUpdateSystem(system2); + + await repository.clearSystemData(); + + const result = await repository.getSystems(); + expect(result).toEqual([]); + }); + + test("clears system data when the repository has data", async () => { + const system = { id: "sys1", name: "System A" }; + await repository.addOrUpdateSystem(system); + + await repository.clearSystemData(); + + const result = await repository.getSystems(); + expect(result).toEqual([]); + }); }); describe("clearShuttleData", () => { + test("clears all shuttles from the repository", async () => { + const shuttle1 = { id: "shuttle1", name: "Shuttle A", systemId: "sys1", routeId: "route1", coordinates: { latitude: 10, longitude: 20 } }; + const shuttle2 = { id: "shuttle2", name: "Shuttle B", systemId: "sys2", routeId: "route2", coordinates: { latitude: 15, longitude: 25 } }; + await repository.addOrUpdateShuttle(shuttle1); + await repository.addOrUpdateShuttle(shuttle2); + await repository.clearShuttleData(); + + const result = await repository.getShuttlesBySystemId("sys1"); + expect(result).toEqual([]); + }); }); describe("clearEtaData", () => { + test("clears all ETAs from the repository", async () => { + const eta1 = { shuttleId: "shuttle1", stopId: "stop1", secondsRemaining: 120 }; + const eta2 = { shuttleId: "shuttle2", stopId: "stop2", secondsRemaining: 150 }; + await repository.addOrUpdateEta(eta1); + await repository.addOrUpdateEta(eta2); + + await repository.clearEtaData(); + + const result = await repository.getEtasForShuttleId("shuttle1"); + expect(result).toEqual([]); + }); }); describe("clearOrderedStopData", () => { + test("clears all ordered stops from the repository", async () => { + const orderedStop1 = { routeId: "route1", stopId: "stop1", position: 1 }; + const orderedStop2 = { routeId: "route2", stopId: "stop2", position: 2 }; + await repository.addOrUpdateOrderedStop(orderedStop1); + await repository.addOrUpdateOrderedStop(orderedStop2); + + await repository.clearOrderedStopData(); + + const result = await repository.getOrderedStopsByRouteId("route1"); + expect(result).toEqual([]); + }); }); describe("clearRouteData", () => { + test("clears all routes from the repository", async () => { + const route1 = { id: "route1", name: "Route 1", systemId: "sys1", color: "#ffffff", polylineCoordinates: [] }; + const route2 = { id: "route2", name: "Route 2", systemId: "sys2", color: "#ffffff", polylineCoordinates: [] }; + await repository.addOrUpdateRoute(route1); + await repository.addOrUpdateRoute(route2); + + await repository.clearRouteData(); + + const result = await repository.getRoutesBySystemId("sys1"); + expect(result).toEqual([]); + }); }); describe("clearStopData", () => { + test("clears all stops from the repository", async () => { + const stop1 = { id: "stop1", name: "Stop A", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }; + const stop2 = { id: "stop2", name: "Stop B", systemId: "sys2", coordinates: { latitude: 10, longitude: 20 } }; + await repository.addOrUpdateStop(stop1); + await repository.addOrUpdateStop(stop2); + + await repository.clearStopData(); + + const result = await repository.getStopsBySystemId("sys1"); + expect(result).toEqual([]); + }); }); }); \ No newline at end of file From 05b3538a91d601a6ec8f0ee921f5487e6d4037ae Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Tue, 21 Jan 2025 15:12:53 -0800 Subject: [PATCH 06/12] add and use generator method for system objects --- test/generators.ts | 10 ++++++ ...UnoptimizedInMemoryRepositoryTests.test.ts | 34 +++++++++---------- 2 files changed, 26 insertions(+), 18 deletions(-) create mode 100644 test/generators.ts diff --git a/test/generators.ts b/test/generators.ts new file mode 100644 index 0000000..964c0e7 --- /dev/null +++ b/test/generators.ts @@ -0,0 +1,10 @@ +import { ISystem } from "../src/entities/entities"; + + +export function generateMockSystems(): ISystem[] { + return [ + { id: "1", name: "System A" }, + { id: "2", name: "System B" }, + { id: "3", name: "System C" }, + ]; +} \ No newline at end of file diff --git a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts index a997b7c..972c2d6 100644 --- a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts +++ b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts @@ -1,5 +1,7 @@ import { beforeEach, describe, expect, test } from "@jest/globals"; import { UnoptimizedInMemoryRepository } from "../../src/repositories/UnoptimizedInMemoryRepository"; +import { generateMockSystems } from "../generators"; +import { mock } from "node:test"; // For repositories created in the future, reuse core testing // logic from here and differentiate setup (e.g. creating mocks) @@ -18,10 +20,7 @@ describe("UnoptimizedInMemoryRepository", () => { describe("getSystems", () => { test("gets the systems stored in the repository", async () => { - const mockSystems = [ - { id: "1", name: "System A" }, - { id: "2", name: "System B" }, - ]; + const mockSystems = generateMockSystems(); await repository.addOrUpdateSystem(mockSystems[0]); await repository.addOrUpdateSystem(mockSystems[1]); @@ -39,11 +38,7 @@ describe("UnoptimizedInMemoryRepository", () => { describe("getSystemById", () => { test("gets a system by the ID if it exists", async () => { - const mockSystems = [ - { id: "1", name: "System A" }, - { id: "2", name: "System B" }, - { id: "3", name: "System C" }, - ]; + const mockSystems = generateMockSystems(); for (const system of mockSystems) { await repository.addOrUpdateSystem(system); } @@ -313,7 +308,8 @@ describe("UnoptimizedInMemoryRepository", () => { describe("addOrUpdateSystem", () => { test("adds a new system if nonexistent", async () => { - const newSystem = { id: "sys1", name: "System A", millisecondsSinceEpoch: 1620000000000 }; + const mockSystems = generateMockSystems(); + const newSystem = mockSystems[0]; await repository.addOrUpdateSystem(newSystem); @@ -322,8 +318,10 @@ describe("UnoptimizedInMemoryRepository", () => { }); test("updates an existing system if it exists", async () => { - const existingSystem = { id: "sys1", name: "System A", millisecondsSinceEpoch: 1620000000000 }; - const updatedSystem = { id: "sys1", name: "Updated System A", millisecondsSinceEpoch: 1625000000000 }; + const mockSystems = generateMockSystems(); + const existingSystem = mockSystems[0]; + const updatedSystem = structuredClone(existingSystem); + updatedSystem.name = "Updated System"; await repository.addOrUpdateSystem(existingSystem); await repository.addOrUpdateSystem(updatedSystem); @@ -445,11 +443,10 @@ describe("UnoptimizedInMemoryRepository", () => { describe("clearSystemData", () => { test("clears all systems from the repository", async () => { - const system1 = { id: "sys1", name: "System A" }; - const system2 = { id: "sys2", name: "System B" }; - - await repository.addOrUpdateSystem(system1); - await repository.addOrUpdateSystem(system2); + const mockSystems = generateMockSystems(); + for (const system of mockSystems) { + await repository.addOrUpdateSystem(system); + } await repository.clearSystemData(); @@ -458,7 +455,8 @@ describe("UnoptimizedInMemoryRepository", () => { }); test("clears system data when the repository has data", async () => { - const system = { id: "sys1", name: "System A" }; + const mockSystems = generateMockSystems(); + const system = mockSystems[0]; await repository.addOrUpdateSystem(system); await repository.clearSystemData(); From f71e5894933e3c20debd423c1046bd44360766d9 Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Tue, 21 Jan 2025 15:14:20 -0800 Subject: [PATCH 07/12] fix test with generator method --- test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts index 972c2d6..8035d50 100644 --- a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts +++ b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts @@ -21,8 +21,9 @@ describe("UnoptimizedInMemoryRepository", () => { describe("getSystems", () => { test("gets the systems stored in the repository", async () => { const mockSystems = generateMockSystems(); - await repository.addOrUpdateSystem(mockSystems[0]); - await repository.addOrUpdateSystem(mockSystems[1]); + for (const system of mockSystems) { + await repository.addOrUpdateSystem(system); + } const result = await repository.getSystems(); From 02ebeb478277a02435619ab61de86f8070d57c79 Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Tue, 21 Jan 2025 15:19:06 -0800 Subject: [PATCH 08/12] use generator method for shuttles --- test/generators.ts | 10 ++++- ...UnoptimizedInMemoryRepositoryTests.test.ts | 39 +++++++------------ 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/test/generators.ts b/test/generators.ts index 964c0e7..9d323b1 100644 --- a/test/generators.ts +++ b/test/generators.ts @@ -1,4 +1,4 @@ -import { ISystem } from "../src/entities/entities"; +import { IShuttle, ISystem } from "../src/entities/entities"; export function generateMockSystems(): ISystem[] { @@ -7,4 +7,12 @@ export function generateMockSystems(): ISystem[] { { id: "2", name: "System B" }, { id: "3", name: "System C" }, ]; +} + +export function generateMockShuttles(): IShuttle[] { + return [ + { id: "sh1", name: "Shuttle A", routeId: "r1", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }, + { id: "sh2", name: "Shuttle B", routeId: "r2", systemId: "sys2", coordinates: { latitude: 15, longitude: 25 } }, + { id: "sh3", name: "Shuttle C", routeId: "r3", systemId: "sys3", coordinates: { latitude: 30, longitude: 40 } }, + ]; } \ No newline at end of file diff --git a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts index 8035d50..0cb20d8 100644 --- a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts +++ b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts @@ -1,7 +1,6 @@ import { beforeEach, describe, expect, test } from "@jest/globals"; import { UnoptimizedInMemoryRepository } from "../../src/repositories/UnoptimizedInMemoryRepository"; -import { generateMockSystems } from "../generators"; -import { mock } from "node:test"; +import { generateMockShuttles, generateMockSystems } from "../generators"; // For repositories created in the future, reuse core testing // logic from here and differentiate setup (e.g. creating mocks) @@ -129,11 +128,7 @@ describe("UnoptimizedInMemoryRepository", () => { }); describe("getShuttlesBySystemId", () => { test("gets all shuttles for a specific system ID", async () => { - const mockShuttles = [ - { id: "sh1", name: "Shuttle A", routeId: "r1", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }, - { id: "sh2", name: "Shuttle B", routeId: "r2", systemId: "sys1", coordinates: { latitude: 15, longitude: 25 } }, - { id: "sh3", name: "Shuttle C", routeId: "r3", systemId: "sys2", coordinates: { latitude: 30, longitude: 40 } }, - ]; + const mockShuttles = generateMockShuttles(); for (const shuttle of mockShuttles) { await repository.addOrUpdateShuttle(shuttle); } @@ -150,11 +145,7 @@ describe("UnoptimizedInMemoryRepository", () => { describe("getShuttlesByRouteId", () => { test("gets all shuttles for a specific route ID", async () => { - const mockShuttles = [ - { id: "sh1", name: "Shuttle A", routeId: "r1", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }, - { id: "sh2", name: "Shuttle B", routeId: "r1", systemId: "sys1", coordinates: { latitude: 15, longitude: 25 } }, - { id: "sh3", name: "Shuttle C", routeId: "r2", systemId: "sys2", coordinates: { latitude: 30, longitude: 40 } }, - ]; + const mockShuttles = generateMockShuttles(); for (const shuttle of mockShuttles) { await repository.addOrUpdateShuttle(shuttle); } @@ -171,15 +162,12 @@ describe("UnoptimizedInMemoryRepository", () => { describe("getShuttleById", () => { test("gets a shuttle by ID if it exists", async () => { - const mockShuttles = [ - { id: "1", name: "Shuttle A", routeId: "r1", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }, - { id: "2", name: "Shuttle B", routeId: "r2", systemId: "sys1", coordinates: { latitude: 15, longitude: 25 } }, - ]; + const mockShuttles = generateMockShuttles(); for (const shuttle of mockShuttles) { await repository.addOrUpdateShuttle(shuttle); } - const result = await repository.getShuttleById("2"); + const result = await repository.getShuttleById("sh2"); expect(result).toEqual(mockShuttles[1]); }); @@ -356,7 +344,8 @@ describe("UnoptimizedInMemoryRepository", () => { describe("addOrUpdateShuttle", () => { test("adds a new shuttle if nonexistent", async () => { - const newShuttle = { id: "shuttle1", name: "Shuttle A", coordinates: { latitude: 10, longitude: 20 }, routeId: "route1", systemId: "sys1" }; + const mockShuttles = generateMockShuttles(); + const newShuttle = mockShuttles[0]; await repository.addOrUpdateShuttle(newShuttle); @@ -365,8 +354,10 @@ describe("UnoptimizedInMemoryRepository", () => { }); test("updates an existing shuttle if it exists", async () => { - const existingShuttle = { id: "shuttle1", name: "Shuttle A", coordinates: { latitude: 10, longitude: 20 }, routeId: "route1", systemId: "sys1" }; - const updatedShuttle = { id: "shuttle1", name: "Updated Shuttle A", coordinates: { latitude: 30, longitude: 40 }, routeId: "route1", systemId: "sys1" }; + const mockShuttles = generateMockShuttles(); + const existingShuttle = mockShuttles[0]; + const updatedShuttle = structuredClone(existingShuttle); + updatedShuttle.name = "Updated Shuttle"; await repository.addOrUpdateShuttle(existingShuttle); await repository.addOrUpdateShuttle(updatedShuttle); @@ -469,10 +460,10 @@ describe("UnoptimizedInMemoryRepository", () => { describe("clearShuttleData", () => { test("clears all shuttles from the repository", async () => { - const shuttle1 = { id: "shuttle1", name: "Shuttle A", systemId: "sys1", routeId: "route1", coordinates: { latitude: 10, longitude: 20 } }; - const shuttle2 = { id: "shuttle2", name: "Shuttle B", systemId: "sys2", routeId: "route2", coordinates: { latitude: 15, longitude: 25 } }; - await repository.addOrUpdateShuttle(shuttle1); - await repository.addOrUpdateShuttle(shuttle2); + const mockShuttles = generateMockShuttles(); + for (const shuttle of mockShuttles) { + await repository.addOrUpdateShuttle(shuttle); + } await repository.clearShuttleData(); From dd2fde30b9cd5f5984ed82a7be27d4582bef6c7e Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Tue, 21 Jan 2025 15:22:56 -0800 Subject: [PATCH 09/12] do the same for mock routes --- test/generators.ts | 12 +++++++- ...UnoptimizedInMemoryRepositoryTests.test.ts | 29 +++++++++---------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/test/generators.ts b/test/generators.ts index 9d323b1..fb80ae3 100644 --- a/test/generators.ts +++ b/test/generators.ts @@ -1,5 +1,7 @@ -import { IShuttle, ISystem } from "../src/entities/entities"; +import { IRoute, IShuttle, ISystem } from "../src/entities/entities"; +// Use a single set of generators in case any of the +// interfaces change in the future export function generateMockSystems(): ISystem[] { return [ @@ -15,4 +17,12 @@ export function generateMockShuttles(): IShuttle[] { { id: "sh2", name: "Shuttle B", routeId: "r2", systemId: "sys2", coordinates: { latitude: 15, longitude: 25 } }, { id: "sh3", name: "Shuttle C", routeId: "r3", systemId: "sys3", coordinates: { latitude: 30, longitude: 40 } }, ]; +} + +export function generateMockRoutes(): IRoute[] { + return [ + { id: "r1", name: "Route 1", color: "red", systemId: "sys1", polylineCoordinates: [] }, + { id: "r2", name: "Route 2", color: "blue", systemId: "sys2", polylineCoordinates: [] }, + { id: "r3", name: "Route 3", color: "green", systemId: "sys3", polylineCoordinates: [] }, + ]; } \ No newline at end of file diff --git a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts index 0cb20d8..3da1e9f 100644 --- a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts +++ b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts @@ -1,6 +1,6 @@ import { beforeEach, describe, expect, test } from "@jest/globals"; import { UnoptimizedInMemoryRepository } from "../../src/repositories/UnoptimizedInMemoryRepository"; -import { generateMockShuttles, generateMockSystems } from "../generators"; +import { generateMockRoutes, generateMockShuttles, generateMockSystems } from "../generators"; // For repositories created in the future, reuse core testing // logic from here and differentiate setup (e.g. creating mocks) @@ -93,11 +93,7 @@ describe("UnoptimizedInMemoryRepository", () => { describe("getRoutesBySystemId", () => { test("gets all routes for a specific system ID", async () => { - const mockRoutes = [ - { id: "r1", name: "Route 1", color: "red", systemId: "sys1", polylineCoordinates: [] }, - { id: "r2", name: "Route 2", color: "blue", systemId: "sys1", polylineCoordinates: [] }, - { id: "r3", name: "Route 3", color: "green", systemId: "sys2", polylineCoordinates: [] }, - ]; + const mockRoutes = generateMockRoutes(); for (const route of mockRoutes) { await repository.addOrUpdateRoute(route); } @@ -114,7 +110,8 @@ describe("UnoptimizedInMemoryRepository", () => { describe("getRouteById", () => { test("gets a route by ID if it exists", async () => { - const mockRoute = { id: "r1", name: "Route 1", color: "red", systemId: "sys1", polylineCoordinates: [] }; + const mockRoutes = generateMockRoutes(); + const mockRoute = mockRoutes[0]; await repository.addOrUpdateRoute(mockRoute); const result = await repository.getRouteById("r1"); @@ -322,7 +319,8 @@ describe("UnoptimizedInMemoryRepository", () => { describe("addOrUpdateRoute", () => { test("adds a new route if nonexistent", async () => { - const newRoute = { id: "route1", name: "Route 1", color: "red", systemId: "sys1", polylineCoordinates: [] }; + const mockRoutes = generateMockRoutes(); + const newRoute = mockRoutes[0]; await repository.addOrUpdateRoute(newRoute); @@ -331,8 +329,10 @@ describe("UnoptimizedInMemoryRepository", () => { }); test("updates an existing route if it exists", async () => { - const existingRoute = { id: "route1", name: "Route 1", color: "red", systemId: "sys1", polylineCoordinates: [] }; - const updatedRoute = { id: "route1", name: "Updated Route 1", color: "blue", systemId: "sys1", polylineCoordinates: [] }; + const mockRoutes = generateMockRoutes(); + const existingRoute = mockRoutes[0]; + const updatedRoute = structuredClone(existingRoute); + updatedRoute.name = "Updated Route"; await repository.addOrUpdateRoute(existingRoute); await repository.addOrUpdateRoute(updatedRoute); @@ -504,11 +504,10 @@ describe("UnoptimizedInMemoryRepository", () => { describe("clearRouteData", () => { test("clears all routes from the repository", async () => { - const route1 = { id: "route1", name: "Route 1", systemId: "sys1", color: "#ffffff", polylineCoordinates: [] }; - const route2 = { id: "route2", name: "Route 2", systemId: "sys2", color: "#ffffff", polylineCoordinates: [] }; - - await repository.addOrUpdateRoute(route1); - await repository.addOrUpdateRoute(route2); + const mockRoutes = generateMockRoutes(); + for (const route of mockRoutes) { + await repository.addOrUpdateRoute(route); + } await repository.clearRouteData(); From 7b3f7e5960a23eca4956d8ff2d3026eb5148c49b Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Tue, 21 Jan 2025 15:25:47 -0800 Subject: [PATCH 10/12] do the same with mock stops --- test/generators.ts | 10 ++++++- ...UnoptimizedInMemoryRepositoryTests.test.ts | 29 +++++++++---------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/test/generators.ts b/test/generators.ts index fb80ae3..dffaf3b 100644 --- a/test/generators.ts +++ b/test/generators.ts @@ -1,4 +1,4 @@ -import { IRoute, IShuttle, ISystem } from "../src/entities/entities"; +import { IRoute, IShuttle, IStop, ISystem } from "../src/entities/entities"; // Use a single set of generators in case any of the // interfaces change in the future @@ -25,4 +25,12 @@ export function generateMockRoutes(): IRoute[] { { id: "r2", name: "Route 2", color: "blue", systemId: "sys2", polylineCoordinates: [] }, { id: "r3", name: "Route 3", color: "green", systemId: "sys3", polylineCoordinates: [] }, ]; +} + +export function generateMockStops(): IStop[] { + return [ + { id: "st1", name: "Stop A", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }, + { id: "st2", name: "Stop B", systemId: "sys2", coordinates: { latitude: 15, longitude: 25 } }, + { id: "st3", name: "Stop C", systemId: "sys3", coordinates: { latitude: 30, longitude: 40 } }, + ]; } \ No newline at end of file diff --git a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts index 3da1e9f..eff0fbd 100644 --- a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts +++ b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts @@ -1,6 +1,6 @@ import { beforeEach, describe, expect, test } from "@jest/globals"; import { UnoptimizedInMemoryRepository } from "../../src/repositories/UnoptimizedInMemoryRepository"; -import { generateMockRoutes, generateMockShuttles, generateMockSystems } from "../generators"; +import { generateMockRoutes, generateMockShuttles, generateMockStops, generateMockSystems } from "../generators"; // For repositories created in the future, reuse core testing // logic from here and differentiate setup (e.g. creating mocks) @@ -57,11 +57,7 @@ describe("UnoptimizedInMemoryRepository", () => { describe("getStopsBySystemId", () => { test("gets stops by system ID", async () => { - const mockStops = [ - { id: "1", name: "Stop A", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }, - { id: "2", name: "Stop B", systemId: "sys1", coordinates: { latitude: 15, longitude: 25 } }, - { id: "3", name: "Stop C", systemId: "sys2", coordinates: { latitude: 30, longitude: 40 } }, - ]; + const mockStops = generateMockStops(); for (const stop of mockStops) { await repository.addOrUpdateStop(stop); } @@ -78,7 +74,8 @@ describe("UnoptimizedInMemoryRepository", () => { describe("getStopById", () => { test("gets a stop by ID if it exists", async () => { - const mockStop = { id: "st1", name: "Stop A", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }; + const mockStops = generateMockStops(); + const mockStop = mockStops[0]; await repository.addOrUpdateStop(mockStop); const result = await repository.getStopById("st1"); @@ -369,7 +366,8 @@ describe("UnoptimizedInMemoryRepository", () => { describe("addOrUpdateStop", () => { test("adds a new stop if nonexistent", async () => { - const newStop = { id: "stop1", name: "Stop A", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }; + const mockStops = generateMockStops(); + const newStop = mockStops[0]; await repository.addOrUpdateStop(newStop); @@ -378,8 +376,10 @@ describe("UnoptimizedInMemoryRepository", () => { }); test("updates an existing stop if it exists", async () => { - const existingStop = { id: "stop1", name: "Stop A", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }; - const updatedStop = { id: "stop1", name: "Updated Stop A", systemId: "sys1", coordinates: { latitude: 30, longitude: 40 } }; + const mockStops = generateMockStops(); + const existingStop = mockStops[0]; + const updatedStop = structuredClone(existingStop); + updatedStop.name = "Updated Stop"; await repository.addOrUpdateStop(existingStop); await repository.addOrUpdateStop(updatedStop); @@ -518,11 +518,10 @@ describe("UnoptimizedInMemoryRepository", () => { describe("clearStopData", () => { test("clears all stops from the repository", async () => { - const stop1 = { id: "stop1", name: "Stop A", systemId: "sys1", coordinates: { latitude: 10, longitude: 20 } }; - const stop2 = { id: "stop2", name: "Stop B", systemId: "sys2", coordinates: { latitude: 10, longitude: 20 } }; - - await repository.addOrUpdateStop(stop1); - await repository.addOrUpdateStop(stop2); + const mockStops = generateMockStops(); + for (const stop of mockStops) { + await repository.addOrUpdateStop(stop); + } await repository.clearStopData(); From d617d22b6db4040021865bf005907c3abef888e8 Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Tue, 21 Jan 2025 15:34:05 -0800 Subject: [PATCH 11/12] do the same for ordered stops --- test/generators.ts | 11 +++- ...UnoptimizedInMemoryRepositoryTests.test.ts | 60 +++++++++---------- 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/test/generators.ts b/test/generators.ts index dffaf3b..6efcef7 100644 --- a/test/generators.ts +++ b/test/generators.ts @@ -1,4 +1,4 @@ -import { IRoute, IShuttle, IStop, ISystem } from "../src/entities/entities"; +import { IOrderedStop, IRoute, IShuttle, IStop, ISystem } from "../src/entities/entities"; // Use a single set of generators in case any of the // interfaces change in the future @@ -33,4 +33,13 @@ export function generateMockStops(): IStop[] { { id: "st2", name: "Stop B", systemId: "sys2", coordinates: { latitude: 15, longitude: 25 } }, { id: "st3", name: "Stop C", systemId: "sys3", coordinates: { latitude: 30, longitude: 40 } }, ]; +} + +export function generateMockOrderedStops(): IOrderedStop[] { + return [ + { stopId: "st1", routeId: "r1", position: 1 }, + { stopId: "st1", routeId: "r2", position: 2 }, + { stopId: "st2", routeId: "r1", position: 3 }, + { stopId: "st2", routeId: "r2", position: 4 }, + ]; } \ No newline at end of file diff --git a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts index eff0fbd..58e1e7d 100644 --- a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts +++ b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts @@ -1,15 +1,18 @@ import { beforeEach, describe, expect, test } from "@jest/globals"; import { UnoptimizedInMemoryRepository } from "../../src/repositories/UnoptimizedInMemoryRepository"; -import { generateMockRoutes, generateMockShuttles, generateMockStops, generateMockSystems } from "../generators"; +import { + generateMockOrderedStops, + generateMockRoutes, + generateMockShuttles, + generateMockStops, + generateMockSystems +} from "../generators"; // For repositories created in the future, reuse core testing // logic from here and differentiate setup (e.g. creating mocks) // Do this by creating a function which takes a GetterRepository // or GetterSetterRepository instance -// Full disclosure: most of this was generated by ChatGPT -// https://chatgpt.com/share/67902072-3adc-800d-bd22-06f7b3e6f4a4 - describe("UnoptimizedInMemoryRepository", () => { let repository: UnoptimizedInMemoryRepository; @@ -230,14 +233,15 @@ describe("UnoptimizedInMemoryRepository", () => { describe("getOrderedStopByRouteAndStopId", () => { test("gets an ordered stop by route ID and stop ID", async () => { - const mockOrderedStop = { - routeId: "r1", - stopId: "st1", - position: 1, - }; - await repository.addOrUpdateOrderedStop(mockOrderedStop); + const mockOrderedStops = generateMockOrderedStops(); + for (const orderedStop of mockOrderedStops) { + await repository.addOrUpdateOrderedStop(orderedStop); + } - const result = await repository.getOrderedStopByRouteAndStopId("r1", "st1"); + const mockOrderedStop = mockOrderedStops[0]; + const { routeId, stopId } = mockOrderedStop; + + const result = await repository.getOrderedStopByRouteAndStopId(routeId, stopId); expect(result).toEqual(mockOrderedStop); }); @@ -249,11 +253,7 @@ describe("UnoptimizedInMemoryRepository", () => { describe("getOrderedStopsByStopId", () => { test("gets all ordered stops for a specific stop ID", async () => { - const mockOrderedStops = [ - { stopId: "st1", routeId: "r1", position: 1 }, - { stopId: "st1", routeId: "r2", position: 2 }, - { stopId: "st2", routeId: "r3", position: 3 }, - ]; + const mockOrderedStops = generateMockOrderedStops(); for (const orderedStop of mockOrderedStops) { await repository.addOrUpdateOrderedStop(orderedStop); } @@ -270,11 +270,7 @@ describe("UnoptimizedInMemoryRepository", () => { describe("getOrderedStopsByRouteId", () => { test("gets all ordered stops for a specific route ID", async () => { - const mockOrderedStops = [ - { stopId: "st1", routeId: "r1", position: 1 }, - { stopId: "st2", routeId: "r1", position: 2 }, - { stopId: "st3", routeId: "r2", position: 3 }, - ]; + const mockOrderedStops = generateMockOrderedStops(); for (const orderedStop of mockOrderedStops) { await repository.addOrUpdateOrderedStop(orderedStop); } @@ -391,22 +387,25 @@ describe("UnoptimizedInMemoryRepository", () => { describe("addOrUpdateOrderedStop", () => { test("adds a new ordered stop if nonexistent", async () => { - const newOrderedStop = { routeId: "route1", stopId: "stop1", position: 1 }; + const mockOrderedStops = generateMockOrderedStops(); + const newOrderedStop = mockOrderedStops[0]; await repository.addOrUpdateOrderedStop(newOrderedStop); - const result = await repository.getOrderedStopsByRouteId("route1"); + const result = await repository.getOrderedStopsByRouteId(newOrderedStop.routeId); expect(result).toEqual([newOrderedStop]); }); test("updates an existing ordered stop if it exists", async () => { - const existingOrderedStop = { routeId: "route1", stopId: "stop1", position: 1 }; - const updatedOrderedStop = { routeId: "route1", stopId: "stop1", position: 2 }; + const mockOrderedStops = generateMockOrderedStops(); + const existingOrderedStop = mockOrderedStops[0]; + const updatedOrderedStop = structuredClone(existingOrderedStop); + updatedOrderedStop.position = 5; await repository.addOrUpdateOrderedStop(existingOrderedStop); await repository.addOrUpdateOrderedStop(updatedOrderedStop); - const result = await repository.getOrderedStopsByRouteId("route1"); + const result = await repository.getOrderedStopsByRouteId(existingOrderedStop.routeId); expect(result).toEqual([updatedOrderedStop]); }); }); @@ -489,11 +488,10 @@ describe("UnoptimizedInMemoryRepository", () => { describe("clearOrderedStopData", () => { test("clears all ordered stops from the repository", async () => { - const orderedStop1 = { routeId: "route1", stopId: "stop1", position: 1 }; - const orderedStop2 = { routeId: "route2", stopId: "stop2", position: 2 }; - - await repository.addOrUpdateOrderedStop(orderedStop1); - await repository.addOrUpdateOrderedStop(orderedStop2); + const mockOrderedStops = await generateMockOrderedStops(); + for (const system of mockOrderedStops) { + await repository.addOrUpdateOrderedStop(system); + } await repository.clearOrderedStopData(); From 82a69ca46483ffe7b5c31ea11d21a1f2032abbdf Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Tue, 21 Jan 2025 15:37:28 -0800 Subject: [PATCH 12/12] do the same with eta data --- test/generators.ts | 10 ++++- ...UnoptimizedInMemoryRepositoryTests.test.ts | 38 +++++++++---------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/test/generators.ts b/test/generators.ts index 6efcef7..eac524a 100644 --- a/test/generators.ts +++ b/test/generators.ts @@ -1,4 +1,4 @@ -import { IOrderedStop, IRoute, IShuttle, IStop, ISystem } from "../src/entities/entities"; +import { IEta, IOrderedStop, IRoute, IShuttle, IStop, ISystem } from "../src/entities/entities"; // Use a single set of generators in case any of the // interfaces change in the future @@ -42,4 +42,12 @@ export function generateMockOrderedStops(): IOrderedStop[] { { stopId: "st2", routeId: "r1", position: 3 }, { stopId: "st2", routeId: "r2", position: 4 }, ]; +} + +export function generateMockEtas(): IEta[] { + return [ + { shuttleId: "sh1", stopId: "st1", secondsRemaining: 120 }, + { shuttleId: "sh1", stopId: "st2", secondsRemaining: 180 }, + { shuttleId: "sh2", stopId: "st3", secondsRemaining: 240 }, + ]; } \ No newline at end of file diff --git a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts index 58e1e7d..e9e8166 100644 --- a/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts +++ b/test/repositories/UnoptimizedInMemoryRepositoryTests.test.ts @@ -1,6 +1,7 @@ import { beforeEach, describe, expect, test } from "@jest/globals"; import { UnoptimizedInMemoryRepository } from "../../src/repositories/UnoptimizedInMemoryRepository"; import { + generateMockEtas, generateMockOrderedStops, generateMockRoutes, generateMockShuttles, @@ -176,11 +177,7 @@ describe("UnoptimizedInMemoryRepository", () => { describe("getEtasForShuttleId", () => { test("gets ETAs for a specific shuttle ID", async () => { - const mockEtas = [ - { shuttleId: "sh1", stopId: "st1", secondsRemaining: 120 }, - { shuttleId: "sh1", stopId: "st2", secondsRemaining: 180 }, - { shuttleId: "sh2", stopId: "st3", secondsRemaining: 240 }, - ]; + const mockEtas = generateMockEtas(); for (const eta of mockEtas) { await repository.addOrUpdateEta(eta); } @@ -197,11 +194,7 @@ describe("UnoptimizedInMemoryRepository", () => { describe("getEtasForStopId", () => { test("gets ETAs for a specific stop ID", async () => { - const mockEtas = [ - { shuttleId: "s1", stopId: "st1", secondsRemaining: 120 }, - { shuttleId: "s2", stopId: "st1", secondsRemaining: 180 }, - { shuttleId: "s3", stopId: "st2", secondsRemaining: 240 }, - ]; + const mockEtas = generateMockEtas(); for (const eta of mockEtas) { await repository.addOrUpdateEta(eta); } @@ -218,7 +211,8 @@ describe("UnoptimizedInMemoryRepository", () => { describe("getEtaForShuttleAndStopId", () => { test("gets a single ETA for a specific shuttle and stop ID", async () => { - const mockEta = { shuttleId: "sh1", stopId: "st1", secondsRemaining: 120 }; + const mockEtas = generateMockEtas(); + const mockEta = mockEtas[0]; await repository.addOrUpdateEta(mockEta); const result = await repository.getEtaForShuttleAndStopId("sh1", "st1"); @@ -412,22 +406,25 @@ describe("UnoptimizedInMemoryRepository", () => { describe("addOrUpdateEta", () => { test("adds a new ETA if nonexistent", async () => { - const newEta = { shuttleId: "shuttle1", stopId: "stop1", secondsRemaining: 120 }; + const mockEtas = generateMockEtas(); + const newEta = mockEtas[0]; await repository.addOrUpdateEta(newEta); - const result = await repository.getEtasForShuttleId("shuttle1"); + const result = await repository.getEtasForShuttleId(newEta.shuttleId); expect(result).toEqual([newEta]); }); test("updates an existing ETA if it exists", async () => { - const existingEta = { shuttleId: "shuttle1", stopId: "stop1", secondsRemaining: 120 }; - const updatedEta = { shuttleId: "shuttle1", stopId: "stop1", secondsRemaining: 60 }; + const mockEtas = generateMockEtas(); + const existingEta = mockEtas[0]; + const updatedEta = structuredClone(existingEta); + updatedEta.secondsRemaining = existingEta.secondsRemaining + 60; await repository.addOrUpdateEta(existingEta); await repository.addOrUpdateEta(updatedEta); - const result = await repository.getEtasForShuttleId("shuttle1"); + const result = await repository.getEtasForShuttleId(existingEta.shuttleId); expect(result).toEqual([updatedEta]); }); }); @@ -473,11 +470,10 @@ describe("UnoptimizedInMemoryRepository", () => { describe("clearEtaData", () => { test("clears all ETAs from the repository", async () => { - const eta1 = { shuttleId: "shuttle1", stopId: "stop1", secondsRemaining: 120 }; - const eta2 = { shuttleId: "shuttle2", stopId: "stop2", secondsRemaining: 150 }; - - await repository.addOrUpdateEta(eta1); - await repository.addOrUpdateEta(eta2); + const mockEtas = generateMockEtas(); + for (const eta of mockEtas) { + await repository.addOrUpdateEta(eta); + } await repository.clearEtaData();