Skip to content

Commit 78a18cc

Browse files
committed
dev: prioritize core regression coverage and reduce tests to 29
1 parent 048c61a commit 78a18cc

16 files changed

Lines changed: 35 additions & 809 deletions

‎doc/core-tests.md‎

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,41 @@
11
# Core regression tests
22

3-
The default `npm test` suite retains exactly 30 tests, reduced from 158. Selection prioritizes document or annotation loss, credential exposure, incorrect translation routing, core PDF extraction, restart persistence, and unbounded resource use. Existing assertions remain intact; small UI-policy checks and redundant helper-level variants were removed.
3+
The repository retains 29 automated Node tests, reduced from 77 during the October 5, 2026 review. `npm test` runs every remaining `server/*.test.mjs` test; there is no hidden extended suite or skipped-test filter. The unused Electron recents unit suite was also removed.
44

5-
Run `npm run build` before `npm test`: the production-stage check consumes the built frontend. Provider requests use mocks; these tests do not establish live translation quality or visual rendering correctness. Electron smoke scripts remain available for focused desktop validation outside this 30-test suite. Historical performance reports retain their original counts.
5+
Selection ranks original PDF and annotation integrity first, credential protection and authenticated document access next, then translation routing, cancellation, cache persistence and document isolation. Extraction, session recovery, settings preservation, production packaging and bounded rendering complete the suite. Existing retained assertions remain intact.
6+
7+
Removed lower-priority checks cover annotation browser filters, topic/keyword emphasis, translation spacing, outline tracking, quick links, pins, navigation helpers and row layout. Helper-level page-edit variants are replaced in the retained coverage by the existing save integration test, which checks disk contents, annotation geometry, rotation and rejection without modifying the PDF. Redundant cache variants were removed. These areas have less automatic regression coverage; additions should replace a lower-priority case to keep the suite below 30.
8+
9+
Run `npm run build` before `npm test`: the production-stage check consumes the built frontend. Provider requests use mocks; passing tests do not establish live translation quality or visual rendering correctness. Electron smoke scripts remain available for targeted desktop checks outside this Node suite. Historical performance reports retain their original counts.
610

