Files
leaysgur 0f4af5d7df test(formatter_tests): assert fingerprint survives formatting (#26322)
Historically, only JS formatter has had the `detect_code_removal` feature, which uses CI to check for missing nodes or comments.

While this would be useful in other languages (especially CSS), but setting up the mechanism is difficult. For now, just start with something simple that just guarantees the number of comments.

That said, even with a mechanism in place, it can't detect anything unless the cases are fully covered by fixtures, so this only tells us that the current state is problem-free.
2026-09-04 07:14:53 +00:00
..
…
…

Oxc Formatter Tests

This directory contains snapshot-based tests for the oxc_formatter crate.

Overview

The test infrastructure is designed to be simple and flexible:

  • File-based testing: Just create .js, .jsx, .ts, or .tsx files in the fixtures/ directory
  • Hierarchical options: Configure format options via options.json files at any directory level
  • Automatic discovery: Tests are automatically discovered via build script - no manual registration needed
  • Nested modules: Directory structure becomes module hierarchy, enabling targeted test execution
  • Individual test functions: Each file gets its own test function, visible in cargo test output
  • Snapshot testing: Uses insta for snapshot testing with easy review workflow
  • Co-located snapshots: Snapshots are stored next to test files for easy navigation

Directory Structure

tests/
├── mod.rs                    # Main test runner
└── fixtures/                 # Test input files
    ├── js/                  # JavaScript/JSX tests
    │   ├── options.json     # Shared options for all js tests
    │   ├── arrow-functions.js
    │   ├── arrow-functions.js.snap   # Snapshot file (includes extension)
    │   ├── simple.jsx
    │   ├── simple.jsx.snap
    │   └── nested/
    │       ├── options.json # Overrides parent options
    │       ├── example.js
    │       └── example.js.snap
    └── ts/                  # TypeScript/TSX tests
        ├── generics.ts
        └── generics.ts.snap

Adding New Tests

Simple Test (using default options)

Just create a new file in fixtures/js/ or fixtures/ts/:

# Create a new test file
echo "const foo = bar;" > tests/fixtures/js/my-test.js

# The test is automatically discovered - just run tests
cargo test -p oxc_formatter --test mod

The test function is automatically generated by the build script in the module fixtures::js::my_test. The snapshot will be created as tests/fixtures/js/my-test.js.snap next to your test file.

Test with Custom Options

Create an options.json file in the same directory (or parent directory):

[
  {
    "semi": true,
    "singleQuote": false,
    "arrowParens": "always"
  },
  {
    "semi": false,
    "singleQuote": true,
    "arrowParens": "avoid",
    "printWidth": 120
  }
]

Note: Each object in the array is a separate option set. The options are displayed in the snapshot output.

Nested/Organized Tests

Create subdirectories to organize related tests:

mkdir -p tests/fixtures/js/classes
echo "class Foo {}" > tests/fixtures/js/classes/simple.js

The test will inherit options from the nearest options.json file in the directory tree.

Supported Options

The following format options are supported in options.json:

  • semi: true | false - Semicolons (maps to Semicolons::Always / Semicolons::AsNeeded)
  • singleQuote: true | false - Quote style
  • jsxSingleQuote: true | false - JSX quote style
  • arrowParens: "always" | "avoid" - Arrow function parentheses
  • trailingComma: "none" | "es5" | "all" - Trailing commas
  • printWidth: number - Line width
  • tabWidth: number - Indentation width
  • useTabs: true | false - Use tabs for indentation
  • bracketSpacing: true | false - Object literal spacing
  • bracketSameLine: true | false - JSX bracket on same line
  • jsxBracketSameLine: true | false - (alias for bracketSameLine)

Running Tests

Run all tests

cargo test -p oxc_formatter --test mod

Run tests in a specific directory

# Run all tests in the js/comments directory
cargo test -p oxc_formatter fixtures::js::comments

# Run all tests in the js directory (including subdirectories)
cargo test -p oxc_formatter fixtures::js

# Run a specific test file
cargo test -p oxc_formatter fixtures::js::comments::test

Accept new/changed snapshots

cargo insta test --accept -p oxc_formatter --test mod

Accept snapshots for specific tests

FILTER="arrow" cargo insta test --accept -p oxc_formatter --test mod

Review snapshots interactively

cargo insta review -p oxc_formatter

How It Works

  1. Build-time Discovery: The build script (build.rs) scans tests/fixtures/ for all .{js,jsx,ts,tsx} files
  2. Module Generation: Directories become nested modules matching the file system structure
  3. Code Generation: For each file, a test function is generated in the appropriate module
    • Example: fixtures/js/comments/test.js → fixtures::js::comments::test()
  4. Test Execution: Each generated test function calls the shared test_file() helper
  5. Filtering: If FILTER env var is set, only matching paths are tested
  6. Option Resolution: For each file, walk up the directory tree to find options.json
  7. Formatting: Format the file with each option set
  8. Snapshot: Generate a snapshot showing input + all outputs (stored next to test file)
  9. Comparison: Compare with existing snapshot (if any)

Tips

  • Auto-discovery: Just add a .js/.jsx/.ts/.tsx file to fixtures/ - no need to register it anywhere
  • Nested Modules: Directories become modules, enabling targeted test execution:
    • fixtures/js/comments/test.js → cargo test fixtures::js::comments::test
    • fixtures/js/comments/ → cargo test fixtures::js::comments (all tests in directory)
    • fixtures/js/ → cargo test fixtures::js (all tests including subdirectories)
  • Organization: Use subdirectories to group related tests (e.g., fixtures/js/arrows/, fixtures/js/classes/)
  • Shared Options: Put options.json at the directory level to apply to all files in that directory
  • Override Options: Create options.json in a subdirectory to override parent options
  • Default Options: If no options.json is found, FormatOptions::default() is used
  • File Extensions: The source type is detected automatically from the file extension
  • Co-located Snapshots: Snapshots are stored next to test files for easy navigation and review
  • Rebuilds: The build script automatically rebuilds when files in tests/fixtures/ change