mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-21 17:27:54 +00:00
154 lines
4.1 KiB
TypeScript
154 lines
4.1 KiB
TypeScript
/**
|
||
* @license
|
||
* Copyright 2025 Google LLC
|
||
* SPDX-License-Identifier: Apache-2.0
|
||
*/
|
||
|
||
import { describe, expect, it } from 'vitest';
|
||
import {
|
||
countOccurrences,
|
||
maybeAugmentOldStringForDeletion,
|
||
normalizeEditStrings,
|
||
} from './editHelper.js';
|
||
|
||
describe('normalizeEditStrings', () => {
|
||
const file = `const one = 1;
|
||
const two = 2;
|
||
`;
|
||
|
||
it('returns literal matches unchanged and trims new_string trailing whitespace', () => {
|
||
const result = normalizeEditStrings(
|
||
file,
|
||
'const two = 2;',
|
||
' const two = 42; ',
|
||
);
|
||
expect(result).toEqual({
|
||
oldString: 'const two = 2;',
|
||
newString: ' const two = 42;',
|
||
});
|
||
});
|
||
|
||
it('normalizes smart quotes to match on-disk text', () => {
|
||
const result = normalizeEditStrings(
|
||
"const greeting = 'Don't';\n",
|
||
'const greeting = ‘Don’t’;',
|
||
'const greeting = “Hello”; ',
|
||
);
|
||
expect(result).toEqual({
|
||
oldString: "const greeting = 'Don't';",
|
||
newString: 'const greeting = “Hello”;',
|
||
});
|
||
});
|
||
|
||
it('falls back to original strings when no match is found', () => {
|
||
const result = normalizeEditStrings(file, 'missing text', 'replacement');
|
||
expect(result).toEqual({
|
||
oldString: 'missing text',
|
||
newString: 'replacement',
|
||
});
|
||
});
|
||
|
||
it('still trims new_string when editing a brand-new file', () => {
|
||
const result = normalizeEditStrings(null, '', 'new file contents ');
|
||
expect(result).toEqual({
|
||
oldString: '',
|
||
newString: 'new file contents',
|
||
});
|
||
});
|
||
|
||
it('matches unicode dash variants', () => {
|
||
const result = normalizeEditStrings(
|
||
'const range = "1-2";\n',
|
||
'const range = "1\u20132";',
|
||
'const range = "3\u20135"; ',
|
||
);
|
||
expect(result).toEqual({
|
||
oldString: 'const range = "1-2";',
|
||
newString: 'const range = "3\u20135";',
|
||
});
|
||
});
|
||
|
||
it('matches when trailing whitespace differs only at line ends', () => {
|
||
const result = normalizeEditStrings(
|
||
'value = 1;\n',
|
||
'value = 1; \n',
|
||
'value = 2; \n',
|
||
);
|
||
expect(result).toEqual({
|
||
oldString: 'value = 1;\n',
|
||
newString: 'value = 2;\n',
|
||
});
|
||
});
|
||
|
||
it('treats non-breaking spaces as regular spaces', () => {
|
||
const result = normalizeEditStrings(
|
||
'const label = "hello world";\n',
|
||
'const label = "hello\u00a0world";',
|
||
'const label = "hi\u00a0world";',
|
||
);
|
||
expect(result).toEqual({
|
||
oldString: 'const label = "hello world";',
|
||
newString: 'const label = "hi\u00a0world";',
|
||
});
|
||
});
|
||
|
||
it('drops trailing newline from new content when the file lacks it', () => {
|
||
const result = normalizeEditStrings(
|
||
'console.log("hi")',
|
||
'console.log("hi")\n',
|
||
'console.log("bye")\n',
|
||
);
|
||
expect(result).toEqual({
|
||
oldString: 'console.log("hi")',
|
||
newString: 'console.log("bye")',
|
||
});
|
||
});
|
||
});
|
||
|
||
describe('countOccurrences', () => {
|
||
it('returns zero when substring empty or missing', () => {
|
||
expect(countOccurrences('abc', '')).toBe(0);
|
||
expect(countOccurrences('abc', 'z')).toBe(0);
|
||
});
|
||
|
||
it('counts non-overlapping occurrences', () => {
|
||
expect(countOccurrences('aaaa', 'aa')).toBe(2);
|
||
});
|
||
});
|
||
|
||
describe('maybeAugmentOldStringForDeletion', () => {
|
||
const file = 'console.log("hi")\nconsole.log("bye")\n';
|
||
|
||
it('appends newline when deleting text followed by newline', () => {
|
||
expect(
|
||
maybeAugmentOldStringForDeletion(file, 'console.log("hi")', ''),
|
||
).toBe('console.log("hi")\n');
|
||
});
|
||
|
||
it('leaves strings untouched when not deleting', () => {
|
||
expect(
|
||
maybeAugmentOldStringForDeletion(
|
||
file,
|
||
'console.log("hi")',
|
||
'replacement',
|
||
),
|
||
).toBe('console.log("hi")');
|
||
});
|
||
|
||
it('does not append newline when file lacks the variant', () => {
|
||
expect(
|
||
maybeAugmentOldStringForDeletion(
|
||
'console.log("hi")',
|
||
'console.log("hi")',
|
||
'',
|
||
),
|
||
).toBe('console.log("hi")');
|
||
});
|
||
|
||
it('no-ops when the old string already ends with a newline', () => {
|
||
expect(
|
||
maybeAugmentOldStringForDeletion(file, 'console.log("bye")\n', ''),
|
||
).toBe('console.log("bye")\n');
|
||
});
|
||
});
|