70 lines
3.3 KiB
TypeScript
70 lines
3.3 KiB
TypeScript
// @ts-expect-error -- bun:test is a runtime built-in with no types installed
|
|
import { describe, expect, test } from 'bun:test';
|
|
import { applyQuickFix } from '../../src/lib/utils/compose-quick-fix';
|
|
|
|
describe('applyQuickFix', () => {
|
|
test('delete-line removes exactly that 1-based line', () => {
|
|
const src = `version: "3.8"\nservices:\n web:\n image: nginx:1.27\n`;
|
|
expect(applyQuickFix(src, { kind: 'delete-line', line: 1 })).toBe(
|
|
`services:\n web:\n image: nginx:1.27\n`
|
|
);
|
|
});
|
|
|
|
test('replace-in-line swaps the first occurrence, keeping indentation', () => {
|
|
const src = `services:\n web:\n image: nginx:1.27\n restar: always\n`;
|
|
expect(applyQuickFix(src, { kind: 'replace-in-line', line: 4, find: 'restar', replace: 'restart' })).toBe(
|
|
`services:\n web:\n image: nginx:1.27\n restart: always\n`
|
|
);
|
|
});
|
|
|
|
test('replace-in-line prefixes a port binding without touching quotes', () => {
|
|
const src = `services:\n db:\n ports:\n - "5432:5432"\n`;
|
|
expect(
|
|
applyQuickFix(src, { kind: 'replace-in-line', line: 4, find: '5432:5432', replace: '127.0.0.1:5432:5432' })
|
|
).toBe(`services:\n db:\n ports:\n - "127.0.0.1:5432:5432"\n`);
|
|
});
|
|
|
|
test('a fix whose text no longer matches leaves the source unchanged (stale)', () => {
|
|
const src = `services:\n web:\n image: nginx:1.27\n`;
|
|
expect(applyQuickFix(src, { kind: 'replace-in-line', line: 3, find: 'gone', replace: 'x' })).toBe(src);
|
|
});
|
|
|
|
test('an out-of-range line leaves the source unchanged', () => {
|
|
const src = `services:\n web:\n image: nginx:1.27\n`;
|
|
expect(applyQuickFix(src, { kind: 'delete-line', line: 99 })).toBe(src);
|
|
});
|
|
|
|
test('insert-after adds the text as the next line, verbatim (indent in text)', () => {
|
|
const src = `services:\n web:\n image: nginx:1.27\n`;
|
|
expect(applyQuickFix(src, { kind: 'insert-after', line: 2, text: ' restart: unless-stopped' })).toBe(
|
|
`services:\n web:\n restart: unless-stopped\n image: nginx:1.27\n`
|
|
);
|
|
});
|
|
|
|
test('CRLF line endings on other lines are preserved', () => {
|
|
const src = `version: "3.8"\r\nservices:\r\n web:\r\n image: nginx:1.27\r\n`;
|
|
// delete the version line; the remaining \r stay intact.
|
|
expect(applyQuickFix(src, { kind: 'delete-line', line: 1 })).toBe(
|
|
`services:\r\n web:\r\n image: nginx:1.27\r\n`
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('replace-in-line anchoring (review regression)', () => {
|
|
test("`at` anchors to the intended occurrence, not the first substring", () => {
|
|
// The short "80:80" token is a substring of the earlier "8080:80" token.
|
|
const line = ' ports: ["8080:80", "80:80"]';
|
|
const src = `services:\n db:\n${line}\n`;
|
|
const at = line.indexOf('"80:80"') + 1; // column of the 2nd token
|
|
const out = applyQuickFix(src, { kind: 'replace-in-line', line: 3, find: '80:80', replace: '127.0.0.1:80:80', at });
|
|
expect(out).toContain('"8080:80"'); // earlier token intact
|
|
expect(out).toContain('"127.0.0.1:80:80"'); // correct token rewritten
|
|
expect(out).not.toContain('80127.0.0.1'); // no corruption
|
|
});
|
|
test('without `at`, falls back to first occurrence (unchanged behavior)', () => {
|
|
const src = `services:\n a:\n restar: always\n`;
|
|
const out = applyQuickFix(src, { kind: 'replace-in-line', line: 3, find: 'restar', replace: 'restart' });
|
|
expect(out).toContain('restart: always');
|
|
});
|
|
});
|