floatnote 1.0.0 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/bin/floatnote.js +16 -0
  2. package/package.json +13 -5
  3. package/.beads/config.json +0 -6
  4. package/.beads/issues/floatnote-1.md +0 -21
  5. package/.beads/issues/floatnote-10.md +0 -28
  6. package/.beads/issues/floatnote-11.md +0 -36
  7. package/.beads/issues/floatnote-12.md +0 -25
  8. package/.beads/issues/floatnote-13.md +0 -37
  9. package/.beads/issues/floatnote-14.md +0 -22
  10. package/.beads/issues/floatnote-15.md +0 -22
  11. package/.beads/issues/floatnote-16.md +0 -20
  12. package/.beads/issues/floatnote-17.md +0 -20
  13. package/.beads/issues/floatnote-18.md +0 -21
  14. package/.beads/issues/floatnote-19.md +0 -19
  15. package/.beads/issues/floatnote-2.md +0 -32
  16. package/.beads/issues/floatnote-20.md +0 -22
  17. package/.beads/issues/floatnote-3.md +0 -50
  18. package/.beads/issues/floatnote-4.md +0 -31
  19. package/.beads/issues/floatnote-5.md +0 -28
  20. package/.beads/issues/floatnote-6.md +0 -30
  21. package/.beads/issues/floatnote-7.md +0 -38
  22. package/.beads/issues/floatnote-8.md +0 -29
  23. package/.beads/issues/floatnote-9.md +0 -32
  24. package/CLAUDE.md +0 -61
  25. package/coverage/base.css +0 -224
  26. package/coverage/bin/floatnote.js.html +0 -739
  27. package/coverage/bin/index.html +0 -116
  28. package/coverage/block-navigation.js +0 -87
  29. package/coverage/favicon.png +0 -0
  30. package/coverage/index.html +0 -131
  31. package/coverage/lcov-report/base.css +0 -224
  32. package/coverage/lcov-report/bin/floatnote.js.html +0 -739
  33. package/coverage/lcov-report/bin/index.html +0 -116
  34. package/coverage/lcov-report/block-navigation.js +0 -87
  35. package/coverage/lcov-report/favicon.png +0 -0
  36. package/coverage/lcov-report/index.html +0 -131
  37. package/coverage/lcov-report/prettify.css +0 -1
  38. package/coverage/lcov-report/prettify.js +0 -2
  39. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  40. package/coverage/lcov-report/sorter.js +0 -210
  41. package/coverage/lcov-report/src/index.html +0 -146
  42. package/coverage/lcov-report/src/main.js.html +0 -1483
  43. package/coverage/lcov-report/src/preload.js.html +0 -361
  44. package/coverage/lcov-report/src/renderer.js.html +0 -8767
  45. package/coverage/lcov.info +0 -3273
  46. package/coverage/prettify.css +0 -1
  47. package/coverage/prettify.js +0 -2
  48. package/coverage/sort-arrow-sprite.png +0 -0
  49. package/coverage/sorter.js +0 -210
  50. package/coverage/src/index.html +0 -146
  51. package/coverage/src/main.js.html +0 -1483
  52. package/coverage/src/preload.js.html +0 -361
  53. package/coverage/src/renderer.js.html +0 -8767
  54. package/jest.config.js +0 -48
  55. package/src/icon-template.png +0 -0
  56. package/src/index.html +0 -296
  57. package/src/main.js +0 -494
  58. package/src/preload.js +0 -96
  59. package/src/renderer.js +0 -3203
  60. package/src/styles.css +0 -1448
  61. package/tests/cli/floatnote.test.js +0 -167
  62. package/tests/main/main.test.js +0 -287
  63. package/tests/mocks/electron.js +0 -126
  64. package/tests/mocks/fs.js +0 -17
  65. package/tests/preload/preload.test.js +0 -218
  66. package/tests/renderer/history.test.js +0 -234
  67. package/tests/renderer/notes.test.js +0 -262
  68. package/tests/renderer/settings.test.js +0 -178
