feat: refactor tests and improve mocking for file-service and GitHub polling
- Updated mocking strategy for node:fs and node:fs/promises in file-service tests. - Removed redundant test files and improved test implementations for better clarity. - Enhanced GitHub polling service tests with rate limiter integration.
This commit is contained in:
@@ -94,7 +94,7 @@ function createMockServer(portToReturn: number = 0) {
|
|||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mockListen = vi.fn<(port: number) => EventEmitter<DefaultEventMap> & { listen: ReturnType<typeof vi.fn>; address: ReturnType<typeof vi.fn>; close: ReturnType<typeof vi.fn> }>((port: number) => {
|
const mockListen = vi.fn((port: number) => {
|
||||||
const server = createMockServer(port);
|
const server = createMockServer(port);
|
||||||
process.nextTick(() => server.emit("listening"));
|
process.nextTick(() => server.emit("listening"));
|
||||||
return server;
|
return server;
|
||||||
@@ -828,14 +828,14 @@ describe("runDashboard — port fallback on EADDRINUSE", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Override mockListen for one call: simulate EADDRINUSE
|
// Override mockListen for one call: simulate EADDRINUSE
|
||||||
mockListen.mockImplementationOnce((_port: number) => {
|
mockListen.mockImplementationOnce(((_port: number) => {
|
||||||
process.nextTick(() => {
|
process.nextTick(() => {
|
||||||
const err = new Error("listen EADDRINUSE: address already in use") as NodeJS.ErrnoException;
|
const err = new Error("listen EADDRINUSE: address already in use") as NodeJS.ErrnoException;
|
||||||
err.code = "EADDRINUSE";
|
err.code = "EADDRINUSE";
|
||||||
serverEmitter.emit("error", err);
|
serverEmitter.emit("error", err);
|
||||||
});
|
});
|
||||||
return serverEmitter;
|
return serverEmitter;
|
||||||
});
|
}) as any);
|
||||||
|
|
||||||
await runDashboard(4040, { open: false });
|
await runDashboard(4040, { open: false });
|
||||||
|
|
||||||
@@ -866,14 +866,14 @@ describe("runDashboard — port fallback on EADDRINUSE", () => {
|
|||||||
close: vi.fn(),
|
close: vi.fn(),
|
||||||
});
|
});
|
||||||
|
|
||||||
mockListen.mockImplementationOnce((_port: number) => {
|
mockListen.mockImplementationOnce(((_port: number) => {
|
||||||
process.nextTick(() => {
|
process.nextTick(() => {
|
||||||
const err = new Error("listen EADDRINUSE: address already in use") as NodeJS.ErrnoException;
|
const err = new Error("listen EADDRINUSE: address already in use") as NodeJS.ErrnoException;
|
||||||
err.code = "EADDRINUSE";
|
err.code = "EADDRINUSE";
|
||||||
serverEmitter.emit("error", err);
|
serverEmitter.emit("error", err);
|
||||||
});
|
});
|
||||||
return serverEmitter;
|
return serverEmitter;
|
||||||
});
|
}) as any);
|
||||||
|
|
||||||
await runDashboard(4040, { open: false });
|
await runDashboard(4040, { open: false });
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ vi.mock("lucide-react", () => ({
|
|||||||
Lightbulb: () => null,
|
Lightbulb: () => null,
|
||||||
ListTree: () => null,
|
ListTree: () => null,
|
||||||
Zap: () => null,
|
Zap: () => null,
|
||||||
|
ChevronDown: () => null,
|
||||||
|
ChevronUp: () => null,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Mock the api module
|
// Mock the api module
|
||||||
@@ -28,6 +30,7 @@ vi.mock("../../api", () => ({
|
|||||||
defaultPresetBySize: {},
|
defaultPresetBySize: {},
|
||||||
}),
|
}),
|
||||||
uploadAttachment: vi.fn(),
|
uploadAttachment: vi.fn(),
|
||||||
|
updateGlobalSettings: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const MOCK_MODELS: ModelInfo[] = [
|
const MOCK_MODELS: ModelInfo[] = [
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
||||||
import type { TaskStore } from "@fusion/core";
|
|
||||||
|
|
||||||
// Create mock functions that can be configured in tests
|
|
||||||
const mocks = vi.hoisted(() => ({
|
|
||||||
mockReaddir: vi.fn(),
|
|
||||||
mockReadFile: vi.fn(),
|
|
||||||
mockWriteFile: vi.fn(),
|
|
||||||
mockStat: vi.fn(),
|
|
||||||
mockExistsSync: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Use vi.mock with __mocks__ pattern
|
|
||||||
vi.mock("node:fs/promises", () => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
},
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.mock("node:fs", () => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
},
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Import file-service
|
|
||||||
import { listProjectFiles } from "../file-service";
|
|
||||||
|
|
||||||
describe("debug", () => {
|
|
||||||
it("test", async () => {
|
|
||||||
const mockGetRootDir = vi.fn();
|
|
||||||
const mockStore = {
|
|
||||||
getRootDir: mockGetRootDir,
|
|
||||||
} as unknown as TaskStore;
|
|
||||||
|
|
||||||
mockGetRootDir.mockReturnValue("/project");
|
|
||||||
|
|
||||||
mocks.mockStat.mockResolvedValue({
|
|
||||||
isDirectory: () => true,
|
|
||||||
isFile: () => false,
|
|
||||||
});
|
|
||||||
mocks.mockReaddir.mockResolvedValue([]);
|
|
||||||
|
|
||||||
console.log("Calling listProjectFiles...");
|
|
||||||
try {
|
|
||||||
const result = await listProjectFiles(mockStore, "./src");
|
|
||||||
console.log("Result:", result);
|
|
||||||
console.log("mockStat calls:", mocks.mockStat.mock.calls);
|
|
||||||
expect(result.path).toBe("src");
|
|
||||||
expect(result.entries).toEqual([]);
|
|
||||||
} catch (e) {
|
|
||||||
console.log("Error:", e);
|
|
||||||
console.log("mockStat calls:", mocks.mockStat.mock.calls);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
||||||
import type { TaskStore } from "@fusion/core";
|
|
||||||
import { dirname, resolve } from "path";
|
|
||||||
|
|
||||||
// Create mock functions that can be configured in tests
|
|
||||||
const mocks = vi.hoisted(() => ({
|
|
||||||
mockReaddir: vi.fn(),
|
|
||||||
mockReadFile: vi.fn(),
|
|
||||||
mockWriteFile: vi.fn(),
|
|
||||||
mockStat: vi.fn(),
|
|
||||||
mockExistsSync: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Hoist mocks alongside vi.mock
|
|
||||||
vi.mock("node:fs/promises", async () => {
|
|
||||||
const actual = await import("node:fs/promises");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
},
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.mock("node:fs", async () => {
|
|
||||||
const actual = await import("node:fs");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
},
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Import AFTER mocks are set up
|
|
||||||
import { writeProjectFile } from "../file-service";
|
|
||||||
|
|
||||||
describe("debug", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
mocks.mockStat.mockReset();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("test", async () => {
|
|
||||||
const mockGetRootDir = vi.fn();
|
|
||||||
const mockStore = {
|
|
||||||
getRootDir: mockGetRootDir,
|
|
||||||
} as unknown as TaskStore;
|
|
||||||
|
|
||||||
mockGetRootDir.mockReturnValue("/test/project");
|
|
||||||
|
|
||||||
const basePath = resolve("/test/project");
|
|
||||||
const filePath = "file.txt/sub.txt";
|
|
||||||
const resolvedPath = resolve(basePath, filePath);
|
|
||||||
const parentDir = dirname(resolvedPath);
|
|
||||||
|
|
||||||
// Test the mock directly
|
|
||||||
mocks.mockStat.mockResolvedValue({
|
|
||||||
isDirectory: () => false,
|
|
||||||
isFile: () => true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await mocks.mockStat("/test/some/path");
|
|
||||||
console.log("Direct mock result:", result);
|
|
||||||
console.log("Direct mock isDirectory():", result.isDirectory());
|
|
||||||
|
|
||||||
// Now test writeProjectFile
|
|
||||||
try {
|
|
||||||
await writeProjectFile(mockStore, filePath, "content");
|
|
||||||
console.log("Success!");
|
|
||||||
} catch (e: any) {
|
|
||||||
console.log("Error:", e.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
||||||
import type { TaskStore } from "@fusion/core";
|
|
||||||
import { dirname, resolve } from "path";
|
|
||||||
|
|
||||||
// Create mock functions that can be configured in tests
|
|
||||||
const mocks = vi.hoisted(() => ({
|
|
||||||
mockReaddir: vi.fn(),
|
|
||||||
mockReadFile: vi.fn(),
|
|
||||||
mockWriteFile: vi.fn(),
|
|
||||||
mockStat: vi.fn(),
|
|
||||||
mockExistsSync: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Hoist mocks alongside vi.mock
|
|
||||||
vi.mock("node:fs/promises", async () => {
|
|
||||||
const actual = await import("node:fs/promises");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
},
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.mock("node:fs", async () => {
|
|
||||||
const actual = await import("node:fs");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
},
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Import AFTER mocks are set up
|
|
||||||
import { writeProjectFile } from "../file-service";
|
|
||||||
|
|
||||||
describe("debug", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
mocks.mockStat.mockReset();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("test", async () => {
|
|
||||||
const mockGetRootDir = vi.fn();
|
|
||||||
const mockStore = {
|
|
||||||
getRootDir: mockGetRootDir,
|
|
||||||
} as unknown as TaskStore;
|
|
||||||
|
|
||||||
mockGetRootDir.mockReturnValue("/test/project");
|
|
||||||
|
|
||||||
// Track all stat calls
|
|
||||||
let callCount = 0;
|
|
||||||
mocks.mockStat.mockImplementation(async (path: string) => {
|
|
||||||
callCount++;
|
|
||||||
console.log(`stat call #${callCount}:`, path);
|
|
||||||
|
|
||||||
if (callCount === 1) {
|
|
||||||
// First call - file doesn't exist
|
|
||||||
throw Object.assign(new Error("ENOENT"), { code: "ENOENT" });
|
|
||||||
}
|
|
||||||
if (callCount === 2) {
|
|
||||||
// Second call - parent is a file
|
|
||||||
return {
|
|
||||||
isDirectory: () => false,
|
|
||||||
isFile: () => true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (callCount === 3) {
|
|
||||||
// Third call - after write
|
|
||||||
return {
|
|
||||||
isDirectory: () => false,
|
|
||||||
isFile: () => true,
|
|
||||||
size: 100,
|
|
||||||
mtime: new Date(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
throw Object.assign(new Error("ENOENT"), { code: "ENOENT" });
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
await writeProjectFile(mockStore, "file.txt/sub.txt", "content");
|
|
||||||
console.log("Success!");
|
|
||||||
} catch (e: any) {
|
|
||||||
console.log("Error:", e.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
||||||
import type { TaskStore } from "@fusion/core";
|
|
||||||
import { dirname, resolve } from "path";
|
|
||||||
|
|
||||||
// Create mock functions that can be configured in tests
|
|
||||||
const mocks = vi.hoisted(() => ({
|
|
||||||
mockReaddir: vi.fn(),
|
|
||||||
mockReadFile: vi.fn(),
|
|
||||||
mockWriteFile: vi.fn(),
|
|
||||||
mockStat: vi.fn(),
|
|
||||||
mockExistsSync: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Hoist mocks alongside vi.mock
|
|
||||||
vi.mock("node:fs/promises", async () => {
|
|
||||||
const actual = await import("node:fs/promises");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
},
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.mock("node:fs", async () => {
|
|
||||||
const actual = await import("node:fs");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
},
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Import AFTER mocks are set up
|
|
||||||
import { writeProjectFile } from "../file-service";
|
|
||||||
|
|
||||||
describe("debug", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
mocks.mockStat.mockReset();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("test", async () => {
|
|
||||||
const mockGetRootDir = vi.fn();
|
|
||||||
const mockStore = {
|
|
||||||
getRootDir: mockGetRootDir,
|
|
||||||
} as unknown as TaskStore;
|
|
||||||
|
|
||||||
mockGetRootDir.mockReturnValue("/test/project");
|
|
||||||
|
|
||||||
let callCount = 0;
|
|
||||||
mocks.mockStat.mockImplementation(async (path: string) => {
|
|
||||||
callCount++;
|
|
||||||
console.log(`stat call #${callCount}:`, path);
|
|
||||||
|
|
||||||
// Return a simple object
|
|
||||||
const result = {
|
|
||||||
isDirectory: () => path.includes("/file.txt"),
|
|
||||||
isFile: () => !path.includes("/file.txt"),
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log(`stat #${callCount} returning:`, result);
|
|
||||||
console.log(`stat #${callCount} isDirectory():`, result.isDirectory());
|
|
||||||
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
await writeProjectFile(mockStore, "file.txt/sub.txt", "content");
|
|
||||||
console.log("Success!");
|
|
||||||
} catch (e: any) {
|
|
||||||
console.log("Error:", e.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
||||||
import type { TaskStore } from "@fusion/core";
|
|
||||||
|
|
||||||
// Create mock functions that can be configured in tests
|
|
||||||
const mocks = vi.hoisted(() => ({
|
|
||||||
mockReaddir: vi.fn(),
|
|
||||||
mockReadFile: vi.fn(),
|
|
||||||
mockWriteFile: vi.fn(),
|
|
||||||
mockStat: vi.fn(),
|
|
||||||
mockExistsSync: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Hoist mocks alongside vi.mock
|
|
||||||
vi.mock("node:fs/promises", async () => {
|
|
||||||
const actual = await import("node:fs/promises");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
},
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.mock("node:fs", async () => {
|
|
||||||
const actual = await import("node:fs");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
},
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Import AFTER mocks are set up
|
|
||||||
import { writeProjectFile } from "../file-service";
|
|
||||||
|
|
||||||
describe("debug", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
mocks.mockStat.mockReset();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("test - parent is not a directory", async () => {
|
|
||||||
const mockGetRootDir = vi.fn();
|
|
||||||
const mockStore = {
|
|
||||||
getRootDir: mockGetRootDir,
|
|
||||||
} as unknown as TaskStore;
|
|
||||||
|
|
||||||
mockGetRootDir.mockReturnValue("/test/project");
|
|
||||||
|
|
||||||
// First call: file doesn't exist (throw ENOENT)
|
|
||||||
// Second call: parent is a file, not a directory (return object with isDirectory: false)
|
|
||||||
// Third call: after write, get file stats
|
|
||||||
mocks.mockStat
|
|
||||||
.mockRejectedValueOnce({ code: "ENOENT" }) // First: file doesn't exist
|
|
||||||
.mockResolvedValueOnce({ // Second: parent is a file
|
|
||||||
isDirectory: () => false,
|
|
||||||
isFile: () => true,
|
|
||||||
})
|
|
||||||
.mockResolvedValueOnce({ // Third: after write
|
|
||||||
isDirectory: () => false,
|
|
||||||
isFile: () => true,
|
|
||||||
size: 100,
|
|
||||||
mtime: new Date(),
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
await writeProjectFile(mockStore, "file.txt/sub.txt", "content");
|
|
||||||
console.log("Success!");
|
|
||||||
} catch (e: any) {
|
|
||||||
console.log("Error:", e.message);
|
|
||||||
expect(e.message).toContain("Parent is not a directory");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
||||||
import type { TaskStore } from "@fusion/core";
|
|
||||||
|
|
||||||
// Create mock functions that can be configured in tests
|
|
||||||
const mocks = vi.hoisted(() => ({
|
|
||||||
mockReaddir: vi.fn(),
|
|
||||||
mockReadFile: vi.fn(),
|
|
||||||
mockWriteFile: vi.fn(),
|
|
||||||
mockStat: vi.fn(),
|
|
||||||
mockExistsSync: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Hoist mocks alongside vi.mock
|
|
||||||
vi.mock("node:fs/promises", async () => {
|
|
||||||
const actual = await import("node:fs/promises");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
},
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.mock("node:fs", async () => {
|
|
||||||
const actual = await import("node:fs");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
},
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Import AFTER mocks are set up
|
|
||||||
import { writeProjectFile } from "../file-service";
|
|
||||||
|
|
||||||
describe("debug", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
mocks.mockStat.mockReset();
|
|
||||||
mocks.mockStat.mockImplementation(async (path: string) => {
|
|
||||||
console.log("stat called:", path);
|
|
||||||
throw { code: "ENOENT" };
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("test - parent is not a directory", async () => {
|
|
||||||
const mockGetRootDir = vi.fn();
|
|
||||||
const mockStore = {
|
|
||||||
getRootDir: mockGetRootDir,
|
|
||||||
} as unknown as TaskStore;
|
|
||||||
|
|
||||||
mockGetRootDir.mockReturnValue("/test/project");
|
|
||||||
|
|
||||||
// First call: file doesn't exist (throw ENOENT)
|
|
||||||
// Second call: parent is a file, not a directory (return object with isDirectory: false)
|
|
||||||
mocks.mockStat
|
|
||||||
.mockRejectedValueOnce({ code: "ENOENT" }) // First: file doesn't exist
|
|
||||||
.mockImplementation(async (path: string) => { // Subsequent calls
|
|
||||||
console.log("Second stat call:", path);
|
|
||||||
return {
|
|
||||||
isDirectory: () => false,
|
|
||||||
isFile: () => true,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
await writeProjectFile(mockStore, "file.txt/sub.txt", "content");
|
|
||||||
console.log("Success!");
|
|
||||||
} catch (e: any) {
|
|
||||||
console.log("Error:", e.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
import { describe, it, expect, vi } from "vitest";
|
|
||||||
import { writeProjectFile } from "../file-service";
|
|
||||||
import type { TaskStore } from "@fusion/core";
|
|
||||||
|
|
||||||
// Create mock functions that can be configured in tests
|
|
||||||
const mocks = vi.hoisted(() => ({
|
|
||||||
mockReaddir: vi.fn(),
|
|
||||||
mockReadFile: vi.fn(),
|
|
||||||
mockWriteFile: vi.fn(),
|
|
||||||
mockStat: vi.fn(),
|
|
||||||
mockExistsSync: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("node:fs/promises", () => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
},
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.mock("node:fs", () => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
},
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("debug", () => {
|
|
||||||
it("test", async () => {
|
|
||||||
const mockGetRootDir = vi.fn();
|
|
||||||
const mockStore = {
|
|
||||||
getRootDir: mockGetRootDir,
|
|
||||||
} as unknown as TaskStore;
|
|
||||||
|
|
||||||
mockGetRootDir.mockReturnValue("/test/project");
|
|
||||||
|
|
||||||
mocks.mockStat
|
|
||||||
.mockRejectedValueOnce({ code: "ENOENT" }) // File doesn't exist
|
|
||||||
.mockResolvedValueOnce({
|
|
||||||
isDirectory: () => false,
|
|
||||||
isFile: () => true,
|
|
||||||
}); // Parent is a file
|
|
||||||
|
|
||||||
console.log("mockStat calls before:", mocks.mockStat.mock.calls);
|
|
||||||
|
|
||||||
try {
|
|
||||||
await writeProjectFile(mockStore, "file.txt/sub.txt", "content");
|
|
||||||
} catch (e) {
|
|
||||||
console.log("Error:", e);
|
|
||||||
console.log("mockStat calls after:", mocks.mockStat.mock.calls);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
import { describe, it, expect, vi } from "vitest";
|
|
||||||
import { writeProjectFile } from "../file-service";
|
|
||||||
import type { TaskStore } from "@fusion/core";
|
|
||||||
|
|
||||||
// Create mock functions that can be configured in tests
|
|
||||||
const mocks = vi.hoisted(() => ({
|
|
||||||
mockReaddir: vi.fn(),
|
|
||||||
mockReadFile: vi.fn(),
|
|
||||||
mockWriteFile: vi.fn(),
|
|
||||||
mockStat: vi.fn(),
|
|
||||||
mockExistsSync: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("node:fs/promises", () => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
},
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.mock("node:fs", () => {
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
},
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("debug", () => {
|
|
||||||
it("test", async () => {
|
|
||||||
const mockGetRootDir = vi.fn();
|
|
||||||
const mockStore = {
|
|
||||||
getRootDir: mockGetRootDir,
|
|
||||||
} as unknown as TaskStore;
|
|
||||||
|
|
||||||
mockGetRootDir.mockReturnValue("/test/project");
|
|
||||||
|
|
||||||
// Setup mock to return specific values for each call
|
|
||||||
mocks.mockStat.mockImplementation((path: string) => {
|
|
||||||
console.log("stat called with:", path);
|
|
||||||
if (path === "/test/project/file.txt/sub.txt") {
|
|
||||||
return Promise.reject({ code: "ENOENT" });
|
|
||||||
}
|
|
||||||
if (path === "/test/project/file.txt") {
|
|
||||||
return Promise.resolve({
|
|
||||||
isDirectory: () => false,
|
|
||||||
isFile: () => true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Promise.reject({ code: "ENOENT" });
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
await writeProjectFile(mockStore, "file.txt/sub.txt", "content");
|
|
||||||
} catch (e) {
|
|
||||||
console.log("Error:", e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
||||||
import type { TaskStore } from "@fusion/core";
|
|
||||||
|
|
||||||
// Create mock functions that can be configured in tests
|
|
||||||
const mocks = vi.hoisted(() => ({
|
|
||||||
mockReaddir: vi.fn(),
|
|
||||||
mockReadFile: vi.fn(),
|
|
||||||
mockWriteFile: vi.fn(),
|
|
||||||
mockStat: vi.fn(),
|
|
||||||
mockExistsSync: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Hoist mocks alongside vi.mock
|
|
||||||
vi.mock("node:fs/promises", async () => {
|
|
||||||
const actual = await import("node:fs/promises");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
},
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.mock("node:fs", async () => {
|
|
||||||
const actual = await import("node:fs");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
},
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Import AFTER mocks are set up
|
|
||||||
import { writeProjectFile } from "../file-service";
|
|
||||||
|
|
||||||
describe("debug", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
mocks.mockStat.mockReset();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("test", async () => {
|
|
||||||
const mockGetRootDir = vi.fn();
|
|
||||||
const mockStore = {
|
|
||||||
getRootDir: mockGetRootDir,
|
|
||||||
} as unknown as TaskStore;
|
|
||||||
|
|
||||||
mockGetRootDir.mockReturnValue("/test/project");
|
|
||||||
|
|
||||||
// Setup mock to return specific values for each call
|
|
||||||
mocks.mockStat.mockImplementation((path: string) => {
|
|
||||||
console.log("stat called with:", path);
|
|
||||||
if (path === "/test/project/file.txt/sub.txt") {
|
|
||||||
return Promise.reject({ code: "ENOENT" });
|
|
||||||
}
|
|
||||||
if (path === "/test/project/file.txt") {
|
|
||||||
return Promise.resolve({
|
|
||||||
isDirectory: () => false,
|
|
||||||
isFile: () => true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Promise.reject({ code: "ENOENT" });
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
await writeProjectFile(mockStore, "file.txt/sub.txt", "content");
|
|
||||||
console.log("Success!");
|
|
||||||
} catch (e: any) {
|
|
||||||
console.log("Error:", e.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
||||||
import type { TaskStore } from "@fusion/core";
|
|
||||||
|
|
||||||
// Create mock functions that can be configured in tests
|
|
||||||
const mocks = vi.hoisted(() => ({
|
|
||||||
mockReaddir: vi.fn(),
|
|
||||||
mockReadFile: vi.fn(),
|
|
||||||
mockWriteFile: vi.fn(),
|
|
||||||
mockStat: vi.fn(),
|
|
||||||
mockExistsSync: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Hoist mocks alongside vi.mock
|
|
||||||
vi.mock("node:fs/promises", async () => {
|
|
||||||
const actual = await import("node:fs/promises");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
},
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.mock("node:fs", async () => {
|
|
||||||
const actual = await import("node:fs");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
},
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Import AFTER mocks are set up
|
|
||||||
import { writeProjectFile } from "../file-service";
|
|
||||||
|
|
||||||
describe("debug", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
mocks.mockStat.mockReset();
|
|
||||||
mocks.mockStat.mockImplementation((path: string) => {
|
|
||||||
console.log("stat called with:", path);
|
|
||||||
if (path === "/test/project/file.txt/sub.txt") {
|
|
||||||
return Promise.reject({ code: "ENOENT" });
|
|
||||||
}
|
|
||||||
if (path === "/test/project/file.txt") {
|
|
||||||
return Promise.resolve({
|
|
||||||
isDirectory: () => false,
|
|
||||||
isFile: () => true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Promise.reject({ code: "ENOENT" });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("test", async () => {
|
|
||||||
const mockGetRootDir = vi.fn();
|
|
||||||
const mockStore = {
|
|
||||||
getRootDir: mockGetRootDir,
|
|
||||||
} as unknown as TaskStore;
|
|
||||||
|
|
||||||
mockGetRootDir.mockReturnValue("/test/project");
|
|
||||||
|
|
||||||
try {
|
|
||||||
await writeProjectFile(mockStore, "file.txt/sub.txt", "content");
|
|
||||||
console.log("Success!");
|
|
||||||
} catch (e: any) {
|
|
||||||
console.log("Error:", e.message);
|
|
||||||
expect(e.message).toContain("Parent is not a directory");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
||||||
import type { TaskStore } from "@fusion/core";
|
|
||||||
|
|
||||||
// Create mock functions that can be configured in tests
|
|
||||||
const mocks = vi.hoisted(() => ({
|
|
||||||
mockReaddir: vi.fn(),
|
|
||||||
mockReadFile: vi.fn(),
|
|
||||||
mockWriteFile: vi.fn(),
|
|
||||||
mockStat: vi.fn(),
|
|
||||||
mockExistsSync: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Hoist mocks alongside vi.mock
|
|
||||||
vi.mock("node:fs/promises", async () => {
|
|
||||||
const actual = await import("node:fs/promises");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
},
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.mock("node:fs", async () => {
|
|
||||||
const actual = await import("node:fs");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
},
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Import AFTER mocks are set up
|
|
||||||
import { writeProjectFile } from "../file-service";
|
|
||||||
|
|
||||||
describe("debug", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
mocks.mockStat.mockReset();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("test", async () => {
|
|
||||||
const mockGetRootDir = vi.fn();
|
|
||||||
const mockStore = {
|
|
||||||
getRootDir: mockGetRootDir,
|
|
||||||
} as unknown as TaskStore;
|
|
||||||
|
|
||||||
mockGetRootDir.mockReturnValue("/test/project");
|
|
||||||
|
|
||||||
// Setup mock
|
|
||||||
mocks.mockStat
|
|
||||||
.mockRejectedValueOnce({ code: "ENOENT" }) // First call - file doesn't exist
|
|
||||||
.mockResolvedValueOnce({ // Second call - parent is a file
|
|
||||||
isDirectory: () => false,
|
|
||||||
isFile: () => true,
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("Before call");
|
|
||||||
|
|
||||||
try {
|
|
||||||
await writeProjectFile(mockStore, "file.txt/sub.txt", "content");
|
|
||||||
console.log("Success!");
|
|
||||||
} catch (e: any) {
|
|
||||||
console.log("Error:", e.message);
|
|
||||||
console.log("mockStat calls:", mocks.mockStat.mock.calls);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
||||||
import type { TaskStore } from "@fusion/core";
|
|
||||||
|
|
||||||
// Create mock functions that can be configured in tests
|
|
||||||
const mocks = vi.hoisted(() => ({
|
|
||||||
mockReaddir: vi.fn(),
|
|
||||||
mockReadFile: vi.fn(),
|
|
||||||
mockWriteFile: vi.fn(),
|
|
||||||
mockStat: vi.fn(),
|
|
||||||
mockExistsSync: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Hoist mocks alongside vi.mock
|
|
||||||
vi.mock("node:fs/promises", async () => {
|
|
||||||
const actual = await import("node:fs/promises");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
},
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.mock("node:fs", async () => {
|
|
||||||
const actual = await import("node:fs");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
},
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Import AFTER mocks are set up
|
|
||||||
import { writeProjectFile } from "../file-service";
|
|
||||||
|
|
||||||
describe("debug", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
mocks.mockStat.mockReset();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("test", async () => {
|
|
||||||
const mockGetRootDir = vi.fn();
|
|
||||||
const mockStore = {
|
|
||||||
getRootDir: mockGetRootDir,
|
|
||||||
} as unknown as TaskStore;
|
|
||||||
|
|
||||||
mockGetRootDir.mockReturnValue("/test/project");
|
|
||||||
|
|
||||||
// Setup mock to return specific values
|
|
||||||
mocks.mockStat.mockImplementation(async (path: string) => {
|
|
||||||
console.log("stat called:", path);
|
|
||||||
if (path === "/test/project/file.txt/sub.txt") {
|
|
||||||
throw { code: "ENOENT" };
|
|
||||||
}
|
|
||||||
if (path === "/test/project/file.txt") {
|
|
||||||
const result = {
|
|
||||||
isDirectory: () => false,
|
|
||||||
isFile: () => true,
|
|
||||||
};
|
|
||||||
console.log("Returning for parent:", result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
throw { code: "ENOENT" };
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
await writeProjectFile(mockStore, "file.txt/sub.txt", "content");
|
|
||||||
console.log("Success!");
|
|
||||||
} catch (e: any) {
|
|
||||||
console.log("Error:", e.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
||||||
import type { TaskStore } from "@fusion/core";
|
|
||||||
import { join, resolve, dirname } from "path";
|
|
||||||
|
|
||||||
// Create mock functions that can be configured in tests
|
|
||||||
const mocks = vi.hoisted(() => ({
|
|
||||||
mockReaddir: vi.fn(),
|
|
||||||
mockReadFile: vi.fn(),
|
|
||||||
mockWriteFile: vi.fn(),
|
|
||||||
mockStat: vi.fn(),
|
|
||||||
mockExistsSync: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Hoist mocks alongside vi.mock
|
|
||||||
vi.mock("node:fs/promises", async () => {
|
|
||||||
const actual = await import("node:fs/promises");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
},
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.mock("node:fs", async () => {
|
|
||||||
const actual = await import("node:fs");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
},
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Import AFTER mocks are set up
|
|
||||||
import { writeProjectFile } from "../file-service";
|
|
||||||
|
|
||||||
describe("debug", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
mocks.mockStat.mockReset();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("test", async () => {
|
|
||||||
const mockGetRootDir = vi.fn();
|
|
||||||
const mockStore = {
|
|
||||||
getRootDir: mockGetRootDir,
|
|
||||||
} as unknown as TaskStore;
|
|
||||||
|
|
||||||
mockGetRootDir.mockReturnValue("/test/project");
|
|
||||||
|
|
||||||
// Log what paths will be used
|
|
||||||
const basePath = resolve("/test/project");
|
|
||||||
const filePath = "file.txt/sub.txt";
|
|
||||||
const resolvedPath = resolve(basePath, filePath);
|
|
||||||
const parentDir = dirname(resolvedPath);
|
|
||||||
|
|
||||||
console.log("basePath:", basePath);
|
|
||||||
console.log("filePath:", filePath);
|
|
||||||
console.log("resolvedPath:", resolvedPath);
|
|
||||||
console.log("parentDir:", parentDir);
|
|
||||||
|
|
||||||
// Setup mock to return specific values
|
|
||||||
mocks.mockStat.mockImplementation(async (path: string) => {
|
|
||||||
console.log("stat called:", path);
|
|
||||||
if (path === resolvedPath) {
|
|
||||||
console.log("File path match!");
|
|
||||||
throw { code: "ENOENT" };
|
|
||||||
}
|
|
||||||
if (path === parentDir) {
|
|
||||||
console.log("Parent dir match!");
|
|
||||||
return {
|
|
||||||
isDirectory: () => false,
|
|
||||||
isFile: () => true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
console.log("No match for:", path);
|
|
||||||
throw { code: "ENOENT" };
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
await writeProjectFile(mockStore, filePath, "content");
|
|
||||||
console.log("Success!");
|
|
||||||
} catch (e: any) {
|
|
||||||
console.log("Error:", e.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
||||||
import type { TaskStore } from "@fusion/core";
|
|
||||||
import { dirname, resolve } from "path";
|
|
||||||
|
|
||||||
// Create mock functions that can be configured in tests
|
|
||||||
const mocks = vi.hoisted(() => ({
|
|
||||||
mockReaddir: vi.fn(),
|
|
||||||
mockReadFile: vi.fn(),
|
|
||||||
mockWriteFile: vi.fn(),
|
|
||||||
mockStat: vi.fn(),
|
|
||||||
mockExistsSync: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Hoist mocks alongside vi.mock
|
|
||||||
vi.mock("node:fs/promises", async () => {
|
|
||||||
const actual = await import("node:fs/promises");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
},
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.mock("node:fs", async () => {
|
|
||||||
const actual = await import("node:fs");
|
|
||||||
return {
|
|
||||||
default: {
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
},
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Import AFTER mocks are set up
|
|
||||||
import { writeProjectFile } from "../file-service";
|
|
||||||
|
|
||||||
describe("debug", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
mocks.mockStat.mockReset();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("test", async () => {
|
|
||||||
const mockGetRootDir = vi.fn();
|
|
||||||
const mockStore = {
|
|
||||||
getRootDir: mockGetRootDir,
|
|
||||||
} as unknown as TaskStore;
|
|
||||||
|
|
||||||
mockGetRootDir.mockReturnValue("/test/project");
|
|
||||||
|
|
||||||
const basePath = resolve("/test/project");
|
|
||||||
const filePath = "file.txt/sub.txt";
|
|
||||||
const resolvedPath = resolve(basePath, filePath);
|
|
||||||
const parentDir = dirname(resolvedPath);
|
|
||||||
|
|
||||||
// Create a proper stats object
|
|
||||||
const fileNotDirStats = {
|
|
||||||
isDirectory: () => false,
|
|
||||||
isFile: () => true,
|
|
||||||
size: 100,
|
|
||||||
mtime: new Date(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Setup mock - note: use .mockResolvedValue for promises
|
|
||||||
mocks.mockStat.mockImplementation(async (path: string) => {
|
|
||||||
console.log("stat called:", path);
|
|
||||||
if (path === resolvedPath) {
|
|
||||||
console.log("File path - throwing ENOENT");
|
|
||||||
throw Object.assign(new Error("ENOENT"), { code: "ENOENT" });
|
|
||||||
}
|
|
||||||
if (path === parentDir) {
|
|
||||||
console.log("Parent dir - returning file stats");
|
|
||||||
console.log("Returning:", fileNotDirStats);
|
|
||||||
console.log("isDirectory():", fileNotDirStats.isDirectory());
|
|
||||||
return fileNotDirStats;
|
|
||||||
}
|
|
||||||
throw Object.assign(new Error("ENOENT"), { code: "ENOENT" });
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
await writeProjectFile(mockStore, filePath, "content");
|
|
||||||
console.log("Success!");
|
|
||||||
} catch (e: any) {
|
|
||||||
console.log("Error:", e.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -14,44 +14,34 @@ import {
|
|||||||
} from "../file-service.js";
|
} from "../file-service.js";
|
||||||
import type { TaskStore } from "@fusion/core";
|
import type { TaskStore } from "@fusion/core";
|
||||||
|
|
||||||
// Create mock functions that can be configured in tests
|
// Mock node:fs/promises
|
||||||
// Use vi.hoisted to hoist alongside vi.mock
|
const mockReaddir = vi.fn();
|
||||||
const mocks = vi.hoisted(() => ({
|
const mockReadFile = vi.fn();
|
||||||
mockReaddir: vi.fn(),
|
const mockWriteFile = vi.fn();
|
||||||
mockReadFile: vi.fn(),
|
const mockStat = vi.fn();
|
||||||
mockWriteFile: vi.fn(),
|
|
||||||
mockStat: vi.fn(),
|
|
||||||
mockExistsSync: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Hoist mocks alongside vi.mock - must include default export
|
vi.mock("node:fs/promises", async (importOriginal) => {
|
||||||
vi.mock("node:fs/promises", () => {
|
const actual = await importOriginal<typeof import("node:fs/promises")>();
|
||||||
return {
|
return {
|
||||||
default: {
|
...actual,
|
||||||
readdir: mocks.mockReaddir,
|
readdir: (...args: any[]) => mockReaddir(...args),
|
||||||
readFile: mocks.mockReadFile,
|
readFile: (...args: any[]) => mockReadFile(...args),
|
||||||
writeFile: mocks.mockWriteFile,
|
writeFile: (...args: any[]) => mockWriteFile(...args),
|
||||||
stat: mocks.mockStat,
|
stat: (...args: any[]) => mockStat(...args),
|
||||||
},
|
|
||||||
readdir: mocks.mockReaddir,
|
|
||||||
readFile: mocks.mockReadFile,
|
|
||||||
writeFile: mocks.mockWriteFile,
|
|
||||||
stat: mocks.mockStat,
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
vi.mock("node:fs", () => {
|
// Mock node:fs
|
||||||
|
const mockExistsSync = vi.fn();
|
||||||
|
|
||||||
|
vi.mock("node:fs", async (importOriginal) => {
|
||||||
|
const actual = await importOriginal<typeof import("node:fs")>();
|
||||||
return {
|
return {
|
||||||
default: {
|
...actual,
|
||||||
existsSync: mocks.mockExistsSync,
|
existsSync: (...args: any[]) => mockExistsSync(...args),
|
||||||
},
|
|
||||||
existsSync: mocks.mockExistsSync,
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// Export mocks for use in tests
|
|
||||||
export const { mockReaddir, mockReadFile, mockWriteFile, mockStat, mockExistsSync } = mocks;
|
|
||||||
|
|
||||||
describe("FileServiceError", () => {
|
describe("FileServiceError", () => {
|
||||||
it("constructor sets code and name correctly", () => {
|
it("constructor sets code and name correctly", () => {
|
||||||
const error = new FileServiceError("Test message", "ETEST");
|
const error = new FileServiceError("Test message", "ETEST");
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ describe("GitHubPollingService", () => {
|
|||||||
store: mockStore,
|
store: mockStore,
|
||||||
token: "test-token",
|
token: "test-token",
|
||||||
pollingIntervalMs: 60_000,
|
pollingIntervalMs: 60_000,
|
||||||
|
rateLimiter: new GitHubRateLimiter(),
|
||||||
});
|
});
|
||||||
|
|
||||||
mockGetBadgeStatusesBatch.mockReset();
|
mockGetBadgeStatusesBatch.mockReset();
|
||||||
|
|||||||
Reference in New Issue
Block a user