Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch from Gaze to Chokidar #146

Merged
merged 5 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/dev.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Gaze } from "gaze";
import { FSWatcher } from "chokidar";
import path from "path";
import { Server as IoServer } from "socket.io";
import { buildApp } from "@/lib/build";
Expand All @@ -15,7 +15,7 @@ var appDevJsons = [];
var appDevJsonPath = "bos-loader.json";
var appDevOptions: null | DevOptions = null;
let io: null | IoServer = null;
let fileWatcher: null | Gaze = null;
let fileWatcher: null | FSWatcher = null;

export type DevOptions = {
port?: number; // port to run dev server
Expand Down
21 changes: 15 additions & 6 deletions lib/watcher.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import { Gaze } from "gaze";
import path from "path"
import chokidar, { FSWatcher } from "chokidar";

export function startFileWatcher(watchPaths: string[], callback: Function): Gaze {
const gaze = new Gaze(watchPaths, { debounceDelay: 100 });
export function startFileWatcher(watchPaths: string[], callback: Function): FSWatcher {
const watcher = chokidar.watch(watchPaths, {
ignoreInitial: true,
awaitWriteFinish: {
stabilityThreshold: 100,
pollInterval: 100
}
});

// @ts-ignore
gaze.on("all", callback);
watcher.on('all', (event, relativePath) => {
const absolutePath = path.resolve(relativePath)
callback(event, absolutePath);
});

return gaze;
return watcher;
}
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@
"@near-js/types": "^0.2.0",
"axios": "^1.7.2",
"body-parser": "^1.20.2",
"chokidar": "^3.6.0",
"commander": "^11.1.0",
"crypto-js": "^4.2.0",
"express": "^4.18.2",
"fs-extra": "^11.2.0",
"gaze": "^1.1.3",
"glob": "^10.3.10",
"http-proxy": "^1.18.1",
"https": "^1.0.0",
Expand All @@ -55,7 +55,6 @@
"@types/crypto-js": "^4.2.2",
"@types/express": "^4.17.21",
"@types/fs-extra": "^11.0.4",
"@types/gaze": "^1.1.5",
"@types/jest": "^29.5.11",
"@types/node": "^20.11.30",
"@types/supertest": "^6.0.2",
Expand Down
17 changes: 12 additions & 5 deletions tests/unit/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { startFileWatcher } from "@/lib/watcher";
import http from "http";
import path from "path";
import { Server as IoServer } from "socket.io";
import { Gaze } from "gaze";
import chokidar from "chokidar";

import { vol } from 'memfs';
jest.mock('fs', () => require('memfs').fs);
Expand Down Expand Up @@ -43,7 +43,6 @@ describe("dev", () => {
(loadConfig as jest.MockedFunction<typeof loadConfig>).mockResolvedValue(mockConfig);
(startDevServer as jest.MockedFunction<typeof startDevServer>).mockReturnValue({} as http.Server);
(startSocket as jest.MockedFunction<typeof startSocket>).mockReturnValue(new IoServer());
(startFileWatcher as jest.MockedFunction<typeof startFileWatcher>).mockReturnValue(new Gaze(mockSrc));
(buildApp as jest.MockedFunction<typeof buildApp>).mockReturnValue({} as Promise<any>);
});

Expand Down Expand Up @@ -89,8 +88,16 @@ describe("dev", () => {
});

it("should add correct watch paths after adding apps", async () => {
const mockedGazeAdd = jest.spyOn(Gaze.prototype, 'add');

const mockAdd = jest.fn();
const mockWatch = jest.fn().mockReturnValue({
add: mockAdd,
});
(chokidar.watch as jest.Mock) = mockWatch;

(startFileWatcher as jest.MockedFunction<typeof startFileWatcher>).mockReturnValue(
mockWatch([], {}) as chokidar.FSWatcher
);

const mockOpts: DevOptions = { hot: false };
await dev(mockSrc, "build", mockOpts);

Expand All @@ -106,6 +113,6 @@ describe("dev", () => {
path.join(mockSrc2, 'bos.config.json'),
path.join(mockSrc2, 'aliases.json'),
];
expect(mockedGazeAdd).toHaveBeenCalledWith(expectedWatchPaths);
expect(mockAdd).toHaveBeenCalledWith(expectedWatchPaths);
});
});
40 changes: 40 additions & 0 deletions tests/unit/devNoMock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { startFileWatcher } from "@/lib/watcher";
import path from "path";
import fs from "fs";

describe("File Watcher Tests", () => {
let watcher;
const tempDirPath = path.join(__dirname, "temp-test");

it("should call the file watcher callback with the correct attributes", async () => {
const mockCallback = jest.fn();

fs.mkdirSync(tempDirPath, { recursive: true });

const tempFilePath = path.join(tempDirPath, "temp-file.txt");

const relativeTempFilePath = path.relative("./", tempFilePath)

fs.writeFileSync(tempFilePath, "initial content");

watcher = startFileWatcher([relativeTempFilePath], mockCallback);

await new Promise((resolve) => setTimeout(resolve, 1000));

fs.appendFileSync(tempFilePath, "\nadded content");

await new Promise((resolve) => setTimeout(resolve, 1000));

expect(mockCallback).toHaveBeenCalled();
expect(mockCallback.mock.calls[0][0]).toBe("change");
expect(mockCallback.mock.calls[0][1]).toBe(path.resolve(tempFilePath));
});

afterAll(async () => {
if (watcher) await watcher.close();

if (fs.existsSync(tempDirPath)) {
fs.rmSync(tempDirPath, { recursive: true, force: true });
}
});
});
Loading
Loading