From 3dcfb5c0fc5fda1c72ab120def9d79417afb739b Mon Sep 17 00:00:00 2001 From: Marco Roth Date: Wed, 14 Oct 2026 17:09:24 +0900 Subject: [PATCH] Raise on unknown browsers in `targets` --- README.md | 2 ++ rust/src/options.rs | 22 +++++++++++++++++++++- test/lightningcss/targets_test.rb | 24 ++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ad12170..852f1ef 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,8 @@ LightningCSS.transform(".a { color: oklch(60% .2 30) }", targets: { safari: "15. Prefer a `String` for a minor version above 9, since `16.10` as a `Float` is `16.1`. +The browsers it reads are `android`, `chrome`, `edge`, `firefox`, `ie`, `ios_saf` (or `ios`), `opera`, `safari`, and `samsung`. Any other name raises a `LightningCSS::OptionError`. + #### Bundling `bundle` resolves the `@import` statements a stylesheet was written with by reading the files they name, so it takes a path on disk to the entry stylesheet. diff --git a/rust/src/options.rs b/rust/src/options.rs index 42f7c20..732bc92 100644 --- a/rust/src/options.rs +++ b/rust/src/options.rs @@ -102,12 +102,32 @@ impl Version { } } +const BROWSERS: [&str; 10] = [ + "android", "chrome", "edge", "firefox", "ie", "ios", "ios_saf", "opera", "safari", "samsung", +]; + impl TransformOptions { pub fn to_targets(&self) -> Result { let Some(versions) = &self.targets else { return Ok(Targets::default()); }; + let mut unknown: Vec<&str> = versions + .keys() + .map(String::as_str) + .filter(|name| !BROWSERS.contains(name)) + .collect(); + + if !unknown.is_empty() { + unknown.sort_unstable(); + + return Err(format!( + "Unknown browser{} in targets: {}", + if unknown.len() > 1 { "s" } else { "" }, + unknown.join(", ") + )); + } + let mut browsers = Browsers::default(); for (name, version) in versions { @@ -127,7 +147,7 @@ impl TransformOptions { "opera" => browsers.opera = encoded, "safari" => browsers.safari = encoded, "samsung" => browsers.samsung = encoded, - _ => {} + _ => unreachable!(), } } diff --git a/test/lightningcss/targets_test.rb b/test/lightningcss/targets_test.rb index f484832..636dd0b 100644 --- a/test/lightningcss/targets_test.rb +++ b/test/lightningcss/targets_test.rb @@ -85,6 +85,30 @@ class TargetsTest < Minitest::Spec end end + test "raises an option error for a browser it does not know" do + error = assert_raises(OptionError) { LightningCSS.transform(".a{}", targets: { safar: 15 }) } + + assert_equal "Unknown browser in targets: safar", error.message + end + + test "names every browser it does not know, in order" do + error = assert_raises(OptionError) { LightningCSS.transform(".a{}", targets: { netscape: 4, chrome: 100, mosaic: 1 }) } + + assert_equal "Unknown browsers in targets: mosaic, netscape", error.message + end + + test "raises for a browser it does not know before reading any version" do + error = assert_raises(OptionError) { LightningCSS.transform(".a{}", targets: { safari: "x", safar: 15 }) } + + assert_equal "Unknown browser in targets: safar", error.message + end + + test "reads ios as ios_saf" do + code = LightningCSS.transform(".a { color: oklch(60% .2 30) }", targets: { ios: "15.4" }, minify: true).code + + assert_equal ".a{color:oklch(60% .2 30)}", code + end + test "raises an option error for a negative version" do error = assert_raises(OptionError) { LightningCSS.transform(".a{}", targets: { safari: -1 }) }