diff --git a/AGENTS.md b/AGENTS.md index 590026e98a4d5..902d6ba34fe27 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -138,7 +138,7 @@ Oxc uses multiple testing approaches tailored to each crate: - **Unit/Integration tests**: Standard Rust tests in `tests/` directories - **Conformance tests**: Against external suites (Test262, Babel, TypeScript, Prettier) -- **Snapshot tests**: Track failures and expected outputs using `insta` +- **Snapshot tests**: Track failures and expected outputs using `cargo insta` ### Quick Test Commands @@ -146,6 +146,8 @@ Oxc uses multiple testing approaches tailored to each crate: just test # Run all Rust tests just conformance # Run all conformance tests (alias: cargo coverage) cargo test -p # Test specific crate +cargo insta test # Run snapshot tests +cargo insta review # Review/update snapshots after running test # Conformance for specific tools cargo coverage -- parser # Parser conformance @@ -181,6 +183,8 @@ fn test() { } ``` +- **Fixer**: Use `expect_fix(fix)` method after `test_and_snapshot()` for auto-fix tests in rules. + #### oxc_formatter - **Prettier conformance** only (no unit tests) @@ -290,18 +294,18 @@ Tests are TypeScript files in each package's `test/` directory. ### Where to Add Tests -| Crate | Location | -| --------------------- | --------------------------------------- | -| Parser | `tasks/coverage/misc/pass/` or `fail/` | -| Linter | Inline in rule files | -| Formatter | Prettier conformance suite | -| Minifier | `tests/` subdirectories | -| Transformer | `tests/integrations/` or Babel fixtures | -| Codegen | `tests/integration/` | -| Isolated Declarations | `tests/fixtures/*.ts` | -| Semantic | `tests/` directory | -| NAPI packages | `test/` directory (Vitest) | -| Language Server | Inline and `/fixtures` | +| Crate | Location | +| --------------------- | ----------------------------------------------------------- | +| Parser | `tasks/coverage/misc/pass/` or `fail/` | +| Linter | Inline in rule files and `tests/` subdirectory for fixtures | +| Formatter | Prettier conformance suite | +| Minifier | `tests/` subdirectories | +| Transformer | `tests/integrations/` or Babel fixtures | +| Codegen | `tests/integration/` | +| Isolated Declarations | `tests/fixtures/*.ts` | +| Semantic | `tests/` directory | +| NAPI packages | `test/` directory (Vitest) | +| Language Server | Inline and `/fixtures` | ## Notes diff --git a/Cargo.lock b/Cargo.lock index b361d6f0251f3..d8c9f1f5a73c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,20 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom 0.3.4", + "once_cell", + "serde", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.4" @@ -56,6 +70,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.5.0" @@ -107,6 +127,21 @@ dependencies = [ "virtue", ] +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + [[package]] name = "bitflags" version = "2.10.0" @@ -173,6 +208,12 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "bytecount" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" + [[package]] name = "bytes" version = "1.10.1" @@ -531,6 +572,12 @@ dependencies = [ "parking_lot_core", ] +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + [[package]] name = "deranged" version = "0.5.5" @@ -643,6 +690,15 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +[[package]] +name = "email_address" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e079f19b08ca6239f47f8ba8509c11cf3ea30095831f7fed61441475edd8c449" +dependencies = [ + "serde", +] + [[package]] name = "encode_unicode" version = "1.0.0" @@ -703,6 +759,17 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "fancy-regex" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "998b056554fbe42e03ae0e152895cd1a7e1002aec800fdc6635d20270260c46f" +dependencies = [ + "bit-set", + "regex-automata", + "regex-syntax", +] + [[package]] name = "fast-glob" version = "1.0.0" @@ -759,6 +826,17 @@ dependencies = [ "ref-cast", ] +[[package]] +name = "fluent-uri" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc74ac4d8359ae70623506d512209619e5cf8f347124910440dbc221714b328e" +dependencies = [ + "borrow-or-share", + "ref-cast", + "serde", +] + [[package]] name = "fnv" version = "1.0.7" @@ -786,6 +864,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fraction" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f158e3ff0a1b334408dc9fb811cd99b446986f4d8b741bb08f9df1604085ae7" +dependencies = [ + "lazy_static", + "num", +] + [[package]] name = "futures" version = "0.3.31" @@ -903,9 +991,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi", "wasip2", + "wasm-bindgen", ] [[package]] @@ -1009,6 +1099,29 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.10.1" @@ -1024,6 +1137,51 @@ dependencies = [ "libm", ] +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-util" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + [[package]] name = "icu_collections" version = "2.1.1" @@ -1220,6 +1378,22 @@ dependencies = [ "walkdir", ] +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "is_ci" version = "1.2.0" @@ -1299,6 +1473,34 @@ dependencies = [ "memchr", ] +[[package]] +name = "jsonschema" +version = "0.37.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73c9ffb2b5c56d58030e1b532d8e8389da94590515f118cf35b5cb68e4764a7e" +dependencies = [ + "ahash", + "bytecount", + "data-encoding", + "email_address", + "fancy-regex", + "fraction", + "getrandom 0.3.4", + "idna", + "itoa", + "num-cmp", + "num-traits", + "percent-encoding", + "referencing", + "regex", + "regex-syntax", + "reqwest", + "serde", + "serde_json", + "unicode-general-category", + "uuid-simd", +] + [[package]] name = "language-tags" version = "0.3.2" @@ -1407,7 +1609,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a7deb98ef9daaa7500324351a5bab7c80c644cfb86b4be0c4433b582af93510" dependencies = [ "bitflags", - "fluent-uri", + "fluent-uri 0.3.2", "percent-encoding", "serde", "serde_json", @@ -1447,6 +1649,17 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "mio" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + [[package]] name = "napi" version = "3.8.1" @@ -1561,6 +1774,20 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + [[package]] name = "num-bigint" version = "0.4.6" @@ -1571,6 +1798,21 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-cmp" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63335b2e2c34fae2fb0aa2cecfd9f0832a1e24b3b32ecec612c3426d46dc8aaa" + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -1586,6 +1828,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-modular" version = "0.6.1" @@ -1601,6 +1854,17 @@ dependencies = [ "num-modular", ] +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -2045,6 +2309,7 @@ dependencies = [ "itertools", "javascript-globals", "json-strip-comments", + "jsonschema", "language-tags", "lazy-regex", "markdown", @@ -2899,6 +3164,21 @@ dependencies = [ "syn", ] +[[package]] +name = "referencing" +version = "0.37.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4283168a506f0dcbdce31c9f9cce3129c924da4c6bca46e46707fcb746d2d70c" +dependencies = [ + "ahash", + "fluent-uri 0.4.1", + "getrandom 0.3.4", + "hashbrown 0.16.1", + "parking_lot", + "percent-encoding", + "serde_json", +] + [[package]] name = "regex" version = "1.12.2" @@ -2928,6 +3208,40 @@ version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +[[package]] +name = "reqwest" +version = "0.12.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6eff9328d40131d43bd911d42d79eb6a47312002a4daefc9e37f17e74a7701a" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "ring" version = "0.17.14" @@ -3175,6 +3489,18 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "sha1" version = "0.10.6" @@ -3283,6 +3609,16 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +[[package]] +name = "socket2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + [[package]] name = "sort-package-json" version = "0.0.7" @@ -3357,6 +3693,9 @@ name = "sync_wrapper" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] [[package]] name = "synstructure" @@ -3471,8 +3810,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ "bytes", + "libc", + "mio", "pin-project-lite", + "socket2", "tokio-macros", + "windows-sys 0.61.2", ] [[package]] @@ -3548,6 +3891,25 @@ dependencies = [ "futures-util", "pin-project-lite", "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", "tower-layer", "tower-service", ] @@ -3641,6 +4003,12 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "typenum" version = "1.19.0" @@ -3653,6 +4021,12 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" +[[package]] +name = "unicode-general-category" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b993bddc193ae5bd0d623b49ec06ac3e9312875fdae725a975c51db1cc1677f" + [[package]] name = "unicode-id" version = "0.3.6" @@ -3767,6 +4141,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "uuid-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b082222b4f6619906941c17eb2297fff4c2fb96cb60164170522942a200bd8" +dependencies = [ + "outref", + "vsimd", +] + [[package]] name = "valuable" version = "0.1.1" @@ -3822,6 +4206,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -3850,6 +4243,19 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.105" @@ -3882,6 +4288,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "web-sys" +version = "0.3.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "webpki-roots" version = "1.0.4" @@ -4047,7 +4463,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -4056,7 +4472,16 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", ] [[package]] @@ -4074,14 +4499,31 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -4099,48 +4541,96 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + [[package]] name = "winnow" version = "0.7.13" diff --git a/crates/oxc_linter/Cargo.toml b/crates/oxc_linter/Cargo.toml index d9660995c7fe2..ed518c4eaba5e 100644 --- a/crates/oxc_linter/Cargo.toml +++ b/crates/oxc_linter/Cargo.toml @@ -76,5 +76,6 @@ url = { workspace = true } [dev-dependencies] insta = { workspace = true } +jsonschema = { version = "0.37" } markdown = { workspace = true } project-root = { workspace = true } diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/invalid/env_wrong_type.json b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/env_wrong_type.json new file mode 100644 index 0000000000000..f4ebc3bc54c4d --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/env_wrong_type.json @@ -0,0 +1,3 @@ +{ + "env": "not-an-object" +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/invalid/globals_writeable_not_allowed.json b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/globals_writeable_not_allowed.json new file mode 100644 index 0000000000000..cbad0f235d177 --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/globals_writeable_not_allowed.json @@ -0,0 +1,5 @@ +{ + "globals": { + "Foo": "writeable" + } +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/invalid/globals_wrong_value.json b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/globals_wrong_value.json new file mode 100644 index 0000000000000..aded9ebc69ee1 --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/globals_wrong_value.json @@ -0,0 +1,5 @@ +{ + "globals": { + "Foo": "foobar" + } +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_category.json b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_category.json new file mode 100644 index 0000000000000..9bd75be1d4cfd --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_category.json @@ -0,0 +1,5 @@ +{ + "categories": { + "invalid": "off" + } +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_overrides_with_categories.json b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_overrides_with_categories.json new file mode 100644 index 0000000000000..5ce08eb1759be --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_overrides_with_categories.json @@ -0,0 +1,18 @@ +{ + "rules": { + "curly": "off" + }, + "overrides": [ + { + "files": [ + "**/*.js" + ], + "rules": { + "no-console": "error" + }, + "categories": { + "perf": true + } + } + ] +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_overrides_without_files.json b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_overrides_without_files.json new file mode 100644 index 0000000000000..5af53b250cdca --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_overrides_without_files.json @@ -0,0 +1,12 @@ +{ + "rules": { + "curly": "off" + }, + "overrides": [ + { + "rules": { + "no-console": "error" + } + } + ] +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_plugin.json b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_plugin.json new file mode 100644 index 0000000000000..fb245477a8968 --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_plugin.json @@ -0,0 +1,5 @@ +{ + "plugins": [ + "invalid" + ] +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_settings.json b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_settings.json new file mode 100644 index 0000000000000..84037789cc7cc --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_settings.json @@ -0,0 +1,11 @@ +{ + "$schema": "../../../../../../npm/oxlint/configuration_schema.json", + "plugins": [ + "react" + ], + "settings": { + "react": { + "version": "invalid" + } + } +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_settings_react_version.json b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_settings_react_version.json new file mode 100644 index 0000000000000..97ab9aaa1d49c --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_settings_react_version.json @@ -0,0 +1,11 @@ +{ + "$schema": "../../../../../../npm/oxlint/configuration_schema.json", + "plugins": [ + "react" + ], + "settings": { + "react": { + "version": "5.10.9.1" + } + } +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_severity.json b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_severity.json new file mode 100644 index 0000000000000..5969bed9d2d15 --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/invalid_severity.json @@ -0,0 +1,5 @@ +{ + "categories": { + "correctness": "invalid-severity" + } +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/invalid/plugins_wrong_type.json b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/plugins_wrong_type.json new file mode 100644 index 0000000000000..175ffc44e605a --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/invalid/plugins_wrong_type.json @@ -0,0 +1,3 @@ +{ + "plugins": "not-an-array" +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/valid/basic_plugins.json b/crates/oxc_linter/tests/fixtures/schema_validation/valid/basic_plugins.json new file mode 100644 index 0000000000000..e9fa8e688576e --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/valid/basic_plugins.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + "import", + "typescript", + "unicorn" + ] +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/valid/combined_sources.json b/crates/oxc_linter/tests/fixtures/schema_validation/valid/combined_sources.json new file mode 100644 index 0000000000000..a69509b2c1c93 --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/valid/combined_sources.json @@ -0,0 +1,79 @@ +{ + "$schema": "../../../../../../npm/oxlint/configuration_schema.json", + "env": { + "browser": true, + "node": true + }, + "globals": { + "globalThis": "readonly", + "window": "readonly" + }, + "plugins": [ + "typescript", + "jest", + "unicorn" + ], + "rules": { + "curly": [ + "error", + "all" + ], + "no-shadow": "warn", + "jest/valid-title": "warn", + "unicorn/prefer-string-replace-all": "warn", + "typescript/no-explicit-any": "off" + }, + "overrides": [ + { + "files": [ + "src/**" + ], + "env": { + "browser": true + }, + "rules": { + "no-console": [ + "warn", + { + "allow": [ + "warn", + "error" + ] + } + ] + } + }, + { + "files": [ + "server/**" + ], + "env": { + "node": true + }, + "globals": { + "__dirname": "readonly" + }, + "rules": { + "no-console": "off", + "unicorn/no-process-exit": "off" + } + }, + { + "files": [ + "tests/**" + ], + "env": { + "jest": true + }, + "rules": { + "jest/no-identical-title": "error", + "jest/no-conditional-expect": "warn" + } + } + ], + "ignorePatterns": [ + "**/.cache/**", + "**/dist/**", + "**/coverage/**" + ] +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/valid/complex_nested.json b/crates/oxc_linter/tests/fixtures/schema_validation/valid/complex_nested.json new file mode 100644 index 0000000000000..575eb426657d8 --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/valid/complex_nested.json @@ -0,0 +1,101 @@ +{ + "$schema": "../../../../../../npm/oxlint/configuration_schema.json", + "plugins": [ + "typescript", + "jest", + "unicorn" + ], + "env": { + "browser": true, + "node": true, + "jest": true + }, + "globals": { + "__DEV__": "readonly", + "process": "readonly", + "Buffer": "readonly" + }, + "ignorePatterns": [ + "**/dist/**", + "**/build/**", + "**/.cache/**", + "coverage/**" + ], + "rules": { + "no-unused-vars": [ + "error", + { + "argsIgnorePattern": "^_", + "varsIgnorePattern": "^_" + } + ], + "no-console": [ + "warn", + { + "allow": [ + "warn", + "error" + ] + } + ], + "eqeqeq": "error", + "unicorn/prefer-query-selector": "off", + "jest/no-disabled-tests": "warn", + "typescript/no-explicit-any": [ + "warn", + { + "ignoreRestArgs": true + } + ] + }, + "overrides": [ + { + "files": [ + "**/*.ts", + "**/*.tsx" + ], + "env": { + "browser": true + }, + "rules": { + "typescript/explicit-module-boundary-types": "off", + "typescript/no-non-null-assertion": "warn" + } + }, + { + "files": [ + "**/*.test.ts", + "**/*.spec.ts" + ], + "env": { + "jest": true + }, + "rules": { + "no-console": "off", + "jest/expect-expect": [ + "warn", + { + "assertFunctionNames": [ + "expect" + ] + } + ] + } + }, + { + "files": [ + "scripts/**" + ], + "env": { + "node": true + }, + "globals": { + "__DEV__": "writable" + }, + "rules": { + "no-process-exit": "off", + "no-console": "off" + } + } + ] +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/valid/empty_config.json b/crates/oxc_linter/tests/fixtures/schema_validation/valid/empty_config.json new file mode 100644 index 0000000000000..0967ef424bce6 --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/valid/empty_config.json @@ -0,0 +1 @@ +{} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/valid/env_config.json b/crates/oxc_linter/tests/fixtures/schema_validation/valid/env_config.json new file mode 100644 index 0000000000000..5c9b772d3549e --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/valid/env_config.json @@ -0,0 +1,7 @@ +{ + "env": { + "browser": true, + "node": true, + "es2021": true + } +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/valid/extends_and_overrides.json b/crates/oxc_linter/tests/fixtures/schema_validation/valid/extends_and_overrides.json new file mode 100644 index 0000000000000..fb9dbe2a0a0f7 --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/valid/extends_and_overrides.json @@ -0,0 +1,61 @@ +{ + "$schema": "../../../../../../npm/oxlint/configuration_schema.json", + "extends": [ + "oxlint:recommended", + "plugin:typescript/recommended", + "plugin:unicorn/recommended" + ], + "plugins": [ + "typescript", + "unicorn" + ], + "rules": { + "no-debugger": "error", + "no-alert": "error" + }, + "overrides": [ + { + "files": [ + "**/*.js" + ], + "rules": { + "typescript/no-explicit-any": "off", + "unicorn/filename-case": [ + "warn", + { + "case": "kebabCase" + } + ] + } + }, + { + "files": [ + "**/*.ts", + "**/*.tsx" + ], + "env": { + "browser": true + }, + "rules": { + "no-unused-vars": [ + "warn", + { + "vars": "all", + "args": "none" + } + ], + "typescript/no-explicit-any": [ + "warn", + { + "ignoreRestArgs": true + } + ] + } + } + ], + "ignorePatterns": [ + "**/vendor/**", + "**/fixtures/**", + "**/generated/**" + ] +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/valid/full_config.json b/crates/oxc_linter/tests/fixtures/schema_validation/valid/full_config.json new file mode 100644 index 0000000000000..239d559dee821 --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/valid/full_config.json @@ -0,0 +1,39 @@ +{ + "plugins": [ + "import", + "typescript", + "unicorn" + ], + "jsPlugins": [ + "eslint-plugin-foo", + "eslint-plugin-bar" + ], + "env": { + "browser": true + }, + "globals": { + "foo": "readonly" + }, + "settings": {}, + "rules": { + "eqeqeq": "warn", + "import/no-cycle": "error", + "react/self-closing-comp": [ + "error", + { + "html": false + } + ] + }, + "overrides": [ + { + "files": [ + "*.test.ts", + "*.spec.ts" + ], + "rules": { + "@typescript-eslint/no-explicit-any": "off" + } + } + ] +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/valid/globals_config.json b/crates/oxc_linter/tests/fixtures/schema_validation/valid/globals_config.json new file mode 100644 index 0000000000000..67cf3076bb7af --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/valid/globals_config.json @@ -0,0 +1,7 @@ +{ + "globals": { + "Foo": "writable", + "Bar": "readonly", + "Baz": "off" + } +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/valid/ignore_patterns.json b/crates/oxc_linter/tests/fixtures/schema_validation/valid/ignore_patterns.json new file mode 100644 index 0000000000000..a8d64cb415d2e --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/valid/ignore_patterns.json @@ -0,0 +1,8 @@ +{ + "ignorePatterns": [ + "dist", + "node_modules", + "*.min.js", + "**/*.ts" + ] +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/valid/rules_config.json b/crates/oxc_linter/tests/fixtures/schema_validation/valid/rules_config.json new file mode 100644 index 0000000000000..1996555324806 --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/valid/rules_config.json @@ -0,0 +1,7 @@ +{ + "rules": { + "no-unused-vars": "error", + "eqeqeq": ["warn"], + "no-console": ["error", { "allow": ["warn", "error"] }] + } +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/valid/valid_categories.json b/crates/oxc_linter/tests/fixtures/schema_validation/valid/valid_categories.json new file mode 100644 index 0000000000000..2e75a9c280a56 --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/valid/valid_categories.json @@ -0,0 +1,11 @@ +{ + "categories": { + "correctness": "warn", + "suspicious": "error", + "pedantic": "off", + "style": "warn", + "perf": "error", + "nursery": "error", + "restriction": "off" + } +} diff --git a/crates/oxc_linter/tests/fixtures/schema_validation/valid/valid_settings.json b/crates/oxc_linter/tests/fixtures/schema_validation/valid/valid_settings.json new file mode 100644 index 0000000000000..a37c588b294c6 --- /dev/null +++ b/crates/oxc_linter/tests/fixtures/schema_validation/valid/valid_settings.json @@ -0,0 +1,11 @@ +{ + "$schema": "../../../../../../npm/oxlint/configuration_schema.json", + "plugins": [ + "react" + ], + "settings": { + "react": { + "version": "19.1.0" + } + } +} diff --git a/crates/oxc_linter/tests/rule_configuration_test.rs b/crates/oxc_linter/tests/rule_configuration_test.rs index 096f12680baca..0897f1dfe75a8 100644 --- a/crates/oxc_linter/tests/rule_configuration_test.rs +++ b/crates/oxc_linter/tests/rule_configuration_test.rs @@ -54,7 +54,6 @@ fn test_rule_default_matches_from_configuration_null() { "Rule '{plugin_name}/{rule_name}' has different configurations between default() and from_configuration(null).\n\ Default: {default_debug}\n\ From null: {null_debug}", - )); } } diff --git a/crates/oxc_linter/tests/schema_validation_test.rs b/crates/oxc_linter/tests/schema_validation_test.rs new file mode 100644 index 0000000000000..68b9362a0d7df --- /dev/null +++ b/crates/oxc_linter/tests/schema_validation_test.rs @@ -0,0 +1,135 @@ +//! Test to ensure JSON Schema validation is working correctly +//! +//! This test validates that the generated JSON schema for oxlintrc configuration +//! files correctly validates both valid and invalid configurations. This helps +//! prevent regressions in the schema generation process. + +use std::fs; +use std::path::PathBuf; + +use insta::assert_snapshot; +use jsonschema::Validator; +use project_root::get_project_root; + +/// Get the path to the test fixtures directory +fn get_fixtures_path() -> PathBuf { + get_project_root().unwrap().join("crates/oxc_linter/tests/fixtures/schema_validation") +} + +fn schema_content() -> String { + // Load the generated schema from the expected location + let schema_json = get_project_root().unwrap().join("npm/oxlint/configuration_schema.json"); + + fs::read_to_string(&schema_json).expect("Failed to read generated schema") +} + +/// Load the JSON schema from 'npm/oxlint/configuration_schema.json' +fn load_schema() -> Validator { + let schema: serde_json::Value = + serde_json::from_str(&schema_content()).expect("Failed to parse generated schema as JSON"); + + Validator::new(&schema).expect("Failed to compile JSON schema") +} + +/// Return a sorted list of JSON files in `dir` +fn list_json_files(dir: &PathBuf) -> Vec { + let mut files: Vec = fs::read_dir(dir) + .unwrap_or_else(|e| panic!("Failed to read dir {}: {e}", dir.display())) + .filter_map(|entry| entry.ok().map(|e| e.path())) + .filter(|p| p.extension().and_then(|s| s.to_str()) == Some("json")) + .collect(); + + files.sort_by_key(|p| p.file_name().map(|s| s.to_string_lossy().to_string())); + files +} + +/// Test that valid configuration files pass schema validation +#[test] +fn test_valid_configs_pass_validation() { + let schema = load_schema(); + let valid_dir = get_fixtures_path().join("valid"); + + // Get all json files in the valid fixture directory. + let test_files = list_json_files(&valid_dir); + + for file_path in &test_files { + let file_name = file_path.file_name().and_then(|s| s.to_str()).unwrap(); + let content = fs::read_to_string(file_path) + .unwrap_or_else(|e| panic!("Failed to read {file_name}: {e}")); + + let instance: serde_json::Value = serde_json::from_str(&content) + .unwrap_or_else(|e| panic!("Failed to parse {file_name} as JSON: {e}")); + + // Use iter_errors to get all validation errors + let errors: Vec<_> = schema.iter_errors(&instance).collect(); + + if !errors.is_empty() { + let error_messages: Vec = errors.iter().map(|e| format!(" - {e}")).collect(); + panic!( + "Valid config '{file_name}' failed schema validation:\n{}", + error_messages.join("\n") + ); + } + } +} + +/// Test that invalid configuration files fail schema validation +#[test] +fn test_invalid_configs_fail_validation() { + let schema = load_schema(); + let invalid_dir = get_fixtures_path().join("invalid"); + + // TODO: Add another invalid test case to ensure that unknown fields are caught. + // `additionalProperties` needs to be set to false for this to work and we need + // to explicitly allow the "$schema" field. + // Get all json files in the invalid fixture directory. + let test_files = list_json_files(&invalid_dir); + + for file_path in &test_files { + let file_name = file_path.file_name().and_then(|s| s.to_str()).unwrap(); + let content = fs::read_to_string(file_path) + .unwrap_or_else(|e| panic!("Failed to read {file_name}: {e}")); + + let instance: serde_json::Value = serde_json::from_str(&content) + .unwrap_or_else(|e| panic!("Failed to parse {file_name} as JSON: {e}")); + + // Collect validation errors + let errors: Vec<_> = schema.iter_errors(&instance).collect(); + + // Ensure there are errors + assert!( + !errors.is_empty(), + "Invalid config '{file_name}' unexpectedly passed schema validation" + ); + + // Snapshot the invalid JSON content and human-readable error messages together + let error_messages: String = + errors.iter().map(|e| format!("- {e}")).collect::>().join("\n"); + + let snapshot_body = + format!("File: {file_name}\n\n.oxlintrc.json:\n{content}\nErrors:\n{error_messages}\n"); + + // Name snapshots by file to keep them stable and readable + let snap_name = format!("invalid_{file_name}_errors"); + insta::with_settings!({ prepend_module_to_snapshot => false }, { + assert_snapshot!(snap_name, snapshot_body); + }); + } +} + +/// Test that the schema itself is valid JSON Schema Draft 7 +#[test] +fn test_schema_is_valid() { + let schema: serde_json::Value = + serde_json::from_str(&schema_content()).expect("Failed to parse generated schema as JSON"); + + // Check that the schema has the expected $schema field + assert_eq!( + schema.get("$schema").and_then(|v| v.as_str()), + Some("http://json-schema.org/draft-07/schema#"), + "Schema should declare JSON Schema Draft 7" + ); + + // Check that we can compile it (this validates the schema structure) + Validator::new(&schema).expect("Generated schema should be valid JSON Schema"); +} diff --git a/crates/oxc_linter/tests/snapshots/invalid_env_wrong_type.json_errors.snap b/crates/oxc_linter/tests/snapshots/invalid_env_wrong_type.json_errors.snap new file mode 100644 index 0000000000000..e06c79187016b --- /dev/null +++ b/crates/oxc_linter/tests/snapshots/invalid_env_wrong_type.json_errors.snap @@ -0,0 +1,13 @@ +--- +source: crates/oxc_linter/tests/schema_validation_test.rs +expression: snapshot_body +--- +File: env_wrong_type.json + +.oxlintrc.json: +{ + "env": "not-an-object" +} + +Errors: +- "not-an-object" is not of type "object" diff --git a/crates/oxc_linter/tests/snapshots/invalid_globals_writeable_not_allowed.json_errors.snap b/crates/oxc_linter/tests/snapshots/invalid_globals_writeable_not_allowed.json_errors.snap new file mode 100644 index 0000000000000..7e154516574b6 --- /dev/null +++ b/crates/oxc_linter/tests/snapshots/invalid_globals_writeable_not_allowed.json_errors.snap @@ -0,0 +1,15 @@ +--- +source: crates/oxc_linter/tests/schema_validation_test.rs +expression: snapshot_body +--- +File: globals_writeable_not_allowed.json + +.oxlintrc.json: +{ + "globals": { + "Foo": "writeable" + } +} + +Errors: +- "writeable" is not one of "readonly", "writable" or "off" diff --git a/crates/oxc_linter/tests/snapshots/invalid_globals_wrong_value.json_errors.snap b/crates/oxc_linter/tests/snapshots/invalid_globals_wrong_value.json_errors.snap new file mode 100644 index 0000000000000..008e31106c9d6 --- /dev/null +++ b/crates/oxc_linter/tests/snapshots/invalid_globals_wrong_value.json_errors.snap @@ -0,0 +1,15 @@ +--- +source: crates/oxc_linter/tests/schema_validation_test.rs +expression: snapshot_body +--- +File: globals_wrong_value.json + +.oxlintrc.json: +{ + "globals": { + "Foo": "foobar" + } +} + +Errors: +- "foobar" is not one of "readonly", "writable" or "off" diff --git a/crates/oxc_linter/tests/snapshots/invalid_invalid_category.json_errors.snap b/crates/oxc_linter/tests/snapshots/invalid_invalid_category.json_errors.snap new file mode 100644 index 0000000000000..d13d5bd3c102e --- /dev/null +++ b/crates/oxc_linter/tests/snapshots/invalid_invalid_category.json_errors.snap @@ -0,0 +1,15 @@ +--- +source: crates/oxc_linter/tests/schema_validation_test.rs +expression: snapshot_body +--- +File: invalid_category.json + +.oxlintrc.json: +{ + "categories": { + "invalid": "off" + } +} + +Errors: +- Additional properties are not allowed ('invalid' was unexpected) diff --git a/crates/oxc_linter/tests/snapshots/invalid_invalid_overrides_with_categories.json_errors.snap b/crates/oxc_linter/tests/snapshots/invalid_invalid_overrides_with_categories.json_errors.snap new file mode 100644 index 0000000000000..6d35a16ae58aa --- /dev/null +++ b/crates/oxc_linter/tests/snapshots/invalid_invalid_overrides_with_categories.json_errors.snap @@ -0,0 +1,28 @@ +--- +source: crates/oxc_linter/tests/schema_validation_test.rs +expression: snapshot_body +--- +File: invalid_overrides_with_categories.json + +.oxlintrc.json: +{ + "rules": { + "curly": "off" + }, + "overrides": [ + { + "files": [ + "**/*.js" + ], + "rules": { + "no-console": "error" + }, + "categories": { + "perf": true + } + } + ] +} + +Errors: +- Additional properties are not allowed ('categories' was unexpected) diff --git a/crates/oxc_linter/tests/snapshots/invalid_invalid_overrides_without_files.json_errors.snap b/crates/oxc_linter/tests/snapshots/invalid_invalid_overrides_without_files.json_errors.snap new file mode 100644 index 0000000000000..37816667cf672 --- /dev/null +++ b/crates/oxc_linter/tests/snapshots/invalid_invalid_overrides_without_files.json_errors.snap @@ -0,0 +1,22 @@ +--- +source: crates/oxc_linter/tests/schema_validation_test.rs +expression: snapshot_body +--- +File: invalid_overrides_without_files.json + +.oxlintrc.json: +{ + "rules": { + "curly": "off" + }, + "overrides": [ + { + "rules": { + "no-console": "error" + } + } + ] +} + +Errors: +- "files" is a required property diff --git a/crates/oxc_linter/tests/snapshots/invalid_invalid_plugin.json_errors.snap b/crates/oxc_linter/tests/snapshots/invalid_invalid_plugin.json_errors.snap new file mode 100644 index 0000000000000..2e324c0ac0d9d --- /dev/null +++ b/crates/oxc_linter/tests/snapshots/invalid_invalid_plugin.json_errors.snap @@ -0,0 +1,15 @@ +--- +source: crates/oxc_linter/tests/schema_validation_test.rs +expression: snapshot_body +--- +File: invalid_plugin.json + +.oxlintrc.json: +{ + "plugins": [ + "invalid" + ] +} + +Errors: +- ["invalid"] is not valid under any of the schemas listed in the 'anyOf' keyword diff --git a/crates/oxc_linter/tests/snapshots/invalid_invalid_settings.json_errors.snap b/crates/oxc_linter/tests/snapshots/invalid_invalid_settings.json_errors.snap new file mode 100644 index 0000000000000..d6c770cd2add0 --- /dev/null +++ b/crates/oxc_linter/tests/snapshots/invalid_invalid_settings.json_errors.snap @@ -0,0 +1,21 @@ +--- +source: crates/oxc_linter/tests/schema_validation_test.rs +expression: snapshot_body +--- +File: invalid_settings.json + +.oxlintrc.json: +{ + "$schema": "../../../../../../npm/oxlint/configuration_schema.json", + "plugins": [ + "react" + ], + "settings": { + "react": { + "version": "invalid" + } + } +} + +Errors: +- "invalid" does not match "^[1-9][0-9]*(\.(0|[1-9][0-9]*))?(\.(0|[1-9][0-9]*))?$" diff --git a/crates/oxc_linter/tests/snapshots/invalid_invalid_settings_react_version.json_errors.snap b/crates/oxc_linter/tests/snapshots/invalid_invalid_settings_react_version.json_errors.snap new file mode 100644 index 0000000000000..836f21d8c0b66 --- /dev/null +++ b/crates/oxc_linter/tests/snapshots/invalid_invalid_settings_react_version.json_errors.snap @@ -0,0 +1,21 @@ +--- +source: crates/oxc_linter/tests/schema_validation_test.rs +expression: snapshot_body +--- +File: invalid_settings_react_version.json + +.oxlintrc.json: +{ + "$schema": "../../../../../../npm/oxlint/configuration_schema.json", + "plugins": [ + "react" + ], + "settings": { + "react": { + "version": "5.10.9.1" + } + } +} + +Errors: +- "5.10.9.1" does not match "^[1-9][0-9]*(\.(0|[1-9][0-9]*))?(\.(0|[1-9][0-9]*))?$" diff --git a/crates/oxc_linter/tests/snapshots/invalid_invalid_severity.json_errors.snap b/crates/oxc_linter/tests/snapshots/invalid_invalid_severity.json_errors.snap new file mode 100644 index 0000000000000..28dc220949c20 --- /dev/null +++ b/crates/oxc_linter/tests/snapshots/invalid_invalid_severity.json_errors.snap @@ -0,0 +1,15 @@ +--- +source: crates/oxc_linter/tests/schema_validation_test.rs +expression: snapshot_body +--- +File: invalid_severity.json + +.oxlintrc.json: +{ + "categories": { + "correctness": "invalid-severity" + } +} + +Errors: +- "invalid-severity" is not valid under any of the schemas listed in the 'oneOf' keyword diff --git a/crates/oxc_linter/tests/snapshots/invalid_plugins_wrong_type.json_errors.snap b/crates/oxc_linter/tests/snapshots/invalid_plugins_wrong_type.json_errors.snap new file mode 100644 index 0000000000000..95b8bbdd3d1d9 --- /dev/null +++ b/crates/oxc_linter/tests/snapshots/invalid_plugins_wrong_type.json_errors.snap @@ -0,0 +1,13 @@ +--- +source: crates/oxc_linter/tests/schema_validation_test.rs +expression: snapshot_body +--- +File: plugins_wrong_type.json + +.oxlintrc.json: +{ + "plugins": "not-an-array" +} + +Errors: +- "not-an-array" is not valid under any of the schemas listed in the 'anyOf' keyword diff --git a/npm/oxlint/configuration_schema.json b/npm/oxlint/configuration_schema.json index 46d66f94861c0..f78e3ddcac8e6 100644 --- a/npm/oxlint/configuration_schema.json +++ b/npm/oxlint/configuration_schema.json @@ -721,4 +721,4 @@ } }, "markdownDescription": "Oxlint Configuration File\n\nThis configuration is aligned with ESLint v8's configuration schema (`eslintrc.json`).\n\nUsage: `oxlint -c oxlintrc.json --import-plugin`\n\n::: danger NOTE\n\nOnly the `.json` format is supported. You can use comments in configuration files.\n\n:::\n\nExample\n\n`.oxlintrc.json`\n\n```json\n{\n\"$schema\": \"./node_modules/oxlint/configuration_schema.json\",\n\"plugins\": [\"import\", \"typescript\", \"unicorn\"],\n\"env\": {\n\"browser\": true\n},\n\"globals\": {\n\"foo\": \"readonly\"\n},\n\"settings\": {\n},\n\"rules\": {\n\"eqeqeq\": \"warn\",\n\"import/no-cycle\": \"error\",\n\"react/self-closing-comp\": [\"error\", { \"html\": false }]\n},\n\"overrides\": [\n{\n\"files\": [\"*.test.ts\", \"*.spec.ts\"],\n\"rules\": {\n\"@typescript-eslint/no-explicit-any\": \"off\"\n}\n}\n]\n}\n```" -} \ No newline at end of file +}