Commit graph

54 commits

Author SHA1 Message Date
wujunchen
0801b644f6 fix: address CR findings — bump script, test runner, temp cleanup
- bump-version.mjs: reject duplicate versions (use --force to override),
  auto git-add manifest.json + versions.json for npm version hook
- run-tests.mjs: use execFileSync to handle paths with spaces
- test-setup.js: clean up esbuild temp directory on process exit

Change-Id: I44410b550d09487dd7f5e30a8f9385a2c500252a
2026-04-27 20:19:53 +08:00
wujunchen
199ab73188 refactor: split main.test.js into focused test files
Reduce main.test.js from 560 to 70 lines by keeping only architecture
guards and export smoke tests. Moved provider error tests, Anthropic
tool-use parsing, and cancellationNoticeKey tests to providers.test.js.
Settings, cache, and other tests were already covered in their
dedicated test files.

Change-Id: I8f0f3c576dec7fcf5a4c6e0c2b6071601940349d
2026-04-27 19:59:46 +08:00
wujunchen
f5f974fd74 build: remove __test barrel from production bundle
Tests now load src/test-exports.ts via esbuild buildSync instead of
importing __test from the production main.js. This removes ~60 internal
symbols and all test-only module code from the shipped plugin bundle.

Change-Id: I2caf5232f6894c7514215e1751f2e268b74d7dc4
2026-04-27 19:57:28 +08:00
wujunchen
0bf5ab12b1 lint: extend Biome coverage to tests/ and scripts/
Add tests/**/*.js and scripts/**/*.mjs to biome.json includes and
update npm lint scripts to cover these directories. Auto-fixed all
formatting issues in 26 files.

Change-Id: I8c2763cb9683616a8abc1484d91bf8af79bb590e
2026-04-27 19:53:35 +08:00
wujunchen
b26b241c7f refactor: centralize obsidian mock into tests/obsidian-mock.js
Extracts the duplicated Module._load obsidian stub from main.test.js,
generation-job-manager.test.js, and test-setup.js into a single shared
file. All three now require('./obsidian-mock') instead of defining
their own copy.

Change-Id: I8ac38f779299ac250963357eee9f7824e13c7d33
2026-04-27 19:52:34 +08:00
wujunchen
df48dc2cc4 fix: remove unsupported --max-tokens flag from claude CLI args
The Claude Code CLI doesn't support --max-tokens. This caused the CLI
backend to always fail with exit code 1. Also adds args validation tests
for both claude and codex CLI backends.

Change-Id: I57c5cc672ed08de291e3941511ce68ba56e5b4ff
2026-04-27 19:07:53 +08:00
wujunchen
05ac2b923f test: add batch.ts comprehensive tests including isFileInBatchFolder
Tests cover isFileInBatchFolder (root, subfolder, nested), edge cases
for normalizeBatchFolderInput (null, undefined, only slashes),
hasUnsafeBatchFolderSegments (null, single dot, dotfile), selectBatchFiles
with complex folder structures, and stats immutability verification.

Change-Id: If4964355db427347060ea3f902e8f6ef71ea2471
2026-04-27 15:31:37 +08:00
wujunchen
741012e535 test: add settings.ts edge case tests for utility functions
Tests cover stableStringify (key sorting, nested, types), isApiBackend,
getApiFormat/getApiAuthType fallback behavior, normalizeMaxCacheEntries,
hashContent consistency, normalizeSettings validation (invalid uiLanguage,
apiProvider, apiFormat, apiAuthType, non-string customSystemPrompt),
and pruneCacheEntries with null/empty/non-object inputs.

Change-Id: I96269c69871e3c17ccb06a71ac9cfb9733a382f6
2026-04-27 15:30:33 +08:00
wujunchen
6f80d0de03 test: add generation.ts cancellationNoticeKey edge case tests
Tests cover all backend types (api, anthropic-api, claude-code, codex),
all generation phases (queued, reading, cache-check, generating, saving),
and null settings/job edge cases.

Change-Id: I722fb0cf1129c7cf45dfc5bf2544577652df843d
2026-04-27 15:29:29 +08:00
wujunchen
0f8625874e test: add comprehensive markdown.ts unit tests
Tests cover cardToMarkdown, cardToPlain, and cardsToMarkdown with
edge cases: empty/missing fields, anchor whitespace normalization,
null cards array, empty title fallback, plain text bullet formatting.

Change-Id: I1972705d385f0393c9fd1be7f80d6513f5328d06
2026-04-27 15:28:34 +08:00
wujunchen
1e2ccc0840 test: add comprehensive prompt.ts unit tests
Tests cover promptLanguageInstruction, promptSchemaExample,
renderPromptTemplate, and buildPrompts edge cases including
auto language, truncation markers, custom prompt variable
substitution, card count normalization, and fallback behavior.

