Files
wehub-resource-sync e30e75b5d4
Changesets / Create Version PR (push) Has been cancelled
Deploy Shadcn Registry / Deploy Production (push) Has been cancelled
Template Metrics / LOC + Bundle Size (push) Has been cancelled
Code Quality / Oxlint + Oxfmt (push) Has been cancelled
Code Quality / Template Sync (push) Has been cancelled
Code Quality / Build Changed Packages (push) Has been cancelled
Code Quality / Test Changed Packages (push) Has been cancelled
Deploy Expo Example / Deploy Production (push) Has been cancelled
Deploy Ink Example / Deploy Production (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.12) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.12) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:40:13 +08:00

166 lines
5.2 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach } from "vitest";
import * as fs from "node:fs";
import * as path from "node:path";
import * as os from "node:os";
import {
scanForImport,
getFilesContaining,
} from "../../src/lib/utils/file-scanner";
describe("file-scanner utilities", () => {
let testDir: string;
beforeEach(() => {
testDir = fs.mkdtempSync(path.join(os.tmpdir(), "cli-test-"));
});
afterEach(() => {
if (fs.existsSync(testDir)) {
fs.rmSync(testDir, { recursive: true, force: true });
}
});
describe("scanForImport", () => {
it("should return false when no files match", () => {
const result = scanForImport("@assistant-ui/react", { cwd: testDir });
expect(result).toBe(false);
});
it("should return true when import is found in a file", () => {
const filePath = path.join(testDir, "test.ts");
fs.writeFileSync(
filePath,
'import { Thread } from "@assistant-ui/react";',
);
const result = scanForImport("@assistant-ui/react", { cwd: testDir });
expect(result).toBe(true);
});
it("should handle array of import patterns", () => {
const filePath = path.join(testDir, "test.tsx");
fs.writeFileSync(
filePath,
'import { useChat } from "@assistant-ui/react-ai-sdk";',
);
const result = scanForImport(
["@assistant-ui/react", "@assistant-ui/react-ai-sdk"],
{ cwd: testDir },
);
expect(result).toBe(true);
});
it("should return false when none of the patterns match", () => {
const filePath = path.join(testDir, "test.ts");
fs.writeFileSync(filePath, 'import React from "react";');
const result = scanForImport(
["@assistant-ui/react", "@assistant-ui/react-ai-sdk"],
{ cwd: testDir },
);
expect(result).toBe(false);
});
it("should ignore node_modules directory", () => {
const nodeModulesPath = path.join(testDir, "node_modules");
fs.mkdirSync(nodeModulesPath);
fs.writeFileSync(
path.join(nodeModulesPath, "test.ts"),
'import { Thread } from "@assistant-ui/react";',
);
const result = scanForImport("@assistant-ui/react", { cwd: testDir });
expect(result).toBe(false);
});
it("should ignore build and dist directories", () => {
const distPath = path.join(testDir, "dist");
fs.mkdirSync(distPath);
fs.writeFileSync(
path.join(distPath, "test.js"),
'import { Thread } from "@assistant-ui/react";',
);
const result = scanForImport("@assistant-ui/react", { cwd: testDir });
expect(result).toBe(false);
});
it("should handle nested directories", () => {
const srcPath = path.join(testDir, "src", "components");
fs.mkdirSync(srcPath, { recursive: true });
fs.writeFileSync(
path.join(srcPath, "Chat.tsx"),
'import { Thread } from "@assistant-ui/react";',
);
const result = scanForImport("@assistant-ui/react", { cwd: testDir });
expect(result).toBe(true);
});
});
describe("getFilesContaining", () => {
it("should return empty array when no files match", () => {
const result = getFilesContaining("@assistant-ui/react", {
cwd: testDir,
});
expect(result).toEqual([]);
});
it("should return list of files containing the search string", () => {
const file1 = path.join(testDir, "test1.ts");
const file2 = path.join(testDir, "test2.ts");
const file3 = path.join(testDir, "test3.ts");
fs.writeFileSync(file1, 'import { Thread } from "@assistant-ui/react";');
fs.writeFileSync(file2, 'import React from "react";');
fs.writeFileSync(file3, 'import { useChat } from "@assistant-ui/react";');
const result = getFilesContaining("@assistant-ui/react", {
cwd: testDir,
});
expect(result).toHaveLength(2);
expect(result).toContain(file1);
expect(result).toContain(file3);
expect(result).not.toContain(file2);
});
it("should handle nested directories", () => {
const srcPath = path.join(testDir, "src");
fs.mkdirSync(srcPath);
const file1 = path.join(srcPath, "Chat.tsx");
const file2 = path.join(testDir, "App.tsx");
fs.writeFileSync(file1, 'import { Thread } from "@assistant-ui/react";');
fs.writeFileSync(file2, 'import { Thread } from "@assistant-ui/react";');
const result = getFilesContaining("@assistant-ui/react", {
cwd: testDir,
});
expect(result).toHaveLength(2);
expect(result).toContain(file1);
expect(result).toContain(file2);
});
it("should ignore unreadable files gracefully", () => {
const file1 = path.join(testDir, "test1.ts");
fs.writeFileSync(file1, 'import { Thread } from "@assistant-ui/react";');
// Create a directory with the same name as a file pattern would match
// This tests the error handling
const unreadableDir = path.join(testDir, "unreadable.ts");
fs.mkdirSync(unreadableDir);
const result = getFilesContaining("@assistant-ui/react", {
cwd: testDir,
});
expect(result).toContain(file1);
expect(result).not.toContain(unreadableDir);
});
});
});