Files
paseo/packages/app/src/utils/file-mention-autocomplete.test.ts
T
bd937850b3 feat: add workspace files to chat from Files and Changes
* feat(app): open changed files from context menu

* fix(app): preserve changed-file row behavior

* feat(app): add changed files to open chats

* feat(app): share file actions across explorer and changes

* feat(app): attach workspace files to focused chat

* feat(app): drag workspace files into chat

* refactor(app): use file actions menu for changed files

* fix(app): open changed-file actions on right click

* test(app): cover direct file attachment flow

* fix(app): enable add to chat on native

* fix(app): align workspace file pane rows

* refactor(app): simplify workspace file attachments

* fix(app): preserve uploaded file draft attachments

---------

Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
2026-07-22 15:58:24 +02:00

82 lines
2.3 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
applyFileMentionReplacement,
findActiveFileMention,
formatQuotedFileMentionPath,
} from "./file-mention-autocomplete";
describe("findActiveFileMention", () => {
it("detects mentions at the start of input", () => {
const mention = findActiveFileMention({
text: "@src/components",
cursorIndex: "@src/components".length,
});
expect(mention).toEqual({
start: 0,
end: "@src/components".length,
query: "src/components",
});
});
it("detects mentions in the middle of input using cursor position", () => {
const text = 'read "@src/com" before merging';
const cursorIndex = text.indexOf('"') + 9;
const mention = findActiveFileMention({
text,
cursorIndex,
});
expect(mention).toEqual({
start: text.indexOf("@"),
end: cursorIndex,
query: "src/com",
});
});
it("returns null when cursor is outside the mention token", () => {
const text = "please review @src/components now";
const mention = findActiveFileMention({
text,
cursorIndex: text.length,
});
expect(mention).toBeNull();
});
it("returns null when @ at start is followed by a delimiter", () => {
const mention = findActiveFileMention({
text: "@ ",
cursorIndex: 2,
});
expect(mention).toBeNull();
});
});
describe("formatQuotedFileMentionPath", () => {
it("quotes workspace-relative paths using file mention escaping", () => {
expect(formatQuotedFileMentionPath('src/changed "file".ts')).toBe(
'"src/changed \\"file\\".ts"',
);
});
});
describe("applyFileMentionReplacement", () => {
it("replaces only the active @query segment with a quoted relative path", () => {
const text = "open @src/com next";
const next = applyFileMentionReplacement({
text,
mention: { start: 5, end: 13, query: "src/com" },
relativePath: "src/components/chat.tsx",
});
expect(next).toBe('open "src/components/chat.tsx" next');
});
it("escapes double quotes in replacement path", () => {
const text = "@foo";
const next = applyFileMentionReplacement({
text,
mention: { start: 0, end: 4, query: "foo" },
relativePath: 'src/"quoted".ts',
});
expect(next).toBe('"src/\\"quoted\\".ts"');
});
});