Files
openmaic/OpenMAIC/tests/course-framework/module-digest.test.ts
2026-08-16 14:58:47 +08:00

125 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { describe, expect, test } from 'vitest';
import type { PersistedClassroomData } from '@/lib/server/classroom-storage';
import {
buildCourseModuleOutputDigest,
formatPreviousModuleContext,
} from '@/lib/course-framework/module-digest';
function classroomFixture(): PersistedClassroomData {
return {
id: 'classroom-actual-1',
createdAt: '2026-08-15T09:00:00.000Z',
stage: { id: 'stage-1', name: '实际生成的机器学习基础' } as never,
scenes: [
{
id: 'scene-slide',
stageId: 'stage-1',
order: 1,
title: '监督学习基础',
type: 'slide',
content: {
type: 'slide',
canvas: {
id: 'slide-1',
viewportSize: 1000,
viewportRatio: 0.5625,
theme: {},
elements: [
{
id: 'text-1',
type: 'text',
content: '<p>特征、标签与训练样本</p>',
},
],
},
},
actions: [{ id: 'speech-1', type: 'speech', text: '比较监督学习和无监督学习。' }],
},
{
id: 'scene-interactive',
stageId: 'stage-1',
order: 2,
title: '分类边界实验室',
type: 'interactive',
content: {
type: 'interactive',
widgetType: 'simulation',
widgetConfig: { type: 'simulation', concept: '决策边界', challenge: '调整样本分布' },
html: '<style>.noise{color:red}</style><h1>拖动数据点观察边界变化</h1><script>ignore()</script>',
},
},
{
id: 'scene-quiz',
stageId: 'stage-1',
order: 3,
title: '概念检查',
type: 'quiz',
content: {
type: 'quiz',
questions: [
{
id: 'q-1',
type: 'single',
question: '标签在监督学习中承担什么作用?',
},
],
},
},
{
id: 'scene-pbl',
stageId: 'stage-1',
order: 4,
title: '识别真实业务问题',
type: 'pbl',
content: {
type: 'pbl',
projectV2: {
title: '业务问题分类项目',
description: '判断问题适合监督学习还是无监督学习。',
learningObjective: '能够把业务目标转成学习任务。',
milestones: [{ title: '提交问题定义' }],
},
},
},
] as never,
};
}
describe('course module output digest', () => {
test('extracts bounded evidence from all four actual scene types', () => {
const digest = buildCourseModuleOutputDigest(classroomFixture());
expect(digest.sceneTypeCounts).toEqual({ slide: 1, quiz: 1, interactive: 1, pbl: 1 });
expect(digest.sceneCount).toBe(4);
expect(digest.coveredConcepts).toContain('监督学习基础');
expect(digest.coveredConcepts).toContain('特征、标签与训练样本');
expect(digest.coveredConcepts).toContain('拖动数据点观察边界变化');
expect(digest.coveredConcepts.join(' ')).not.toContain('ignore()');
expect(digest.assessments).toContain('标签在监督学习中承担什么作用?');
expect(digest.assessments).toContain('提交问题定义');
expect(digest.interactiveExperiences).toEqual([
'分类边界实验室simulation, interactive-html',
'识别真实业务问题PBL',
]);
expect(digest.semanticHash).toMatch(/^sha256:[a-f0-9]{64}$/);
expect(buildCourseModuleOutputDigest(classroomFixture()).semanticHash).toBe(
digest.semanticHash,
);
});
test('formats actual prior outputs as bounded continuity context', () => {
const digest = buildCourseModuleOutputDigest(classroomFixture());
const context = formatPreviousModuleContext([
{ index: 1, title: '基础模块', outputDigest: digest },
{ index: 2, title: '练习模块', outputDigest: { ...digest, classroomId: 'classroom-2' } },
]);
expect(context).toContain('模块 1《基础模块》');
expect(context).toContain('实际摘要');
expect(context).toContain('实际覆盖');
expect(context).toContain('实际语义哈希');
expect(context).toContain('分类边界实验室simulation, interactive-html');
expect(context.length).toBeLessThanOrEqual(12_000);
});
});