711
| # | Test file | Retained behavior |
812
|---|---|---|
9-
| 1 | server/annotation-display.test.mjs | whole-page translation loaded while viewing original does not hide source highlights |
10-
| 2 | server/annotation-display.test.mjs | paragraph annotations follow their own rendered overlay, not another translated paragraph |
11-
| 3 | server/annotations.test.mjs | annotation store round-trips metadata, embeds standard annotations, rewrites only managed entries, and preserves external entries |
12-
| 4 | server/annotations.test.mjs | fingerprint-only documents persist sidecar metadata and serialize concurrent saves |
13-
| 5 | server/annotations.test.mjs | native comments and highlights import, migrate, recover from copied PDF, and delete without affecting other entries |
14-
| 6 | server/bitmap-cache.test.mjs | touches entries on get and evicts the oldest entry |
15-
| 7 | server/bitmap-cache.test.mjs | rejects an oversized canvas without changing it or evicting entries |
16-
| 8 | server/credentials.test.mjs | credential override, reload, clearing and secure-storage failure |
17-
| 9 | server/credentials.test.mjs | Windows keys use system encryption, survive replacement and reload, and never save plaintext |
18-
| 10 | server/desktop.test.mjs | desktop backend has private origin, authenticates API, and releases its port |
19-
| 11 | server/document-search.test.mjs | PDF search spans text runs, ignores layout whitespace, and keeps matching coordinates |
20-
| 12 | server/document-session.test.mjs | session persists multiple documents and positions; closing all restores only the last closed document |
21-
| 13 | server/documents.test.mjs | OS PDF delivery validates files and exposes bytes without filesystem paths |
22-
| 14 | server/documents.test.mjs | document store rejects capacity without evicting active documents and invalidates deletes |
23-
| 15 | server/documents.test.mjs | authenticated registration supports multiple JSON layouts for one stored document |
24-
| 16 | server/engines.test.mjs | fresh kernel assets have valid targets and reuse existing shared models |
25-
| 17 | server/engines.test.mjs | global translation budget holds across simultaneous page workers and releases after failures |
26-
| 18 | server/layout-extraction.test.mjs | coalesces same-entry requests, sorts and deduplicates pages, and splits by one-indexed page |
27-
| 19 | server/layout-extraction.test.mjs | cleanup cancels pending and in-flight waiters and ignores late native results |
28-
| 20 | server/layout-extraction.test.mjs | limits cache by exact JSON bytes and page count with LRU eviction |
29-
| 21 | server/layout.test.mjs | flips visible page coordinates and joins lines without merging columns |
30-
| 22 | server/pdf-extractor.test.mjs | portable extraction preserves selected pages, display-frame positions and font sizes |
31-
| 23 | server/preferences.test.mjs | partial saves keep every current setting and unknown key |
32-
| 24 | server/production-stage.test.mjs | production bundle serves and extracts PDFs without an external Express installation |
33-
| 25 | server/reader-layout.test.mjs | mixed-size row geometry preserves column widths, gaps and four buffered rows |
34-
| 26 | server/render-resolution.test.mjs | large pages remain bounded by backing store memory and canvas dimensions |
35-
| 27 | server/translation-cache.test.mjs | compatible cache survives restart for custom models and strict mode stays isolated |
36-
| 28 | server/translation-cache.test.mjs | paragraph API reuses legacy translations by default, strict mode invokes current provider |
37-
| 29 | server/translation-provider.test.mjs | configured key routes only to OpenAI and aborted fallback sends no translation |
38-
| 30 | server/translation-provider.test.mjs | backend fallback headers survive cache and failure, with independent launch sessions and provider caches |
13+
| 1 | server/annotations.test.mjs | annotation store round-trips metadata, embeds standard annotations, rewrites only managed entries, and preserves external entries |
14+
| 2 | server/annotations.test.mjs | fingerprint-only documents persist sidecar metadata and serialize concurrent saves |
15+
| 3 | server/annotations.test.mjs | native comments and highlights import, migrate, recover from copied PDF, and delete without affecting other entries |
16+
| 4 | server/annotations.test.mjs | opening an unannotated or link-only PDF preserves its exact bytes |
17+
| 5 | server/annotations.test.mjs | prepared PDF removes imported native and managed annotations while preserving unrelated links |
18+
| 6 | server/credentials.test.mjs | credential override, reload, clearing and secure-storage failure |
19+
| 7 | server/credentials.test.mjs | Windows keys use system encryption, survive replacement and reload, and never save plaintext |
20+
| 8 | server/desktop.test.mjs | desktop backend has private origin, authenticates API, and releases its port |
21+
| 9 | server/document-search.test.mjs | PDF search spans text runs, ignores layout whitespace, and keeps matching coordinates |
22+
| 10 | server/document-session.test.mjs | session persists multiple documents and positions; closing all restores only the last closed document |
23+
| 11 | server/documents.test.mjs | OS PDF delivery validates files and exposes bytes without filesystem paths |
24+
| 12 | server/documents.test.mjs | document store rejects capacity without evicting active documents and invalidates deletes |
25+
| 13 | server/documents.test.mjs | authenticated registration supports multiple JSON layouts for one stored document |
26+
| 14 | server/engines.test.mjs | global translation budget holds across simultaneous page workers and releases after failures |
27+
| 15 | server/engines.test.mjs | cancelled queued translations release immediately without running or waiting for a slot |
28+
| 16 | server/engines.test.mjs | Fast and Precise retain compatible pre-update translated PDFs and layouts across app versions |
29+
| 17 | server/layout-extraction.test.mjs | cleanup cancels pending and in-flight waiters and ignores late native results |
30+
| 18 | server/page-edit-save.test.mjs | page edits persist to the original PDF and annotation metadata before resolving |
31+
| 19 | server/pdf-extractor.test.mjs | portable extraction preserves selected pages, display-frame positions and font sizes |
32+
| 20 | server/preferences.test.mjs | partial saves keep every current setting and unknown key |
33+
| 21 | server/production-stage.test.mjs | production bundle serves and extracts PDFs without an external Express installation |
34+
| 22 | server/render-resolution.test.mjs | large pages remain bounded by backing store memory and canvas dimensions |
35+
| 23 | server/translation-cache.test.mjs | compatible cache survives restart for custom models and strict mode stays isolated |
36+
| 24 | server/translation-cache.test.mjs | paragraph API reuses legacy translations by default, strict mode invokes current provider |
37+
| 25 | server/translation-provider.test.mjs | configured key routes only to OpenAI and aborted fallback sends no translation |
38+
| 26 | server/translation-provider.test.mjs | backend fallback headers survive cache and failure, with independent launch sessions and provider caches |
39+
| 27 | server/translation-text-cache.test.mjs | deduplicates concurrent requests and keeps the shared request alive for a remaining waiter |
40+
| 28 | server/translation-text-cache.test.mjs | does not cache failed or empty OpenAI responses |
41+
| 29 | server/translation-text-cache.test.mjs | document cache invalidation bypasses shared text results without changing another document |

