From 4c1623f6bf15ed15f6aba864d15b390ddabb7dd1 Mon Sep 17 00:00:00 2001 From: AlexanderSchicktanz Date: Tue, 21 Oct 2025 16:06:56 +0200 Subject: [PATCH 01/10] fix: word limit --- evap/static/ts/src/text-answer-warnings.ts | 22 ++++++++++++++++++- .../ts/tests/unit/text-answer-warnings.ts | 9 ++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/evap/static/ts/src/text-answer-warnings.ts b/evap/static/ts/src/text-answer-warnings.ts index 6a622ebe16..6dfe40590f 100644 --- a/evap/static/ts/src/text-answer-warnings.ts +++ b/evap/static/ts/src/text-answer-warnings.ts @@ -6,8 +6,27 @@ function isTextMeaningless(text: string): boolean { return text.length > 0 && ["", "ka", "na", "none", "keine", "keines", "keiner"].includes(text.replace(/\W/g, "")); } +function containsSubArray(arr: string[], sub: string[]): boolean{ + for(let i = 0; i < arr.length; i++){ + if(i+sub.length>arr.length) return false; + let j; + for(j = 0; j < sub.length; j++){ + if(arr[i+j]!==sub[j]) return false; + } + return (j==sub.length); + } + return false; +} + +function matchesTriggerString(text: string, triggerString: string): boolean{ + console.log("Works"); + const words = text.split(" "); + const triggerWords = triggerString.split(" "); + return containsSubArray(words, triggerWords); +} + function doesTextContainTriggerString(text: string, triggerStrings: string[]): boolean { - return triggerStrings.some(triggerString => text.includes(triggerString)); + return triggerStrings.some(triggerString => matchesTriggerString(text,triggerString)); } function updateTextareaWarning(textarea: HTMLTextAreaElement, textAnswerWarnings: string[][]) { @@ -53,4 +72,5 @@ export const testable = { normalize, isTextMeaningless, doesTextContainTriggerString, + matchesTriggerString }; diff --git a/evap/static/ts/tests/unit/text-answer-warnings.ts b/evap/static/ts/tests/unit/text-answer-warnings.ts index ffd776c574..9a3f0132bc 100644 --- a/evap/static/ts/tests/unit/text-answer-warnings.ts +++ b/evap/static/ts/tests/unit/text-answer-warnings.ts @@ -34,3 +34,12 @@ test.each([ const normalized = testable.normalize(text); expect(testable.isTextMeaningless(normalized)).toBe(false); }); + +test.each([ + ["", "s.o.", false], + ["s.o.", "s.o.", true], + ["s.o.s", "s.o.", false] +])('matchesTriggerString(%p, %p) should return %p', (a, b, expected) => { + const result = testable.matchesTriggerString(a, b); + expect(result).toBe(expected); +}); \ No newline at end of file From 84854ba4e9f7d76e9a885b3245b73692d4278488 Mon Sep 17 00:00:00 2001 From: AlexanderSchicktanz Date: Mon, 27 Oct 2025 17:47:35 +0100 Subject: [PATCH 02/10] added newline at end of file --- evap/static/ts/src/text-answer-warnings.ts | 18 +++++++++--------- .../ts/tests/unit/text-answer-warnings.ts | 15 ++++++++------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/evap/static/ts/src/text-answer-warnings.ts b/evap/static/ts/src/text-answer-warnings.ts index 6dfe40590f..4332669003 100644 --- a/evap/static/ts/src/text-answer-warnings.ts +++ b/evap/static/ts/src/text-answer-warnings.ts @@ -6,19 +6,19 @@ function isTextMeaningless(text: string): boolean { return text.length > 0 && ["", "ka", "na", "none", "keine", "keines", "keiner"].includes(text.replace(/\W/g, "")); } -function containsSubArray(arr: string[], sub: string[]): boolean{ - for(let i = 0; i < arr.length; i++){ - if(i+sub.length>arr.length) return false; +function containsSubArray(arr: string[], sub: string[]): boolean { + for (let i = 0; i < arr.length; i++) { + if (i + sub.length > arr.length) return false; let j; - for(j = 0; j < sub.length; j++){ - if(arr[i+j]!==sub[j]) return false; + for (j = 0; j < sub.length; j++) { + if (arr[i + j] !== sub[j]) return false; } - return (j==sub.length); + return j == sub.length; } return false; } -function matchesTriggerString(text: string, triggerString: string): boolean{ +function matchesTriggerString(text: string, triggerString: string): boolean { console.log("Works"); const words = text.split(" "); const triggerWords = triggerString.split(" "); @@ -26,7 +26,7 @@ function matchesTriggerString(text: string, triggerString: string): boolean{ } function doesTextContainTriggerString(text: string, triggerStrings: string[]): boolean { - return triggerStrings.some(triggerString => matchesTriggerString(text,triggerString)); + return triggerStrings.some(triggerString => matchesTriggerString(text, triggerString)); } function updateTextareaWarning(textarea: HTMLTextAreaElement, textAnswerWarnings: string[][]) { @@ -72,5 +72,5 @@ export const testable = { normalize, isTextMeaningless, doesTextContainTriggerString, - matchesTriggerString + matchesTriggerString, }; diff --git a/evap/static/ts/tests/unit/text-answer-warnings.ts b/evap/static/ts/tests/unit/text-answer-warnings.ts index 9a3f0132bc..90c61c513a 100644 --- a/evap/static/ts/tests/unit/text-answer-warnings.ts +++ b/evap/static/ts/tests/unit/text-answer-warnings.ts @@ -36,10 +36,11 @@ test.each([ }); test.each([ - ["", "s.o.", false], - ["s.o.", "s.o.", true], - ["s.o.s", "s.o.", false] -])('matchesTriggerString(%p, %p) should return %p', (a, b, expected) => { - const result = testable.matchesTriggerString(a, b); - expect(result).toBe(expected); -}); \ No newline at end of file + ["", "s.o.", false], + ["s.o.", "s.o.", true], + ["s.o.s", "s.o.", false], +])("matchesTriggerString(%p, %p) should return %p", (a, b, expected) => { + const result = testable.matchesTriggerString(a, b); + expect(result).toBe(expected); +}); + From 920ea84b0cbc1559562443189b3b2f6b45ee9dcd Mon Sep 17 00:00:00 2001 From: AlexanderSchicktanz Date: Mon, 27 Oct 2025 17:57:18 +0100 Subject: [PATCH 03/10] fixed formatting for test-answer-warnings.ts --- evap/static/ts/tests/unit/text-answer-warnings.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/evap/static/ts/tests/unit/text-answer-warnings.ts b/evap/static/ts/tests/unit/text-answer-warnings.ts index 90c61c513a..b8d9514808 100644 --- a/evap/static/ts/tests/unit/text-answer-warnings.ts +++ b/evap/static/ts/tests/unit/text-answer-warnings.ts @@ -43,4 +43,3 @@ test.each([ const result = testable.matchesTriggerString(a, b); expect(result).toBe(expected); }); - From c5ff7ea02a9ac3c0269852787863e3b56ac3033a Mon Sep 17 00:00:00 2001 From: AlexanderSchicktanz Date: Mon, 27 Oct 2025 18:15:03 +0100 Subject: [PATCH 04/10] removed console.log --- evap/static/ts/src/text-answer-warnings.ts | 2 +- evap/static/ts/tests/unit/text-answer-warnings.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/evap/static/ts/src/text-answer-warnings.ts b/evap/static/ts/src/text-answer-warnings.ts index 4332669003..1683b1133e 100644 --- a/evap/static/ts/src/text-answer-warnings.ts +++ b/evap/static/ts/src/text-answer-warnings.ts @@ -19,7 +19,6 @@ function containsSubArray(arr: string[], sub: string[]): boolean { } function matchesTriggerString(text: string, triggerString: string): boolean { - console.log("Works"); const words = text.split(" "); const triggerWords = triggerString.split(" "); return containsSubArray(words, triggerWords); @@ -74,3 +73,4 @@ export const testable = { doesTextContainTriggerString, matchesTriggerString, }; + diff --git a/evap/static/ts/tests/unit/text-answer-warnings.ts b/evap/static/ts/tests/unit/text-answer-warnings.ts index b8d9514808..90c61c513a 100644 --- a/evap/static/ts/tests/unit/text-answer-warnings.ts +++ b/evap/static/ts/tests/unit/text-answer-warnings.ts @@ -43,3 +43,4 @@ test.each([ const result = testable.matchesTriggerString(a, b); expect(result).toBe(expected); }); + From d83569a5182aa58a6ba4bb0c51940364b3032fa3 Mon Sep 17 00:00:00 2001 From: AlexanderSchicktanz Date: Mon, 27 Oct 2025 18:59:36 +0100 Subject: [PATCH 05/10] fixed line ending --- evap/static/ts/src/text-answer-warnings.ts | 1 - evap/static/ts/tests/unit/text-answer-warnings.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/evap/static/ts/src/text-answer-warnings.ts b/evap/static/ts/src/text-answer-warnings.ts index 1683b1133e..dbacc4556c 100644 --- a/evap/static/ts/src/text-answer-warnings.ts +++ b/evap/static/ts/src/text-answer-warnings.ts @@ -73,4 +73,3 @@ export const testable = { doesTextContainTriggerString, matchesTriggerString, }; - diff --git a/evap/static/ts/tests/unit/text-answer-warnings.ts b/evap/static/ts/tests/unit/text-answer-warnings.ts index 90c61c513a..b8d9514808 100644 --- a/evap/static/ts/tests/unit/text-answer-warnings.ts +++ b/evap/static/ts/tests/unit/text-answer-warnings.ts @@ -43,4 +43,3 @@ test.each([ const result = testable.matchesTriggerString(a, b); expect(result).toBe(expected); }); - From e07971bd8f14cf150284e009b288cf25f63f0231 Mon Sep 17 00:00:00 2001 From: AlexanderSchicktanz Date: Mon, 27 Oct 2025 20:11:34 +0100 Subject: [PATCH 06/10] fixed false negatives --- evap/static/ts/src/text-answer-warnings.ts | 7 +++---- evap/static/ts/tests/unit/text-answer-warnings.ts | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/evap/static/ts/src/text-answer-warnings.ts b/evap/static/ts/src/text-answer-warnings.ts index dbacc4556c..8f3305b906 100644 --- a/evap/static/ts/src/text-answer-warnings.ts +++ b/evap/static/ts/src/text-answer-warnings.ts @@ -7,13 +7,12 @@ function isTextMeaningless(text: string): boolean { } function containsSubArray(arr: string[], sub: string[]): boolean { - for (let i = 0; i < arr.length; i++) { - if (i + sub.length > arr.length) return false; + for (let i = 0; i <= arr.length - sub.length; i++) { let j; for (j = 0; j < sub.length; j++) { - if (arr[i + j] !== sub[j]) return false; + if (arr[i + j] !== sub[j]) break; } - return j == sub.length; + if (j == sub.length) return true; } return false; } diff --git a/evap/static/ts/tests/unit/text-answer-warnings.ts b/evap/static/ts/tests/unit/text-answer-warnings.ts index b8d9514808..6581ff3f80 100644 --- a/evap/static/ts/tests/unit/text-answer-warnings.ts +++ b/evap/static/ts/tests/unit/text-answer-warnings.ts @@ -39,6 +39,7 @@ test.each([ ["", "s.o.", false], ["s.o.", "s.o.", true], ["s.o.s", "s.o.", false], + ["Antwort: s.o.", true], ])("matchesTriggerString(%p, %p) should return %p", (a, b, expected) => { const result = testable.matchesTriggerString(a, b); expect(result).toBe(expected); From 9bc22376a7175a41d5caea17fb2e78f25a02e226 Mon Sep 17 00:00:00 2001 From: AlexanderSchicktanz Date: Mon, 27 Oct 2025 20:38:05 +0100 Subject: [PATCH 07/10] fixed test --- evap/static/ts/tests/unit/text-answer-warnings.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evap/static/ts/tests/unit/text-answer-warnings.ts b/evap/static/ts/tests/unit/text-answer-warnings.ts index 6581ff3f80..de6a82b83b 100644 --- a/evap/static/ts/tests/unit/text-answer-warnings.ts +++ b/evap/static/ts/tests/unit/text-answer-warnings.ts @@ -39,7 +39,7 @@ test.each([ ["", "s.o.", false], ["s.o.", "s.o.", true], ["s.o.s", "s.o.", false], - ["Antwort: s.o.", true], + ["Antwort: s.o.", "s.o.", true], ])("matchesTriggerString(%p, %p) should return %p", (a, b, expected) => { const result = testable.matchesTriggerString(a, b); expect(result).toBe(expected); From 9a128419a4a3d110347a1cb5e4702d1acc09f604 Mon Sep 17 00:00:00 2001 From: AlexanderSchicktanz Date: Mon, 27 Oct 2025 22:01:27 +0100 Subject: [PATCH 08/10] feat: make array comparison generic --- evap/static/ts/src/text-answer-warnings.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evap/static/ts/src/text-answer-warnings.ts b/evap/static/ts/src/text-answer-warnings.ts index 8f3305b906..faae328ca5 100644 --- a/evap/static/ts/src/text-answer-warnings.ts +++ b/evap/static/ts/src/text-answer-warnings.ts @@ -6,7 +6,7 @@ function isTextMeaningless(text: string): boolean { return text.length > 0 && ["", "ka", "na", "none", "keine", "keines", "keiner"].includes(text.replace(/\W/g, "")); } -function containsSubArray(arr: string[], sub: string[]): boolean { +function containsSubArray(arr: Type[], sub: Type[]): boolean { for (let i = 0; i <= arr.length - sub.length; i++) { let j; for (j = 0; j < sub.length; j++) { From be965e8d33d61bb30bdd8bfbb79c67cff6bcc9d2 Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 12 Jan 2026 22:34:12 +0100 Subject: [PATCH 09/10] ignore punctuation --- evap/static/ts/src/text-answer-warnings.ts | 8 ++++++-- evap/static/ts/tests/unit/text-answer-warnings.ts | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/evap/static/ts/src/text-answer-warnings.ts b/evap/static/ts/src/text-answer-warnings.ts index faae328ca5..6f53662ae0 100644 --- a/evap/static/ts/src/text-answer-warnings.ts +++ b/evap/static/ts/src/text-answer-warnings.ts @@ -10,9 +10,13 @@ function containsSubArray(arr: Type[], sub: Type[]): boolean { for (let i = 0; i <= arr.length - sub.length; i++) { let j; for (j = 0; j < sub.length; j++) { + if (j == sub.length - 1 && arr[i + j].length > sub[j].length) { + if (!arr[i + j].startsWith(sub[j])) break; + if (null !== arr[i + j].substring(sub[j].length).match(RegExp("^[!?.]*$", ""))) return true; + } if (arr[i + j] !== sub[j]) break; } - if (j == sub.length) return true; + if (j >= sub.length) return true; } return false; } @@ -52,7 +56,7 @@ function updateTextareaWarning(textarea: HTMLTextAreaElement, textAnswerWarnings export function initTextAnswerWarnings(textareas: NodeListOf, textAnswerWarnings: string[][]) { textAnswerWarnings = textAnswerWarnings.map(triggerStrings => triggerStrings.map(normalize)); - + console.log(textAnswerWarnings); textareas.forEach(textarea => { let warningDelayTimer: ReturnType; textarea.addEventListener("input", () => { diff --git a/evap/static/ts/tests/unit/text-answer-warnings.ts b/evap/static/ts/tests/unit/text-answer-warnings.ts index de6a82b83b..8b9edfb539 100644 --- a/evap/static/ts/tests/unit/text-answer-warnings.ts +++ b/evap/static/ts/tests/unit/text-answer-warnings.ts @@ -40,6 +40,7 @@ test.each([ ["s.o.", "s.o.", true], ["s.o.s", "s.o.", false], ["Antwort: s.o.", "s.o.", true], + ["siehe oben?!", "siehe oben", true], ])("matchesTriggerString(%p, %p) should return %p", (a, b, expected) => { const result = testable.matchesTriggerString(a, b); expect(result).toBe(expected); From fa8fdc200d423c4c972b535c791cd9933c769bac Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 26 Jan 2026 18:21:10 +0100 Subject: [PATCH 10/10] fix: type error --- evap/static/ts/src/text-answer-warnings.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/evap/static/ts/src/text-answer-warnings.ts b/evap/static/ts/src/text-answer-warnings.ts index 6f53662ae0..609cf314ae 100644 --- a/evap/static/ts/src/text-answer-warnings.ts +++ b/evap/static/ts/src/text-answer-warnings.ts @@ -6,13 +6,13 @@ function isTextMeaningless(text: string): boolean { return text.length > 0 && ["", "ka", "na", "none", "keine", "keines", "keiner"].includes(text.replace(/\W/g, "")); } -function containsSubArray(arr: Type[], sub: Type[]): boolean { +function containsPhrase(arr: string[], sub: string[]): boolean { for (let i = 0; i <= arr.length - sub.length; i++) { let j; for (j = 0; j < sub.length; j++) { if (j == sub.length - 1 && arr[i + j].length > sub[j].length) { if (!arr[i + j].startsWith(sub[j])) break; - if (null !== arr[i + j].substring(sub[j].length).match(RegExp("^[!?.]*$", ""))) return true; + if (null !== RegExp("^[!?.]*$", "").exec(arr[i + j].substring(sub[j].length))) return true; } if (arr[i + j] !== sub[j]) break; } @@ -24,7 +24,7 @@ function containsSubArray(arr: Type[], sub: Type[]): boolean { function matchesTriggerString(text: string, triggerString: string): boolean { const words = text.split(" "); const triggerWords = triggerString.split(" "); - return containsSubArray(words, triggerWords); + return containsPhrase(words, triggerWords); } function doesTextContainTriggerString(text: string, triggerStrings: string[]): boolean {