Change-Id: I75d5b354df15456ddbd08d9d21846f74d6b6cea3
2026-04-27 15:27:19 +08:00
wujunchen
0264ef0b6c refactor: split direct-modules.test.js into 5 per-module test files
Replaces the monolithic direct-modules.test.js (780 lines) with focused
per-module test files sharing a common direct-test-setup.js. Each file
is under 165 lines. All existing test assertions preserved.

New files: direct-test-setup.js, direct-cache.test.js,
direct-providers.test.js, direct-settings.test.js, direct-i18n.test.js,
direct-streaming.test.js

Change-Id: Ie9cceaf3b9b71e618c0d7e524a5186b5c44079c8
2026-04-27 15:24:32 +08:00
wujunchen
7cb68658f5 refactor: split modules.test.js into 12 per-module test files
Replaces the monolithic modules.test.js (983 lines) with focused
per-module test files sharing a common test-setup.js. Each file is
under 225 lines. All existing test assertions preserved.

New files: test-setup.js, anchor.test.js, schema.test.js, cache.test.js,
cards-nav.test.js, markdown.test.js, vault-batch.test.js, i18n.test.js,
scroll.test.js, settings.test.js, providers.test.js, streaming.test.js,
cli.test.js

Change-Id: I37a3342a1588807277e679e6535cde361e650565
2026-04-27 15:21:03 +08:00
fancivez
b2716da4ca test: add getApiKey, cacheEntryMatches, normalizeCardCount edge case tests
Cover normalizeCardCount boundary values (0, negative, NaN, max 30, string).
Test getApiKey with direct key, env var, precedence, and trimming.
Test cacheEntryMatches for valid match, null entry, wrong hash, wrong schema.

Change-Id: I1113d923885e03f6b28d47721cc303bbbb6d70ed
2026-04-27 14:11:37 +08:00
fancivez
c111865fbd test: add resolveCardAnchors unit tests
Cover sorting by startLine, unanchored cards pushed to end, empty/null
input, all-unanchored relative order, and default level value.

Change-Id: I74c48041897e8e4fb44555aaa319e6ebde8f91b1
2026-04-27 14:11:37 +08:00
fancivez
0ef6395ed7 test: add parseApiHeaders unit tests covering all input formats
Export parseApiHeaders for testing. Cover: JSON object input, empty/whitespace,
line-based input, comments/blank lines, malformed JSON, array input fallback,
missing colon, non-string JSON values filtered, colons in values preserved.

Change-Id: Ia00898888c6a0b78a284b43f29e382cc4080ba88
2026-04-27 14:11:37 +08:00
fancivez
3a2c4e6a1c test: add vault.ts normalizeVaultPath and folderPathsForTarget tests
Cover normalizeVaultPath with clean paths, whitespace trimming, parent
traversal stripping, dot segments, null input, and empty segments.
Test folderPathsForTarget ancestor chain generation for various depths.

Change-Id: I4de1744301df1e42d35f0bd5702d5cc58fb9a277
2026-04-27 14:11:37 +08:00
fancivez
d6b89924f2 test: add i18n translate and resolveUiLanguage unit tests
Cover translate() with explicit languages, variable interpolation (single,
multiple, numeric), missing keys, null settings, unmatched placeholders.
Test resolveUiLanguage for explicit/auto/null settings.
Validate zh/en STRINGS parity (same key count, no missing keys).

Change-Id: I06c3bdc9d824eaa0e205b335b9856d872a1aefd1
2026-04-27 14:11:37 +08:00
fancivez
1efacf695c test: add schema.ts edge case coverage for repair and JSON extraction
Test repairTruncatedCardsJson with whitespace variations, escaped quotes,
braces in string values, all-truncated cards, and empty arrays.
Add collectJsonObjectCandidates tests for empty input, nested objects,
braces in strings, and unclosed braces.

Change-Id: I82392bff6eaf457934dbbe63e7c5788ea6a44e19
2026-04-27 14:11:37 +08:00
fancivez
be8ad72ba2 test: add comprehensive parseSseBuffer and deltaExtractor tests
Cover SSE parsing edge cases: single/multiple events, incomplete buffers,
CRLF line endings, [DONE] sentinel, multi-line data fields, malformed JSON
skipping, comment/event lines, data: without trailing space, empty buffer.
Test both OpenAI and Anthropic delta extractors with various input shapes.

Change-Id: I108352e07233490d23b86ed31b855692c360d4d1
2026-04-27 14:11:36 +08:00
fancivez
b3d774f4df test: add provider-parsers edge case coverage
Test all parser functions with empty responses, missing fields, null inputs,
legacy format fallbacks, multi-block concatenation, and tool-use rejection
for wrong tool names and missing content arrays.

