Skip to content

Unit Tests

Relevant Source Files

The PALEE unit test suite ensures the mathematical correctness of core algorithms, defensive file-safety protocols in the storage layer, and strict domain model typing. Unit tests are executed directly from TypeScript source using tsx and the native Node.js test runner (node:test), ensuring high speed and complete test isolation.


1. Engine Core Tests

Engine tests verify spaced repetition scheduling, graph algorithms, and pedagogical mastery computation on pure in-memory data structures decoupled from the filesystem.

SuperMemo SM-2 Spaced Repetition (test/engine-sm2.test.ts)

Tests in test/engine-sm2.test.ts (15 tests) verify the processReview function and scheduling arithmetic:

  • State Transitions: Validates that quality ratings q<3 trigger a lapse, resetting repetition to 0, interval_days to 1, and incrementing lapses.
  • Interval Progression: Verifies the expanding interval progression (Repetition 1 1 day, Repetition 2 6 days, Repetition n>2round(In1×EF)).
  • Ease Factor Clamping: Confirms that ease_factor is adjusted via ΔEF=0.1(5q)×(0.08+(5q)×0.02), is strictly clamped to 1.30, and is rounded to 4 decimal places.
  • Calendar Due Dates: Validates computeDueDate calculation in the local timezone across month and year boundaries.

Dependency Graph & Cycle Detection (test/engine-dependency.test.ts)

Tests in test/engine-dependency.test.ts (7 tests) exercise graph validation and traversal over the canonical depends_on field:

  • 3-Color DFS Cycle Detection: Verifies that detectCycle correctly flags simple circular dependencies (ABA) as well as complex multi-node cycles (ABCA).
  • Frontier Readiness Filtering: Validates getReadyTopics, confirming that topics are only marked ready when all declared prerequisites reach or exceed MASTERY_THRESHOLD (0.70).
  • Missing Dependency Diagnostics: Ensures validateDependencyGraph emits structured error descriptors containing missing topic IDs when unadopted notes are referenced in depends_on.

Alias unioning is no longer tested here — the engine reads depends_on only. The storage-boundary canonicalization (legacy dependencies unioned into depends_on, deduplicated, array and comma-string forms) is covered in test/storage-loader.test.ts (loadTopics unions and dedupes depends_on and dependencies when both keys are present) and test/storage-roadmap-parser.test.ts (normalizes dependency aliases at the parse boundary).

Four-Pillar Pedagogical Mastery (test/engine-mastery.test.ts)

Tests in test/engine-mastery.test.ts (11 tests) verify the multi-dimensional mastery engine:

  • Formula Invariant: Confirms mastery = round((c + p + d + 2f) / 5, 4) with 40% Feynman weighting.
  • Mastery Threshold: Asserts that MASTERY_THRESHOLD = 0.70 serves as the authoritative threshold for dependency satisfaction.
  • Score Normalization & Clamping: Verifies that out-of-range scores (< 0.0 or > 1.0), NaN, null, or undefined inputs are safely clamped within [0.0, 1.0].
  • Archive Topic Exclusion: Ensures archived topics (archived: true) are excluded from active readiness calculations.

2. Storage Layer & Safety Tests

Storage tests enforce PALEE's "File-Safety Contract," guaranteeing non-destructive updates, concurrency control, and crash tolerance across local vaults.

File Locking & Mutex (test/storage-lock.test.ts)

Tests in test/storage-lock.test.ts (11 tests) verify the cross-process lock directory mutex:

  • Atomic Acquisition: Confirms mkdirSync on .palee/locks/<hash>.lockdir provides mutual exclusion, throwing ECONFLICT on concurrent collision.
  • Descriptor & Heartbeat: Validates that lock descriptors record PID, hostname, and timestamp, refreshed every 15 seconds via utimesSync.
  • Stale Lock Quarantine Takeover: Simulates abandoned locks by artificially aging mtime, verifying automatic takeover after 60s on Windows or 120s on POSIX systems.
  • Symlink Canonicalization: Ensures symbolic links resolve to their canonical physical paths prior to lock hash computation.

Atomic Writes & OCC (test/storage-atomic-write.test.ts)

Tests in test/storage-atomic-write.test.ts (10 tests) verify safe filesystem writes:

  • Optimistic Concurrency Control (OCC): Verifies that passing a stale SHA-256 fingerprint triggers an ECONFLICT error, preventing lost updates from external editors.
  • Atomic Swap & Temp Cleanup: Confirms writes flush to unique .tmp.* files and execute atomic renameSync. If write failure occurs, temporary files are cleanly unlinked.

Frontmatter Preservation via CST (test/storage-frontmatter.test.ts)

Tests in test/storage-frontmatter.test.ts (11 tests) exercise the YAML Document API:

  • Comment & Custom Key Preservation: Verifies that updating PALEE keys (palee_id, topic_mastery, due_at) preserves user-authored YAML comments, custom tags, and Obsidian properties.
  • Byte-for-Byte Body Integrity: Asserts that the Markdown document body remains identical byte-for-byte after frontmatter modifications.
  • Fingerprinting: Verifies SHA-256 content hashing for OCC synchronization.

Vault Topic Loader (test/storage-loader.test.ts)

