gravity.nvim Testing Documentation
Overview
gravity.nvim features comprehensive test coverage with 14 automated tests that verify sync functionality, status detection, and state management. The test suite uses isolated environments with mocked paths to ensure tests never interact with real system configurations.
Test Suite Composition:
- 1 Integration Test: End-to-end workflow testing with 9 configs in all possible states
- 13 Unit Tests: Focused tests for status detection, override precedence, and state tracking
Safety First: All test files use test- prefixes (e.g., test-shell.conf, test-git.conf) to ensure they would never conflict with real configuration files, even if mocking fails.
Test Coverage Summary
| Category | Count | What's Covered |
|---|---|---|
| Integration Test | 1 test | Complete workflow with 9 configs in all status states; directory creation; backups; state file updates |
| Status Detection | 7 tests | missing_system, missing_source, unchanged, out_of_sync, source_changed, system_changed, conflict |
| Override Precedence | 3 tests | Base vs override file selection, content syncing, used_override flag tracking |
| State Tracking | 3 tests | .sync_state.json creation, hash persistence, override usage recording |
| Total | 14 tests | All core sync functionality, status detection logic, and state management |
Test Execution Flow
Each test runs in an isolated environment with complete lifecycle management:
sequenceDiagram
participant R as Test Runner
participant T as Test Case
participant E as Test Env
participant G as gravity.nvim
participant V as Verifier
R->>T: before_each()
T->>E: create_test_env()
E-->>T: test_dir path
T->>E: Mock stdpath & HOME
T->>E: Setup test files
E->>E: Create configs
E->>E: Create manifest
E->>E: Create state (if needed)
T->>G: Call gravity function
G->>G: Detect status
G->>G: Perform sync
G->>E: Write files
G->>E: Update state
G-->>T: Return results
T->>V: Assert expectations
V->>E: Check files exist
V->>E: Verify contents
V->>E: Validate state
V-->>T: Pass/Fail
T->>E: after_each()
E->>E: Restore mocks
E->>E: Cleanup test_dir
Key Phases:
- Setup: Create isolated temp directory, mock paths
- Arrange: Write test configs, manifest, and state files
- Act: Execute gravity.nvim function
- Assert: Verify files, content, and state
- Cleanup: Restore mocks and remove test directory
Integration Test
File: tests/gravity/integration_spec.lua (392 lines)
The integration test provides comprehensive end-to-end verification of the entire gravity.nvim workflow. It creates 9 configuration files in different states and verifies the complete sync process.
Test Workflow
graph LR
A[Setup<br/>9 Configs] --> B[Check<br/>Initial Status]
B --> C[Run<br/>sync_all]
C --> D[Verify<br/>Sync Results]
D --> E[Check<br/>File Contents]
E --> F[Verify<br/>State File]
F --> G[Confirm<br/>Backups]
G --> H[Recheck<br/>Final Status]
style C fill:#90EE90
style D fill:#87CEEB
style H fill:#FFD700
Nine Configuration States Tested
The integration test verifies every possible status state in a single comprehensive workflow:
| Config File | Initial State | Target Location | Verification |
|---|---|---|---|
test-shell.conf |
missing_system |
~/test-shell.conf |
Creates new file |
test-init.conf |
unchanged |
~/.test-config/test-init.conf |
Skips sync |
test-app.json |
missing_system + dir creation |
~/.test-local/share/testapp/test-app.json |
Creates parent dirs |
test-git.conf |
source_changed |
~/test-git.conf |
Updates from repo |
test-tmux.conf |
system_changed |
~/test-tmux.conf |
Overwrites with force |
test-settings.json |
conflict |
~/.test-app/test-user/test-settings.json |
Skips (conflict) |
test-vim.conf |
out_of_sync |
~/test-vim.conf |
Syncs with force |
test-override.conf |
missing_system + override |
~/test-override.conf |
Uses override content |
test-missing.conf |
missing_source |
~/test-missing.conf |
Skips (no source) |
Integration Test Verification Steps
1. Initial Status Detection
- Verifies all 9 configs detected with correct status
- Confirms override detection for
test-override.conf - Validates status symbols and messages
2. Sync Execution
- Runs
sync_all({ quiet = true, force = true }) - Expects: 6 synced, 1 unchanged, 2 skipped
- Uses force mode to handle
system_changedandout_of_sync
3. File Content Verification
- Checks all synced files exist in correct locations
- Validates file contents match expected values
- Confirms unchanged file remained untouched
- Verifies skipped files not modified
4. State File Validation
- Confirms
.sync_state.jsoncreated/updated - Verifies hashes stored for all synced files
- Checks override flags recorded correctly
- Validates timestamp updates
5. Backup Verification
- Confirms backups created for overwritten files
- Checks backup directory structure
- Verifies backup filenames include timestamps
6. Final Status Check
- Re-runs status detection after sync
- Expects most files show
unchanged - Confirms conflict still present (not auto-resolved)
- Validates
missing_sourcestill skipped
Unit Tests
File: tests/gravity/sync_spec.lua (352 lines)
Unit tests provide focused verification of specific functionality with isolated test cases.
Status Detection Tests (7 tests)
Tests verify correct detection of all status states through decision tree logic:
graph TD
Start[Status Detection] --> CheckSource{Source file<br/>exists?}
CheckSource -->|No| MissingSource[missing_source]
CheckSource -->|Yes| CheckSystem{System file<br/>exists?}
CheckSystem -->|No| MissingSystem[missing_system]
CheckSystem -->|Yes| ComputeHashes[Compute hashes:<br/>source & system]
ComputeHashes --> CheckState{Previous<br/>state exists?}
CheckState -->|No| CompareFiles{Hashes<br/>match?}
CompareFiles -->|Yes| Unchanged1[unchanged]
CompareFiles -->|No| OutOfSync[out_of_sync]
CheckState -->|Yes| CheckMatch{All hashes<br/>match prev?}
CheckMatch -->|Yes| Unchanged2[unchanged]
CheckMatch -->|No| DetectChanges{Which<br/>changed?}
DetectChanges -->|Source only| SourceChanged[source_changed]
DetectChanges -->|System only| SystemChanged[system_changed]
DetectChanges -->|Both| Conflict[conflict]
style MissingSource fill:#ff6b6b
style MissingSystem fill:#ffd93d
style Unchanged1 fill:#95e1d3
style Unchanged2 fill:#95e1d3
style OutOfSync fill:#a8e6cf
style SourceChanged fill:#87ceeb
style SystemChanged fill:#ffb347
style Conflict fill:#ff6b6b
Test Coverage:
| Test | Scenario | Expected Status |
|---|---|---|
detects missing_system |
Source exists, system doesn't | missing_system |
detects missing_source |
System exists, source doesn't | missing_source |
detects unchanged |
Identical files | unchanged |
detects out_of_sync |
Different files, no state | out_of_sync |
detects source_changed |
Source modified after sync | source_changed |
detects system_changed |
System modified after sync | system_changed |
detects conflict |
Both modified after sync | conflict |
Override Precedence Tests (3 tests)
Tests verify the override system works correctly:
graph TD
A[Config Lookup] --> B{Override<br/>Exists?}
B -->|No| C[Use Base File<br/>configs/test.conf]
B -->|Yes| D[Use Override File<br/>configs.overrides/test.conf]
C --> E[Sync Base Content]
D --> F[Sync Override Content]
E --> G[State: used_override=false]
F --> H[State: used_override=true]
style D fill:#90EE90
style F fill:#90EE90
style H fill:#90EE90
Test Coverage:
| Test | Setup | Verification |
|---|---|---|
uses base file |
Only base file exists | used_override=false, base path returned |
uses override file |
Both base and override exist | used_override=true, override path returned |
syncs override content |
Override with specific content | System file contains override content |
State Tracking Tests (3 tests)
Tests verify state file creation and maintenance:
Test Coverage:
| Test | Action | Verification |
|---|---|---|
creates state file |
First sync | .sync_state.json exists |
tracks hashes |
Sync operation | Source and system hashes stored |
records override usage |
Sync with override | used_override flag saved |
Running Tests
Quick Run (Recommended)
./tests/run_tests.sh
Runs all tests with plenary.nvim, automatically installing dependencies if needed.
Manual Execution
All Tests:
nvim --headless --noplugin \
-u tests/minimal_init.lua \
-c "PlenaryBustedDirectory tests/gravity { minimal_init = 'tests/minimal_init.lua' }"
Integration Test Only:
nvim --headless --noplugin \
-u tests/minimal_init.lua \
-c "PlenaryBustedFile tests/gravity/integration_spec.lua"
Unit Tests Only:
nvim --headless --noplugin \
-u tests/minimal_init.lua \
-c "PlenaryBustedFile tests/gravity/sync_spec.lua"
Test Coverage Details
What's Tested
Core Functionality:
- ✅ All 7 status states detected correctly
- ✅ Override precedence system works
- ✅ State file creation and updates
- ✅ Hash tracking for change detection
- ✅ Directory creation for missing paths
- ✅ Backup creation for overwritten files
- ✅ Force mode overrides system changes
- ✅ Conflicts detected and skipped
- ✅ Missing sources handled gracefully
File Operations:
- ✅ Reading source files (base and override)
- ✅ Writing to system locations
- ✅ Creating parent directories
- ✅ Backup file generation
- ✅ State file persistence
Edge Cases:
- ✅ New configs with missing directories
- ✅ Configs in nested subdirectories
- ✅ Files that should be skipped (unchanged, conflict)
- ✅ Override detection and content usage
- ✅ Multiple configs synced in single operation
What's NOT Tested
UI/Interactive Features:
- ❌ Telescope picker interface
- ❌ User prompts and confirmations
- ❌ Display formatting and colors
External Dependencies:
- ❌ Git operations (if any)
- ❌ File system permissions
- ❌ Real home directory interactions
Performance:
- ❌ Large file handling
- ❌ Many configs (100+) performance
- ❌ Concurrent sync operations
Dependencies
Required:
- plenary.nvim: Test framework and utilities
Automatic Installation:
The test runner (tests/run_tests.sh) automatically clones plenary.nvim if not present.
Test Suite Status: 14 tests, comprehensive coverage of core functionality, isolated execution environment.