Skip to content

Commit db48517

Browse files
committed
fix: add more tests for edit utils
1 parent b001fcb commit db48517

File tree

2 files changed

+112
-12
lines changed

2 files changed

+112
-12
lines changed
Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,77 @@
11
export function hasStartupCode(content: string, start: string, end: string, keys: string[]): boolean {
2-
const startIndex = content.indexOf(start);
3-
const endIndex = content.indexOf(end);
2+
// Normalize line endings to \n
3+
const normalizedContent = content.replace(/\r\n/g, '\n');
4+
const startIndex = normalizedContent.indexOf(start);
5+
const endIndex = normalizedContent.indexOf(end);
46
if (startIndex === -1 || endIndex === -1 || startIndex >= endIndex) {
57
return false;
68
}
7-
const contentBetween = content.substring(startIndex + start.length, endIndex).trim();
9+
const contentBetween = normalizedContent.substring(startIndex + start.length, endIndex).trim();
810
return contentBetween.length > 0 && keys.every((key) => contentBetween.includes(key));
911
}
1012

1113
export function insertStartupCode(content: string, start: string, end: string, code: string): string {
12-
const startIndex = content.indexOf(start);
13-
const endIndex = content.indexOf(end);
14+
// Detect line ending style from content (default to \n if cannot determine)
15+
const lineEnding = content.includes('\r\n') ? '\r\n' : '\n';
1416

17+
// Normalize line endings to \n for processing
18+
const normalizedContent = content.replace(/\r\n/g, '\n');
19+
const startIndex = normalizedContent.indexOf(start);
20+
const endIndex = normalizedContent.indexOf(end);
21+
22+
let result: string;
1523
if (startIndex !== -1 && endIndex !== -1 && startIndex < endIndex) {
16-
return content.substring(0, startIndex + start.length) + '\n\n' + code + '\n\n' + content.substring(endIndex);
24+
// Both markers exist in correct order
25+
result =
26+
normalizedContent.substring(0, startIndex + start.length) +
27+
'\n' +
28+
code +
29+
'\n' +
30+
normalizedContent.substring(endIndex);
31+
} else if (startIndex !== -1) {
32+
// Only start marker exists - truncate everything after the start marker
33+
result = normalizedContent.substring(0, startIndex + start.length) + '\n' + code + '\n' + end + '\n';
1734
} else {
18-
return content + '\n' + start + '\n\n' + code + '\n\n' + end + '\n';
35+
// No markers or only end marker exists
36+
result = normalizedContent + '\n' + start + '\n' + code + '\n' + end + '\n';
37+
}
38+
39+
// Restore original line ending style
40+
if (lineEnding === '\r\n') {
41+
result = result.replace(/\n/g, '\r\n');
1942
}
43+
return result;
2044
}
2145

2246
export function removeStartupCode(content: string, start: string, end: string): string {
23-
const startIndex = content.indexOf(start);
24-
const endIndex = content.indexOf(end);
47+
// Detect line ending style from content (default to \n if cannot determine)
48+
const lineEnding = content.includes('\r\n') ? '\r\n' : '\n';
49+
50+
// Normalize line endings to \n for processing
51+
const normalizedContent = content.replace(/\r\n/g, '\n');
52+
const startIndex = normalizedContent.indexOf(start);
53+
const endIndex = normalizedContent.indexOf(end);
2554

2655
if (startIndex !== -1 && endIndex !== -1 && startIndex < endIndex) {
27-
const before = content.substring(0, startIndex + start.length);
28-
const after = content.substring(endIndex);
29-
return before.trimEnd() + after;
56+
const before = normalizedContent.substring(0, startIndex);
57+
const after = normalizedContent.substring(endIndex + end.length);
58+
59+
let result: string;
60+
if (before === '') {
61+
result = after.startsWith('\n') ? after.substring(1) : after;
62+
} else if (after === '' || after === '\n') {
63+
result = before.endsWith('\n') ? before.substring(0, before.length - 1) : before;
64+
} else if (after.startsWith('\n') && before.endsWith('\n')) {
65+
result = before + after.substring(1);
66+
} else {
67+
result = before + after;
68+
}
69+
70+
// Restore original line ending style
71+
if (lineEnding === '\r\n') {
72+
result = result.replace(/\n/g, '\r\n');
73+
}
74+
return result;
3075
}
3176
return content;
3277
}