Tests in test/storage-loader.test.ts (13 tests) verify batch vault loading and the storage-boundary dependency canonicalization:

  • Extraction & Normalization: Parses frontmatter blocks, converts numeric strings, and clamps invalid values.
  • Fallback Title Hierarchy: Verifies title resolution order in loadTopics: frontmatter title → base filename.
  • Pre-Scanned Performance: Confirms that providing a pre-scanned file list bypasses redundant filesystem scans.
  • Dependency Canonicalization (normalizeDependencies, 5 parameterized cases): Unions and dedupes depends_on + legacy dependencies in canonical-first order, supports comma-separated strings, preserves wikilinks, trims whitespace/drops empty entries, ignores unsupported values.
  • Union at Load (3 cases): loadTopics unions both keys when both are present, supports comma-separated string dependencies, and drops null/empty YAML list entries without coercing to "null".

Roadmap ingestion exercises the same boundary in test/storage-roadmap-parser.test.ts (normalizes dependency aliases at the parse boundary).

Working Memory & Session Recovery (test/storage-memory.test.ts)

Tests in test/storage-memory.test.ts (10 tests) verify the active study context system:

  • Session Identification: Verifies session ID generation format S-YYYYMMDDTHHMMSS-xxxx and draft checkpoints DRAFT-S-xxxxxxxx.
  • Hot Context Truncation: Validates that .palee/hot.md truncates note text to MAX_HOT_WORDS = 250 words to preserve context efficiency.
  • Catalog Regeneration: Ensures .palee/index.md accurately regenerates topic lists, recent sessions, and draft links.

Pattern & Glob Matching (test/storage-pattern-matcher.test.ts)

Tests in test/storage-pattern-matcher.test.ts (14 tests) verify pattern matching utilities:

  • Glob Support: Validates single *, recursive **/*.md, character class [...], and wildcard ? matching.
  • Cross-Platform Path Normalization: Automatically normalizes Windows \ backslashes to canonical / slashes.
  • Obsidian Tag Matching: Extracts and matches exact #tag and nested #category/subcategory tag hierarchies.

Multi-Format Roadmap Parser (test/storage-roadmap-parser.test.ts)

Tests in test/storage-roadmap-parser.test.ts (8 tests) exercise curriculum ingestion:

  • Format Flexibility: Parses roadmaps from pure .yaml/.yml files, Markdown frontmatter headers, and embedded ```yaml codeblocks.
  • Syntax & Schema Diagnostics: Validates topic node requirements and provides clear error diagnostics on missing required fields.

Vault Traversal (test/storage-walker.test.ts)

Tests in test/storage-walker.test.ts (11 tests) verify recursive file discovery:

  • Markdown Discovery: Recursively traverses nested vault folders to locate .md files.
  • Exclusion Filters: Automatically ignores .obsidian, .trash, .git, node_modules, and hidden dot-directories.
  • Symlink Safety: Skips circular symlinks to prevent infinite directory recursion.

In-Memory File Cache (test/storage-cache.test.ts)

Tests in test/storage-cache.test.ts (9 tests) verify caching and invalidation logic:

  • Unsettled Horizon (2000ms): Mitigates filesystem buffer lag by using SHA-256 content hashes within the 2-second edit window, falling back to fast mtime checks outside the window.
  • Cache Invalidation: Invalidates cache entries on size mismatch or explicit deletion.

3. Data Model & Domain Type Tests

Difficulty Coercion & Types (test/types-difficulty.test.ts)

Tests in test/types-difficulty.test.ts (9 tests) enforce type contracts:

  • Difficulty Coercion: Verifies normalizeDifficulty coerces case-insensitive strings ("BEGINNER", " Advanced ") and numeric thresholds (values ≤ 1 → beginner, values ≤ 3 → intermediate, and values > 3 → advanced, including numbers like 0 or 6), safely defaulting unrecognized strings to intermediate.
  • Discriminated Union Session Types: Verifies type discrimination between CompletedSession and DraftSession based on session state and properties.

Code Entity Association Matrix

System ComponentPrimary Functions / ClassesTest FileTest Count
Spaced RepetitionprocessReview, computeDueDatetest/engine-sm2.test.ts15
Dependency GraphdetectCycle, getReadyTopics, validateDependencyGraphtest/engine-dependency.test.ts8
Pedagogical MasterycomputeTopicMastery, MASTERY_THRESHOLDtest/engine-mastery.test.ts11
File LockingLock class, acquireLock, releaseLocktest/storage-lock.test.ts11
Atomic WritesatomicWrite, isConflictErrortest/storage-atomic-write.test.ts10
Frontmatter CSTparseFrontmatter, updateFrontmatter, computeFingerprinttest/storage-frontmatter.test.ts11
Vault LoaderloadTopicstest/storage-loader.test.ts5
Working MemorystartSession, saveDraft, endSessiontest/storage-memory.test.ts10
Pattern MatchermatchesGlob, matchesTagtest/storage-pattern-matcher.test.ts14
Roadmap ParserparseRoadmaptest/storage-roadmap-parser.test.ts8
Vault WalkerwalkVaulttest/storage-walker.test.ts11
File CacheFileCache, UNSETTLED_HORIZONtest/storage-cache.test.ts9
Domain TypesnormalizeDifficulty, Difficulty, Sessiontest/types-difficulty.test.ts9

Released under the MIT License.