- 其余 21 个实验的 task.md:控件名照示例代码,"在平台上怎么试"和评分步骤一致,列出书上的印刷错误和控件名不一致 - 窗体改名:属性窗口里选中窗体可以改名称,类名、构造函数、new X()、Program.cs 和两个文件名一起改;方法名和字符串不变 - 11 个主窗体不叫 Form1 的实验,任务说明提示先改窗体名再双击生成 Load 事件 - 测试:表头只认分隔行上面那一行,数据行里出现"名称"不再被当成表头 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
42 lines
1.8 KiB
TypeScript
42 lines
1.8 KiB
TypeScript
// 示例的任务说明(task.md):表格里写的控件名都要在示例的 Designer.cs 里有,学生照着改名不会被带错。
|
|
import { expect, test } from 'bun:test'
|
|
import { listSamples, loadSample, loadTask } from '../src/samples'
|
|
|
|
/** 控件表格(表头有"名称")里那一列用 `反引号` 写的名字 */
|
|
function tableNames(task: string): string[] {
|
|
const names: string[] = []
|
|
let column = -1
|
|
let previous: string[] = []
|
|
for (const line of task.split('\n')) {
|
|
if (!line.trim().startsWith('|')) {
|
|
column = -1
|
|
previous = []
|
|
continue
|
|
}
|
|
const cells = line.trim().replace(/^\||\|$/g, '').split('|')
|
|
// 表头是分隔行(|---|)上面那一行;数据行里出现"名称"两个字不算表头
|
|
if (cells.every((c) => /^\s*:?-+:?\s*$/.test(c))) column = previous.findIndex((c) => c.includes('名称'))
|
|
else if (column >= 0) names.push(...[...(cells[column] ?? '').matchAll(/`([^`]+)`/g)].map((m) => m[1]))
|
|
previous = cells
|
|
}
|
|
return names
|
|
}
|
|
|
|
test('任务说明里的控件名都在示例的界面里', async () => {
|
|
let checked = 0
|
|
for (const { id } of await listSamples()) {
|
|
const task = await loadTask(id)
|
|
if (!task) continue
|
|
const designer = (await loadSample(id))!.filter((f) => f.path.endsWith('.Designer.cs'))
|
|
const names = tableNames(task)
|
|
expect(names.length, `${id} 的任务说明没有控件表格`).toBeGreaterThan(0)
|
|
for (const name of names) {
|
|
// 窗体本身写的是类名,控件是 this.名字
|
|
const found = designer.some((f) => f.content.includes(`this.${name} `) || f.content.includes(`partial class ${name}`))
|
|
expect(found, `${id}:任务说明里的 ${name} 在 Designer.cs 里找不到`).toBe(true)
|
|
}
|
|
checked++
|
|
}
|
|
expect(checked).toBeGreaterThan(0)
|
|
})
|