Change-Id: Ie3c15aa636a6b421ca6bf4315313368c249f2782
2026-04-27 14:11:36 +08:00
fancivez
f7c4f42a5a test: add comprehensive CacheManager unit test coverage
Cover previously untested methods: get(), move() (success/failure/edge
cases), readFile() with corrupt JSON and missing entries, pruneIfNeeded(),
replaceCards() for missing entries, and scheduleSave()+flush() behavior.

Change-Id: Iee71e574d37925c2111eb70a292d5f59a80dc3c5
2026-04-27 14:11:36 +08:00
wujunchen
538d7bcedd test: add structured output fallback and non-retryable error tests
Cover the two key paths in requestJsonBodyWithStructuredFallback:
1. 400 with response_format mention → retry without structured output
2. 500 server error → no retry, error propagated

Change-Id: If8d0fc484e49238699444131cbadcf1b18bf992f
2026-04-27 12:44:42 +08:00
wujunchen
67a9ccdafb test: add applyApiProviderPreset model swap coverage
Cover the key scenarios for provider switching: model swapped when
matching previous preset, custom model preserved across switches,
empty model triggers swap, and input immutability verified.

Change-Id: I467604d51e8c11e990e54621347094cf914cb6b7
2026-04-27 12:43:29 +08:00
wujunchen
b02d0f4f30 test: add cache pruning interleaved with put test
Verify that when a new entry is added via put() and the cache exceeds
maxCacheEntries, the oldest entry (by timestamp) is pruned and the
pruned state is correctly persisted to disk.

