Skip to content

Test Coverage: Address gaps from PR #861 and improve race condition detection#878

Merged
malibio merged 5 commits into
mainfrom
feature/issue-870-test-coverage
Feb 2, 2026
Merged

Test Coverage: Address gaps from PR #861 and improve race condition detection#878
malibio merged 5 commits into
mainfrom
feature/issue-870-test-coverage

Conversation

@malibio

@malibio malibio commented Feb 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

Complete implementation of #870 - addresses both Part 1 (Unit Test Coverage) and Part 2 (Test Infrastructure Improvements).

Part 1: Unit Test Coverage Gaps

TypeScript (Frontend):

  • 13 tests for calculateOutdentInsertOrderPure() - refactored to pure function for testability
  • 6 tests for flushAndWaitForNodes() - concurrent flush, timeout, error handling
  • 10 tests for pending-operations module - imports actual exports instead of reimplementing

Rust (Backend):

  • 3 tests for node_exists()
  • 3 tests for get_parent_id()
  • 4 tests for get_node_type()

Part 2: Test Infrastructure Improvements

Part 2A: Browser Integration Tests

  • Added rapid-keyboard-operations.test.ts (13 tests):
    • Keyboard event sequencing (Enter→Tab, Tab→Shift+Tab patterns)
    • Focus management during rapid operations
    • High-frequency event handling (500+ events)
    • Event prevention and bubbling

Part 2B: Stress Tests for Race Conditions

Part 2C: test:integration:full Command

  • Added test:integration:full script that runs all tests:
    • Unit tests + Browser tests + Performance tests + Rust tests

Documentation

  • Updated testing-guide.md with stress test documentation and examples

Test Results

  • Frontend: 3546 tests (+45 new)
  • Browser: 90 tests (+13 new)
  • Rust: 777 tests (+10 new)

Test plan

  • All new unit tests pass
  • All browser stress tests pass
  • All Rust tests pass
  • No regressions in existing tests
  • Quality checks pass (eslint, svelte-check)
  • Documentation updated

🤖 Generated with Claude Code

malibio and others added 2 commits February 2, 2026 12:54
Agents repeatedly make the mistake of running `bun run gh:*` commands
from subdirectories like packages/desktop-app/ instead of the repo root.
These commands fail with "Script not found" because the gh scripts are
defined in the root package.json.

Added:
- Prominent warning in startup sequence step 4 with correct/wrong examples
- Reminder notes on steps 7 and 8 (assign/status commands)
- New entry in "Common mistakes agents make" list

Co-Authored-By: Claude <noreply@anthropic.com>
#870 Part 1)

## Part 1: Unit Test Coverage Gaps

### TypeScript (Frontend)
- Add 13 tests for `calculateOutdentInsertOrderPure()` in reactive-node-service
  - Refactored to pure function for testability
  - Tests edge cases: empty parent, missing old parent, single/many children
  - Tests fractional order precision and various positions

- Add 6 tests for `flushAndWaitForNodes()` in shared-node-store-coverage
  - Tests flushing specific nodes, concurrent flush requests
  - Tests timeout behavior, mix of pending/non-pending nodes
  - Tests error reporting for failed operations

