const test=require('node:test'); const assert=require('node:assert/strict'); const path=require('node:path'); const fs=require('node:fs'); const createLoader=require('./load-module.cjs'); function setup(file,api={}) { let definition,id=0;const timers=new Map(),storage=new Map(),writes=[]; const wx={getStorageSync:key=>storage.get(key),setStorageSync:(key,value)=>{writes.push(value);storage.set(key,value);},removeStorageSync:key=>storage.delete(key),showToast(){}}; createLoader({Page:p=>definition=p,wx,console,Promise,Date,clearTimeout:key=>timers.delete(key),setTimeout:fn=>{timers.set(++id,fn);return id;}},{'../../utils/request':{api,getImageUrl:v=>v}})(path.join(__dirname,'../pages',file+'.js')); const patches=[];const page={...definition,data:JSON.parse(JSON.stringify(definition.data)),setData(values){patches.push(values);for(const [key,value] of Object.entries(values)){const parts=key.split('.');let target=this.data;for(const part of parts.slice(0,-1))target=target[part];target[parts.at(-1)]=value;}}}; return {page,timers,storage,writes,patches}; } test('diary input continues past 100 characters and never rewrites the native textarea value',()=>{ for(const file of ['publish/publish','diary_edit/diary_edit']){ const e=setup(file);if(file.startsWith('publish'))e.page.resetForm('diary'); e.patches.length=0; for(const length of [100,101,140,1000,5000]){const value='字'.repeat(length);e.page.onContentInput({detail:{value}});assert.equal(e.page.data.form.content,value);assert.equal(e.page.data.contentLength,length);} assert.ok(e.patches.every(patch=>!('editorContent' in patch))); assert.ok(e.patches.every(patch=>!('form.content' in patch))); } }); test('both diary templates explicitly allow 5000 characters and grow with long text',()=>{ for(const file of ['publish/publish','diary_edit/diary_edit']){ const base=path.join(__dirname,'../pages',file); const template=fs.readFileSync(base+'.wxml','utf8'); const editor=template.match(/]*class="[^"]*diary-editor[^"]*"[^>]*\/>/)[0]; assert.match(editor,/maxlength="5000"/); assert.match(editor,/auto-height="\{\{true\}\}"/); const styles=fs.readFileSync(base+'.wxss','utf8'); assert.doesNotMatch(styles,/textarea\.diary-editor\s*\{[^}]*[;{]\s*height\s*:/); } }); test('rapid typing writes a single draft, and leaving the page flushes the newest content',()=>{ const e=setup('publish/publish');e.page.resetForm('diary');e.page.data.type='diary'; for(let i=1;i<=200;i++)e.page.onContentInput({detail:{value:'字'.repeat(i)}}); assert.equal(e.writes.length,0);assert.equal(e.timers.size,1); for(const callback of [...e.timers.values()])callback();e.timers.clear();assert.equal(e.writes.length,1);assert.equal(JSON.parse(e.writes[0]).form.content.length,200); e.page.onContentInput({detail:{value:'最后的内容'}});e.page.onHide();assert.equal(e.timers.size,0);assert.equal(JSON.parse(e.writes.at(-1)).form.content,'最后的内容'); }); test('published drafts are not recreated by pending timers or page teardown',()=>{ const e=setup('publish/publish');e.page.resetForm('diary');e.page.data.type='diary';e.page.onContentInput({detail:{value:'已发布'}}); e.page._clearDraft();e.page.onHide();e.page.onUnload();assert.equal(e.timers.size,0);assert.equal(e.writes.length,0);assert.equal(e.storage.has('publishDraft_diary'),false); }); test('restoring a draft and loading an existing diary initialize the textarea display value',async()=>{ const e=setup('publish/publish');e.page.resetForm('diary');e.storage.set('publishDraft_diary',JSON.stringify({form:{title:'标题',content:'字'.repeat(1000)}}));e.page.loadDraft('diary');assert.equal(e.page.data.editorContent.length,1000); const edited=setup('diary_edit/diary_edit',{diaryDetail:async()=>({content:'字'.repeat(1500),images:[]})});edited.page.data.diaryId=1;await edited.page.loadDiary();assert.equal(edited.page.data.editorContent.length,1500);assert.equal(edited.page.data.contentLength,1500); });