‎electron/recents.test.mjs‎

Lines changed: 0 additions & 37 deletions
This file was deleted.

‎server/annotation-browser.test.mjs‎

Lines changed: 0 additions & 102 deletions
This file was deleted.

‎server/engines.test.mjs‎

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -50,44 +50,3 @@ test('Fast and Precise retain compatible pre-update translated PDFs and layouts
5050
}
5151
}finally{await rm(root,{recursive:true,force:true});}
5252
});
53-
54-
test('kernel cache-only lookup misses without starting a worker or creating a job',async()=>{
55-
const root=await mkdtemp(join(tmpdir(),'kernel-cache-probe-'));
56-
try{
57-
const engines=createEngines({root,cacheDir:join(root,'math'),findUvImpl:async()=>({available:true}),execImpl:async()=>({stdout:'1.0.0'})});
58-
for(const id of ['pdf_math_fast','pdf_math_precise'])assert.equal(await engines.translate({id,bytes:Buffer.from('%PDF fixture'),page:1,language:'French',model:'fixture',cacheOnly:true}),null);
59-
const {readdir}=await import('node:fs/promises');assert.deepEqual(await readdir(root),[]);
60-
engines.close();
61-
}finally{await rm(root,{recursive:true,force:true});}
62-
});
63-
64-
test('Fast CJK layout upgrade rejects PDFs typeset with the prior schema',async()=>{
65-
const {createHash}=await import('node:crypto');
66-
const root=await mkdtemp(join(tmpdir(),'kernel-layout-upgrade-')),cacheDir=join(root,'math'),bytes=Buffer.from('%PDF prior layout fixture');
67-
try{
68-
await mkdir(cacheDir,{recursive:true});
69-
const key=createHash('sha256').update(bytes).update(JSON.stringify({id:'pdf_math_fast',version:'1.0.0',page:1,language:'Simplified Chinese',model:'fixture',prompt:2,layoutSchema:4})).digest('hex');
70-
await writeFile(join(cacheDir,key+'.pdf'),'%PDF obsolete typesetting');await writeFile(join(cacheDir,key+'.layout.json'),JSON.stringify({paragraphs:[]}));
71-
const engines=createEngines({root,cacheDir,findUvImpl:async()=>({available:true}),execImpl:async()=>({stdout:'1.0.0'})});
72-
assert.equal(await engines.translate({id:'pdf_math_fast',bytes,page:1,language:'Simplified Chinese',model:'fixture',cacheOnly:true,reuseTranslations:true}),null);
73-
engines.close();
74-
}finally{await rm(root,{recursive:true,force:true});}
75-
});
76-
77-
test('a page filled while waiting reuses its cache instead of starting another worker',async()=>{
78-
const {createHash}=await import('node:crypto');
79-
const {readdir}=await import('node:fs/promises');
80-
const root=await mkdtemp(join(tmpdir(),'kernel-queued-cache-')),cacheDir=join(root,'math');
81-
const bytes=Buffer.from('%PDF queued fixture'),id='pdf_math_fast',model='fixture';
82-
const key=createHash('sha256').update(bytes).update(JSON.stringify({id,version:'1.0.0',page:1,language:'French',model,prompt:2,layoutSchema:4})).digest('hex');
83-
try{
84-
const engines=createEngines({root,cacheDir,findUvImpl:async()=>({available:true}),execImpl:async()=>({stdout:'1.0.0'})});
85-
const result=await engines.translate({id,bytes,page:1,language:'French',model,runWorker:async fn=>{
86-
await mkdir(cacheDir,{recursive:true});await writeFile(join(cacheDir,key+'.pdf'),'%PDF completed by preceding worker');
87-
await writeFile(join(cacheDir,key+'.layout.json'),JSON.stringify({paragraphs:[]}));
88-
return fn();
89-
}});
90-
assert.equal(result.cached,true);assert.equal(result.layoutKey,key);
91-
assert.deepEqual(await readdir(root),['math']);engines.close();
92-
}finally{await rm(root,{recursive:true,force:true});}
93-
});

0 commit comments

Comments
 (0)