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:
@@ -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";
|
||||
import type { TaskStore } from "@fusion/core";
|
||||
|
||||
// Create mock functions that can be configured in tests
|
||||
// Use vi.hoisted to hoist alongside vi.mock
|
||||
const mocks = vi.hoisted(() => ({
|
||||
mockReaddir: vi.fn(),
|
||||
mockReadFile: vi.fn(),
|
||||
mockWriteFile: vi.fn(),
|
||||
mockStat: vi.fn(),
|
||||
mockExistsSync: vi.fn(),
|
||||
}));
|
||||
// Mock node:fs/promises
|
||||
const mockReaddir = vi.fn();
|
||||
const mockReadFile = vi.fn();
|
||||
const mockWriteFile = vi.fn();
|
||||
const mockStat = vi.fn();
|
||||
|
||||
// Hoist mocks alongside vi.mock - must include default export
|
||||
vi.mock("node:fs/promises", () => {
|
||||
vi.mock("node:fs/promises", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof 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,
|
||||
...actual,
|
||||
readdir: (...args: any[]) => mockReaddir(...args),
|
||||
readFile: (...args: any[]) => mockReadFile(...args),
|
||||
writeFile: (...args: any[]) => mockWriteFile(...args),
|
||||
stat: (...args: any[]) => mockStat(...args),
|
||||
};
|
||||
});
|
||||
|
||||
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 {
|
||||
default: {
|
||||
existsSync: mocks.mockExistsSync,
|
||||
},
|
||||
existsSync: mocks.mockExistsSync,
|
||||
...actual,
|
||||
existsSync: (...args: any[]) => mockExistsSync(...args),
|
||||
};
|
||||
});
|
||||
|
||||
// Export mocks for use in tests
|
||||
export const { mockReaddir, mockReadFile, mockWriteFile, mockStat, mockExistsSync } = mocks;
|
||||
|
||||
describe("FileServiceError", () => {
|
||||
it("constructor sets code and name correctly", () => {
|
||||
const error = new FileServiceError("Test message", "ETEST");
|
||||
|
||||
@@ -118,6 +118,7 @@ describe("GitHubPollingService", () => {
|
||||
store: mockStore,
|
||||
token: "test-token",
|
||||
pollingIntervalMs: 60_000,
|
||||
rateLimiter: new GitHubRateLimiter(),
|
||||
});
|
||||
|
||||
mockGetBadgeStatusesBatch.mockReset();
|
||||
|
||||
Reference in New Issue
Block a user