Change-Id: Ia937800a97d7591877e1d2d1fe808b86858735e1
2026-04-27 12:30:56 +08:00
wujunchen
cfdd985f78 test: add batch state isolation and cancellation tests
Verify that two concurrent BatchRunState objects don't interfere with
each other (cancelling one doesn't affect the other), and that stats
accumulate correctly when processing is stopped mid-iteration.

Change-Id: Id32b27307beafe49594cfde6fa818b2f22b87c66
2026-04-27 12:29:42 +08:00
wujunchen
593817734b test: add streaming cancellation edge case tests
Cover pre-aborted signal (aborted before fetch starts) and mid-read
abort (signal aborted while reading response body). Both verify that
abort listeners are properly cleaned up after rejection.

Change-Id: I0760f6ed051de1504e9b7aeead01a10cfd12476e
2026-04-27 12:28:36 +08:00
wujunchen
09f39dde8d fix: make normalizeSettings return a new object instead of mutating input
normalizeSettings previously modified its input parameter in-place.
While callers already created copies before calling it, the function
signature was misleading. Now it creates a shallow copy internally and
operates on that, with a Readonly<PluginSettings> parameter type to
signal intent. Added a test verifying the original object is unchanged.

Change-Id: I7600ac37930bbcebb02aa7c84d8988cb7aa71196
2026-04-27 12:20:56 +08:00
wujunchen
abce923f14 fix: salvage truncated LLM JSON and make errors copyable
- Add repairTruncatedCardsJson to recover complete cards when output
  is cut off mid-card (e.g. token limit reached)
- Log raw LLM response to console on parse failure for debugging
- Make error panel text selectable and add "copy error" button

Change-Id: I4e76121138888234d42f84f3695cbbfd6beba886
2026-04-27 11:56:40 +08:00
wujunchen
5f12113fcd chore: improve engineering quality and hardening
- Fix CI to run all 4 test files (was missing direct-modules.test.js)
- Remove unused ESLint dependencies (eslint, @typescript-eslint/*, eslint-plugin-obsidianmd)
- Enable noImplicitReturns in tsconfig.json for stricter type safety
- Make applyApiProviderPreset return new object instead of mutating input
- Add per-file error handling in batch processing loop with error count in summary
- Narrow all catch clause types to unknown with proper instanceof narrowing

Change-Id: I76975dbd5ebdb5645d18c5858c8a52fd6da3405e
2026-04-27 11:15:35 +08:00
wujunchen
486060bddf test: cover cache manager with fake adapter
Change-Id: I83f6b71a46af31f783522faa53bffbfc6c4bc54d
2026-04-26 18:31:17 +08:00
wujunchen
557908ca44 fix: clean up streaming abort listener
Change-Id: I9fa8ace7bc0fa723466ef851f7ec2960c6638eba
2026-04-26 18:29:48 +08:00
wujunchen
bc51acd00e fix: parse multiline sse events
Change-Id: I9c013dbe6840a0892836eb5d71206c6fcde5ec78
2026-04-26 18:27:28 +08:00
wujunchen
846e32301a test: import pure modules directly
Change-Id: Ia029de2ac4c3cb3ddb7ea638c868d6347af5c67e
2026-04-26 18:25:50 +08:00
wujunchen
70f9a39cd7 refactor: extract provider response parsers
Change-Id: I6884999f34594faec349378deb59e68972e07355
2026-04-26 18:20:49 +08:00
wujunchen
6dd7ef15a4 test: cover cli edge cases
Change-Id: Ia6114ab7ba24e32f7f86ff76710a596b0c24682c
2026-04-26 18:16:38 +08:00
wujunchen
174fa7295d feat: expose streaming timeout setting
Change-Id: Ide69c0f0fe208a557024f9f77d83c9d1215391cf
2026-04-26 18:14:43 +08:00
wujunchen
9098de6884 feat: validate batch folder input
Change-Id: I137fa046e77781e063ee782af4321b7277d64d51
2026-04-26 18:12:38 +08:00
wujunchen
d8dc82362b feat: support cancellable batch generation
Change-Id: I89302f58995e4e15fbf77c20c87a94832e572d20
2026-04-26 18:10:17 +08:00
wujunchen
ebc882c2f1 refactor: encapsulate cache rename
Change-Id: I89ee56c071c8e5404f8eb9ea744172957811d714
2026-04-26 18:05:38 +08:00
wujunchen
fe05ed1a2d test: cover generation orchestration
Change-Id: Iff416f01c0f09111e67e1ad67957b85fdb19623a
2026-04-26 17:59:35 +08:00
wujunchen
2d4bef9539 refactor: extract batch generation helpers
Change-Id: I16ad657b783b65cc5b3e36a6ea163cc19740b651
2026-04-26 17:54:35 +08:00
Claude
a74e7c3e07
test: add tests for i18n, streaming, and cli modules
Extend tests/modules.test.js with:
- parseSseBuffer: partial buffer, multi-event chunk, skipped non-data lines,
  malformed JSON line handling
- i18n: multi-variable interpolation, zh translation, missing-key fallback
- cli: resolveCliPath with override path trimming and mocked fs.existsSync
  to verify filesystem search and bare-name fallback

https://claude.ai/code/session_016QvEfqw6YZ3RjwBHrJ4w8S
2026-04-26 06:15:30 +00:00
Claude
dbb8ea4a5b
refactor: make cache entry updates immutable
touchCacheEntry() now returns a new object via spread instead of mutating
the entry in-place. CacheManager.replaceCards() likewise creates a new entry
object instead of mutating existing fields. Update tests to assert the new
immutable semantics (returned value differs from input by reference).

https://claude.ai/code/session_016QvEfqw6YZ3RjwBHrJ4w8S
2026-04-26 06:12:55 +00:00
wujunchen
b7d1a25543 security: strip path traversal segments from vault paths
Reject '..' and '.' segments in normalizeVaultPath to prevent
exportFolder from escaping the vault root directory.

Change-Id: Ib4da19f9d0aa1236a3b77b6f2cc722fcff408131
2026-04-26 09:48:19 +08:00
wujunchen
447ad1414b feat: add streaming API responses for OpenAI Chat and Anthropic
Implement SSE streaming for API backends that support it (OpenAI Chat
Completions and Anthropic Messages). During generation the view shows
a live streaming preview with accumulated text. Adds a streaming toggle
in settings (enabled by default). Non-streaming-capable formats (Gemini,
OpenAI Responses) and CLI backends continue using the existing path.

Change-Id: I3361a5ca5aec3e25a7d16e4fb585185f6fc0695e
2026-04-26 09:30:51 +08:00
wujunchen
3b02cfa480 test: add comprehensive unit tests for pure modules
Cover anchor, schema, cache, cards, navigation, markdown, vault, i18n,
scroll, settings, prompt, providers, and generation-job-manager modules
with focused assertions testing edge cases and expected behavior.

Change-Id: I49e1f104e04a3dbafe66c19adf24ac5d0e3a7c54
2026-04-26 09:25:23 +08:00
wujunchen
532cd31ef4 refactor: extract View, Modal, and SettingsTab from main.ts
Move ParallelReaderView to src/view.ts (341 lines),
CardEditModal to src/modal.ts (56 lines),
ParallelReaderSettingTab to src/settings-tab.ts (370 lines).
Add PluginHost interface in types.ts to break circular deps.
main.ts reduced from 1613 to 588 lines.

Change-Id: I90902e914f162ff92b9a7f7c190b4d397a2c8c12
2026-04-25 23:40:56 +08:00
wujunchen
d8880d41b2 refactor: split UI helpers module
Change-Id: I1abcd20b75608261b2d004550c011eeba76d35bf
2026-04-25 21:32:32 +08:00
wujunchen
5f6f18677b refactor: split CLI backend module
Change-Id: I7450dface429972b71b173973e6f71393d83303e
2026-04-25 19:58:29 +08:00