mirror of
https://github.com/tiennm99/ccstatusline.git
synced 2026-08-07 00:22:56 +00:00
chore: Fix for test failures when testing with vitest, remove 'test' script from package.json, prefer running tests using 'bun test'
This commit is contained in:
@@ -17,7 +17,6 @@
|
||||
"example": "cat scripts/payload.example.json | bun start",
|
||||
"prepublishOnly": "bun run build",
|
||||
"lint": "bun tsc --noEmit; eslint . --config eslint.config.js --max-warnings=999999 --fix",
|
||||
"test": "bun vitest",
|
||||
"docs": "typedoc",
|
||||
"docs:clean": "rm -rf docs"
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as os from 'node:os';
|
||||
import {
|
||||
afterEach,
|
||||
beforeEach,
|
||||
describe,
|
||||
expect,
|
||||
it,
|
||||
@@ -12,12 +13,24 @@ import type { Settings } from '../../types/Settings';
|
||||
import type { WidgetItem } from '../../types/Widget';
|
||||
import { CurrentWorkingDirWidget } from '../CurrentWorkingDir';
|
||||
|
||||
vi.mock('node:os', () => ({ homedir: vi.fn() }));
|
||||
|
||||
const mockHomedir = os.homedir as unknown as {
|
||||
mockReset: () => void;
|
||||
mockReturnValue: (value: string) => void;
|
||||
};
|
||||
|
||||
describe('CurrentWorkingDirWidget', () => {
|
||||
const widget = new CurrentWorkingDirWidget();
|
||||
const homeDir = os.homedir();
|
||||
const defaultHomeDir = '/Users/alice';
|
||||
|
||||
beforeEach(() => {
|
||||
mockHomedir.mockReset();
|
||||
mockHomedir.mockReturnValue(defaultHomeDir);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
const createContext = (cwd?: string, isPreview = false): RenderContext => ({
|
||||
@@ -57,10 +70,11 @@ describe('CurrentWorkingDirWidget', () => {
|
||||
|
||||
describe('abbreviateHome', () => {
|
||||
it('should replace home directory with ~ when enabled', () => {
|
||||
mockHomedir.mockReturnValue(defaultHomeDir);
|
||||
const item = createItem({ abbreviateHome: 'true' }, true);
|
||||
const result = widget.render(
|
||||
item,
|
||||
createContext(`${homeDir}/Documents/Projects`),
|
||||
createContext(`${defaultHomeDir}/Documents/Projects`),
|
||||
defaultSettings
|
||||
);
|
||||
expect(result).toBe('~/Documents/Projects');
|
||||
@@ -70,10 +84,10 @@ describe('CurrentWorkingDirWidget', () => {
|
||||
const item = createItem(undefined, true);
|
||||
const result = widget.render(
|
||||
item,
|
||||
createContext(`${homeDir}/Documents/Projects`),
|
||||
createContext(`${defaultHomeDir}/Documents/Projects`),
|
||||
defaultSettings
|
||||
);
|
||||
expect(result).toBe(`${homeDir}/Documents/Projects`);
|
||||
expect(result).toBe(`${defaultHomeDir}/Documents/Projects`);
|
||||
});
|
||||
|
||||
it('should not modify paths outside home directory', () => {
|
||||
@@ -87,7 +101,7 @@ describe('CurrentWorkingDirWidget', () => {
|
||||
});
|
||||
|
||||
it('should not abbreviate non-home sibling paths with shared prefix', () => {
|
||||
vi.spyOn(os, 'homedir').mockReturnValue('/Users/al');
|
||||
mockHomedir.mockReturnValue('/Users/al');
|
||||
|
||||
const item = createItem({ abbreviateHome: 'true' }, true);
|
||||
const result = widget.render(
|
||||
@@ -100,10 +114,11 @@ describe('CurrentWorkingDirWidget', () => {
|
||||
});
|
||||
|
||||
it('should combine with segments option', () => {
|
||||
mockHomedir.mockReturnValue(defaultHomeDir);
|
||||
const item = createItem({ abbreviateHome: 'true', segments: '2' }, true);
|
||||
const result = widget.render(
|
||||
item,
|
||||
createContext(`${homeDir}/Documents/Projects/my-project`),
|
||||
createContext(`${defaultHomeDir}/Documents/Projects/my-project`),
|
||||
defaultSettings
|
||||
);
|
||||
expect(result).toBe('~/.../Projects/my-project');
|
||||
@@ -140,7 +155,7 @@ describe('CurrentWorkingDirWidget', () => {
|
||||
});
|
||||
|
||||
it('should preserve windows path separators when combining home abbreviation and segments', () => {
|
||||
vi.spyOn(os, 'homedir').mockReturnValue('C:\\Users\\alice');
|
||||
mockHomedir.mockReturnValue('C:\\Users\\alice');
|
||||
|
||||
const item = createItem({ abbreviateHome: 'true', segments: '2' }, true);
|
||||
const result = widget.render(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as childProcess from 'child_process';
|
||||
import { execSync } from 'child_process';
|
||||
import os from 'os';
|
||||
import {
|
||||
afterEach,
|
||||
@@ -16,18 +16,47 @@ import type {
|
||||
import { DEFAULT_SETTINGS } from '../../types/Settings';
|
||||
import { FreeMemoryWidget } from '../FreeMemory';
|
||||
|
||||
vi.mock('child_process', () => ({ execSync: vi.fn() }));
|
||||
vi.mock('os', () => {
|
||||
const mockOs = {
|
||||
totalmem: vi.fn(),
|
||||
freemem: vi.fn(),
|
||||
platform: vi.fn()
|
||||
};
|
||||
|
||||
return {
|
||||
default: mockOs,
|
||||
...mockOs
|
||||
};
|
||||
});
|
||||
|
||||
const mockTotalmem = os.totalmem as unknown as {
|
||||
mockReturnValue: (value: number) => void;
|
||||
mockReset: () => void;
|
||||
};
|
||||
const mockFreemem = os.freemem as unknown as {
|
||||
mockReturnValue: (value: number) => void;
|
||||
mockReset: () => void;
|
||||
};
|
||||
const mockPlatform = os.platform as unknown as {
|
||||
mockReturnValue: (value: NodeJS.Platform) => void;
|
||||
mockReset: () => void;
|
||||
};
|
||||
const mockExecSync = execSync as unknown as {
|
||||
mockReturnValue: (value: string) => void;
|
||||
mockImplementation: (impl: () => never) => void;
|
||||
mockReset: () => void;
|
||||
};
|
||||
|
||||
describe('FreeMemoryWidget', () => {
|
||||
const widget = new FreeMemoryWidget();
|
||||
let totalmemSpy = vi.spyOn(os, 'totalmem');
|
||||
let freememSpy = vi.spyOn(os, 'freemem');
|
||||
let platformSpy = vi.spyOn(os, 'platform');
|
||||
let execSyncSpy = vi.spyOn(childProcess, 'execSync');
|
||||
|
||||
beforeEach(() => {
|
||||
totalmemSpy = vi.spyOn(os, 'totalmem');
|
||||
freememSpy = vi.spyOn(os, 'freemem');
|
||||
platformSpy = vi.spyOn(os, 'platform');
|
||||
execSyncSpy = vi.spyOn(childProcess, 'execSync');
|
||||
vi.clearAllMocks();
|
||||
mockTotalmem.mockReset();
|
||||
mockFreemem.mockReset();
|
||||
mockPlatform.mockReset();
|
||||
mockExecSync.mockReset();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -79,14 +108,14 @@ describe('FreeMemoryWidget', () => {
|
||||
|
||||
describe('render on macOS (vm_stat)', () => {
|
||||
beforeEach(() => {
|
||||
platformSpy.mockReturnValue('darwin');
|
||||
totalmemSpy.mockReturnValue(16 * 1024 ** 3); // 16GB total
|
||||
mockPlatform.mockReturnValue('darwin');
|
||||
mockTotalmem.mockReturnValue(16 * 1024 ** 3); // 16GB total
|
||||
});
|
||||
|
||||
it('should calculate used memory from vm_stat (active + wired)', () => {
|
||||
// Page size 16384, active 500000 pages, wired 100000 pages
|
||||
// Used = (500000 + 100000) * 16384 = 9,830,400,000 bytes ≈ 9.2G
|
||||
execSyncSpy.mockReturnValue(`Mach Virtual Memory Statistics: (page size of 16384 bytes)
|
||||
mockExecSync.mockReturnValue(`Mach Virtual Memory Statistics: (page size of 16384 bytes)
|
||||
Pages free: 100000.
|
||||
Pages active: 500000.
|
||||
Pages inactive: 200000.
|
||||
@@ -105,7 +134,7 @@ Pages purgeable: 5000.
|
||||
});
|
||||
|
||||
it('should show raw value without label', () => {
|
||||
execSyncSpy.mockReturnValue(`Mach Virtual Memory Statistics: (page size of 16384 bytes)
|
||||
mockExecSync.mockReturnValue(`Mach Virtual Memory Statistics: (page size of 16384 bytes)
|
||||
Pages free: 100000.
|
||||
Pages active: 500000.
|
||||
Pages inactive: 200000.
|
||||
@@ -121,10 +150,10 @@ Pages wired down: 100000.
|
||||
});
|
||||
|
||||
it('should fallback to os.freemem if vm_stat fails', () => {
|
||||
execSyncSpy.mockImplementation(() => {
|
||||
mockExecSync.mockImplementation(() => {
|
||||
throw new Error('command not found');
|
||||
});
|
||||
freememSpy.mockReturnValue(8 * 1024 ** 3); // 8GB free -> 8GB used
|
||||
mockFreemem.mockReturnValue(8 * 1024 ** 3); // 8GB free -> 8GB used
|
||||
|
||||
const context: RenderContext = {};
|
||||
const item: WidgetItem = { id: 'mem', type: 'free-memory', rawValue: true };
|
||||
@@ -135,8 +164,8 @@ Pages wired down: 100000.
|
||||
});
|
||||
|
||||
it('should fallback if vm_stat output is malformed', () => {
|
||||
execSyncSpy.mockReturnValue('garbage output');
|
||||
freememSpy.mockReturnValue(4 * 1024 ** 3); // 4GB free -> 12GB used
|
||||
mockExecSync.mockReturnValue('garbage output');
|
||||
mockFreemem.mockReturnValue(4 * 1024 ** 3); // 4GB free -> 12GB used
|
||||
|
||||
const context: RenderContext = {};
|
||||
const item: WidgetItem = { id: 'mem', type: 'free-memory', rawValue: true };
|
||||
@@ -149,12 +178,12 @@ Pages wired down: 100000.
|
||||
|
||||
describe('render on non-macOS (os.freemem fallback)', () => {
|
||||
beforeEach(() => {
|
||||
platformSpy.mockReturnValue('linux');
|
||||
mockPlatform.mockReturnValue('linux');
|
||||
});
|
||||
|
||||
it('should use total - free calculation on Linux', () => {
|
||||
freememSpy.mockReturnValue(8 * 1024 ** 3); // 8GB free
|
||||
totalmemSpy.mockReturnValue(16 * 1024 ** 3); // 16GB total -> 8GB used
|
||||
mockFreemem.mockReturnValue(8 * 1024 ** 3); // 8GB free
|
||||
mockTotalmem.mockReturnValue(16 * 1024 ** 3); // 16GB total -> 8GB used
|
||||
|
||||
const context: RenderContext = {};
|
||||
const item: WidgetItem = { id: 'mem', type: 'free-memory' };
|
||||
@@ -165,8 +194,8 @@ Pages wired down: 100000.
|
||||
});
|
||||
|
||||
it('should handle fractional gigabytes', () => {
|
||||
freememSpy.mockReturnValue(4.5 * 1024 ** 3); // 4.5GB free
|
||||
totalmemSpy.mockReturnValue(32 * 1024 ** 3); // 32GB total -> 27.5GB used
|
||||
mockFreemem.mockReturnValue(4.5 * 1024 ** 3); // 4.5GB free
|
||||
mockTotalmem.mockReturnValue(32 * 1024 ** 3); // 32GB total -> 27.5GB used
|
||||
|
||||
const context: RenderContext = {};
|
||||
const item: WidgetItem = { id: 'mem', type: 'free-memory', rawValue: true };
|
||||
@@ -177,8 +206,8 @@ Pages wired down: 100000.
|
||||
});
|
||||
|
||||
it('should handle megabyte values', () => {
|
||||
freememSpy.mockReturnValue(512 * 1024 ** 2); // 512MB free
|
||||
totalmemSpy.mockReturnValue(1024 * 1024 ** 2); // 1GB total -> 512MB used
|
||||
mockFreemem.mockReturnValue(512 * 1024 ** 2); // 512MB free
|
||||
mockTotalmem.mockReturnValue(1024 * 1024 ** 2); // 1GB total -> 512MB used
|
||||
|
||||
const context: RenderContext = {};
|
||||
const item: WidgetItem = { id: 'mem', type: 'free-memory', rawValue: true };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as fs from 'fs';
|
||||
import { readFileSync } from 'fs';
|
||||
import {
|
||||
afterEach,
|
||||
beforeEach,
|
||||
@@ -15,6 +15,13 @@ import type {
|
||||
import { DEFAULT_SETTINGS } from '../../types/Settings';
|
||||
import { SessionNameWidget } from '../SessionName';
|
||||
|
||||
vi.mock('fs', () => ({ readFileSync: vi.fn() }));
|
||||
|
||||
const mockReadFileSync = readFileSync as unknown as {
|
||||
mockImplementation: (impl: () => string) => void;
|
||||
mockReset: () => void;
|
||||
};
|
||||
|
||||
function render(transcriptPath: string | undefined, fileContent: string | null, rawValue = false, isPreview = false) {
|
||||
const widget = new SessionNameWidget();
|
||||
const context: RenderContext = {
|
||||
@@ -27,11 +34,10 @@ function render(transcriptPath: string | undefined, fileContent: string | null,
|
||||
rawValue
|
||||
};
|
||||
|
||||
const readFileSyncSpy = vi.spyOn(fs, 'readFileSync');
|
||||
if (fileContent !== null) {
|
||||
readFileSyncSpy.mockImplementation(() => fileContent as never);
|
||||
mockReadFileSync.mockImplementation(() => fileContent);
|
||||
} else {
|
||||
readFileSyncSpy.mockImplementation(() => {
|
||||
mockReadFileSync.mockImplementation(() => {
|
||||
throw new Error('File not found');
|
||||
});
|
||||
}
|
||||
@@ -42,6 +48,7 @@ function render(transcriptPath: string | undefined, fileContent: string | null,
|
||||
describe('SessionNameWidget', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
mockReadFileSync.mockReset();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
Reference in New Issue
Block a user