src/test/features/terminal/shells/common/editUtils.unit.test.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,18 @@ suite('Shell Edit Utils', () => {
6060
const result = hasStartupCode(content, '# START', '# END', ['key1', 'key2']);
6161
assert.strictEqual(result, false);
6262
});
63+
64+
test('should handle Windows line endings (CRLF) correctly', () => {
65+
const content = 'content\r\n# START\r\nsome key content\r\n# END\r\nmore content';
66+
const result = hasStartupCode(content, '# START', '# END', ['key']);
67+
assert.strictEqual(result, true);
68+
});
69+
70+
test('should handle mixed line endings correctly', () => {
71+
const content = 'content\n# START\r\nsome key content\n# END\r\nmore content';
72+
const result = hasStartupCode(content, '# START', '# END', ['key']);
73+
assert.strictEqual(result, true);
74+
});
6375
});
6476

6577
suite('insertStartupCode', () => {
@@ -122,6 +134,30 @@ suite('Shell Edit Utils', () => {
122134

123135
assert.strictEqual(result, expected);
124136
});
137+
138+
test('should handle Windows line endings (CRLF) correctly', () => {
139+
const content = 'before\r\n# START\r\nold code\r\n# END\r\nafter';
140+
const start = '# START';
141+
const end = '# END';
142+
const code = 'new code';
143+
144+
const result = insertStartupCode(content, start, end, code);
145+
const expected = 'before\r\n# START\r\nnew code\r\n# END\r\nafter';
146+
147+
assert.strictEqual(result, expected);
148+
});
149+
150+
test('should preserve original line ending style when inserting', () => {
151+
// Content with Windows line endings
152+
const contentWindows = 'before\r\n# START\r\nold code\r\n# END\r\nafter';
153+
const resultWindows = insertStartupCode(contentWindows, '# START', '# END', 'new code');
154+
assert.ok(resultWindows.includes('\r\n'), 'Windows line endings should be preserved');
155+
156+
// Content with Unix line endings
157+
const contentUnix = 'before\n# START\nold code\n# END\nafter';
158+
const resultUnix = insertStartupCode(contentUnix, '# START', '# END', 'new code');
159+
assert.ok(!resultUnix.includes('\r\n'), 'Unix line endings should be preserved');
160+
});
125161
});
126162

127163
suite('removeStartupCode', () => {
@@ -176,5 +212,24 @@ suite('Shell Edit Utils', () => {
176212
const expected = 'before content';
177213
assert.strictEqual(result, expected);
178214
});
215+
216+
test('should handle Windows line endings (CRLF) correctly', () => {
217+
const content = 'before\r\n# START\r\ncode to remove\r\n# END\r\nafter';
218+
const result = removeStartupCode(content, '# START', '# END');
219+
const expected = 'before\r\nafter';
220+
assert.strictEqual(result, expected);
221+
});
222+
223+
test('should preserve original line ending style when removing', () => {
224+
// Content with Windows line endings
225+
const contentWindows = 'before\r\n# START\r\ncode to remove\r\n# END\r\nafter';
226+
const resultWindows = removeStartupCode(contentWindows, '# START', '# END');
227+
assert.ok(resultWindows.includes('\r\n'), 'Windows line endings should be preserved');
228+
229+
// Content with Unix line endings
230+
const contentUnix = 'before\n# START\ncode to remove\n# END\nafter';
231+
const resultUnix = removeStartupCode(contentUnix, '# START', '# END');
232+
assert.ok(!resultUnix.includes('\r\n'), 'Unix line endings should be preserved');
233+
});
179234
});
180235
});

0 commit comments

Comments
 (0)