|
| 1 | +# Oxc Formatter Tests |
| 2 | + |
| 3 | +This directory contains snapshot-based tests for the oxc_formatter crate. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The test infrastructure is designed to be simple and flexible: |
| 8 | + |
| 9 | +- **File-based testing**: Just create `.js`, `.jsx`, `.ts`, or `.tsx` files in the `fixtures/` directory |
| 10 | +- **Hierarchical options**: Configure format options via `options.json` files at any directory level |
| 11 | +- **Automatic discovery**: Tests are automatically discovered via build script - no manual registration needed |
| 12 | +- **Individual test functions**: Each file gets its own test function, visible in `cargo test` output |
| 13 | +- **Snapshot testing**: Uses `insta` for snapshot testing with easy review workflow |
| 14 | +- **Co-located snapshots**: Snapshots are stored next to test files for easy navigation |
| 15 | + |
| 16 | +## Directory Structure |
| 17 | + |
| 18 | +``` |
| 19 | +tests/ |
| 20 | +├── mod.rs # Main test runner |
| 21 | +└── fixtures/ # Test input files |
| 22 | + ├── js/ # JavaScript/JSX tests |
| 23 | + │ ├── options.json # Shared options for all js tests |
| 24 | + │ ├── arrow-functions.js |
| 25 | + │ ├── arrow-functions.js.snap # Snapshot file (includes extension) |
| 26 | + │ ├── simple.jsx |
| 27 | + │ ├── simple.jsx.snap |
| 28 | + │ └── nested/ |
| 29 | + │ ├── options.json # Overrides parent options |
| 30 | + │ ├── example.js |
| 31 | + │ └── example.js.snap |
| 32 | + └── ts/ # TypeScript/TSX tests |
| 33 | + ├── generics.ts |
| 34 | + └── generics.ts.snap |
| 35 | +``` |
| 36 | + |
| 37 | +## Adding New Tests |
| 38 | + |
| 39 | +### Simple Test (using default options) |
| 40 | + |
| 41 | +Just create a new file in `fixtures/js/` or `fixtures/ts/`: |
| 42 | + |
| 43 | +```bash |
| 44 | +# Create a new test file |
| 45 | +echo "const foo = bar;" > tests/fixtures/js/my-test.js |
| 46 | + |
| 47 | +# The test is automatically discovered - just run tests |
| 48 | +cargo test -p oxc_formatter --test mod |
| 49 | +``` |
| 50 | + |
| 51 | +The test function is automatically generated by the build script and will be named `js_my_test`. The snapshot will be created as `tests/fixtures/js/my-test.js.snap` next to your test file. |
| 52 | + |
| 53 | +### Test with Custom Options |
| 54 | + |
| 55 | +Create an `options.json` file in the same directory (or parent directory): |
| 56 | + |
| 57 | +```json |
| 58 | +[ |
| 59 | + { |
| 60 | + "semi": true, |
| 61 | + "singleQuote": false, |
| 62 | + "arrowParens": "always" |
| 63 | + }, |
| 64 | + { |
| 65 | + "semi": false, |
| 66 | + "singleQuote": true, |
| 67 | + "arrowParens": "avoid", |
| 68 | + "printWidth": 120 |
| 69 | + } |
| 70 | +] |
| 71 | +``` |
| 72 | + |
| 73 | +**Note**: Each object in the array is a separate option set. The options are displayed in the snapshot output. |
| 74 | + |
| 75 | +### Nested/Organized Tests |
| 76 | + |
| 77 | +Create subdirectories to organize related tests: |
| 78 | + |
| 79 | +```bash |
| 80 | +mkdir -p tests/fixtures/js/classes |
| 81 | +echo "class Foo {}" > tests/fixtures/js/classes/simple.js |
| 82 | +``` |
| 83 | + |
| 84 | +The test will inherit options from the nearest `options.json` file in the directory tree. |
| 85 | + |
| 86 | +## Supported Options |
| 87 | + |
| 88 | +The following format options are supported in `options.json`: |
| 89 | + |
| 90 | +- `semi`: `true` | `false` - Semicolons (maps to `Semicolons::Always` / `Semicolons::AsNeeded`) |
| 91 | +- `singleQuote`: `true` | `false` - Quote style |
| 92 | +- `jsxSingleQuote`: `true` | `false` - JSX quote style |
| 93 | +- `arrowParens`: `"always"` | `"avoid"` - Arrow function parentheses |
| 94 | +- `trailingComma`: `"none"` | `"es5"` | `"all"` - Trailing commas |
| 95 | +- `printWidth`: number - Line width |
| 96 | +- `tabWidth`: number - Indentation width |
| 97 | +- `useTabs`: `true` | `false` - Use tabs for indentation |
| 98 | +- `bracketSpacing`: `true` | `false` - Object literal spacing |
| 99 | +- `bracketSameLine`: `true` | `false` - JSX bracket on same line |
| 100 | +- `jsxBracketSameLine`: `true` | `false` - (alias for bracketSameLine) |
| 101 | + |
| 102 | +## Running Tests |
| 103 | + |
| 104 | +### Run all tests |
| 105 | +```bash |
| 106 | +cargo test -p oxc_formatter --test mod |
| 107 | +``` |
| 108 | + |
| 109 | +K |
| 110 | +### Accept new/changed snapshots |
| 111 | +```bash |
| 112 | +cargo insta test --accept -p oxc_formatter --test mod |
| 113 | +``` |
| 114 | + |
| 115 | +### Accept snapshots for specific tests |
| 116 | +```bash |
| 117 | +FILTER="arrow" cargo insta test --accept -p oxc_formatter --test mod |
| 118 | +``` |
| 119 | + |
| 120 | +### Review snapshots interactively |
| 121 | +```bash |
| 122 | +cargo insta review -p oxc_formatter |
| 123 | +``` |
| 124 | + |
| 125 | +## How It Works |
| 126 | + |
| 127 | +1. **Build-time Discovery**: The build script (`build.rs`) scans `tests/fixtures/` for all `.{js,jsx,ts,tsx}` files |
| 128 | +2. **Code Generation**: For each file, a test function is generated (e.g., `js_arrow_functions_js()`) |
| 129 | +3. **Test Execution**: Each generated test function calls the shared `test_file()` helper |
| 130 | +4. **Filtering**: If `FILTER` env var is set, only matching paths are tested |
| 131 | +5. **Option Resolution**: For each file, walk up the directory tree to find `options.json` |
| 132 | +6. **Formatting**: Format the file with each option set |
| 133 | +7. **Snapshot**: Generate a snapshot showing input + all outputs (stored next to test file) |
| 134 | +8. **Comparison**: Compare with existing snapshot (if any) |
| 135 | + |
| 136 | +## Tips |
| 137 | + |
| 138 | +- **Auto-discovery**: Just add a `.js/.jsx/.ts/.tsx` file to `fixtures/` - no need to register it anywhere |
| 139 | +- **Test names**: Test function names are generated from file paths (e.g., `js/nested/example.js` → `js_nested_example_js`) |
| 140 | +- **Organization**: Use subdirectories to group related tests (e.g., `fixtures/js/arrows/`, `fixtures/js/classes/`) |
| 141 | +- **Shared Options**: Put `options.json` at the directory level to apply to all files in that directory |
| 142 | +- **Override Options**: Create `options.json` in a subdirectory to override parent options |
| 143 | +- **Default Options**: If no `options.json` is found, `FormatOptions::default()` is used |
| 144 | +- **File Extensions**: The source type is detected automatically from the file extension |
| 145 | +- **Co-located Snapshots**: Snapshots are stored next to test files for easy navigation and review |
| 146 | +- **Rebuilds**: The build script automatically rebuilds when files in `tests/fixtures/` change |
0 commit comments