Merge pull request #24 from pullfrog/add-basic-unit-tests
Initial unit tests
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "24"
|
||||
cache: "pnpm"
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Run type check
|
||||
run: pnpm typecheck
|
||||
|
||||
- name: Run tests
|
||||
run: pnpm test
|
||||
+3
-2
@@ -13,7 +13,7 @@
|
||||
"main.d.ts"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"test": "vitest",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"build": "node esbuild.config.js",
|
||||
"play": "node play.ts",
|
||||
@@ -47,7 +47,8 @@
|
||||
"arg": "^5.0.2",
|
||||
"esbuild": "^0.25.9",
|
||||
"husky": "^9.0.0",
|
||||
"typescript": "^5.9.3"
|
||||
"typescript": "^5.9.3",
|
||||
"vitest": "^4.0.17"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
Generated
+874
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,7 @@
|
||||
"target": "ESNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"lib": ["ESNext"],
|
||||
"types": ["vitest/globals"],
|
||||
"allowImportingTsExtensions": true,
|
||||
"rewriteRelativeImportExtensions": true,
|
||||
"skipLibCheck": true,
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
import { Timer } from './timer.ts';
|
||||
import * as cli from './cli.ts';
|
||||
|
||||
describe('Timer', () => {
|
||||
beforeEach(() => {
|
||||
vi.spyOn(cli.log, 'debug');
|
||||
// Mock Date.now to have predictable timestamps
|
||||
vi.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
describe('constructor', () => {
|
||||
it('should initialize with current timestamp', () => {
|
||||
const mockTime = 1000000;
|
||||
vi.setSystemTime(mockTime);
|
||||
|
||||
const timer = new Timer();
|
||||
timer.checkpoint('test');
|
||||
|
||||
expect(cli.log.debug).toHaveBeenCalledWith(
|
||||
expect.stringContaining('test')
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('checkpoint', () => {
|
||||
it('should log duration from initial timestamp on first checkpoint', () => {
|
||||
const startTime = 1000000;
|
||||
vi.setSystemTime(startTime);
|
||||
const timer = new Timer();
|
||||
|
||||
const checkpointTime = startTime + 100;
|
||||
vi.setSystemTime(checkpointTime);
|
||||
timer.checkpoint('first');
|
||||
|
||||
expect(cli.log.debug).toHaveBeenCalledWith('» first: 100ms');
|
||||
});
|
||||
|
||||
it('should log duration from last checkpoint on subsequent checkpoints', () => {
|
||||
const startTime = 1000000;
|
||||
vi.setSystemTime(startTime);
|
||||
const timer = new Timer();
|
||||
|
||||
// First checkpoint
|
||||
const firstCheckpointTime = startTime + 50;
|
||||
vi.setSystemTime(firstCheckpointTime);
|
||||
timer.checkpoint('first');
|
||||
|
||||
// Second checkpoint
|
||||
const secondCheckpointTime = firstCheckpointTime + 75;
|
||||
vi.setSystemTime(secondCheckpointTime);
|
||||
timer.checkpoint('second');
|
||||
|
||||
expect(cli.log.debug).toHaveBeenCalledTimes(2);
|
||||
expect(cli.log.debug).toHaveBeenNthCalledWith(1, '» first: 50ms');
|
||||
expect(cli.log.debug).toHaveBeenNthCalledWith(2, '» second: 75ms');
|
||||
});
|
||||
|
||||
it('should handle multiple checkpoints correctly', () => {
|
||||
const startTime = 1000000;
|
||||
vi.setSystemTime(startTime);
|
||||
const timer = new Timer();
|
||||
|
||||
// First checkpoint
|
||||
vi.setSystemTime(startTime + 10);
|
||||
timer.checkpoint('step1');
|
||||
|
||||
// Second checkpoint
|
||||
vi.setSystemTime(startTime + 25);
|
||||
timer.checkpoint('step2');
|
||||
|
||||
// Third checkpoint
|
||||
vi.setSystemTime(startTime + 45);
|
||||
timer.checkpoint('step3');
|
||||
|
||||
expect(cli.log.debug).toHaveBeenCalledTimes(3);
|
||||
expect(cli.log.debug).toHaveBeenNthCalledWith(1, '» step1: 10ms');
|
||||
expect(cli.log.debug).toHaveBeenNthCalledWith(2, '» step2: 15ms');
|
||||
expect(cli.log.debug).toHaveBeenNthCalledWith(3, '» step3: 20ms');
|
||||
});
|
||||
|
||||
it('should handle zero duration correctly', () => {
|
||||
const startTime = 1000000;
|
||||
vi.setSystemTime(startTime);
|
||||
const timer = new Timer();
|
||||
|
||||
// Checkpoint immediately
|
||||
timer.checkpoint('immediate');
|
||||
|
||||
expect(cli.log.debug).toHaveBeenCalledWith('» immediate: 0ms');
|
||||
});
|
||||
|
||||
it('should handle custom checkpoint names', () => {
|
||||
const startTime = 1000000;
|
||||
vi.setSystemTime(startTime);
|
||||
const timer = new Timer();
|
||||
|
||||
vi.setSystemTime(startTime + 200);
|
||||
timer.checkpoint('Custom Checkpoint Name');
|
||||
|
||||
expect(cli.log.debug).toHaveBeenCalledWith(
|
||||
'» Custom Checkpoint Name: 200ms'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import { defineConfig } from 'vitest/config';
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
globals: true,
|
||||
environment: 'node',
|
||||
exclude: ['node_modules', '.temp'],
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user