summaryrefslogtreecommitdiff
path: root/packages/server/src/utils/editCorrector.test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/server/src/utils/editCorrector.test.ts')
-rw-r--r--packages/server/src/utils/editCorrector.test.ts117
1 files changed, 117 insertions, 0 deletions
diff --git a/packages/server/src/utils/editCorrector.test.ts b/packages/server/src/utils/editCorrector.test.ts
new file mode 100644
index 00000000..8b27bdf1
--- /dev/null
+++ b/packages/server/src/utils/editCorrector.test.ts
@@ -0,0 +1,117 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { describe, it, expect } from 'vitest';
+import {
+ countOccurrences,
+ unescapeStringForGeminiBug,
+} from './editCorrector.js';
+
+describe('editCorrector', () => {
+ describe('countOccurrences', () => {
+ it('should return 0 for empty string', () => {
+ expect(countOccurrences('', 'a')).toBe(0);
+ });
+
+ it('should return 0 for empty substring', () => {
+ expect(countOccurrences('abc', '')).toBe(0);
+ });
+
+ it('should return 0 if substring is not found', () => {
+ expect(countOccurrences('abc', 'd')).toBe(0);
+ });
+
+ it('should return 1 if substring is found once', () => {
+ expect(countOccurrences('abc', 'b')).toBe(1);
+ });
+
+ it('should return correct count for multiple occurrences', () => {
+ expect(countOccurrences('ababa', 'a')).toBe(3);
+ expect(countOccurrences('ababab', 'ab')).toBe(3);
+ });
+
+ it('should count non-overlapping occurrences', () => {
+ expect(countOccurrences('aaaaa', 'aa')).toBe(2); // Non-overlapping: aa_aa_
+ expect(countOccurrences('ababab', 'aba')).toBe(1); // Non-overlapping: aba_ab -> 1
+ });
+
+ it('should correctly count occurrences when substring is longer', () => {
+ expect(countOccurrences('abc', 'abcdef')).toBe(0);
+ });
+
+ it('should be case sensitive', () => {
+ expect(countOccurrences('abcABC', 'a')).toBe(1);
+ expect(countOccurrences('abcABC', 'A')).toBe(1);
+ });
+ });
+
+ describe('unescapeStringForGeminiBug', () => {
+ it('should unescape common sequences', () => {
+ expect(unescapeStringForGeminiBug('\\n')).toBe('\n');
+ expect(unescapeStringForGeminiBug('\\t')).toBe('\t');
+ expect(unescapeStringForGeminiBug("\\'")).toBe("'");
+ expect(unescapeStringForGeminiBug('\\"')).toBe('"');
+ expect(unescapeStringForGeminiBug('\\`')).toBe('`');
+ });
+
+ it('should handle multiple escaped sequences', () => {
+ expect(unescapeStringForGeminiBug('Hello\\nWorld\\tTest')).toBe(
+ 'Hello\nWorld\tTest',
+ );
+ });
+
+ it('should not alter already correct sequences', () => {
+ expect(unescapeStringForGeminiBug('\n')).toBe('\n');
+ expect(unescapeStringForGeminiBug('Correct string')).toBe(
+ 'Correct string',
+ );
+ });
+
+ it('should handle mixed correct and incorrect sequences', () => {
+ expect(unescapeStringForGeminiBug('\\nCorrect\t\\`')).toBe(
+ '\nCorrect\t`',
+ );
+ });
+
+ it('should handle backslash followed by actual newline character', () => {
+ expect(unescapeStringForGeminiBug('\\\n')).toBe('\n');
+ expect(unescapeStringForGeminiBug('First line\\\nSecond line')).toBe(
+ 'First line\nSecond line',
+ );
+ });
+
+ it('should handle multiple backslashes before an escapable character', () => {
+ expect(unescapeStringForGeminiBug('\\\\n')).toBe('\n'); // \\n -> \n
+ expect(unescapeStringForGeminiBug('\\\\\\t')).toBe('\t'); // \\\t -> \t
+ expect(unescapeStringForGeminiBug('\\\\\\\\`')).toBe('`'); // \\\\` -> `
+ });
+
+ it('should return empty string for empty input', () => {
+ expect(unescapeStringForGeminiBug('')).toBe('');
+ });
+
+ it('should not alter strings with no targeted escape sequences', () => {
+ expect(unescapeStringForGeminiBug('abc def')).toBe('abc def');
+ // \\F and \\S are not targeted escapes, so they should remain as \\F and \\S
+ expect(unescapeStringForGeminiBug('C:\\Folder\\File')).toBe(
+ 'C:\\Folder\\File',
+ );
+ });
+
+ it('should correctly process strings with some targeted escapes', () => {
+ // \\U is not targeted, \\n is.
+ expect(unescapeStringForGeminiBug('C:\\Users\\name')).toBe(
+ 'C:\\Users\name',
+ );
+ });
+
+ it('should handle complex cases with mixed slashes and characters', () => {
+ expect(
+ unescapeStringForGeminiBug('\\\\\\nLine1\\\nLine2\\tTab\\\\`Tick\\"'),
+ ).toBe('\nLine1\nLine2\tTab`Tick"');
+ });
+ });
+});