@@ -1,167 +0,0 @@
1
- // Tests for bin/floatnote.js CLI
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
-
6
- // Mock fs module
7
- jest.mock('fs', () => ({
8
- existsSync: jest.fn(),
9
- readFileSync: jest.fn(),
10
- writeFileSync: jest.fn(),
11
- mkdirSync: jest.fn(),
12
- rmSync: jest.fn(),
13
- unlinkSync: jest.fn(),
14
- createWriteStream: jest.fn(() => ({
15
- on: jest.fn((event, cb) => {
16
- if (event === 'finish') setTimeout(cb, 0);
17
- return { on: jest.fn() };
18
- }),
19
- close: jest.fn()
20
- }))
21
- }));
22
-
23
- // Mock https module
24
- jest.mock('https', () => ({
25
- get: jest.fn()
26
- }));
27
-
28
- // Mock child_process
29
- jest.mock('child_process', () => ({
30
- spawn: jest.fn(() => ({
31
- unref: jest.fn()
32
- })),
33
- execSync: jest.fn()
34
- }));
35
-
36
- describe('CLI utility functions', () => {
37
- beforeEach(() => {
38
- jest.clearAllMocks();
39
- // Reset process.argv
40
- process.argv = ['node', 'floatnote'];
41
- });
42
-
43
- describe('formatBytes', () => {
44
- // We can't directly test formatBytes since it's not exported,
45
- // but we can test it indirectly through the download progress
46
- test('should handle byte formatting logic', () => {
47
- // Test the logic that would be in formatBytes
48
- const formatBytes = (bytes) => {
49
- if (bytes < 1024) return bytes + ' B';
50
- if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
51
- return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
52
- };
53
-
54
- expect(formatBytes(500)).toBe('500 B');
55
- expect(formatBytes(1024)).toBe('1.0 KB');
56
- expect(formatBytes(1536)).toBe('1.5 KB');
57
- expect(formatBytes(1048576)).toBe('1.0 MB');
58
- expect(formatBytes(2621440)).toBe('2.5 MB');
59
- });
60
- });
61
-
62
- describe('log function', () => {
63
- test('should format log messages correctly', () => {
64
- const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
65
-
66
- // Test the log function logic
67
- const log = (message) => {
68
- console.log(`[floatnote] ${message}`);
69
- };
70
-
71
- log('test message');
72
- expect(consoleSpy).toHaveBeenCalledWith('[floatnote] test message');
73
-
74
- consoleSpy.mockRestore();
75
- });
76
- });
77
-
78
- describe('APP_DIR and paths', () => {
79
- test('should use correct paths', () => {
80
- const APP_NAME = 'Floatnote';
81
- const APP_DIR = path.join(process.env.HOME, '.floatnote');
82
- const APP_PATH = path.join(APP_DIR, `${APP_NAME}.app`);
83
- const VERSION_FILE = path.join(APP_DIR, 'version');
84
-
85
- expect(APP_DIR).toContain('.floatnote');
86
- expect(APP_PATH).toContain('Floatnote.app');
87
- expect(VERSION_FILE).toContain('version');
88
- });
89
- });
90
- });
91
-
92
- describe('CLI argument handling', () => {
93
- test('--version flag should be recognized', () => {
94
- const args = ['--version'];
95
- expect(args.includes('--version') || args.includes('-v')).toBe(true);
96
- });
97
-
98
- test('-v flag should be recognized', () => {
99
- const args = ['-v'];
100
- expect(args.includes('--version') || args.includes('-v')).toBe(true);
101
- });
102
-
103
- test('--help flag should be recognized', () => {
104
- const args = ['--help'];
105
- expect(args.includes('--help') || args.includes('-h')).toBe(true);
106
- });
107
-
108
- test('-h flag should be recognized', () => {
109
- const args = ['-h'];
110
- expect(args.includes('--help') || args.includes('-h')).toBe(true);
111
- });
112
-
113
- test('--update flag should be recognized', () => {
114
- const args = ['--update'];
115
- expect(args.includes('--update')).toBe(true);
116
- });
117
-
118
- test('--uninstall flag should be recognized', () => {
119
- const args = ['--uninstall'];
120
- expect(args.includes('--uninstall')).toBe(true);
121
- });
122
- });
123
-
124
- describe('GitHub API integration', () => {
125
- test('should construct correct API URL', () => {
126
- const GITHUB_REPO = 'josmanvis/floatnote';
127
- const apiPath = `/repos/${GITHUB_REPO}/releases/latest`;
128
- expect(apiPath).toBe('/repos/josmanvis/floatnote/releases/latest');
129
- });
130
-
131
- test('should use correct User-Agent header', () => {
132
- const headers = { 'User-Agent': 'floatnote-cli' };
133
- expect(headers['User-Agent']).toBe('floatnote-cli');
134
- });
135
- });
136
-
137
- describe('File operations', () => {
138
- test('should check if app directory exists', () => {
139
- fs.existsSync.mockReturnValue(false);
140
- const result = fs.existsSync('/mock/.floatnote');
141
- expect(result).toBe(false);
142
- expect(fs.existsSync).toHaveBeenCalled();
143
- });
144
-
145
- test('should create app directory if not exists', () => {
146
- fs.existsSync.mockReturnValue(false);
147
- fs.mkdirSync('/mock/.floatnote', { recursive: true });
148
- expect(fs.mkdirSync).toHaveBeenCalledWith('/mock/.floatnote', { recursive: true });
149
- });
150
-
151
- test('should read version file', () => {
152
- fs.existsSync.mockReturnValue(true);
153
- fs.readFileSync.mockReturnValue('v1.0.0');
154
- const version = fs.readFileSync('/mock/.floatnote/version', 'utf8');
155
- expect(version).toBe('v1.0.0');
156
- });
157
-
158
- test('should write version file', () => {
159
- fs.writeFileSync('/mock/.floatnote/version', 'v1.0.1');
160
- expect(fs.writeFileSync).toHaveBeenCalledWith('/mock/.floatnote/version', 'v1.0.1');
161
- });
162
-
163
- test('should remove directory on uninstall', () => {
164
- fs.rmSync('/mock/.floatnote', { recursive: true });
165
- expect(fs.rmSync).toHaveBeenCalledWith('/mock/.floatnote', { recursive: true });
166
- });
167
- });
@@ -1,287 +0,0 @@
1
- // Tests for src/main.js - Main Process
2
-
3
- describe('Main Process', () => {
4
- let mockBrowserWindow;
5
- let mockApp;
6
- let mockDialog;
7
- let mockScreen;
8
- let mockShell;
9
- let mockFs;
10
-
11
- beforeEach(() => {
12
- jest.clearAllMocks();
13
-
14
- // Create fresh mocks for each test
15
- mockBrowserWindow = {
16
- loadFile: jest.fn(),
17
- show: jest.fn(),
18
- hide: jest.fn(),
19
- focus: jest.fn(),
20
- close: jest.fn(),
21
- destroy: jest.fn(),
22
- isDestroyed: jest.fn(() => false),
23
- isMinimized: jest.fn(() => false),
24
- isVisible: jest.fn(() => true),
25
- restore: jest.fn(),
26
- setAlwaysOnTop: jest.fn(),
27
- setVisibleOnAllWorkspaces: jest.fn(),
28
- setVibrancy: jest.fn(),
29
- setBackgroundColor: jest.fn(),
30
- setBounds: jest.fn(),
31
- getBounds: jest.fn(() => ({ x: 0, y: 0, width: 800, height: 600 })),
32
- on: jest.fn(),
33
- webContents: {
34
- send: jest.fn()
35
- }
36
- };
37
-
38
- mockApp = {
39
- getPath: jest.fn((name) => {
40
- if (name === 'userData') return '/mock/userData';
41
- if (name === 'home') return '/mock/home';
42
- return '/mock/path';
43
- }),
44
- requestSingleInstanceLock: jest.fn(() => true)
45
- };
46
-
47
- mockDialog = {
48
- showMessageBox: jest.fn(() => Promise.resolve({ response: 0 })),
49
- showSaveDialog: jest.fn(() => Promise.resolve({ canceled: false, filePath: '/test/path.png' }))
50
- };
51
-
52
- mockScreen = {
53
- getCursorScreenPoint: jest.fn(() => ({ x: 500, y: 500 })),
54
- getDisplayNearestPoint: jest.fn(() => ({
55
- workAreaSize: { width: 1920, height: 1080 },
56
- workArea: { x: 0, y: 0 }
57
- }))
58
- };
59
-
60
- mockShell = {
61
- openPath: jest.fn(() => Promise.resolve(''))
62
- };
63
-
64
- mockFs = {
65
- existsSync: jest.fn(() => false),
66
- readFileSync: jest.fn(() => '{}'),
67
- writeFileSync: jest.fn(),
68
- mkdirSync: jest.fn()
69
- };
70
- });
71
-
72
- describe('Data storage paths', () => {
73
- test('should use correct user data path', () => {
74
- const userDataPath = mockApp.getPath('userData');
75
- expect(userDataPath).toBe('/mock/userData');
76
- });
77
-
78
- test('should use correct home path', () => {
79
- const homePath = mockApp.getPath('home');
80
- expect(homePath).toBe('/mock/home');
81
- });
82
- });
83
-
84
- describe('Single instance lock', () => {
85
- test('should request single instance lock', () => {
86
- const gotLock = mockApp.requestSingleInstanceLock();
87
- expect(gotLock).toBe(true);
88
- });
89
- });
90
-
91
- describe('Window creation', () => {
92
- test('window should load correct file', () => {
93
- mockBrowserWindow.loadFile('src/index.html');
94
- expect(mockBrowserWindow.loadFile).toHaveBeenCalledWith('src/index.html');
95
- });
96
-
97
- test('window should set always on top', () => {
98
- mockBrowserWindow.setAlwaysOnTop(true, 'floating', 1);
99
- expect(mockBrowserWindow.setAlwaysOnTop).toHaveBeenCalledWith(true, 'floating', 1);
100
- });
101
-
102
- test('window should be visible on all workspaces', () => {
103
- mockBrowserWindow.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });
104
- expect(mockBrowserWindow.setVisibleOnAllWorkspaces).toHaveBeenCalledWith(true, { visibleOnFullScreen: true });
105
- });
106
- });
107
-
108
- describe('IPC handlers', () => {
109
- test('save-data handler should write file', () => {
110
- const data = { notes: [], settings: {} };
111
- mockFs.writeFileSync('/mock/userData/floatnote-data.json', JSON.stringify(data, null, 2));
112
- expect(mockFs.writeFileSync).toHaveBeenCalled();
113
- });
114
-
115
- test('load-data handler should read file when exists', () => {
116
- mockFs.existsSync.mockReturnValue(true);
117
- mockFs.readFileSync.mockReturnValue('{"notes":[],"settings":{}}');
118
-
119
- if (mockFs.existsSync('/mock/userData/floatnote-data.json')) {
120
- const data = mockFs.readFileSync('/mock/userData/floatnote-data.json', 'utf-8');
121
- expect(data).toBeDefined();
122
- }
123
- });
124
-
125
- test('load-data handler should return null when file does not exist', () => {
126
- mockFs.existsSync.mockReturnValue(false);
127
- const exists = mockFs.existsSync('/mock/userData/floatnote-data.json');
128
- expect(exists).toBe(false);
129
- });
130
- });
131
-
132
- describe('Export to ~/.floatnote', () => {
133
- test('should create folder if not exists', () => {
134
- mockFs.existsSync.mockReturnValue(false);
135
-
136
- const floatnoteFolder = '/mock/home/.floatnote';
137
- if (!mockFs.existsSync(floatnoteFolder)) {
138
- mockFs.mkdirSync(floatnoteFolder, { recursive: true });
139
- }
140
-
141
- expect(mockFs.mkdirSync).toHaveBeenCalledWith(floatnoteFolder, { recursive: true });
142
- });
143
-
144
- test('should write note file', () => {
145
- const noteData = { id: '123', lines: [], textItems: [] };
146
- const filePath = '/mock/home/.floatnote/note-123.json';
147
- mockFs.writeFileSync(filePath, JSON.stringify(noteData, null, 2));
148
- expect(mockFs.writeFileSync).toHaveBeenCalled();
149
- });
150
- });
151
-
152
- describe('Open folder in Finder', () => {
153
- test('should call shell.openPath', async () => {
154
- const floatnoteFolder = '/mock/home/.floatnote';
155
- await mockShell.openPath(floatnoteFolder);
156
- expect(mockShell.openPath).toHaveBeenCalledWith(floatnoteFolder);
157
- });
158
- });
159
-
160
- describe('Export PNG', () => {
161
- test('should show save dialog', async () => {
162
- await mockDialog.showSaveDialog(mockBrowserWindow, {
163
- title: 'Export Note as PNG',
164
- defaultPath: 'floatnote.png',
165
- filters: [{ name: 'PNG Images', extensions: ['png'] }]
166
- });
167
- expect(mockDialog.showSaveDialog).toHaveBeenCalled();
168
- });
169
-
170
- test('should write PNG file', () => {
171
- const base64Data = 'iVBORw0KGgo=';
172
- mockFs.writeFileSync('/test/path.png', Buffer.from(base64Data, 'base64'));
173
- expect(mockFs.writeFileSync).toHaveBeenCalled();
174
- });
175
- });
176
-
177
- describe('Screen utilities', () => {
178
- test('should get cursor screen point', () => {
179
- const point = mockScreen.getCursorScreenPoint();
180
- expect(point).toEqual({ x: 500, y: 500 });
181
- });
182
-
183
- test('should get display nearest to cursor', () => {
184
- const point = mockScreen.getCursorScreenPoint();
185
- const display = mockScreen.getDisplayNearestPoint(point);
186
- expect(display.workAreaSize).toBeDefined();
187
- expect(display.workArea).toBeDefined();
188
- });
189
- });
190
-
191
- describe('Window size presets', () => {
192
- test('should calculate small size (33% x 50%)', () => {
193
- const screenWidth = 1920;
194
- const screenHeight = 1080;
195
- const newWidth = Math.round(screenWidth * 0.33);
196
- const newHeight = Math.round(screenHeight * 0.5);
197
- expect(newWidth).toBe(634);
198
- expect(newHeight).toBe(540);
199
- });
200
-
201
- test('should calculate medium size (33% x 100%)', () => {
202
- const screenWidth = 1920;
203
- const screenHeight = 1080;
204
- const newWidth = Math.round(screenWidth * 0.33);
205
- const newHeight = screenHeight;
206
- expect(newWidth).toBe(634);
207
- expect(newHeight).toBe(1080);
208
- });
209
-
210
- test('should calculate large size (100% x 100%)', () => {
211
- const screenWidth = 1920;
212
- const screenHeight = 1080;
213
- const newWidth = screenWidth;
214
- const newHeight = screenHeight;
215
- expect(newWidth).toBe(1920);
216
- expect(newHeight).toBe(1080);
217
- });
218
- });
219
-
220
- describe('Background modes', () => {
221
- test('blur mode should set vibrancy', () => {
222
- mockBrowserWindow.setVibrancy('fullscreen-ui');
223
- mockBrowserWindow.setBackgroundColor('#00000000');
224
- expect(mockBrowserWindow.setVibrancy).toHaveBeenCalledWith('fullscreen-ui');
225
- expect(mockBrowserWindow.setBackgroundColor).toHaveBeenCalledWith('#00000000');
226
- });
227
-
228
- test('dark mode should clear vibrancy', () => {
229
- mockBrowserWindow.setVibrancy(null);
230
- mockBrowserWindow.setBackgroundColor('#00000000');
231
- expect(mockBrowserWindow.setVibrancy).toHaveBeenCalledWith(null);
232
- });
233
-
234
- test('transparent mode should clear vibrancy', () => {
235
- mockBrowserWindow.setVibrancy(null);
236
- mockBrowserWindow.setBackgroundColor('#00000000');
237
- expect(mockBrowserWindow.setVibrancy).toHaveBeenCalledWith(null);
238
- });
239
- });
240
-
241
- describe('Left edge resize', () => {
242
- test('should calculate new bounds correctly', () => {
243
- const bounds = { x: 1000, y: 0, width: 400, height: 600 };
244
- const deltaX = 50;
245
- const minWidth = 200;
246
- const newWidth = bounds.width - deltaX;
247
-
248
- if (newWidth >= minWidth) {
249
- const newBounds = {
250
- x: bounds.x + deltaX,
251
- y: bounds.y,
252
- width: newWidth,
253
- height: bounds.height
254
- };
255
- expect(newBounds.x).toBe(1050);
256
- expect(newBounds.width).toBe(350);
257
- }
258
- });
259
-
260
- test('should not resize below minimum width', () => {
261
- const bounds = { x: 1000, y: 0, width: 250, height: 600 };
262
- const deltaX = 100;
263
- const minWidth = 200;
264
- const newWidth = bounds.width - deltaX;
265
-
266
- expect(newWidth).toBe(150);
267
- expect(newWidth < minWidth).toBe(true);
268
- });
269
- });
270
- });
271
-
272
- describe('Dialog interactions', () => {
273
- test('close confirmation dialog should have correct options', async () => {
274
- const mockDialog = {
275
- showMessageBox: jest.fn(() => Promise.resolve({ response: 0 }))
276
- };
277
-
278
- const result = await mockDialog.showMessageBox({}, {
279
- type: 'warning',
280
- buttons: ['Close', 'Cancel'],
281
- defaultId: 1,
282
- title: 'Close Floatnote?',
283
- message: 'Are you sure you want to close Floatnote?'
284
- });
285
- expect(result.response).toBe(0);
286
- });
287
- });
@@ -1,126 +0,0 @@
1
- // Mock Electron for testing
2
-
3
- const mockBrowserWindow = {
4
- loadFile: jest.fn(),
5
- show: jest.fn(),
6
- hide: jest.fn(),
7
- focus: jest.fn(),
8
- close: jest.fn(),
9
- destroy: jest.fn(),
10
- isDestroyed: jest.fn(() => false),
11
- isMinimized: jest.fn(() => false),
12
- isVisible: jest.fn(() => true),
13
- restore: jest.fn(),
14
- setAlwaysOnTop: jest.fn(),
15
- setVisibleOnAllWorkspaces: jest.fn(),
16
- setVibrancy: jest.fn(),
17
- setBackgroundColor: jest.fn(),
18
- setBounds: jest.fn(),
19
- getBounds: jest.fn(() => ({ x: 0, y: 0, width: 800, height: 600 })),
20
- on: jest.fn(),
21
- webContents: {
22
- send: jest.fn()
23
- }
24
- };
25
-
26
- const BrowserWindow = jest.fn(() => mockBrowserWindow);
27
- BrowserWindow.fromWebContents = jest.fn(() => mockBrowserWindow);
28
-
29
- const mockTray = {
30
- setToolTip: jest.fn(),
31
- on: jest.fn(),
32
- popUpContextMenu: jest.fn()
33
- };
34
-
35
- const Tray = jest.fn(() => mockTray);
36
-
37
- const Menu = {
38
- buildFromTemplate: jest.fn(() => ({}))
39
- };
40
-
41
- const nativeImage = {
42
- createFromDataURL: jest.fn(() => ({
43
- setTemplateImage: jest.fn()
44
- }))
45
- };
46
-
47
- const dialog = {
48
- showMessageBox: jest.fn(() => Promise.resolve({ response: 0 })),
49
- showSaveDialog: jest.fn(() => Promise.resolve({ canceled: false, filePath: '/test/path.png' }))
50
- };
51
-
52
- const ipcMain = {
53
- on: jest.fn(),
54
- handle: jest.fn()
55
- };
56
-
57
- const ipcRenderer = {
58
- on: jest.fn(),
59
- send: jest.fn(),
60
- invoke: jest.fn(() => Promise.resolve({ success: true }))
61
- };
62
-
63
- const globalShortcut = {
64
- register: jest.fn(),
65
- unregisterAll: jest.fn()
66
- };
67
-
68
- const screen = {
69
- getCursorScreenPoint: jest.fn(() => ({ x: 500, y: 500 })),
70
- getDisplayNearestPoint: jest.fn(() => ({
71
- workAreaSize: { width: 1920, height: 1080 },
72
- workArea: { x: 0, y: 0 }
73
- }))
74
- };
75
-
76
- const shell = {
77
- openPath: jest.fn(() => Promise.resolve(''))
78
- };
79
-
80
- const clipboard = {
81
- availableFormats: jest.fn(() => []),
82
- readImage: jest.fn(() => ({
83
- isEmpty: jest.fn(() => true),
84
- toDataURL: jest.fn(() => ''),
85
- getSize: jest.fn(() => ({ width: 0, height: 0 }))
86
- })),
87
- readText: jest.fn(() => '')
88
- };
89
-
90
- const contextBridge = {
91
- exposeInMainWorld: jest.fn()
92
- };
93
-
94
- const app = {
95
- getPath: jest.fn((name) => {
96
- if (name === 'userData') return '/mock/userData';
97
- if (name === 'home') return '/mock/home';
98
- return '/mock/path';
99
- }),
100
- whenReady: jest.fn(() => Promise.resolve()),
101
- on: jest.fn(),
102
- quit: jest.fn(),
103
- requestSingleInstanceLock: jest.fn(() => true),
104
- dock: {
105
- setIcon: jest.fn()
106
- }
107
- };
108
-
109
- module.exports = {
110
- app,
111
- BrowserWindow,
112
- Tray,
113
- Menu,
114
- nativeImage,
115
- dialog,
116
- ipcMain,
117
- ipcRenderer,
118
- globalShortcut,
119
- screen,
120
- shell,
121
- clipboard,
122
- contextBridge,
123
- // Export mocks for direct access in tests
124
- mockBrowserWindow,
125
- mockTray
126
- };
package/tests/mocks/fs.js DELETED
@@ -1,17 +0,0 @@
1
- // Mock fs module for testing
2
-
3
- const mockFs = {
4
- existsSync: jest.fn(() => false),
5
- readFileSync: jest.fn(() => '{}'),
6
- writeFileSync: jest.fn(),
7
- mkdirSync: jest.fn(),
8
- rmSync: jest.fn(),
9
- unlinkSync: jest.fn(),
10
- readdirSync: jest.fn(() => []),
11
- statSync: jest.fn(() => ({
12
- isDirectory: jest.fn(() => false),
13
- isFile: jest.fn(() => true)
14
- }))
15
- };
16
-
17
- module.exports = mockFs;