Skip to content

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:

  1. Setup: Create isolated temp directory, mock paths
  2. Arrange: Write test configs, manifest, and state files
  3. Act: Execute gravity.nvim function
  4. Assert: Verify files, content, and state
  5. 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_changed and out_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.json created/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_source still 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

./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:

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.