import { test } from 'node:test' import assert from 'node:assert/strict' import { readFile } from 'node:fs/promises' import { createRequire } from 'node:module' import { transform } from 'esbuild' const require = createRequire(import.meta.url) const source = await readFile(new URL('../src/utils/teaching-schedule.ts', import.meta.url), 'utf8') const { code } = await transform(source, { loader: 'ts', format: 'cjs' }) const module = { exports: {} } new Function('require', 'module', 'exports', code)(require, module, module.exports) const { getTeachingScheduleLessons } = module.exports function slot(id, statuses) { return { slotId: id, date: '2026-10-29', startTime: '18:00', endTime: '19:00', bookedCount: statuses.length, capacity: 5, students: statuses.map((status, index) => ({ bookingId: `${id}-${index}`, userId: `u-${index}`, nickname: '测试', phone: null, status })), } } test('只计待确认、已确认、已完成;取消和未出席的独立时段不计课', () => { const result = getTeachingScheduleLessons([ slot('pending', ['PENDING_CONFIRMATION']), slot('confirmed', ['CONFIRMED']), slot('completed', ['COMPLETED']), slot('cancelled', ['CANCELLED']), slot('no-show', ['NO_SHOW']), slot('empty', []), ]) assert.deepEqual(result.map(item => item.slotId), ['pending', 'confirmed', 'completed']) assert.equal(result.reduce((sum, item) => sum + item.students.length, 0), 3) }) test('混合状态团课仍计一节课,人数只计有效预约,且保留完成状态', () => { const source = [slot('group', ['CANCELLED', 'CONFIRMED', 'COMPLETED', 'NO_SHOW'])] const snapshot = structuredClone(source) const result = getTeachingScheduleLessons(source) assert.equal(result.length, 1) assert.equal(result[0].students.length, 2) assert.deepEqual(result[0].students.map(student => student.status), ['CONFIRMED', 'COMPLETED']) assert.deepEqual(source, snapshot) }) test('全部取消或无预约时,课程数和人数均为零', () => { assert.deepEqual(getTeachingScheduleLessons([slot('cancelled', ['CANCELLED', 'CANCELLED'])]), []) assert.deepEqual(getTeachingScheduleLessons([]), []) })