From 5ad2242850191fc9860cd854e7ef1b1223681b71 Mon Sep 17 00:00:00 2001 From: Kvnstrck Date: Fri, 14 Feb 2025 15:26:02 +0100 Subject: [PATCH 1/2] feat: introduce new compareItinerary method for excluding attributes --- visual-debugger/package.json | 1 + .../src/data-processing/compareObjects.ts | 57 +++++++++++++++++++ .../src/data-processing/comparePlans.ts | 14 ++--- .../src/data-processing/planParsing.ts | 1 + .../type-declarations/planTypes.ts | 3 + 5 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 visual-debugger/src/data-processing/compareObjects.ts diff --git a/visual-debugger/package.json b/visual-debugger/package.json index c61edae9d..d57cc074e 100644 --- a/visual-debugger/package.json +++ b/visual-debugger/package.json @@ -21,6 +21,7 @@ "axios": "^1.7.9", "bits-ui": "^0.22.0", "clsx": "^2.1.1", + "deep-equal": "^2.2.3", "lucide-svelte": "^0.469.0", "svelte": "^5.0.0", "svelte-check": "^4.0.0", diff --git a/visual-debugger/src/data-processing/compareObjects.ts b/visual-debugger/src/data-processing/compareObjects.ts new file mode 100644 index 000000000..6d36e61e1 --- /dev/null +++ b/visual-debugger/src/data-processing/compareObjects.ts @@ -0,0 +1,57 @@ +import {Itinerary, Leg} from "@data/type-declarations/planTypes.ts"; +// @ts-ignore +import deepEqual from "deep-equal"; + + +export function compareItineraries(currentItinerary: Itinerary, currentDefaultItinerary: Itinerary): boolean { + // First, check if the number of keys are the same + const keys1 = Object.keys(currentItinerary) as (keyof Itinerary)[]; + + + // Compare the values of each key in both objects + return keys1.every((key) => { + + if (key == "legs") { + let result = true; + for (let i = 0; i < currentItinerary.legs.length; i++) { + if (compareLegs(currentItinerary.legs[i], currentDefaultItinerary.legs[i]).length != 0) { + result = false; + } + } + return result; + } + + return deepEqual(currentItinerary[key], currentDefaultItinerary[key]); + }); +} + +/** + * Compares the parameters and puts the mismatched attributes in a list + * @returns an array with the mismatched attributes of the function parameters + * @param currentLeg + * @param currentDefaultLeg + */ +function compareLegs(currentLeg: Leg, currentDefaultLeg: Leg): string[] { + + let mismatchedAttributes: string[] = [] + + const keys1 = Object.keys(currentLeg) as (keyof Leg)[]; + + keys1.every((key) => { + switch (key) { + case "source": + return true + case "tripId": + return true + default: { + if (!deepEqual(currentLeg[key], currentDefaultLeg[key])) { + mismatchedAttributes.push(key); + return true + } + return true + } + } + }); + + return mismatchedAttributes +} \ No newline at end of file diff --git a/visual-debugger/src/data-processing/comparePlans.ts b/visual-debugger/src/data-processing/comparePlans.ts index 4f6723f23..977debc90 100644 --- a/visual-debugger/src/data-processing/comparePlans.ts +++ b/visual-debugger/src/data-processing/comparePlans.ts @@ -1,4 +1,4 @@ -import type {Plan} from "./type-declarations/planTypes.ts"; +import {type Plan} from "./type-declarations/planTypes.ts"; import { currentDefaultPlanStore, currentPlanStore, @@ -7,6 +7,7 @@ import { } from "sveltestore"; import {cssClasses} from "./styling/cssClasses.ts"; import {resetCssClassesForPlanEntries} from "./planParsing.ts"; +import {compareItineraries} from "@data/compareObjects.ts"; /** * Compares the computed results of the queries with the uploaded default plan and sets colors of the matches/mismatches @@ -54,16 +55,15 @@ export function comparePlans() { let currentDefaultItinerary = currentDefaultPlan.itineraries[itineraryIndex]; // compare strings of itineraries and set colors(CSS-Classes) accordingly - if (JSON.stringify(currentItinerary) == JSON.stringify(currentDefaultItinerary)) { + if (compareItineraries(currentItinerary, currentDefaultItinerary)) { // itineraries are equal, mark them as such - plans[planIndex].itineraries[itineraryIndex].cssClass = cssClasses.planEntryValid - defaultPlans[planIndex].itineraries[itineraryIndex].cssClass = cssClasses.planEntryValid - + currentItinerary.cssClass = cssClasses.planEntryValid + currentDefaultItinerary.cssClass = cssClasses.planEntryValid } else { // itineraries are not equal - plans[planIndex].itineraries[itineraryIndex].cssClass = cssClasses.planEntryInvalid - defaultPlans[planIndex].itineraries[itineraryIndex].cssClass = cssClasses.planEntryInvalid + currentItinerary.cssClass = cssClasses.planEntryInvalid + currentDefaultItinerary.cssClass = cssClasses.planEntryInvalid } } diff --git a/visual-debugger/src/data-processing/planParsing.ts b/visual-debugger/src/data-processing/planParsing.ts index 6624d5ee5..8311a08e7 100644 --- a/visual-debugger/src/data-processing/planParsing.ts +++ b/visual-debugger/src/data-processing/planParsing.ts @@ -42,6 +42,7 @@ export async function computePlan() { resetCssClassesForPlanEntries(plan) } + // index all itineraries as they are parsed for (let plan of plans) { let itineraryIndex =0 for (let itinerary of plan.itineraries) { diff --git a/visual-debugger/src/data-processing/type-declarations/planTypes.ts b/visual-debugger/src/data-processing/type-declarations/planTypes.ts index d3ff5583b..82d26ef61 100644 --- a/visual-debugger/src/data-processing/type-declarations/planTypes.ts +++ b/visual-debugger/src/data-processing/type-declarations/planTypes.ts @@ -62,6 +62,9 @@ export class Leg { legGeometry: EncodedPolyline = new EncodedPolyline(); headsign: string = ""; routeShortName: string = ""; + intermediateStops: Array = new Array(); + source: string = ""; + tripId: string = ""; } /** From a2fb877e398cf5ea491d4d61df100344ff54c8e6 Mon Sep 17 00:00:00 2001 From: Kvnstrck Date: Fri, 14 Feb 2025 16:26:06 +0100 Subject: [PATCH 2/2] chore: add comments and documentation --- .../src/data-processing/compareObjects.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/visual-debugger/src/data-processing/compareObjects.ts b/visual-debugger/src/data-processing/compareObjects.ts index 6d36e61e1..7d5392fc6 100644 --- a/visual-debugger/src/data-processing/compareObjects.ts +++ b/visual-debugger/src/data-processing/compareObjects.ts @@ -2,7 +2,11 @@ import {Itinerary, Leg} from "@data/type-declarations/planTypes.ts"; // @ts-ignore import deepEqual from "deep-equal"; - +/** + * compares the parameters and returns true when all of their attributes are equal in value + * @param currentItinerary + * @param currentDefaultItinerary + */ export function compareItineraries(currentItinerary: Itinerary, currentDefaultItinerary: Itinerary): boolean { // First, check if the number of keys are the same const keys1 = Object.keys(currentItinerary) as (keyof Itinerary)[]; @@ -11,6 +15,7 @@ export function compareItineraries(currentItinerary: Itinerary, currentDefaultIt // Compare the values of each key in both objects return keys1.every((key) => { + // recursively check the legs attribute and evaluate it for equality if (key == "legs") { let result = true; for (let i = 0; i < currentItinerary.legs.length; i++) { @@ -21,12 +26,14 @@ export function compareItineraries(currentItinerary: Itinerary, currentDefaultIt return result; } + // evaluate all attributes except legs for equality return deepEqual(currentItinerary[key], currentDefaultItinerary[key]); }); } /** * Compares the parameters and puts the mismatched attributes in a list + * IMPORTANT: excludes the source and tripId parameters because they are not deterministic * @returns an array with the mismatched attributes of the function parameters * @param currentLeg * @param currentDefaultLeg @@ -35,15 +42,20 @@ function compareLegs(currentLeg: Leg, currentDefaultLeg: Leg): string[] { let mismatchedAttributes: string[] = [] + //get list of attributes const keys1 = Object.keys(currentLeg) as (keyof Leg)[]; + // iterates over all attributes keys1.every((key) => { + + // exclude "source" and "tripId" parameters and evaluate the rest switch (key) { case "source": return true case "tripId": return true default: { + // add the attribute name to the list if the parameters differ in value if (!deepEqual(currentLeg[key], currentDefaultLeg[key])) { mismatchedAttributes.push(key); return true