更新
This commit is contained in:
@@ -69,12 +69,6 @@ coverage/
|
||||
*.[oO][gG][vV]
|
||||
|
||||
# Runtime databases, secrets and local configuration.
|
||||
*.db
|
||||
*.db-*
|
||||
*.sqlite
|
||||
*.sqlite-*
|
||||
*.sqlite3
|
||||
*.sqlite3-*
|
||||
*.log
|
||||
*.bak
|
||||
*.pem
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import {buildStoryboardPlan,dialogueTimingProblems,sectionBatchProblems,sectionCoverage,spokenLiterals,splitSpeech,speechSeconds,fitDraftDialogueTiming} from '../src/utils/storyboard-coverage.js'
|
||||
import {buildStoryboardPlan,dialogueTimingProblems,sectionBatchProblems,sectionCoverage,spokenLiterals,splitSpeech,speechSeconds,fitDraftDialogueTiming,coverageAdvanced,resumableDraftPrefix} from '../src/utils/storyboard-coverage.js'
|
||||
|
||||
const dialogue='请先检查每一扇窗户是否关好,再把桌上的图纸按照编号摆放整齐,确认材料数量以后我们才能开始修理屋顶。'
|
||||
test('long dialogue cannot fit in a four-second timeline slot even with a long total duration',()=>{
|
||||
@@ -70,3 +70,36 @@ test('coverage requires repeated speech in original order',()=>{
|
||||
shot.video_prompt+='甲说:「准备好了。」'
|
||||
assert.equal(sectionCoverage(section,[shot]).ready,true)
|
||||
})
|
||||
|
||||
test('shouting and cries with intervening performance details are spoken dialogue',()=>{
|
||||
for(const cue of ['怒吼','大叫','咆哮','惊呼','嘀咕','低语','哭诉','惨叫着猛甩手,脸上满是惊恐']) {
|
||||
assert.deepEqual(spokenLiterals(`0-9秒:@工人 ${cue}:「先关窗户,再检查工具!」`),['先关窗户,再检查工具!'])
|
||||
}
|
||||
const [section]=buildStoryboardPlan('工人:先关窗户,再检查工具!\n同事:啊!')
|
||||
const shot={shot_number:1,duration:12,source_ids:section.units.map(u=>u.id),video_prompt:'0-8秒:@工人 怒吼:「先关窗户,再检查工具!」\n8-12秒:@同事 惨叫着后退,手遮住脸:「啊!」'}
|
||||
assert.equal(sectionCoverage(section,[shot]).ready,true)
|
||||
assert.deepEqual(dialogueTimingProblems(shot),[])
|
||||
assert.ok(dialogueTimingProblems({...shot,duration:8,video_prompt:`0-8秒:@工人 怒吼:「${dialogue}」`}).length)
|
||||
})
|
||||
|
||||
test('onscreen quotations cannot satisfy dialogue coverage',()=>{
|
||||
for(const p of ['门牌写着:「先关窗户。」','@工人 指向显示屏,屏幕显示:「先关窗户。」','旁白停止,字幕:「先关窗户。」'])assert.deepEqual(spokenLiterals(p),[])
|
||||
})
|
||||
|
||||
test('repeated shots do not count as progress once time and source quotas are met',()=>{
|
||||
const [section]=buildStoryboardPlan('工人:先关窗户,再检查工具。')
|
||||
const shot={shot_number:1,duration:12,source_ids:section.units.map(u=>u.id),video_prompt:'0-12秒:工人看着工具。'}
|
||||
const before=sectionCoverage(section,[shot])
|
||||
assert.equal(coverageAdvanced(before,sectionCoverage(section,[shot,{...shot,shot_number:2}])),false)
|
||||
assert.equal(coverageAdvanced(before,sectionCoverage(section,[{...shot,video_prompt:'0-12秒:工人怒吼:「先关窗户,再检查工具。」'}])),true)
|
||||
})
|
||||
|
||||
test('resuming reuses only validated complete scenes, never inflated failed retries',()=>{
|
||||
const sections=buildStoryboardPlan('## S01 | 修复室\n工人:工具准备好了。\n## S02 | 屋顶\n同事:先检查安全绳。')
|
||||
const shots=[{shot_number:1,source_section:0,duration:12,source_ids:sections[0].units.map(u=>u.id),video_prompt:'0-12秒:工人说:「工具准备好了。」'},...Array.from({length:20},(_,i)=>({shot_number:i+2,source_section:1,duration:12,source_ids:sections[1].units.map(u=>u.id),video_prompt:'0-12秒:同事检查工具。'}))]
|
||||
const prefix=resumableDraftPrefix(sections,shots,1)
|
||||
assert.equal(prefix.sectionIndex,1);assert.deepEqual(prefix.drafts,[shots[0]])
|
||||
assert.equal(shots.length,21)
|
||||
shots[0].video_prompt='0-12秒:工人走进房间。'
|
||||
assert.equal(resumableDraftPrefix(sections,shots,1).sectionIndex,0)
|
||||
})
|
||||
|
||||
@@ -22,6 +22,11 @@ test('screen text instructions are still rejected, including quoted instructions
|
||||
assert.ok(storyboardSegmentProblems({shot_number:1,duration:9,video_prompt:p},[]).some(p=>p.includes('画面里出现文字')))
|
||||
}
|
||||
})
|
||||
|
||||
test('shouted words use the same speech classifier as timing and coverage',()=>{
|
||||
const p='0-9秒:@高天明怒吼:「血红文字写着什么?」画面中不出现任何文字。'
|
||||
assert.deepEqual(storyboardSegmentProblems({shot_number:1,duration:9,video_prompt:p,character_ids:[2]},characters),[])
|
||||
})
|
||||
test('timeline and character binding checks still apply',()=>{
|
||||
const problems=storyboardSegmentProblems({shot_number:1,duration:12,video_prompt:'0-9秒:@高天明说:「血红文字。」'},characters)
|
||||
assert.ok(problems.some(p=>p.includes('时间轴')))
|
||||
|
||||
Reference in New Issue
Block a user