- Add 10 tests for pending-operations module
  - Now imports actual module exports instead of reimplementing logic
  - Tests trackMoveOperation, waitForPendingMoveOperations, getPendingMoveOperation
  - Tests race condition prevention patterns (Issue #662 scenario)

### Rust (Backend)
- Add 3 tests for `node_exists()` in surreal_store
  - Tests existing node returns true, non-existent returns false
  - Tests returns false after deletion

- Add 3 tests for `get_parent_id()` in surreal_store
  - Tests root node returns None, child returns correct parent ID
  - Tests non-existent node returns None

- Add 4 tests for `get_node_type()` in surreal_store
  - Tests correct type for text, task, date nodes
  - Tests non-existent node returns None

## Test Summary
- Frontend: +28 tests (3501 → 3529)
- Rust: +10 tests (767 → 777)

Part 2 (test infrastructure improvements) to be addressed separately.

Co-Authored-By: Claude <noreply@anthropic.com>
@malibio

malibio commented Feb 2, 2026

Copy link
Copy Markdown
Collaborator Author

Code Review Report - PR #878

Reviewer: Principal Engineer (AI Agent)
Verdict: APPROVE (pending CI)


Summary

This PR adds comprehensive test coverage for critical functions identified in Issue #870 Part 1. The implementation is well-structured, follows project conventions, and improves testability by refactoring the calculateOutdentInsertOrder function into a pure, testable form.


Requirements Validation

Issue #870 Part 1 Acceptance Criteria:

  • calculateOutdentInsertOrder() - 13 tests added via calculateOutdentInsertOrderPure
  • flushAndWaitForNodes() - 6 tests added in shared-node-store-coverage.test.ts
  • pending-operations.ts - 10 tests import actual module exports (not reimplementation)
  • node_exists() - 3 Rust tests added
  • get_parent_id() - 3 Rust tests added
  • get_node_type() - 4 Rust tests added

Test counts match PR description: Frontend +28, Rust +10


Findings by Priority

Architectural Design & Integrity

[Positive] Pure Function Refactoring:
The refactoring of calculateOutdentInsertOrder into calculateOutdentInsertOrderPure in /packages/desktop-app/src/lib/services/reactive-node-service.svelte.ts is an excellent design decision:

  • Separates side effects (accessing structureTree) from business logic
  • Follows Single Responsibility Principle
  • Enables comprehensive unit testing without mocking global state
// Before: tightly coupled to structureTree
function calculateOutdentInsertOrder(newParentId: string, oldParentId: string): number {
  const newParentChildren = structureTree.getChildrenWithOrder(newParentId);
  // ... logic using newParentChildren
}

// After: pure function with injected dependencies
export function calculateOutdentInsertOrderPure(
  children: Array<{ nodeId: string; order: number }>,
  oldParentId: string
): number { /* pure logic */ }

[Positive] Module Import Compliance:
The pending-operations.test.ts correctly imports from the actual $lib/services/pending-operations module rather than reimplementing the logic locally. This directly addresses the issue requirement and ensures tests validate real production code.

[Positive] CLAUDE.md Documentation:
The additional warnings about running gh:* commands from the repository root is a valuable improvement that prevents common agent mistakes.

Functionality & Correctness

All test scenarios verify correct behavior:

Function Test Coverage
calculateOutdentInsertOrderPure Midpoint calculation, last child, single child, first child, fractional orders, fallback paths, edge cases (precision, large values, negative, zero)
flushAndWaitForNodes Specific node flush, empty list, concurrent requests, mixed pending/non-pending, error reporting
pending-operations Track/cleanup operations, success/failure cleanup, wait semantics, race condition prevention
node_exists Existing node, non-existent, after deletion
get_parent_id Root node, child node, non-existent node
get_node_type text, task, date types, non-existent node

Testing Strategy

Excellent test organization:

  • Clear test file naming following existing patterns (*.test.ts)
  • Comprehensive JSDoc headers explaining test purpose
  • Logical grouping of edge cases (found vs. not-found, normal vs. error)
  • Unique node IDs prevent test interference (Math.random().toString(36).slice(2))

Security

No security concerns - this PR adds test coverage only, no changes to security-sensitive paths.

Performance

No performance concerns - tests use appropriate timeouts and add no overhead to production code.


Nitpicks (Optional)

Nit: /packages/desktop-app/src/tests/unit/pending-operations.test.ts (lines 785-820)

The vi.useRealTimers() call inside the describe block is acceptable since tests use unique node IDs, but consider documenting why real timers are needed:

// Use real timers because we're testing actual timing coordination
// (fake timers don't properly simulate Promise.race/setTimeout interactions)
vi.useRealTimers();

Nit: Consider extracting the repeated unique ID generation pattern:

const uniqueNodeId = (prefix: string) => `${prefix}-${Math.random().toString(36).slice(2)}`;
// Usage: const nodeId = uniqueNodeId('test-node');

Conclusion

This is a well-executed PR that directly addresses Issue #870 Part 1 requirements. The refactoring of calculateOutdentInsertOrder into a pure function is a valuable improvement beyond just adding tests.

Net Positive: YES - Improves test coverage + improves code testability
Recommendation: Merge after CI passes


Reviewed using the Pragmatic Code Review framework

Reviewer nitpicks addressed:
- Added `uniqueNodeId()` helper function for generating unique test node IDs
- Added JSDoc explaining why unique IDs are needed (global module state)
- Added comment block explaining why real timers are required for race
  condition tests (fake timers don't properly simulate Promise.race)

Co-Authored-By: Claude <noreply@anthropic.com>
@malibio

malibio commented Feb 2, 2026

Copy link
Copy Markdown
Collaborator Author

Review Feedback Addressed

Addressed all reviewer nitpicks:

Recommendation Status Changes
🟢 Extract unique ID generation ✅ Addressed Added uniqueNodeId() helper with JSDoc
🟢 Document why real timers needed ✅ Addressed Added comment block explaining Promise.race behavior

Commit: a56caba


No re-review needed - these were minor documentation/style improvements with no logic changes.

## Part 2A: Browser Integration Test Infrastructure
- Added `rapid-keyboard-operations.test.ts` with 13 tests for:
  - Keyboard event sequencing (Enter→Tab, Tab→Shift+Tab patterns)
  - Focus management during rapid operations
  - High-frequency event handling (500+ events)
  - Event prevention and bubbling behavior

## Part 2B: Stress Tests for Rapid Indent/Outdent
- Added `rapid-hierarchy-operations.test.ts` with 17 tests for:
  - `calculateOutdentInsertOrderPure()` edge cases
  - Floating point precision limits (50+ rapid insertions)
  - Concurrent operation simulation
  - Out-of-order completion patterns
  - PR #861 race condition scenarios

## Part 2C: test:integration:full Command
- Added `test:integration:full` script that runs:
  - Unit tests (bun run test)
  - Browser tests (bun run test:browser)
  - Performance tests (bun run test:perf)
  - Rust tests (bun run rust:test)

## Documentation
- Updated testing-guide.md with:
  - Stress test documentation and examples
  - Instructions for running tests
  - Future E2E testing considerations

Test Results:
- Frontend: 3546 tests passed (45 new tests added)
- Browser: 90 tests passed (13 new tests added)
- Rust: 777 tests passed

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@malibio

malibio commented Feb 2, 2026

Copy link
Copy Markdown
Collaborator Author

Part 2 Complete ✅

Added stress tests and browser integration tests for race condition detection.

Part 2A: Browser Integration Tests

  • Added rapid-keyboard-operations.test.ts (13 tests):
    • Keyboard event sequencing (Enter→Tab, Tab→Shift+Tab patterns)
    • Focus management during rapid operations
    • High-frequency event handling (500+ events)
    • Event prevention and bubbling behavior

Part 2B: Stress Tests

Part 2C: test:integration:full Command

  • Added test:integration:full script that runs all tests:
    • Unit tests + Browser tests + Performance tests + Rust tests

Updated Documentation

  • Updated testing-guide.md with stress test documentation

Final Test Results

  • Frontend: 3546 tests passed (+45 new from Part 2)
  • Browser: 90 tests passed (+13 new)
  • Rust: 777 tests passed

All acceptance criteria from #870 are now complete.

Documents the workflow for converting discovered UX bugs into
regression tests:

- Workflow steps: Discover → Fix → Test → Commit
- Table mapping bug types to test file locations
- Concrete example with Backspace→Enter sequence
- Commit message convention for bug fixes with tests

Key principle: Manual testing finds bugs, automated tests prevent regressions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@malibio

malibio commented Feb 2, 2026

Copy link
Copy Markdown
Collaborator Author

Code Review Report - PR #878 (Re-Review: Part 2 Additions)

Reviewer: Principal Engineer (AI Agent)
Review Type: Re-Review (Part 2 additions since initial review)
Verdict: APPROVE


Summary

This re-review covers the Part 2 additions to Issue #870: stress tests for race condition detection, browser integration tests, and documentation updates. The initial review approved Part 1 (unit test coverage gaps) and the two nitpick suggestions have been addressed.

Scope of Re-Review:

  • rapid-keyboard-operations.test.ts (13 new browser tests)
  • rapid-hierarchy-operations.test.ts (17 new stress tests)
  • testing-guide.md updates
  • package.json - new test:integration:full command

Requirements Validation

Issue #870 Acceptance Criteria:

Criterion Status Evidence
Part 1: All listed unit tests added and passing PASS Initial review verified 28 TS + 10 Rust tests
Part 2A: Browser integration test infrastructure PASS rapid-keyboard-operations.test.ts with 13 tests
Part 2B: At least one stress test for rapid indent/outdent PASS rapid-hierarchy-operations.test.ts with 17 tests
Part 2C: test:integration:full command works PASS Added to package.json (line 31)
Documentation updated with testing strategy PASS testing-guide.md lines 1057-1253

Findings by Priority

Architectural Design & Integrity

[Positive] Well-Structured Browser Tests:
The browser tests in rapid-keyboard-operations.test.ts correctly focus on testing browser-specific APIs (keyboard event sequencing, focus management, event bubbling) rather than trying to test full Svelte components. This pragmatic approach aligns with the testing guide philosophy documented in the PR.

[Positive] Stress Test Coverage:
The stress tests in rapid-hierarchy-operations.test.ts effectively demonstrate the floating-point precision limits of fractional ordering and document why backend rebalancing is necessary. The comment at line 169-170 is particularly valuable documentation.

[Positive] Pure Function Testing Pattern Maintained:
The Part 2B tests continue to leverage the calculateOutdentInsertOrderPure pure function introduced in Part 1, demonstrating good separation of testable logic from side effects.

Functionality & Correctness

[Positive] Race Condition Scenario Coverage:
The tests effectively cover the exact scenarios from PR #861:

  • Enter→Tab sequence (lines 27-56 in keyboard tests)
  • Tab→Shift+Tab sequence (lines 58-81 in keyboard tests)
  • Out-of-order operation completion (lines 302-325 in hierarchy tests)
  • Concurrent pending operation tracking (lines 277-299)

[Positive] Floating Point Precision Demonstration:
The test at lines 166-209 (should handle 50 rapid order calculations) is an excellent demonstration of the precision limits, correctly asserting that at least 45 of 50 orders should be unique while acknowledging that some collisions are expected behavior.

Testing Strategy

[Positive] Test:Integration:Full Command:
The test:integration:full command (package.json line 31) provides a comprehensive way to run all test types:

bun run test && bun run test:browser && bun run test:perf && bun run rust:test

This directly addresses acceptance criterion Part 2C.

[Positive] Documentation Quality:
The testing-guide.md updates (lines 1057-1253) include:

  • Clear explanation of stress test purpose
  • Table summarizing test coverage
  • Code examples for adding new stress tests
  • UX bug → regression test workflow documentation

Security

No security concerns - this PR adds test coverage only.

Performance

No performance concerns - test execution times are appropriate for their purpose.


Minor Observations (Non-Blocking)

Nit: In rapid-hierarchy-operations.test.ts, the test "should simulate overlapping async operations" (lines 277-299) uses synchronous simulation rather than actual async timing. The comment explains this is intentional to avoid timer-related complexity, which is acceptable. The async behavior is properly tested in pending-operations.test.ts.

Nit: The test:integration:full command in package.json includes rust:test which runs Rust backend tests. Consider whether browser tests should run before or after Rust tests for optimal CI feedback time (fail fast).


Comparison: Initial Review vs Re-Review

Aspect Initial Review Re-Review
Part 1 Unit Tests Reviewed + Approved N/A (already approved)
Nitpick: uniqueNodeId helper Suggested Implemented (commit a56caba)
Nitpick: Real timer documentation Suggested Implemented (commit a56caba)
Part 2A Browser Tests Not yet added Reviewed + Approved
Part 2B Stress Tests Not yet added Reviewed + Approved
Part 2C Integration Command Not yet added Reviewed + Approved
Documentation Not yet updated Reviewed + Approved

Conclusion

All Part 2 acceptance criteria are met. The stress tests provide valuable race condition detection capabilities that would have caught the PR #861 bugs proactively. The browser tests focus appropriately on browser-specific APIs rather than overcomplicating with full component rendering.

Net Positive: YES - Significantly improves race condition detection and documents testing strategy
Recommendation: APPROVE - Ready to merge


Reviewed using the Pragmatic Code Review framework

@malibio malibio left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

REVIEW COMPLETE: All Issue #870 acceptance criteria satisfied. Part 1 unit tests and Part 2 stress tests/browser tests provide comprehensive coverage for race condition detection. Documentation is thorough. Recommendation: APPROVE (pending human reviewer approval due to GitHub self-review restriction).

@malibio

malibio commented Feb 2, 2026

Copy link
Copy Markdown
Collaborator Author

Review Feedback Assessment

Reviewed the re-review nitpicks from the code review:

Recommendation Decision Reasoning
🟢 Async simulation comment ⏭️ No change needed Code already has explanatory comment at lines 269-270 explaining why synchronous simulation is used
🟢 test:integration:full ordering ⏭️ No change needed Current order (test → browser → perf → rust) already follows fail-fast principle - fastest frontend tests run first

Summary:

  • ✅ Addressed: 0 (both nitpicks already handled or optimal)
  • ⏭️ Skipped: 2 (no changes needed)
  • 📝 Commits created: 0

Conclusion: The implementation is already optimal. No additional changes required.

@malibio
malibio merged commit 62bb2ee into main Feb 2, 2026
@malibio
malibio deleted the feature/issue-870-test-coverage branch February 2, 2026 14:31
malibio added a commit that referenced this pull request Feb 4, 2026
…etection (#878)

* Docs: Add explicit warning about gh script directory requirement

Agents repeatedly make the mistake of running `bun run gh:*` commands
from subdirectories like packages/desktop-app/ instead of the repo root.
These commands fail with "Script not found" because the gh scripts are
defined in the root package.json.

Added:
- Prominent warning in startup sequence step 4 with correct/wrong examples
- Reminder notes on steps 7 and 8 (assign/status commands)
- New entry in "Common mistakes agents make" list

Co-Authored-By: Claude <noreply@anthropic.com>

* Test: Add comprehensive unit tests for PR #861 helper functions (closes #870 Part 1)

## Part 1: Unit Test Coverage Gaps

### TypeScript (Frontend)
- Add 13 tests for `calculateOutdentInsertOrderPure()` in reactive-node-service
  - Refactored to pure function for testability
  - Tests edge cases: empty parent, missing old parent, single/many children
  - Tests fractional order precision and various positions

- Add 6 tests for `flushAndWaitForNodes()` in shared-node-store-coverage
  - Tests flushing specific nodes, concurrent flush requests
  - Tests timeout behavior, mix of pending/non-pending nodes
  - Tests error reporting for failed operations

- Add 10 tests for pending-operations module
  - Now imports actual module exports instead of reimplementing logic
  - Tests trackMoveOperation, waitForPendingMoveOperations, getPendingMoveOperation
  - Tests race condition prevention patterns (Issue #662 scenario)

### Rust (Backend)
- Add 3 tests for `node_exists()` in surreal_store
  - Tests existing node returns true, non-existent returns false
  - Tests returns false after deletion

- Add 3 tests for `get_parent_id()` in surreal_store
  - Tests root node returns None, child returns correct parent ID
  - Tests non-existent node returns None

- Add 4 tests for `get_node_type()` in surreal_store
  - Tests correct type for text, task, date nodes
  - Tests non-existent node returns None

## Test Summary
- Frontend: +28 tests (3501 → 3529)
- Rust: +10 tests (767 → 777)

Part 2 (test infrastructure improvements) to be addressed separately.

Co-Authored-By: Claude <noreply@anthropic.com>

* Address review: Add helper function and document real timer usage

Reviewer nitpicks addressed:
- Added `uniqueNodeId()` helper function for generating unique test node IDs
- Added JSDoc explaining why unique IDs are needed (global module state)
- Added comment block explaining why real timers are required for race
  condition tests (fake timers don't properly simulate Promise.race)

Co-Authored-By: Claude <noreply@anthropic.com>

* Test: Add stress tests for race condition detection (closes #870 Part 2)

## Part 2A: Browser Integration Test Infrastructure
- Added `rapid-keyboard-operations.test.ts` with 13 tests for:
  - Keyboard event sequencing (Enter→Tab, Tab→Shift+Tab patterns)
  - Focus management during rapid operations
  - High-frequency event handling (500+ events)
  - Event prevention and bubbling behavior

## Part 2B: Stress Tests for Rapid Indent/Outdent
- Added `rapid-hierarchy-operations.test.ts` with 17 tests for:
  - `calculateOutdentInsertOrderPure()` edge cases
  - Floating point precision limits (50+ rapid insertions)
  - Concurrent operation simulation
  - Out-of-order completion patterns
  - PR #861 race condition scenarios

## Part 2C: test:integration:full Command
- Added `test:integration:full` script that runs:
  - Unit tests (bun run test)
  - Browser tests (bun run test:browser)
  - Performance tests (bun run test:perf)
  - Rust tests (bun run rust:test)

## Documentation
- Updated testing-guide.md with:
  - Stress test documentation and examples
  - Instructions for running tests
  - Future E2E testing considerations

Test Results:
- Frontend: 3546 tests passed (45 new tests added)
- Browser: 90 tests passed (13 new tests added)
- Rust: 777 tests passed

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Docs: Add UX bug → regression test workflow to testing guide

Documents the workflow for converting discovered UX bugs into
regression tests:

- Workflow steps: Discover → Fix → Test → Commit
- Table mapping bug types to test file locations
- Concrete example with Backspace→Enter sequence
- Commit message convention for bug fixes with tests

Key principle: Manual testing finds bugs, automated tests prevent regressions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
malibio added a commit that referenced this pull request Feb 5, 2026
…etection (#878)

* Docs: Add explicit warning about gh script directory requirement

Agents repeatedly make the mistake of running `bun run gh:*` commands
from subdirectories like packages/desktop-app/ instead of the repo root.
These commands fail with "Script not found" because the gh scripts are
defined in the root package.json.

Added:
- Prominent warning in startup sequence step 4 with correct/wrong examples
- Reminder notes on steps 7 and 8 (assign/status commands)
- New entry in "Common mistakes agents make" list

Co-Authored-By: Claude <noreply@anthropic.com>

* Test: Add comprehensive unit tests for PR #861 helper functions (closes #870 Part 1)

## Part 1: Unit Test Coverage Gaps

### TypeScript (Frontend)
- Add 13 tests for `calculateOutdentInsertOrderPure()` in reactive-node-service
  - Refactored to pure function for testability
  - Tests edge cases: empty parent, missing old parent, single/many children
  - Tests fractional order precision and various positions

- Add 6 tests for `flushAndWaitForNodes()` in shared-node-store-coverage
  - Tests flushing specific nodes, concurrent flush requests
  - Tests timeout behavior, mix of pending/non-pending nodes
  - Tests error reporting for failed operations

- Add 10 tests for pending-operations module
  - Now imports actual module exports instead of reimplementing logic
  - Tests trackMoveOperation, waitForPendingMoveOperations, getPendingMoveOperation
  - Tests race condition prevention patterns (Issue #662 scenario)

### Rust (Backend)
- Add 3 tests for `node_exists()` in surreal_store
  - Tests existing node returns true, non-existent returns false
  - Tests returns false after deletion

- Add 3 tests for `get_parent_id()` in surreal_store
  - Tests root node returns None, child returns correct parent ID
  - Tests non-existent node returns None

- Add 4 tests for `get_node_type()` in surreal_store
  - Tests correct type for text, task, date nodes
  - Tests non-existent node returns None

## Test Summary
- Frontend: +28 tests (3501 → 3529)
- Rust: +10 tests (767 → 777)

Part 2 (test infrastructure improvements) to be addressed separately.

Co-Authored-By: Claude <noreply@anthropic.com>

* Address review: Add helper function and document real timer usage

Reviewer nitpicks addressed:
- Added `uniqueNodeId()` helper function for generating unique test node IDs
- Added JSDoc explaining why unique IDs are needed (global module state)
- Added comment block explaining why real timers are required for race
  condition tests (fake timers don't properly simulate Promise.race)

Co-Authored-By: Claude <noreply@anthropic.com>

* Test: Add stress tests for race condition detection (closes #870 Part 2)

## Part 2A: Browser Integration Test Infrastructure
- Added `rapid-keyboard-operations.test.ts` with 13 tests for:
  - Keyboard event sequencing (Enter→Tab, Tab→Shift+Tab patterns)
  - Focus management during rapid operations
  - High-frequency event handling (500+ events)
  - Event prevention and bubbling behavior

## Part 2B: Stress Tests for Rapid Indent/Outdent
- Added `rapid-hierarchy-operations.test.ts` with 17 tests for:
  - `calculateOutdentInsertOrderPure()` edge cases
  - Floating point precision limits (50+ rapid insertions)
  - Concurrent operation simulation
  - Out-of-order completion patterns
  - PR #861 race condition scenarios

## Part 2C: test:integration:full Command
- Added `test:integration:full` script that runs:
  - Unit tests (bun run test)
  - Browser tests (bun run test:browser)
  - Performance tests (bun run test:perf)
  - Rust tests (bun run rust:test)

## Documentation
- Updated testing-guide.md with:
  - Stress test documentation and examples
  - Instructions for running tests
  - Future E2E testing considerations

Test Results:
- Frontend: 3546 tests passed (45 new tests added)
- Browser: 90 tests passed (13 new tests added)
- Rust: 777 tests passed

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Docs: Add UX bug → regression test workflow to testing guide

Documents the workflow for converting discovered UX bugs into
regression tests:

- Workflow steps: Discover → Fix → Test → Commit
- Table mapping bug types to test file locations
- Concrete example with Backspace→Enter sequence
- Commit message convention for bug fixes with tests

Key principle: Manual testing finds bugs, automated tests prevent regressions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
malibio added a commit that referenced this pull request Feb 26, 2026
…etection (#878)

* Docs: Add explicit warning about gh script directory requirement

Agents repeatedly make the mistake of running `bun run gh:*` commands
from subdirectories like packages/desktop-app/ instead of the repo root.
These commands fail with "Script not found" because the gh scripts are
defined in the root package.json.

Added:
- Prominent warning in startup sequence step 4 with correct/wrong examples
- Reminder notes on steps 7 and 8 (assign/status commands)
- New entry in "Common mistakes agents make" list

Co-Authored-By: Claude <noreply@anthropic.com>

* Test: Add comprehensive unit tests for PR #861 helper functions (closes #870 Part 1)

## Part 1: Unit Test Coverage Gaps

### TypeScript (Frontend)
- Add 13 tests for `calculateOutdentInsertOrderPure()` in reactive-node-service
  - Refactored to pure function for testability
  - Tests edge cases: empty parent, missing old parent, single/many children
  - Tests fractional order precision and various positions

- Add 6 tests for `flushAndWaitForNodes()` in shared-node-store-coverage
  - Tests flushing specific nodes, concurrent flush requests
  - Tests timeout behavior, mix of pending/non-pending nodes
  - Tests error reporting for failed operations

- Add 10 tests for pending-operations module
  - Now imports actual module exports instead of reimplementing logic
  - Tests trackMoveOperation, waitForPendingMoveOperations, getPendingMoveOperation
  - Tests race condition prevention patterns (Issue #662 scenario)

### Rust (Backend)
- Add 3 tests for `node_exists()` in surreal_store
  - Tests existing node returns true, non-existent returns false
  - Tests returns false after deletion

- Add 3 tests for `get_parent_id()` in surreal_store
  - Tests root node returns None, child returns correct parent ID
  - Tests non-existent node returns None

- Add 4 tests for `get_node_type()` in surreal_store
  - Tests correct type for text, task, date nodes
  - Tests non-existent node returns None

## Test Summary
- Frontend: +28 tests (3501 → 3529)
- Rust: +10 tests (767 → 777)

Part 2 (test infrastructure improvements) to be addressed separately.

Co-Authored-By: Claude <noreply@anthropic.com>

* Address review: Add helper function and document real timer usage

Reviewer nitpicks addressed:
- Added `uniqueNodeId()` helper function for generating unique test node IDs
- Added JSDoc explaining why unique IDs are needed (global module state)
- Added comment block explaining why real timers are required for race
  condition tests (fake timers don't properly simulate Promise.race)

Co-Authored-By: Claude <noreply@anthropic.com>

* Test: Add stress tests for race condition detection (closes #870 Part 2)

## Part 2A: Browser Integration Test Infrastructure
- Added `rapid-keyboard-operations.test.ts` with 13 tests for:
  - Keyboard event sequencing (Enter→Tab, Tab→Shift+Tab patterns)
  - Focus management during rapid operations
  - High-frequency event handling (500+ events)
  - Event prevention and bubbling behavior

## Part 2B: Stress Tests for Rapid Indent/Outdent
- Added `rapid-hierarchy-operations.test.ts` with 17 tests for:
  - `calculateOutdentInsertOrderPure()` edge cases
  - Floating point precision limits (50+ rapid insertions)
  - Concurrent operation simulation
  - Out-of-order completion patterns
  - PR #861 race condition scenarios

## Part 2C: test:integration:full Command
- Added `test:integration:full` script that runs:
  - Unit tests (bun run test)
  - Browser tests (bun run test:browser)
  - Performance tests (bun run test:perf)
  - Rust tests (bun run rust:test)

## Documentation
- Updated testing-guide.md with:
  - Stress test documentation and examples
  - Instructions for running tests
  - Future E2E testing considerations

Test Results:
- Frontend: 3546 tests passed (45 new tests added)
- Browser: 90 tests passed (13 new tests added)
- Rust: 777 tests passed

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Docs: Add UX bug → regression test workflow to testing guide

Documents the workflow for converting discovered UX bugs into
regression tests:

- Workflow steps: Discover → Fix → Test → Commit
- Table mapping bug types to test file locations
- Concrete example with Backspace→Enter sequence
- Commit message convention for bug fixes with tests

Key principle: Manual testing finds bugs, automated tests prevent regressions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant