import assert from 'node:assert/strict'; import { createRequire } from 'node:module'; import { readFileSync } from 'node:fs'; import vm from 'node:vm'; import ts from 'typescript'; const require = createRequire(import.meta.url); const source = readFileSync(new URL('../src/lib/calculations.ts', import.meta.url), 'utf8'); const compiled = ts.transpileModule(source, { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020, }, }).outputText; const sandbox = { exports: {}, module: { exports: {} }, require, Date, Math, Set, }; sandbox.exports = sandbox.module.exports; vm.runInNewContext(compiled, sandbox, { filename: 'calculations.ts' }); const { calculateDayMinutes } = sandbox.module.exports; function unix(localDateTime) { return Math.floor(new Date(localDateTime).getTime() / 1000); } function entry(id, type, localDateTime) { return { id, employeeId: 1, type, timestamp: unix(localDateTime), isDeleted: false, }; } function minutes(entries, dateStr, options) { return calculateDayMinutes(entries, dateStr, options); } function plain(value) { return JSON.parse(JSON.stringify(value)); } { const entries = [entry(1, 'IN', '2026-05-28T09:00:00'), entry(2, 'OUT', '2026-05-28T17:00:00')]; assert.deepEqual(plain(minutes(entries, '2026-05-28')), { clockMinutes: 480, breakMinutes: 0, workedMinutes: 480, hasErrors: false, errors: [], }); } { const entries = [entry(1, 'IN', '2026-05-28T22:00:00'), entry(2, 'OUT', '2026-05-29T06:00:00')]; assert.equal(minutes(entries, '2026-05-28').workedMinutes, 120); assert.equal(minutes(entries, '2026-05-29').workedMinutes, 360); assert.equal(minutes(entries, '2026-05-28').hasErrors, false); assert.equal(minutes(entries, '2026-05-29').hasErrors, false); } { const entries = [ entry(1, 'IN', '2026-05-28T22:00:00'), entry(2, 'BREAK_OUT', '2026-05-28T23:30:00'), entry(3, 'BREAK_IN', '2026-05-29T00:30:00'), entry(4, 'OUT', '2026-05-29T06:00:00'), ]; assert.equal(minutes(entries, '2026-05-28').clockMinutes, 120); assert.equal(minutes(entries, '2026-05-28').breakMinutes, 30); assert.equal(minutes(entries, '2026-05-28').workedMinutes, 90); assert.equal(minutes(entries, '2026-05-29').clockMinutes, 360); assert.equal(minutes(entries, '2026-05-29').breakMinutes, 30); assert.equal(minutes(entries, '2026-05-29').workedMinutes, 330); } { const entries = [entry(1, 'IN', '2026-05-28T22:00:00')]; const options = { nowUnix: unix('2026-05-29T02:00:00') }; const firstDay = minutes(entries, '2026-05-28', options); const secondDay = minutes(entries, '2026-05-29', options); assert.equal(firstDay.workedMinutes, 120); assert.equal(secondDay.workedMinutes, 120); assert.deepEqual(plain(firstDay.errors), ['Still clocked in']); assert.deepEqual(plain(secondDay.errors), ['Still clocked in']); } console.log('calculation tests passed');