Skip to content

Commit

Permalink
Refactor tests directory to be outside src. (#186)
Browse files Browse the repository at this point in the history
  • Loading branch information
robinjhuang authored Nov 5, 2024
1 parent 7658a4e commit 3ff9f1c
Show file tree
Hide file tree
Showing 4 changed files with 296 additions and 0 deletions.
26 changes: 26 additions & 0 deletions tests/e2e/startup.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { test, _electron as electron, expect } from '@playwright/test';

test('launch app', async () => {
const electronApp = await electron.launch({ args: ['.'] });
electronApp.process().stdout?.on?.('data', (data) => {
console.log(`Electron stdout: ${data}`);
});
electronApp.process().stderr?.on?.('data', (data) => {
console.error(`Electron stderr: ${data}`);
});

const isPackaged = await electronApp.evaluate(async ({ app }) => {
// This runs in Electron's main process, parameter here is always
// the result of the require('electron') in the main app script.
return app.isPackaged;
});

expect(isPackaged).toBe(false);

// Wait for the first BrowserWindow to open
// and return its Page object
const window = await electronApp.firstWindow();
await expect(window).toHaveScreenshot('startup.png');

await electronApp.close();
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
165 changes: 165 additions & 0 deletions tests/unit/comfyConfigManager.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import fs from 'fs';
import { ComfyConfigManager, DirectoryStructure } from '../../src/config/comfyConfigManager';

// Mock the fs module
jest.mock('fs');
jest.mock('electron-log/main', () => ({
info: jest.fn(),
error: jest.fn(),
warn: jest.fn(),
}));

describe('ComfyConfigManager', () => {
// Reset all mocks before each test
beforeEach(() => {
jest.clearAllMocks();
(fs.existsSync as jest.Mock).mockReset();
(fs.mkdirSync as jest.Mock).mockReset();
(fs.writeFileSync as jest.Mock).mockReset();
(fs.renameSync as jest.Mock).mockReset();
});

describe('setUpComfyUI', () => {
it('should use existing directory when it contains ComfyUI structure', () => {
// Mock isComfyUIDirectory to return true for the input path
(fs.existsSync as jest.Mock).mockImplementation((path: string) => {
const requiredDirs = [
'/existing/ComfyUI/models',
'/existing/ComfyUI/input',
'/existing/ComfyUI/user',
'/existing/ComfyUI/output',
'/existing/ComfyUI/custom_nodes',
];
return requiredDirs.includes(path);
});

const result = ComfyConfigManager.setUpComfyUI('/existing/ComfyUI');

expect(result).toBe('/existing/ComfyUI');
});

it('should create ComfyUI subdirectory when it is missing', () => {
(fs.existsSync as jest.Mock).mockImplementationOnce((path: string) => {
if (path === '/some/base/path/ComfyUI') {
return false;
}
return true;
});

const result = ComfyConfigManager.setUpComfyUI('/some/base/path');

expect(result).toBe('/some/base/path/ComfyUI');
});
});

describe('isComfyUIDirectory', () => {
it('should return true when all required directories exist', () => {
(fs.existsSync as jest.Mock).mockImplementation((path: string) => {
const requiredDirs = [
'/fake/path/models',
'/fake/path/input',
'/fake/path/user',
'/fake/path/output',
'/fake/path/custom_nodes',
];
return requiredDirs.includes(path);
});

const result = ComfyConfigManager.isComfyUIDirectory('/fake/path');

expect(result).toBe(true);
expect(fs.existsSync).toHaveBeenCalledTimes(5);
});

it('should return false when some required directories are missing', () => {
(fs.existsSync as jest.Mock)
.mockReturnValueOnce(true) // models exists
.mockReturnValueOnce(true) // input exists
.mockReturnValueOnce(false) // user missing
.mockReturnValueOnce(true) // output exists
.mockReturnValueOnce(true); // custom_nodes exists

const result = ComfyConfigManager.isComfyUIDirectory('/fake/path');

expect(result).toBe(false);
});
});

describe('createComfyDirectories', () => {
it('should create all necessary directories when none exist', () => {
(fs.existsSync as jest.Mock).mockReturnValue(false);

ComfyConfigManager.createComfyDirectories('/fake/path/ComfyUI');

// Verify each required directory was created
expect(fs.mkdirSync).toHaveBeenCalledWith('/fake/path/ComfyUI/models', { recursive: true });
expect(fs.mkdirSync).toHaveBeenCalledWith('/fake/path/ComfyUI/input', { recursive: true });
expect(fs.mkdirSync).toHaveBeenCalledWith('/fake/path/ComfyUI/user', { recursive: true });
expect(fs.mkdirSync).toHaveBeenCalledWith('/fake/path/ComfyUI/output', { recursive: true });
expect(fs.mkdirSync).toHaveBeenCalledWith('/fake/path/ComfyUI/custom_nodes', { recursive: true });
});
});

describe('createComfyConfigFile', () => {
it('should create new config file when none exists', () => {
(fs.existsSync as jest.Mock).mockReturnValue(false);

ComfyConfigManager.createComfyConfigFile('/fake/path', false);

expect(fs.writeFileSync).toHaveBeenCalledTimes(1);
expect(fs.renameSync).not.toHaveBeenCalled();
});

it('should backup existing config file when overwrite is true', () => {
(fs.existsSync as jest.Mock).mockImplementation((path: string) => {
return path === '/user/default/comfy.settings.json';
});

ComfyConfigManager.createComfyConfigFile('/user/default', true);

expect(fs.renameSync).toHaveBeenCalledTimes(1);
expect(fs.writeFileSync).toHaveBeenCalledTimes(1);
});

it('should handle backup failure gracefully', () => {
(fs.existsSync as jest.Mock).mockReturnValue(true);
(fs.renameSync as jest.Mock).mockImplementation(() => {
throw new Error('Backup failed');
});

ComfyConfigManager.createComfyConfigFile('/fake/path', true);

expect(fs.writeFileSync).not.toHaveBeenCalled();
});
});

describe('createNestedDirectories', () => {
it('should create nested directory structure correctly', () => {
(fs.existsSync as jest.Mock).mockReturnValue(false);

const structure = ['dir1', ['dir2', ['subdir1', 'subdir2']], ['dir3', [['subdir3', ['subsubdir1']]]]];

ComfyConfigManager['createNestedDirectories']('/fake/path', structure);

// Verify the correct paths were created
expect(fs.mkdirSync).toHaveBeenCalledWith(expect.stringContaining('dir1'), expect.any(Object));
expect(fs.mkdirSync).toHaveBeenCalledWith(expect.stringContaining('dir2'), expect.any(Object));
expect(fs.mkdirSync).toHaveBeenCalledWith(expect.stringContaining('subdir1'), expect.any(Object));
expect(fs.mkdirSync).toHaveBeenCalledWith(expect.stringContaining('subsubdir1'), expect.any(Object));
});

it('should handle invalid directory structure items', () => {
const invalidStructure = [
'dir1',
['dir2'], // Invalid: array with only one item
[123, ['subdir1']], // Invalid: non-string directory name
];

ComfyConfigManager['createNestedDirectories']('/fake/path', invalidStructure as DirectoryStructure);

// Verify only valid directories were created
expect(fs.mkdirSync).toHaveBeenCalledWith(expect.stringContaining('dir1'), expect.any(Object));
expect(fs.mkdirSync).not.toHaveBeenCalledWith(expect.stringContaining('subdir1'), expect.any(Object));
});
});
});
105 changes: 105 additions & 0 deletions tests/unit/main.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { expect, jest, describe, it } from '@jest/globals';
import { createWindow } from '../../src/main';
import { BrowserWindow } from 'electron';

global.MAIN_WINDOW_VITE_DEV_SERVER_URL = 'http://localhost:5173';
global.MAIN_WINDOW_VITE_NAME = 'index.html';

jest.mock('node:path', () => ({
join: jest.fn((...args) => {
return 'preload.js';
}),
}));

jest.mock('@sentry/electron/main', () => ({
init: jest.fn(),
captureException: jest.fn(),
}));

jest.mock('tar', () => ({
extract: jest.fn(),
}));
jest.mock('axios');
jest.mock('fs');
jest.mock('node:fs/promises');

const mockMenuInstance = {
append: jest.fn(),
popup: jest.fn(),
closePopup: jest.fn(),
};

const MockMenu = jest.fn(() => mockMenuInstance) as jest.Mock & {
buildFromTemplate: jest.Mock;
};
MockMenu.buildFromTemplate = jest.fn().mockReturnValue({
items: [],
});

jest.mock('electron', () => ({
app: {
isPackaged: false,
isReady: true,
on: jest.fn(),
getPath: jest.fn(),
requestSingleInstanceLock: jest.fn().mockReturnValue(true),
},
BrowserWindow: jest.fn().mockImplementation((options) => {
return {
loadURL: jest.fn(),
on: jest.fn(),
webContents: {
openDevTools: jest.fn(),
},
};
}),
ipcMain: {
on: jest.fn(),
handle: jest.fn(),
},
screen: {
getPrimaryDisplay: jest.fn().mockReturnValue({
workAreaSize: { width: 1920, height: 1080 },
}),
},
// Add this line to mock Tray
Tray: jest.fn().mockImplementation(() => ({
setToolTip: jest.fn(),
setContextMenu: jest.fn(),
on: jest.fn(),
setPressedImage: jest.fn(),
})),
// Add this line to mock Menu
Menu: MockMenu,
// Mock other Electron modules if necessary
}));

jest.mock('electron-log/main', () => ({
initialize: jest.fn(),
info: jest.fn(),
error: jest.fn(),
// Add other methods you might use from electron-log
}));

describe('createWindow', () => {
// it('should create a new BrowserWindow with correct options', async () => {
// const window = await createWindow('/');

// expect(BrowserWindow).toHaveBeenCalledWith(
// expect.objectContaining({
// title: 'ComfyUI',
// webPreferences: expect.objectContaining({
// preload: expect.stringContaining('preload.js'),
// nodeIntegration: true,
// contextIsolation: true,
// }),
// autoHideMenuBar: true,
// })
// );
// expect(window.loadURL).toHaveBeenCalled();
// });

it('just passes', () => {
expect(true).toBe(true);
});
});

0 comments on commit 3ff9f1c

Please sign in to comment.