lightningcss/
lib.rs

1//! Lightning CSS is a CSS parser, transformer, and minifier based on the
2//! [cssparser](https://github.com/servo/rust-cssparser) crate used in Firefox.
3//! It supports fully parsing all CSS rules, properties, and values into normalized
4//! structures exactly how a browser would. Once parsed, the CSS can be transformed
5//! to add or remove vendor prefixes, or lower syntax for older browsers as appropriate.
6//! The style sheet can also be minified to merge longhand properties into shorthands,
7//! merge adjacent rules, reduce `calc()` expressions, and more. Finally, the style sheet
8//! can be printed back to CSS syntax, either minified to remove whitespace and compress
9//! the output as much as possible, or pretty printed.
10//!
11//! The [StyleSheet](stylesheet::StyleSheet) struct is the main entrypoint for Lightning CSS,
12//! and supports parsing and transforming entire CSS files. You can also parse and manipulate
13//! individual CSS [rules](rules), [properties](properties), or [values](values). The [bundler](bundler)
14//! module also can be used to combine a CSS file and all of its dependencies together into a single
15//! style sheet. See the individual module documentation for more details and examples.
16
17#![deny(missing_docs)]
18#![cfg_attr(docsrs, feature(doc_cfg))]
19
20#[cfg(feature = "bundler")]
21#[cfg_attr(docsrs, doc(cfg(feature = "bundler")))]
22pub mod bundler;
23mod compat;
24mod context;
25pub mod css_modules;
26pub mod declaration;
27pub mod dependencies;
28pub mod error;
29mod logical;
30mod macros;
31pub mod media_query;
32mod parser;
33mod prefixes;
34pub mod printer;
35pub mod properties;
36pub mod rules;
37pub mod selector;
38pub mod stylesheet;
39pub mod targets;
40pub mod traits;
41pub mod values;
42pub mod vendor_prefix;
43#[cfg(feature = "visitor")]
44#[cfg_attr(docsrs, doc(cfg(feature = "visitor")))]
45pub mod visitor;
46
47#[cfg(feature = "serde")]
48mod serialization;
49
50#[cfg(test)]
51mod tests {
52  use crate::css_modules::{CssModuleExport, CssModuleExports, CssModuleReference, CssModuleReferences};
53  use crate::dependencies::Dependency;
54  use crate::error::{Error, ErrorLocation, MinifyErrorKind, ParserError, PrinterErrorKind, SelectorError};
55  use crate::parser::ParserFlags;
56  use crate::properties::custom::Token;
57  use crate::properties::Property;
58  use crate::rules::CssRule;
59  use crate::rules::Location;
60  use crate::stylesheet::*;
61  use crate::targets::{Browsers, Features, Targets};
62  use crate::traits::{Parse, ToCss};
63  use crate::values::color::CssColor;
64  use crate::vendor_prefix::VendorPrefix;
65  use cssparser::SourceLocation;
66  use indoc::indoc;
67  use pretty_assertions::assert_eq;
68  use std::collections::HashMap;
69
70  fn test(source: &str, expected: &str) {
71    test_with_options(source, expected, ParserOptions::default())
72  }
73
74  fn test_with_options<'i, 'o>(source: &'i str, expected: &'i str, options: ParserOptions<'o, 'i>) {
75    let mut stylesheet = StyleSheet::parse(&source, options).unwrap();
76    stylesheet.minify(MinifyOptions::default()).unwrap();
77    let res = stylesheet.to_css(PrinterOptions::default()).unwrap();
78    assert_eq!(res.code, expected);
79  }
80
81  fn minify_test(source: &str, expected: &str) {
82    minify_test_with_options(source, expected, ParserOptions::default())
83  }
84
85  #[track_caller]
86  fn minify_test_with_options<'i, 'o>(source: &'i str, expected: &'i str, options: ParserOptions<'o, 'i>) {
87    let mut stylesheet = StyleSheet::parse(&source, options.clone()).unwrap();
88    stylesheet.minify(MinifyOptions::default()).unwrap();
89    let res = stylesheet
90      .to_css(PrinterOptions {
91        minify: true,
92        ..PrinterOptions::default()
93      })
94      .unwrap();
95    assert_eq!(res.code, expected);
96  }
97
98  fn minify_error_test_with_options<'i, 'o>(
99    source: &'i str,
100    error: MinifyErrorKind,
101    options: ParserOptions<'o, 'i>,
102  ) {
103    let mut stylesheet = StyleSheet::parse(&source, options.clone()).unwrap();
104    match stylesheet.minify(MinifyOptions::default()) {
105      Err(e) => assert_eq!(e.kind, error),
106      _ => unreachable!(),
107    }
108  }
109
110  fn prefix_test(source: &str, expected: &str, targets: Browsers) {
111    let mut stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
112    stylesheet
113      .minify(MinifyOptions {
114        targets: targets.into(),
115        ..MinifyOptions::default()
116      })
117      .unwrap();
118    let res = stylesheet
119      .to_css(PrinterOptions {
120        targets: targets.into(),
121        ..PrinterOptions::default()
122      })
123      .unwrap();
124    assert_eq!(res.code, expected);
125  }
126
127  fn attr_test(source: &str, expected: &str, minify: bool, targets: Option<Browsers>) {
128    let mut attr = StyleAttribute::parse(source, ParserOptions::default()).unwrap();
129    attr.minify(MinifyOptions {
130      targets: targets.into(),
131      ..MinifyOptions::default()
132    });
133    let res = attr
134      .to_css(PrinterOptions {
135        targets: targets.into(),
136        minify,
137        ..PrinterOptions::default()
138      })
139      .unwrap();
140    assert_eq!(res.code, expected);
141  }
142
143  fn nesting_test(source: &str, expected: &str) {
144    nesting_test_with_targets(
145      source,
146      expected,
147      Browsers {
148        chrome: Some(95 << 16),
149        ..Browsers::default()
150      }
151      .into(),
152    );
153  }
154
155  fn nesting_test_with_targets(source: &str, expected: &str, targets: Targets) {
156    let mut stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
157    stylesheet
158      .minify(MinifyOptions {
159        targets,
160        ..MinifyOptions::default()
161      })
162      .unwrap();
163    let res = stylesheet
164      .to_css(PrinterOptions {
165        targets,
166        ..PrinterOptions::default()
167      })
168      .unwrap();
169    assert_eq!(res.code, expected);
170  }
171
172  fn nesting_test_no_targets(source: &str, expected: &str) {
173    let mut stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
174    stylesheet.minify(MinifyOptions::default()).unwrap();
175    let res = stylesheet.to_css(PrinterOptions::default()).unwrap();
176    assert_eq!(res.code, expected);
177  }
178
179  fn css_modules_test<'i>(
180    source: &'i str,
181    expected: &str,
182    expected_exports: CssModuleExports,
183    expected_references: CssModuleReferences,
184    config: crate::css_modules::Config<'i>,
185  ) {
186    let mut stylesheet = StyleSheet::parse(
187      &source,
188      ParserOptions {
189        filename: "test.css".into(),
190        css_modules: Some(config),
191        ..ParserOptions::default()
192      },
193    )
194    .unwrap();
195    stylesheet.minify(MinifyOptions::default()).unwrap();
196    let res = stylesheet.to_css(PrinterOptions::default()).unwrap();
197    assert_eq!(res.code, expected);
198    assert_eq!(res.exports.unwrap(), expected_exports);
199    assert_eq!(res.references.unwrap(), expected_references);
200  }
201
202  fn custom_media_test(source: &str, expected: &str) {
203    let mut stylesheet = StyleSheet::parse(
204      &source,
205      ParserOptions {
206        flags: ParserFlags::CUSTOM_MEDIA,
207        ..ParserOptions::default()
208      },
209    )
210    .unwrap();
211    stylesheet
212      .minify(MinifyOptions {
213        targets: Browsers {
214          chrome: Some(95 << 16),
215          ..Browsers::default()
216        }
217        .into(),
218        ..MinifyOptions::default()
219      })
220      .unwrap();
221    let res = stylesheet.to_css(PrinterOptions::default()).unwrap();
222    assert_eq!(res.code, expected);
223  }
224
225  fn error_test(source: &str, error: ParserError) {
226    let res = StyleSheet::parse(&source, ParserOptions::default());
227    match res {
228      Ok(_) => unreachable!(),
229      Err(e) => assert_eq!(e.kind, error),
230    }
231  }
232
233  macro_rules! map(
234    { $($key:expr => $name:literal $(referenced: $referenced: literal)? $($value:literal $(global: $global: literal)? $(from $from:literal)?)*),* } => {
235      {
236        #[allow(unused_mut)]
237        let mut m = HashMap::new();
238        $(
239          #[allow(unused_mut)]
240          let mut v = Vec::new();
241          #[allow(unused_macros)]
242          macro_rules! insert {
243            ($local:literal from $specifier:literal) => {
244              v.push(CssModuleReference::Dependency {
245                name: $local.into(),
246                specifier: $specifier.into()
247              });
248            };
249            ($local:literal global: $is_global: literal) => {
250              v.push(CssModuleReference::Global {
251                name: $local.into()
252              });
253            };
254            ($local:literal) => {
255              v.push(CssModuleReference::Local {
256                name: $local.into()
257              });
258            };
259          }
260          $(
261            insert!($value $(global: $global)? $(from $from)?);
262          )*
263
264          macro_rules! is_referenced {
265            ($ref: literal) => {
266              $ref
267            };
268            () => {
269              false
270            };
271          }
272
273          m.insert($key.into(), CssModuleExport {
274            name: $name.into(),
275            composes: v,
276            is_referenced: is_referenced!($($referenced)?)
277          });
278        )*
279        m
280      }
281    };
282  );
283
284  #[test]
285  pub fn test_border_spacing() {
286    minify_test(
287      r#"
288      .foo {
289        border-spacing: 0px;
290      }
291    "#,
292      indoc! {".foo{border-spacing:0}"
293      },
294    );
295    minify_test(
296      r#"
297      .foo {
298        border-spacing: 0px 0px;
299      }
300    "#,
301      indoc! {".foo{border-spacing:0}"
302      },
303    );
304
305    minify_test(
306      r#"
307      .foo {
308        border-spacing: 12px   0px;
309      }
310    "#,
311      indoc! {".foo{border-spacing:12px 0}"
312      },
313    );
314
315    minify_test(
316      r#"
317      .foo {
318        border-spacing: calc(3px * 2) calc(5px * 0);
319      }
320    "#,
321      indoc! {".foo{border-spacing:6px 0}"
322      },
323    );
324
325    minify_test(
326      r#"
327      .foo {
328        border-spacing: calc(3px * 2) max(0px, 8px);
329      }
330    "#,
331      indoc! {".foo{border-spacing:6px 8px}"
332      },
333    );
334
335    // TODO: The `<length>` in border-spacing cannot have a negative value,
336    // we may need to implement NonNegativeLength like Servo does.
337    // Servo Code: https://github.com/servo/servo/blob/08bc2d53579c9ab85415d4363888881b91df073b/components/style/values/specified/length.rs#L875
338    // CSSWG issue: https://lists.w3.org/Archives/Public/www-style/2008Sep/0161.html
339    // `border-spacing = <length> <length>?`
340    minify_test(
341      r#"
342      .foo {
343        border-spacing: -20px;
344      }
345    "#,
346      indoc! {".foo{border-spacing:-20px}"
347      },
348    );
349  }
350
351  #[test]
352  pub fn test_border() {
353    test(
354      r#"
355      .foo {
356        border-left: 2px solid red;
357        border-right: 2px solid red;
358        border-bottom: 2px solid red;
359        border-top: 2px solid red;
360      }
361    "#,
362      indoc! {r#"
363      .foo {
364        border: 2px solid red;
365      }
366    "#
367      },
368    );
369
370    test(
371      r#"
372      .foo {
373        border-left-color: red;
374        border-right-color: red;
375        border-bottom-color: red;
376        border-top-color: red;
377      }
378    "#,
379      indoc! {r#"
380      .foo {
381        border-color: red;
382      }
383    "#
384      },
385    );
386
387    test(
388      r#"
389      .foo {
390        border-left-width: thin;
391        border-right-width: thin;
392        border-bottom-width: thin;
393        border-top-width: thin;
394      }
395    "#,
396      indoc! {r#"
397      .foo {
398        border-width: thin;
399      }
400    "#
401      },
402    );
403
404    test(
405      r#"
406      .foo {
407        border-left-style: dotted;
408        border-right-style: dotted;
409        border-bottom-style: dotted;
410        border-top-style: dotted;
411      }
412    "#,
413      indoc! {r#"
414      .foo {
415        border-style: dotted;
416      }
417    "#
418      },
419    );
420
421    test(
422      r#"
423      .foo {
424        border-left-width: thin;
425        border-left-style: dotted;
426        border-left-color: red;
427      }
428    "#,
429      indoc! {r#"
430      .foo {
431        border-left: thin dotted red;
432      }
433    "#
434      },
435    );
436
437    test(
438      r#"
439      .foo {
440        border-left-width: thick;
441        border-left: thin dotted red;
442      }
443    "#,
444      indoc! {r#"
445      .foo {
446        border-left: thin dotted red;
447      }
448    "#
449      },
450    );
451
452    test(
453      r#"
454      .foo {
455        border-left-width: thick;
456        border: thin dotted red;
457      }
458    "#,
459      indoc! {r#"
460      .foo {
461        border: thin dotted red;
462      }
463    "#
464      },
465    );
466
467    test(
468      r#"
469      .foo {
470        border: thin dotted red;
471        border-right-width: thick;
472      }
473    "#,
474      indoc! {r#"
475      .foo {
476        border: thin dotted red;
477        border-right-width: thick;
478      }
479    "#
480      },
481    );
482
483    test(
484      r#"
485      .foo {
486        border: thin dotted red;
487        border-right: thick dotted red;
488      }
489    "#,
490      indoc! {r#"
491      .foo {
492        border: thin dotted red;
493        border-right-width: thick;
494      }
495    "#
496      },
497    );
498
499    test(
500      r#"
501      .foo {
502        border: thin dotted red;
503        border-right-width: thick;
504        border-right-style: solid;
505      }
506    "#,
507      indoc! {r#"
508      .foo {
509        border: thin dotted red;
510        border-right: thick solid red;
511      }
512    "#
513      },
514    );
515
516    test(
517      r#"
518      .foo {
519        border-top: thin dotted red;
520        border-block-start: thick solid green;
521      }
522    "#,
523      indoc! {r#"
524      .foo {
525        border-top: thin dotted red;
526        border-block-start: thick solid green;
527      }
528    "#
529      },
530    );
531
532    test(
533      r#"
534      .foo {
535        border: thin dotted red;
536        border-block-start-width: thick;
537        border-left-width: medium;
538      }
539    "#,
540      indoc! {r#"
541      .foo {
542        border: thin dotted red;
543        border-block-start-width: thick;
544        border-left-width: medium;
545      }
546    "#
547      },
548    );
549
550    test(
551      r#"
552      .foo {
553        border-block-start: thin dotted red;
554        border-inline-end: thin dotted red;
555      }
556    "#,
557      indoc! {r#"
558      .foo {
559        border-block-start: thin dotted red;
560        border-inline-end: thin dotted red;
561      }
562    "#
563      },
564    );
565
566    test(
567      r#"
568      .foo {
569        border-block-start-width: thin;
570        border-block-start-style: dotted;
571        border-block-start-color: red;
572        border-inline-end: thin dotted red;
573      }
574    "#,
575      indoc! {r#"
576      .foo {
577        border-block-start: thin dotted red;
578        border-inline-end: thin dotted red;
579      }
580    "#
581      },
582    );
583
584    test(
585      r#"
586      .foo {
587        border-block-start: thin dotted red;
588        border-block-end: thin dotted red;
589      }
590    "#,
591      indoc! {r#"
592      .foo {
593        border-block: thin dotted red;
594      }
595    "#
596      },
597    );
598
599    minify_test(
600      r#"
601      .foo {
602        border: none;
603      }
604    "#,
605      indoc! {".foo{border:none}"
606      },
607    );
608
609    minify_test(".foo { border-width: 0 0 1px; }", ".foo{border-width:0 0 1px}");
610    test(
611      r#"
612      .foo {
613        border-block-width: 1px;
614        border-inline-width: 1px;
615      }
616    "#,
617      indoc! {r#"
618      .foo {
619        border-width: 1px;
620      }
621    "#
622      },
623    );
624    test(
625      r#"
626      .foo {
627        border-block-start-width: 1px;
628        border-block-end-width: 1px;
629        border-inline-start-width: 1px;
630        border-inline-end-width: 1px;
631      }
632    "#,
633      indoc! {r#"
634      .foo {
635        border-width: 1px;
636      }
637    "#
638      },
639    );
640    test(
641      r#"
642      .foo {
643        border-block-start-width: 1px;
644        border-block-end-width: 1px;
645        border-inline-start-width: 2px;
646        border-inline-end-width: 2px;
647      }
648    "#,
649      indoc! {r#"
650      .foo {
651        border-block-width: 1px;
652        border-inline-width: 2px;
653      }
654    "#
655      },
656    );
657    test(
658      r#"
659      .foo {
660        border-block-start-width: 1px;
661        border-block-end-width: 1px;
662        border-inline-start-width: 2px;
663        border-inline-end-width: 3px;
664      }
665    "#,
666      indoc! {r#"
667      .foo {
668        border-block-width: 1px;
669        border-inline-width: 2px 3px;
670      }
671    "#
672      },
673    );
674
675    minify_test(
676      ".foo { border-bottom: 1px solid var(--spectrum-global-color-gray-200)}",
677      ".foo{border-bottom:1px solid var(--spectrum-global-color-gray-200)}",
678    );
679    test(
680      r#"
681      .foo {
682        border-width: 0;
683        border-bottom: var(--test, 1px) solid;
684      }
685    "#,
686      indoc! {r#"
687      .foo {
688        border-width: 0;
689        border-bottom: var(--test, 1px) solid;
690      }
691    "#
692      },
693    );
694
695    test(
696      r#"
697      .foo {
698        border: 1px solid black;
699        border-width: 1px 1px 0 0;
700      }
701    "#,
702      indoc! {r#"
703      .foo {
704        border: 1px solid #000;
705        border-width: 1px 1px 0 0;
706      }
707    "#},
708    );
709
710    test(
711      r#"
712      .foo {
713        border-top: 1px solid black;
714        border-bottom: 1px solid black;
715        border-left: 2px solid black;
716        border-right: 2px solid black;
717      }
718    "#,
719      indoc! {r#"
720      .foo {
721        border: 1px solid #000;
722        border-width: 1px 2px;
723      }
724    "#},
725    );
726
727    test(
728      r#"
729      .foo {
730        border-top: 1px solid black;
731        border-bottom: 1px solid black;
732        border-left: 2px solid black;
733        border-right: 1px solid black;
734      }
735    "#,
736      indoc! {r#"
737      .foo {
738        border: 1px solid #000;
739        border-left-width: 2px;
740      }
741    "#},
742    );
743
744    test(
745      r#"
746      .foo {
747        border-top: 1px solid black;
748        border-bottom: 1px solid black;
749        border-left: 1px solid red;
750        border-right: 1px solid red;
751      }
752    "#,
753      indoc! {r#"
754      .foo {
755        border: 1px solid #000;
756        border-color: #000 red;
757      }
758    "#},
759    );
760
761    test(
762      r#"
763      .foo {
764        border-block-start: 1px solid black;
765        border-block-end: 1px solid black;
766        border-inline-start: 1px solid red;
767        border-inline-end: 1px solid red;
768      }
769    "#,
770      indoc! {r#"
771      .foo {
772        border: 1px solid #000;
773        border-inline-color: red;
774      }
775    "#},
776    );
777
778    test(
779      r#"
780      .foo {
781        border-block-start: 1px solid black;
782        border-block-end: 1px solid black;
783        border-inline-start: 2px solid black;
784        border-inline-end: 2px solid black;
785      }
786    "#,
787      indoc! {r#"
788      .foo {
789        border: 1px solid #000;
790        border-inline-width: 2px;
791      }
792    "#},
793    );
794
795    test(
796      r#"
797      .foo {
798        border-block-start: 1px solid black;
799        border-block-end: 1px solid black;
800        border-inline-start: 2px solid red;
801        border-inline-end: 2px solid red;
802      }
803    "#,
804      indoc! {r#"
805      .foo {
806        border: 1px solid #000;
807        border-inline: 2px solid red;
808      }
809    "#},
810    );
811
812    test(
813      r#"
814      .foo {
815        border-block-start: 1px solid black;
816        border-block-end: 1px solid black;
817        border-inline-start: 2px solid red;
818        border-inline-end: 3px solid red;
819      }
820    "#,
821      indoc! {r#"
822      .foo {
823        border: 1px solid #000;
824        border-inline-start: 2px solid red;
825        border-inline-end: 3px solid red;
826      }
827    "#},
828    );
829
830    test(
831      r#"
832      .foo {
833        border-block-start: 2px solid black;
834        border-block-end: 1px solid black;
835        border-inline-start: 2px solid red;
836        border-inline-end: 2px solid red;
837      }
838    "#,
839      indoc! {r#"
840      .foo {
841        border: 2px solid red;
842        border-block-start-color: #000;
843        border-block-end: 1px solid #000;
844      }
845    "#},
846    );
847
848    test(
849      r#"
850      .foo {
851        border-block-start: 2px solid red;
852        border-block-end: 1px solid red;
853        border-inline-start: 2px solid red;
854        border-inline-end: 2px solid red;
855      }
856    "#,
857      indoc! {r#"
858      .foo {
859        border: 2px solid red;
860        border-block-end-width: 1px;
861      }
862    "#},
863    );
864
865    test(
866      r#"
867      .foo {
868        border-block-start: 2px solid red;
869        border-block-end: 2px solid red;
870        border-inline-start: 2px solid red;
871        border-inline-end: 1px solid red;
872      }
873    "#,
874      indoc! {r#"
875      .foo {
876        border: 2px solid red;
877        border-inline-end-width: 1px;
878      }
879    "#},
880    );
881
882    test(
883      r#"
884      .foo {
885        border: 1px solid currentColor;
886      }
887    "#,
888      indoc! {r#"
889      .foo {
890        border: 1px solid;
891      }
892    "#
893      },
894    );
895
896    minify_test(
897      r#"
898      .foo {
899        border: 1px solid currentColor;
900      }
901    "#,
902      ".foo{border:1px solid}",
903    );
904
905    prefix_test(
906      r#"
907      .foo {
908        border-block: 2px solid red;
909      }
910    "#,
911      indoc! {r#"
912      .foo {
913        border-top: 2px solid red;
914        border-bottom: 2px solid red;
915      }
916    "#
917      },
918      Browsers {
919        safari: Some(8 << 16),
920        ..Browsers::default()
921      },
922    );
923
924    prefix_test(
925      r#"
926      .foo {
927        border-block-start: 2px solid red;
928      }
929    "#,
930      indoc! {r#"
931      .foo {
932        border-top: 2px solid red;
933      }
934    "#
935      },
936      Browsers {
937        safari: Some(8 << 16),
938        ..Browsers::default()
939      },
940    );
941
942    prefix_test(
943      r#"
944      .foo {
945        border-block-end: 2px solid red;
946      }
947    "#,
948      indoc! {r#"
949      .foo {
950        border-bottom: 2px solid red;
951      }
952    "#
953      },
954      Browsers {
955        safari: Some(8 << 16),
956        ..Browsers::default()
957      },
958    );
959
960    prefix_test(
961      r#"
962      .foo {
963        border-inline: 2px solid red;
964      }
965    "#,
966      indoc! {r#"
967      .foo {
968        border-left: 2px solid red;
969        border-right: 2px solid red;
970      }
971    "#
972      },
973      Browsers {
974        safari: Some(8 << 16),
975        ..Browsers::default()
976      },
977    );
978
979    prefix_test(
980      r#"
981      .foo {
982        border-block-width: 2px;
983      }
984    "#,
985      indoc! {r#"
986      .foo {
987        border-block-start-width: 2px;
988        border-block-end-width: 2px;
989      }
990    "#
991      },
992      Browsers {
993        safari: Some(13 << 16),
994        ..Browsers::default()
995      },
996    );
997
998    prefix_test(
999      r#"
1000      .foo {
1001        border-block-width: 2px;
1002      }
1003    "#,
1004      indoc! {r#"
1005      .foo {
1006        border-block-width: 2px;
1007      }
1008    "#
1009      },
1010      Browsers {
1011        safari: Some(15 << 16),
1012        ..Browsers::default()
1013      },
1014    );
1015
1016    prefix_test(
1017      r#"
1018      .foo {
1019        border-inline-start: 2px solid red;
1020      }
1021    "#,
1022      indoc! {r#"
1023      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1024        border-left: 2px solid red;
1025      }
1026
1027      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1028        border-left: 2px solid red;
1029      }
1030
1031      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1032        border-right: 2px solid red;
1033      }
1034
1035      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1036        border-right: 2px solid red;
1037      }
1038    "#
1039      },
1040      Browsers {
1041        safari: Some(8 << 16),
1042        ..Browsers::default()
1043      },
1044    );
1045
1046    prefix_test(
1047      r#"
1048      .foo {
1049        border-inline-start-width: 2px;
1050      }
1051    "#,
1052      indoc! {r#"
1053      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1054        border-left-width: 2px;
1055      }
1056
1057      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1058        border-left-width: 2px;
1059      }
1060
1061      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1062        border-right-width: 2px;
1063      }
1064
1065      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1066        border-right-width: 2px;
1067      }
1068    "#
1069      },
1070      Browsers {
1071        safari: Some(8 << 16),
1072        ..Browsers::default()
1073      },
1074    );
1075
1076    prefix_test(
1077      r#"
1078      .foo {
1079        border-inline-end: 2px solid red;
1080      }
1081    "#,
1082      indoc! {r#"
1083      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1084        border-right: 2px solid red;
1085      }
1086
1087      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1088        border-right: 2px solid red;
1089      }
1090
1091      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1092        border-left: 2px solid red;
1093      }
1094
1095      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1096        border-left: 2px solid red;
1097      }
1098    "#
1099      },
1100      Browsers {
1101        safari: Some(8 << 16),
1102        ..Browsers::default()
1103      },
1104    );
1105
1106    prefix_test(
1107      r#"
1108      .foo {
1109        border-inline-start: 2px solid red;
1110        border-inline-end: 5px solid green;
1111      }
1112    "#,
1113      indoc! {r#"
1114      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1115        border-left: 2px solid red;
1116        border-right: 5px solid green;
1117      }
1118
1119      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1120        border-left: 2px solid red;
1121        border-right: 5px solid green;
1122      }
1123
1124      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1125        border-left: 5px solid green;
1126        border-right: 2px solid red;
1127      }
1128
1129      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1130        border-left: 5px solid green;
1131        border-right: 2px solid red;
1132      }
1133    "#
1134      },
1135      Browsers {
1136        safari: Some(8 << 16),
1137        ..Browsers::default()
1138      },
1139    );
1140
1141    prefix_test(
1142      r#"
1143      .foo {
1144        border-inline-start: 2px solid red;
1145        border-inline-end: 5px solid green;
1146      }
1147
1148      .bar {
1149        border-inline-start: 1px dotted gray;
1150        border-inline-end: 1px solid black;
1151      }
1152    "#,
1153      indoc! {r#"
1154      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1155        border-left: 2px solid red;
1156        border-right: 5px solid green;
1157      }
1158
1159      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1160        border-left: 2px solid red;
1161        border-right: 5px solid green;
1162      }
1163
1164      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1165        border-left: 5px solid green;
1166        border-right: 2px solid red;
1167      }
1168
1169      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1170        border-left: 5px solid green;
1171        border-right: 2px solid red;
1172      }
1173
1174      .bar:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1175        border-left: 1px dotted gray;
1176        border-right: 1px solid #000;
1177      }
1178
1179      .bar:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1180        border-left: 1px dotted gray;
1181        border-right: 1px solid #000;
1182      }
1183
1184      .bar:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1185        border-left: 1px solid #000;
1186        border-right: 1px dotted gray;
1187      }
1188
1189      .bar:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1190        border-left: 1px solid #000;
1191        border-right: 1px dotted gray;
1192      }
1193    "#
1194      },
1195      Browsers {
1196        safari: Some(8 << 16),
1197        ..Browsers::default()
1198      },
1199    );
1200
1201    prefix_test(
1202      r#"
1203      .foo {
1204        border-inline-width: 2px;
1205      }
1206    "#,
1207      indoc! {r#"
1208      .foo {
1209        border-left-width: 2px;
1210        border-right-width: 2px;
1211      }
1212    "#
1213      },
1214      Browsers {
1215        safari: Some(8 << 16),
1216        ..Browsers::default()
1217      },
1218    );
1219
1220    prefix_test(
1221      r#"
1222      .foo {
1223        border-inline-width: 2px;
1224      }
1225    "#,
1226      indoc! {r#"
1227      .foo {
1228        border-left-width: 2px;
1229        border-right-width: 2px;
1230      }
1231    "#
1232      },
1233      Browsers {
1234        safari: Some(8 << 16),
1235        ..Browsers::default()
1236      },
1237    );
1238
1239    prefix_test(
1240      r#"
1241      .foo {
1242        border-inline-style: solid;
1243      }
1244    "#,
1245      indoc! {r#"
1246      .foo {
1247        border-left-style: solid;
1248        border-right-style: solid;
1249      }
1250    "#
1251      },
1252      Browsers {
1253        safari: Some(8 << 16),
1254        ..Browsers::default()
1255      },
1256    );
1257
1258    prefix_test(
1259      r#"
1260      .foo {
1261        border-inline-color: red;
1262      }
1263    "#,
1264      indoc! {r#"
1265      .foo {
1266        border-left-color: red;
1267        border-right-color: red;
1268      }
1269    "#
1270      },
1271      Browsers {
1272        safari: Some(8 << 16),
1273        ..Browsers::default()
1274      },
1275    );
1276
1277    prefix_test(
1278      r#"
1279      .foo {
1280        border-inline-end: var(--test);
1281      }
1282    "#,
1283      indoc! {r#"
1284      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1285        border-right: var(--test);
1286      }
1287
1288      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1289        border-right: var(--test);
1290      }
1291
1292      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1293        border-left: var(--test);
1294      }
1295
1296      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1297        border-left: var(--test);
1298      }
1299    "#
1300      },
1301      Browsers {
1302        safari: Some(8 << 16),
1303        ..Browsers::default()
1304      },
1305    );
1306
1307    prefix_test(
1308      r#"
1309      .foo {
1310        border-inline-start: var(--start);
1311        border-inline-end: var(--end);
1312      }
1313    "#,
1314      indoc! {r#"
1315      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1316        border-left: var(--start);
1317        border-right: var(--end);
1318      }
1319
1320      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1321        border-left: var(--start);
1322        border-right: var(--end);
1323      }
1324
1325      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1326        border-right: var(--start);
1327        border-left: var(--end);
1328      }
1329
1330      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1331        border-right: var(--start);
1332        border-left: var(--end);
1333      }
1334    "#
1335      },
1336      Browsers {
1337        safari: Some(8 << 16),
1338        ..Browsers::default()
1339      },
1340    );
1341
1342    for prop in &[
1343      "border-inline-start-color",
1344      "border-inline-end-color",
1345      "border-block-start-color",
1346      "border-block-end-color",
1347      "border-top-color",
1348      "border-bottom-color",
1349      "border-left-color",
1350      "border-right-color",
1351      "border-color",
1352      "border-block-color",
1353      "border-inline-color",
1354    ] {
1355      prefix_test(
1356        &format!(
1357          r#"
1358        .foo {{
1359          {}: lab(40% 56.6 39);
1360        }}
1361      "#,
1362          prop
1363        ),
1364        &format!(
1365          indoc! {r#"
1366        .foo {{
1367          {}: #b32323;
1368          {}: lab(40% 56.6 39);
1369        }}
1370      "#},
1371          prop, prop
1372        ),
1373        Browsers {
1374          chrome: Some(90 << 16),
1375          ..Browsers::default()
1376        },
1377      );
1378    }
1379
1380    for prop in &[
1381      "border",
1382      "border-inline",
1383      "border-block",
1384      "border-left",
1385      "border-right",
1386      "border-top",
1387      "border-bottom",
1388      "border-block-start",
1389      "border-block-end",
1390      "border-inline-start",
1391      "border-inline-end",
1392    ] {
1393      prefix_test(
1394        &format!(
1395          r#"
1396        .foo {{
1397          {}: 2px solid lab(40% 56.6 39);
1398        }}
1399      "#,
1400          prop
1401        ),
1402        &format!(
1403          indoc! {r#"
1404        .foo {{
1405          {}: 2px solid #b32323;
1406          {}: 2px solid lab(40% 56.6 39);
1407        }}
1408      "#},
1409          prop, prop
1410        ),
1411        Browsers {
1412          chrome: Some(90 << 16),
1413          ..Browsers::default()
1414        },
1415      );
1416    }
1417
1418    for prop in &[
1419      "border",
1420      "border-inline",
1421      "border-block",
1422      "border-left",
1423      "border-right",
1424      "border-top",
1425      "border-bottom",
1426      "border-block-start",
1427      "border-block-end",
1428      "border-inline-start",
1429      "border-inline-end",
1430    ] {
1431      prefix_test(
1432        &format!(
1433          r#"
1434        .foo {{
1435          {}: var(--border-width) solid lab(40% 56.6 39);
1436        }}
1437      "#,
1438          prop
1439        ),
1440        &format!(
1441          indoc! {r#"
1442        .foo {{
1443          {}: var(--border-width) solid #b32323;
1444        }}
1445
1446        @supports (color: lab(0% 0 0)) {{
1447          .foo {{
1448            {}: var(--border-width) solid lab(40% 56.6 39);
1449          }}
1450        }}
1451      "#},
1452          prop, prop
1453        ),
1454        Browsers {
1455          chrome: Some(90 << 16),
1456          ..Browsers::default()
1457        },
1458      );
1459    }
1460
1461    prefix_test(
1462      r#"
1463      .foo {
1464        border-inline-start-color: lab(40% 56.6 39);
1465      }
1466    "#,
1467      indoc! {r#"
1468      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1469        border-left-color: #b32323;
1470        border-left-color: lab(40% 56.6 39);
1471      }
1472
1473      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1474        border-left-color: #b32323;
1475        border-left-color: lab(40% 56.6 39);
1476      }
1477
1478      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1479        border-right-color: #b32323;
1480        border-right-color: lab(40% 56.6 39);
1481      }
1482
1483      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1484        border-right-color: #b32323;
1485        border-right-color: lab(40% 56.6 39);
1486      }
1487    "#},
1488      Browsers {
1489        safari: Some(8 << 16),
1490        ..Browsers::default()
1491      },
1492    );
1493
1494    prefix_test(
1495      r#"
1496      .foo {
1497        border-inline-end-color: lab(40% 56.6 39);
1498      }
1499    "#,
1500      indoc! {r#"
1501      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1502        border-right-color: #b32323;
1503        border-right-color: lab(40% 56.6 39);
1504      }
1505
1506      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1507        border-right-color: #b32323;
1508        border-right-color: lab(40% 56.6 39);
1509      }
1510
1511      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1512        border-left-color: #b32323;
1513        border-left-color: lab(40% 56.6 39);
1514      }
1515
1516      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1517        border-left-color: #b32323;
1518        border-left-color: lab(40% 56.6 39);
1519      }
1520    "#},
1521      Browsers {
1522        safari: Some(8 << 16),
1523        ..Browsers::default()
1524      },
1525    );
1526
1527    prefix_test(
1528      r#"
1529      .foo {
1530        border-inline-start-color: lab(40% 56.6 39);
1531        border-inline-end-color: lch(50.998% 135.363 338);
1532      }
1533    "#,
1534      indoc! {r#"
1535      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1536        border-left-color: #b32323;
1537        border-left-color: lab(40% 56.6 39);
1538        border-right-color: #ee00be;
1539        border-right-color: lch(50.998% 135.363 338);
1540      }
1541
1542      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1543        border-left-color: #b32323;
1544        border-left-color: lab(40% 56.6 39);
1545        border-right-color: #ee00be;
1546        border-right-color: lch(50.998% 135.363 338);
1547      }
1548
1549      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1550        border-left-color: #ee00be;
1551        border-left-color: lch(50.998% 135.363 338);
1552        border-right-color: #b32323;
1553        border-right-color: lab(40% 56.6 39);
1554      }
1555
1556      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1557        border-left-color: #ee00be;
1558        border-left-color: lch(50.998% 135.363 338);
1559        border-right-color: #b32323;
1560        border-right-color: lab(40% 56.6 39);
1561      }
1562    "#},
1563      Browsers {
1564        safari: Some(8 << 16),
1565        ..Browsers::default()
1566      },
1567    );
1568
1569    prefix_test(
1570      r#"
1571      .foo {
1572        border-inline-start-color: lab(40% 56.6 39);
1573        border-inline-end-color: lch(50.998% 135.363 338);
1574      }
1575    "#,
1576      indoc! {r#"
1577      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1578        border-left-color: #b32323;
1579        border-left-color: color(display-p3 .643308 .192455 .167712);
1580        border-left-color: lab(40% 56.6 39);
1581        border-right-color: #ee00be;
1582        border-right-color: color(display-p3 .972962 -.362078 .804206);
1583        border-right-color: lch(50.998% 135.363 338);
1584      }
1585
1586      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1587        border-left-color: #ee00be;
1588        border-left-color: color(display-p3 .972962 -.362078 .804206);
1589        border-left-color: lch(50.998% 135.363 338);
1590        border-right-color: #b32323;
1591        border-right-color: color(display-p3 .643308 .192455 .167712);
1592        border-right-color: lab(40% 56.6 39);
1593      }
1594    "#},
1595      Browsers {
1596        chrome: Some(8 << 16),
1597        safari: Some(14 << 16),
1598        ..Browsers::default()
1599      },
1600    );
1601
1602    prefix_test(
1603      r#"
1604      .foo {
1605        border-inline-start: 2px solid lab(40% 56.6 39);
1606      }
1607    "#,
1608      indoc! {r#"
1609      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1610        border-left: 2px solid #b32323;
1611        border-left: 2px solid lab(40% 56.6 39);
1612      }
1613
1614      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1615        border-left: 2px solid #b32323;
1616        border-left: 2px solid lab(40% 56.6 39);
1617      }
1618
1619      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1620        border-right: 2px solid #b32323;
1621        border-right: 2px solid lab(40% 56.6 39);
1622      }
1623
1624      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1625        border-right: 2px solid #b32323;
1626        border-right: 2px solid lab(40% 56.6 39);
1627      }
1628    "#},
1629      Browsers {
1630        safari: Some(8 << 16),
1631        ..Browsers::default()
1632      },
1633    );
1634
1635    prefix_test(
1636      r#"
1637      .foo {
1638        border-inline-end: 2px solid lab(40% 56.6 39);
1639      }
1640    "#,
1641      indoc! {r#"
1642      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1643        border-right: 2px solid #b32323;
1644        border-right: 2px solid lab(40% 56.6 39);
1645      }
1646
1647      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1648        border-right: 2px solid #b32323;
1649        border-right: 2px solid lab(40% 56.6 39);
1650      }
1651
1652      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1653        border-left: 2px solid #b32323;
1654        border-left: 2px solid lab(40% 56.6 39);
1655      }
1656
1657      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1658        border-left: 2px solid #b32323;
1659        border-left: 2px solid lab(40% 56.6 39);
1660      }
1661    "#},
1662      Browsers {
1663        safari: Some(8 << 16),
1664        ..Browsers::default()
1665      },
1666    );
1667
1668    prefix_test(
1669      r#"
1670      .foo {
1671        border-inline-end: var(--border-width) solid lab(40% 56.6 39);
1672      }
1673    "#,
1674      indoc! {r#"
1675      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1676        border-right: var(--border-width) solid #b32323;
1677      }
1678
1679      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1680        border-right: var(--border-width) solid #b32323;
1681      }
1682
1683      @supports (color: lab(0% 0 0)) {
1684        .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
1685          border-right: var(--border-width) solid lab(40% 56.6 39);
1686        }
1687      }
1688
1689      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1690        border-left: var(--border-width) solid #b32323;
1691      }
1692
1693      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1694        border-left: var(--border-width) solid #b32323;
1695      }
1696
1697      @supports (color: lab(0% 0 0)) {
1698        .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
1699          border-left: var(--border-width) solid lab(40% 56.6 39);
1700        }
1701      }
1702    "#},
1703      Browsers {
1704        safari: Some(8 << 16),
1705        ..Browsers::default()
1706      },
1707    );
1708
1709    prefix_test(
1710      r#"
1711      .foo {
1712        border-inline-start: 2px solid red;
1713        border-inline-end: 2px solid red;
1714      }
1715    "#,
1716      indoc! {r#"
1717      .foo {
1718        border-inline-start: 2px solid red;
1719        border-inline-end: 2px solid red;
1720      }
1721    "#
1722      },
1723      Browsers {
1724        safari: Some(13 << 16),
1725        ..Browsers::default()
1726      },
1727    );
1728
1729    prefix_test(
1730      r#"
1731      .foo {
1732        border-inline-start: 2px solid red;
1733        border-inline-end: 2px solid red;
1734      }
1735    "#,
1736      indoc! {r#"
1737      .foo {
1738        border-inline: 2px solid red;
1739      }
1740    "#
1741      },
1742      Browsers {
1743        safari: Some(15 << 16),
1744        ..Browsers::default()
1745      },
1746    );
1747
1748    prefix_test(
1749      r#"
1750      .foo {
1751        border-width: 22px;
1752        border-width: max(2cqw, 22px);
1753      }
1754    "#,
1755      indoc! {r#"
1756      .foo {
1757        border-width: 22px;
1758        border-width: max(2cqw, 22px);
1759      }
1760    "#
1761      },
1762      Browsers {
1763        safari: Some(14 << 16),
1764        ..Browsers::default()
1765      },
1766    );
1767    prefix_test(
1768      r#"
1769      .foo {
1770        border-width: 22px;
1771        border-width: max(2cqw, 22px);
1772      }
1773    "#,
1774      indoc! {r#"
1775      .foo {
1776        border-width: max(2cqw, 22px);
1777      }
1778    "#
1779      },
1780      Browsers {
1781        safari: Some(16 << 16),
1782        ..Browsers::default()
1783      },
1784    );
1785    prefix_test(
1786      r#"
1787      .foo {
1788        border-color: #4263eb;
1789        border-color: color(display-p3 0 .5 1);
1790      }
1791    "#,
1792      indoc! {r#"
1793      .foo {
1794        border-color: #4263eb;
1795        border-color: color(display-p3 0 .5 1);
1796      }
1797    "#
1798      },
1799      Browsers {
1800        chrome: Some(99 << 16),
1801        ..Browsers::default()
1802      },
1803    );
1804    prefix_test(
1805      r#"
1806      .foo {
1807        border-color: #4263eb;
1808        border-color: color(display-p3 0 .5 1);
1809      }
1810    "#,
1811      indoc! {r#"
1812      .foo {
1813        border-color: color(display-p3 0 .5 1);
1814      }
1815    "#
1816      },
1817      Browsers {
1818        safari: Some(16 << 16),
1819        ..Browsers::default()
1820      },
1821    );
1822    prefix_test(
1823      r#"
1824      .foo {
1825        border: 1px solid #4263eb;
1826        border-color: color(display-p3 0 .5 1);
1827      }
1828    "#,
1829      indoc! {r#"
1830      .foo {
1831        border: 1px solid #4263eb;
1832        border-color: color(display-p3 0 .5 1);
1833      }
1834    "#
1835      },
1836      Browsers {
1837        chrome: Some(99 << 16),
1838        ..Browsers::default()
1839      },
1840    );
1841    prefix_test(
1842      r#"
1843      .foo {
1844        border: 1px solid #4263eb;
1845        border-color: color(display-p3 0 .5 1);
1846      }
1847    "#,
1848      indoc! {r#"
1849      .foo {
1850        border: 1px solid color(display-p3 0 .5 1);
1851      }
1852    "#
1853      },
1854      Browsers {
1855        safari: Some(16 << 16),
1856        ..Browsers::default()
1857      },
1858    );
1859    prefix_test(
1860      r#"
1861      .foo {
1862        border-color: var(--fallback);
1863        border-color: color(display-p3 0 .5 1);
1864      }
1865    "#,
1866      indoc! {r#"
1867      .foo {
1868        border-color: var(--fallback);
1869        border-color: color(display-p3 0 .5 1);
1870      }
1871    "#
1872      },
1873      Browsers {
1874        chrome: Some(99 << 16),
1875        ..Browsers::default()
1876      },
1877    );
1878  }
1879
1880  #[test]
1881  pub fn test_border_image() {
1882    test(
1883      r#"
1884      .foo {
1885        border-image: url(test.png) 60;
1886      }
1887    "#,
1888      indoc! {r#"
1889      .foo {
1890        border-image: url("test.png") 60;
1891      }
1892    "#
1893      },
1894    );
1895
1896    test(
1897      r#"
1898      .foo {
1899        border-image: url(test.png) 60;
1900        border-image-source: url(foo.png);
1901      }
1902    "#,
1903      indoc! {r#"
1904      .foo {
1905        border-image: url("foo.png") 60;
1906      }
1907    "#
1908      },
1909    );
1910
1911    test(
1912      r#"
1913      .foo {
1914        border-image-source: url(foo.png);
1915        border-image-slice: 10 40 10 40 fill;
1916        border-image-width: 10px;
1917        border-image-outset: 0;
1918        border-image-repeat: round round;
1919      }
1920    "#,
1921      indoc! {r#"
1922      .foo {
1923        border-image: url("foo.png") 10 40 fill / 10px round;
1924      }
1925    "#
1926      },
1927    );
1928
1929    test(
1930      r#"
1931      .foo {
1932        border-image: url(foo.png) 60;
1933        border-image-source: var(--test);
1934      }
1935    "#,
1936      indoc! {r#"
1937      .foo {
1938        border-image: url("foo.png") 60;
1939        border-image-source: var(--test);
1940      }
1941    "#
1942      },
1943    );
1944
1945    test(
1946      r#"
1947      .foo {
1948        -webkit-border-image: url("test.png") 60;
1949      }
1950    "#,
1951      indoc! {r#"
1952      .foo {
1953        -webkit-border-image: url("test.png") 60;
1954      }
1955    "#
1956      },
1957    );
1958
1959    test(
1960      r#"
1961      .foo {
1962        -webkit-border-image: url("test.png") 60;
1963        border-image: url("test.png") 60;
1964      }
1965    "#,
1966      indoc! {r#"
1967      .foo {
1968        -webkit-border-image: url("test.png") 60;
1969        border-image: url("test.png") 60;
1970      }
1971    "#
1972      },
1973    );
1974
1975    test(
1976      r#"
1977      .foo {
1978        -webkit-border-image: url("test.png") 60;
1979        border-image-source: url(foo.png);
1980      }
1981    "#,
1982      indoc! {r#"
1983      .foo {
1984        -webkit-border-image: url("test.png") 60;
1985        border-image-source: url("foo.png");
1986      }
1987    "#
1988      },
1989    );
1990
1991    test(
1992      r#"
1993      .foo {
1994        border: 1px solid red;
1995        border-image: url(test.png) 60;
1996      }
1997    "#,
1998      indoc! {r#"
1999      .foo {
2000        border: 1px solid red;
2001        border-image: url("test.png") 60;
2002      }
2003    "#
2004      },
2005    );
2006
2007    test(
2008      r#"
2009      .foo {
2010        border-image: url(test.png) 60;
2011        border: 1px solid red;
2012      }
2013    "#,
2014      indoc! {r#"
2015      .foo {
2016        border: 1px solid red;
2017      }
2018    "#
2019      },
2020    );
2021
2022    test(
2023      r#"
2024      .foo {
2025        border: 1px solid red;
2026        border-image: var(--border-image);
2027      }
2028    "#,
2029      indoc! {r#"
2030      .foo {
2031        border: 1px solid red;
2032        border-image: var(--border-image);
2033      }
2034    "#
2035      },
2036    );
2037
2038    prefix_test(
2039      r#"
2040      .foo {
2041        border-image: url("test.png") 60;
2042      }
2043    "#,
2044      indoc! {r#"
2045      .foo {
2046        -webkit-border-image: url("test.png") 60;
2047        -moz-border-image: url("test.png") 60;
2048        -o-border-image: url("test.png") 60;
2049        border-image: url("test.png") 60;
2050      }
2051    "#
2052      },
2053      Browsers {
2054        safari: Some(4 << 16),
2055        firefox: Some(4 << 16),
2056        opera: Some(12 << 16),
2057        ..Browsers::default()
2058      },
2059    );
2060
2061    prefix_test(
2062      r#"
2063      .foo {
2064        border-image: url(foo.png) 10 40 fill / 10px round;
2065      }
2066    "#,
2067      indoc! {r#"
2068      .foo {
2069        border-image: url("foo.png") 10 40 fill / 10px round;
2070      }
2071    "#
2072      },
2073      Browsers {
2074        safari: Some(4 << 16),
2075        firefox: Some(4 << 16),
2076        opera: Some(12 << 16),
2077        ..Browsers::default()
2078      },
2079    );
2080
2081    prefix_test(
2082      r#"
2083      .foo {
2084        border-image: var(--test) 60;
2085      }
2086    "#,
2087      indoc! {r#"
2088      .foo {
2089        -webkit-border-image: var(--test) 60;
2090        -moz-border-image: var(--test) 60;
2091        -o-border-image: var(--test) 60;
2092        border-image: var(--test) 60;
2093      }
2094    "#
2095      },
2096      Browsers {
2097        safari: Some(4 << 16),
2098        firefox: Some(4 << 16),
2099        opera: Some(12 << 16),
2100        ..Browsers::default()
2101      },
2102    );
2103
2104    prefix_test(
2105      r#"
2106      .foo {
2107        -webkit-border-image: url(foo.png) 60;
2108        -moz-border-image: url(foo.png) 60;
2109        -o-border-image: url(foo.png) 60;
2110        border-image: url(foo.png) 60;
2111      }
2112    "#,
2113      indoc! {r#"
2114      .foo {
2115        border-image: url("foo.png") 60;
2116      }
2117    "#
2118      },
2119      Browsers {
2120        chrome: Some(15 << 16),
2121        ..Browsers::default()
2122      },
2123    );
2124
2125    prefix_test(
2126      r#"
2127      .foo {
2128        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 60;
2129      }
2130    "#,
2131      indoc! {r#"
2132      .foo {
2133        -webkit-border-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0f0e), to(#7773ff)) 60;
2134        -webkit-border-image: -webkit-linear-gradient(#ff0f0e, #7773ff) 60;
2135        border-image: linear-gradient(#ff0f0e, #7773ff) 60;
2136        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 60;
2137      }
2138    "#
2139      },
2140      Browsers {
2141        chrome: Some(8 << 16),
2142        ..Browsers::default()
2143      },
2144    );
2145
2146    prefix_test(
2147      r#"
2148      .foo {
2149        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 60;
2150      }
2151    "#,
2152      indoc! {r#"
2153      .foo {
2154        -webkit-border-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0f0e), to(#7773ff)) 60;
2155        -webkit-border-image: -webkit-linear-gradient(#ff0f0e, #7773ff) 60;
2156        -moz-border-image: -moz-linear-gradient(#ff0f0e, #7773ff) 60;
2157        border-image: linear-gradient(#ff0f0e, #7773ff) 60;
2158        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 60;
2159      }
2160    "#
2161      },
2162      Browsers {
2163        chrome: Some(8 << 16),
2164        firefox: Some(4 << 16),
2165        ..Browsers::default()
2166      },
2167    );
2168
2169    prefix_test(
2170      r#"
2171      .foo {
2172        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 60;
2173      }
2174    "#,
2175      indoc! {r#"
2176      .foo {
2177        border-image: -webkit-linear-gradient(#ff0f0e, #7773ff) 60;
2178        border-image: -moz-linear-gradient(#ff0f0e, #7773ff) 60;
2179        border-image: linear-gradient(#ff0f0e, #7773ff) 60;
2180        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 60;
2181      }
2182    "#
2183      },
2184      Browsers {
2185        chrome: Some(15 << 16),
2186        firefox: Some(15 << 16),
2187        ..Browsers::default()
2188      },
2189    );
2190
2191    prefix_test(
2192      r#"
2193      .foo {
2194        border-image-source: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
2195      }
2196    "#,
2197      indoc! {r#"
2198      .foo {
2199        border-image-source: -webkit-linear-gradient(#ff0f0e, #7773ff);
2200        border-image-source: linear-gradient(#ff0f0e, #7773ff);
2201        border-image-source: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
2202      }
2203    "#
2204      },
2205      Browsers {
2206        chrome: Some(15 << 16),
2207        ..Browsers::default()
2208      },
2209    );
2210
2211    prefix_test(
2212      r#"
2213      .foo {
2214        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) var(--foo);
2215      }
2216    "#,
2217      indoc! {r#"
2218      .foo {
2219        border-image: linear-gradient(#ff0f0e, #7773ff) var(--foo);
2220      }
2221
2222      @supports (color: lab(0% 0 0)) {
2223        .foo {
2224          border-image: linear-gradient(lab(56.208% 94.4644 98.8928), lab(51% 70.4544 -115.586)) var(--foo);
2225        }
2226      }
2227    "#
2228      },
2229      Browsers {
2230        chrome: Some(90 << 16),
2231        ..Browsers::default()
2232      },
2233    );
2234
2235    prefix_test(
2236      r#"
2237      .foo {
2238        border-image-source: linear-gradient(red, green);
2239        border-image-source: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
2240      }
2241    "#,
2242      indoc! {r#"
2243      .foo {
2244        border-image-source: linear-gradient(red, green);
2245        border-image-source: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
2246      }
2247    "#
2248      },
2249      Browsers {
2250        chrome: Some(95 << 16),
2251        ..Browsers::default()
2252      },
2253    );
2254
2255    prefix_test(
2256      r#"
2257      .foo {
2258        border-image-source: linear-gradient(red, green);
2259        border-image-source: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
2260      }
2261    "#,
2262      indoc! {r#"
2263      .foo {
2264        border-image-source: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
2265      }
2266    "#
2267      },
2268      Browsers {
2269        chrome: Some(112 << 16),
2270        ..Browsers::default()
2271      },
2272    );
2273
2274    prefix_test(
2275      r#"
2276      .foo {
2277        border-image: linear-gradient(red, green);
2278        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
2279      }
2280    "#,
2281      indoc! {r#"
2282      .foo {
2283        border-image: linear-gradient(red, green);
2284        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
2285      }
2286    "#
2287      },
2288      Browsers {
2289        chrome: Some(95 << 16),
2290        ..Browsers::default()
2291      },
2292    );
2293
2294    prefix_test(
2295      r#"
2296      .foo {
2297        border-image: var(--fallback);
2298        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
2299      }
2300    "#,
2301      indoc! {r#"
2302      .foo {
2303        border-image: var(--fallback);
2304        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
2305      }
2306    "#
2307      },
2308      Browsers {
2309        chrome: Some(95 << 16),
2310        ..Browsers::default()
2311      },
2312    );
2313
2314    prefix_test(
2315      r#"
2316      .foo {
2317        border-image: url("fallback.png") 10 40 fill / 10px;
2318        border-image: url("main.png") 10 40 fill / 10px space;
2319      }
2320    "#,
2321      indoc! {r#"
2322      .foo {
2323        border-image: url("fallback.png") 10 40 fill / 10px;
2324        border-image: url("main.png") 10 40 fill / 10px space;
2325      }
2326    "#
2327      },
2328      Browsers {
2329        chrome: Some(50 << 16),
2330        ..Browsers::default()
2331      },
2332    );
2333
2334    prefix_test(
2335      r#"
2336      .foo {
2337        border-image: url("fallback.png") 10 40 fill / 10px;
2338        border-image: url("main.png") 10 40 fill / 10px space;
2339      }
2340    "#,
2341      indoc! {r#"
2342      .foo {
2343        border-image: url("main.png") 10 40 fill / 10px space;
2344      }
2345    "#
2346      },
2347      Browsers {
2348        chrome: Some(56 << 16),
2349        ..Browsers::default()
2350      },
2351    );
2352
2353    minify_test(".foo { border: none green }", ".foo{border:green}");
2354  }
2355
2356  #[test]
2357  pub fn test_border_radius() {
2358    test(
2359      r#"
2360      .foo {
2361        border-radius: 10px 100px 10px 100px;
2362      }
2363    "#,
2364      indoc! {r#"
2365      .foo {
2366        border-radius: 10px 100px;
2367      }
2368    "#
2369      },
2370    );
2371
2372    test(
2373      r#"
2374      .foo {
2375        border-radius: 10px 100px 10px 100px / 120px 120px;
2376      }
2377    "#,
2378      indoc! {r#"
2379      .foo {
2380        border-radius: 10px 100px / 120px;
2381      }
2382    "#
2383      },
2384    );
2385
2386    test(
2387      r#"
2388      .foo {
2389        border-top-left-radius: 10px 120px;
2390        border-top-right-radius: 100px 120px;
2391        border-bottom-right-radius: 100px 120px;
2392        border-bottom-left-radius: 10px 120px;
2393      }
2394    "#,
2395      indoc! {r#"
2396      .foo {
2397        border-radius: 10px 100px 100px 10px / 120px;
2398      }
2399    "#
2400      },
2401    );
2402
2403    test(
2404      r#"
2405      .foo {
2406        border-top-left-radius: 4px 2px;
2407        border-top-right-radius: 3px 4px;
2408        border-bottom-right-radius: 6px 2px;
2409        border-bottom-left-radius: 3px 4px;
2410      }
2411    "#,
2412      indoc! {r#"
2413      .foo {
2414        border-radius: 4px 3px 6px / 2px 4px;
2415      }
2416    "#
2417      },
2418    );
2419
2420    test(
2421      r#"
2422      .foo {
2423        border-top-left-radius: 1% 2%;
2424        border-top-right-radius: 3% 4%;
2425        border-bottom-right-radius: 5% 6%;
2426        border-bottom-left-radius: 7% 8%;
2427      }
2428    "#,
2429      indoc! {r#"
2430      .foo {
2431        border-radius: 1% 3% 5% 7% / 2% 4% 6% 8%;
2432      }
2433    "#
2434      },
2435    );
2436
2437    test(
2438      r#"
2439      .foo {
2440        border-radius: 10px 100px 10px 100px / 120px 120px;
2441        border-start-start-radius: 10px;
2442      }
2443    "#,
2444      indoc! {r#"
2445      .foo {
2446        border-radius: 10px 100px / 120px;
2447        border-start-start-radius: 10px;
2448      }
2449    "#
2450      },
2451    );
2452
2453    test(
2454      r#"
2455      .foo {
2456        border-start-start-radius: 10px;
2457        border-radius: 10px 100px 10px 100px / 120px 120px;
2458      }
2459    "#,
2460      indoc! {r#"
2461      .foo {
2462        border-radius: 10px 100px / 120px;
2463      }
2464    "#
2465      },
2466    );
2467
2468    test(
2469      r#"
2470      .foo {
2471        border-top-left-radius: 10px 120px;
2472        border-top-right-radius: 100px 120px;
2473        border-start-start-radius: 10px;
2474        border-bottom-right-radius: 100px 120px;
2475        border-bottom-left-radius: 10px 120px;
2476      }
2477    "#,
2478      indoc! {r#"
2479      .foo {
2480        border-top-left-radius: 10px 120px;
2481        border-top-right-radius: 100px 120px;
2482        border-start-start-radius: 10px;
2483        border-bottom-right-radius: 100px 120px;
2484        border-bottom-left-radius: 10px 120px;
2485      }
2486    "#
2487      },
2488    );
2489
2490    test(
2491      r#"
2492      .foo {
2493        border-radius: 10px;
2494        border-top-left-radius: 20px;
2495      }
2496    "#,
2497      indoc! {r#"
2498      .foo {
2499        border-radius: 20px 10px 10px;
2500      }
2501    "#
2502      },
2503    );
2504
2505    test(
2506      r#"
2507      .foo {
2508        border-radius: 10px;
2509        border-top-left-radius: var(--test);
2510      }
2511    "#,
2512      indoc! {r#"
2513      .foo {
2514        border-radius: 10px;
2515        border-top-left-radius: var(--test);
2516      }
2517    "#
2518      },
2519    );
2520
2521    test(
2522      r#"
2523      .foo {
2524        -webkit-border-radius: 10px 100px 10px 100px;
2525        -moz-border-radius: 10px 100px 10px 100px;
2526        border-radius: 10px 100px 10px 100px;
2527      }
2528    "#,
2529      indoc! {r#"
2530      .foo {
2531        -webkit-border-radius: 10px 100px;
2532        -moz-border-radius: 10px 100px;
2533        border-radius: 10px 100px;
2534      }
2535    "#
2536      },
2537    );
2538
2539    test(
2540      r#"
2541      .foo {
2542        -webkit-border-radius: 10px 100px 10px 100px;
2543        -moz-border-radius: 20px;
2544        border-radius: 30px;
2545      }
2546    "#,
2547      indoc! {r#"
2548      .foo {
2549        -webkit-border-radius: 10px 100px;
2550        -moz-border-radius: 20px;
2551        border-radius: 30px;
2552      }
2553    "#
2554      },
2555    );
2556
2557    test(
2558      r#"
2559      .foo {
2560        -webkit-border-top-left-radius: 10px;
2561        -moz-border-top-left-radius: 10px;
2562        border-top-left-radius: 10px;
2563      }
2564    "#,
2565      indoc! {r#"
2566      .foo {
2567        -webkit-border-top-left-radius: 10px;
2568        -moz-border-top-left-radius: 10px;
2569        border-top-left-radius: 10px;
2570      }
2571    "#
2572      },
2573    );
2574
2575    prefix_test(
2576      r#"
2577      .foo {
2578        border-radius: 30px;
2579      }
2580    "#,
2581      indoc! {r#"
2582      .foo {
2583        -webkit-border-radius: 30px;
2584        -moz-border-radius: 30px;
2585        border-radius: 30px;
2586      }
2587    "#
2588      },
2589      Browsers {
2590        safari: Some(4 << 16),
2591        firefox: Some(3 << 16),
2592        ..Browsers::default()
2593      },
2594    );
2595
2596    prefix_test(
2597      r#"
2598      .foo {
2599        border-top-left-radius: 30px;
2600      }
2601    "#,
2602      indoc! {r#"
2603      .foo {
2604        -webkit-border-top-left-radius: 30px;
2605        -moz-border-top-left-radius: 30px;
2606        border-top-left-radius: 30px;
2607      }
2608    "#
2609      },
2610      Browsers {
2611        safari: Some(4 << 16),
2612        firefox: Some(3 << 16),
2613        ..Browsers::default()
2614      },
2615    );
2616
2617    prefix_test(
2618      r#"
2619      .foo {
2620        -webkit-border-radius: 30px;
2621        -moz-border-radius: 30px;
2622        border-radius: 30px;
2623      }
2624    "#,
2625      indoc! {r#"
2626      .foo {
2627        border-radius: 30px;
2628      }
2629    "#
2630      },
2631      Browsers {
2632        safari: Some(14 << 16),
2633        firefox: Some(46 << 16),
2634        ..Browsers::default()
2635      },
2636    );
2637
2638    prefix_test(
2639      r#"
2640      .foo {
2641        -webkit-border-top-left-radius: 30px;
2642        -moz-border-top-left-radius: 30px;
2643        border-top-left-radius: 30px;
2644      }
2645    "#,
2646      indoc! {r#"
2647      .foo {
2648        border-top-left-radius: 30px;
2649      }
2650    "#
2651      },
2652      Browsers {
2653        safari: Some(14 << 16),
2654        firefox: Some(46 << 16),
2655        ..Browsers::default()
2656      },
2657    );
2658
2659    prefix_test(
2660      r#"
2661      .foo {
2662        -webkit-border-radius: 30px;
2663        -moz-border-radius: 30px;
2664      }
2665    "#,
2666      indoc! {r#"
2667      .foo {
2668        -webkit-border-radius: 30px;
2669        -moz-border-radius: 30px;
2670      }
2671    "#
2672      },
2673      Browsers {
2674        safari: Some(14 << 16),
2675        firefox: Some(46 << 16),
2676        ..Browsers::default()
2677      },
2678    );
2679
2680    prefix_test(
2681      r#"
2682      .foo {
2683        -webkit-border-top-left-radius: 30px;
2684        -moz-border-top-right-radius: 30px;
2685        border-bottom-right-radius: 30px;
2686        border-bottom-left-radius: 30px;
2687      }
2688    "#,
2689      indoc! {r#"
2690      .foo {
2691        -webkit-border-top-left-radius: 30px;
2692        -moz-border-top-right-radius: 30px;
2693        border-bottom-right-radius: 30px;
2694        border-bottom-left-radius: 30px;
2695      }
2696    "#
2697      },
2698      Browsers {
2699        safari: Some(14 << 16),
2700        firefox: Some(46 << 16),
2701        ..Browsers::default()
2702      },
2703    );
2704
2705    prefix_test(
2706      r#"
2707      .foo {
2708        border-radius: var(--test);
2709      }
2710    "#,
2711      indoc! {r#"
2712      .foo {
2713        -webkit-border-radius: var(--test);
2714        -moz-border-radius: var(--test);
2715        border-radius: var(--test);
2716      }
2717    "#
2718      },
2719      Browsers {
2720        safari: Some(4 << 16),
2721        firefox: Some(3 << 16),
2722        ..Browsers::default()
2723      },
2724    );
2725
2726    prefix_test(
2727      r#"
2728      .foo {
2729        border-start-start-radius: 5px;
2730      }
2731    "#,
2732      indoc! {r#"
2733      .foo:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
2734        border-top-left-radius: 5px;
2735      }
2736
2737      .foo:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
2738        border-top-right-radius: 5px;
2739      }
2740    "#
2741      },
2742      Browsers {
2743        safari: Some(12 << 16),
2744        ..Browsers::default()
2745      },
2746    );
2747
2748    prefix_test(
2749      r#"
2750      .foo {
2751        border-start-start-radius: 5px;
2752        border-start-end-radius: 10px;
2753      }
2754    "#,
2755      indoc! {r#"
2756      .foo:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
2757        border-top-left-radius: 5px;
2758        border-top-right-radius: 10px;
2759      }
2760
2761      .foo:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
2762        border-top-left-radius: 10px;
2763        border-top-right-radius: 5px;
2764      }
2765    "#
2766      },
2767      Browsers {
2768        safari: Some(12 << 16),
2769        ..Browsers::default()
2770      },
2771    );
2772
2773    prefix_test(
2774      r#"
2775      .foo {
2776        border-end-end-radius: 10px;
2777        border-end-start-radius: 5px;
2778      }
2779    "#,
2780      indoc! {r#"
2781      .foo:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
2782        border-bottom-right-radius: 10px;
2783        border-bottom-left-radius: 5px;
2784      }
2785
2786      .foo:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
2787        border-bottom-right-radius: 5px;
2788        border-bottom-left-radius: 10px;
2789      }
2790    "#
2791      },
2792      Browsers {
2793        safari: Some(12 << 16),
2794        ..Browsers::default()
2795      },
2796    );
2797
2798    prefix_test(
2799      r#"
2800      .foo {
2801        border-start-start-radius: var(--radius);
2802      }
2803    "#,
2804      indoc! {r#"
2805      .foo:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
2806        border-top-left-radius: var(--radius);
2807      }
2808
2809      .foo:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
2810        border-top-right-radius: var(--radius);
2811      }
2812    "#
2813      },
2814      Browsers {
2815        safari: Some(12 << 16),
2816        ..Browsers::default()
2817      },
2818    );
2819
2820    prefix_test(
2821      r#"
2822      .foo {
2823        border-start-start-radius: var(--start);
2824        border-start-end-radius: var(--end);
2825      }
2826    "#,
2827      indoc! {r#"
2828      .foo:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
2829        border-top-left-radius: var(--start);
2830        border-top-right-radius: var(--end);
2831      }
2832
2833      .foo:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
2834        border-top-right-radius: var(--start);
2835        border-top-left-radius: var(--end);
2836      }
2837    "#
2838      },
2839      Browsers {
2840        safari: Some(12 << 16),
2841        ..Browsers::default()
2842      },
2843    );
2844  }
2845
2846  #[test]
2847  pub fn test_outline() {
2848    test(
2849      r#"
2850      .foo {
2851        outline-width: 2px;
2852        outline-style: solid;
2853        outline-color: blue;
2854      }
2855    "#,
2856      indoc! {r#"
2857      .foo {
2858        outline: 2px solid #00f;
2859      }
2860    "#
2861      },
2862    );
2863
2864    test(
2865      r#"
2866      .foo {
2867        outline: 2px solid blue;
2868      }
2869    "#,
2870      indoc! {r#"
2871      .foo {
2872        outline: 2px solid #00f;
2873      }
2874    "#
2875      },
2876    );
2877
2878    test(
2879      r#"
2880      .foo {
2881        outline: 2px solid red;
2882        outline-color: blue;
2883      }
2884    "#,
2885      indoc! {r#"
2886      .foo {
2887        outline: 2px solid #00f;
2888      }
2889    "#
2890      },
2891    );
2892
2893    test(
2894      r#"
2895      .foo {
2896        outline: 2px solid yellow;
2897        outline-color: var(--color);
2898      }
2899    "#,
2900      indoc! {r#"
2901      .foo {
2902        outline: 2px solid #ff0;
2903        outline-color: var(--color);
2904      }
2905    "#
2906      },
2907    );
2908
2909    prefix_test(
2910      ".foo { outline-color: lab(40% 56.6 39) }",
2911      indoc! { r#"
2912        .foo {
2913          outline-color: #b32323;
2914          outline-color: lab(40% 56.6 39);
2915        }
2916      "#},
2917      Browsers {
2918        chrome: Some(90 << 16),
2919        ..Browsers::default()
2920      },
2921    );
2922
2923    prefix_test(
2924      ".foo { outline: 2px solid lab(40% 56.6 39) }",
2925      indoc! { r#"
2926        .foo {
2927          outline: 2px solid #b32323;
2928          outline: 2px solid lab(40% 56.6 39);
2929        }
2930      "#},
2931      Browsers {
2932        chrome: Some(90 << 16),
2933        ..Browsers::default()
2934      },
2935    );
2936
2937    prefix_test(
2938      ".foo { outline: var(--width) solid lab(40% 56.6 39) }",
2939      indoc! { r#"
2940        .foo {
2941          outline: var(--width) solid #b32323;
2942        }
2943
2944        @supports (color: lab(0% 0 0)) {
2945          .foo {
2946            outline: var(--width) solid lab(40% 56.6 39);
2947          }
2948        }
2949      "#},
2950      Browsers {
2951        chrome: Some(90 << 16),
2952        ..Browsers::default()
2953      },
2954    );
2955  }
2956
2957  #[test]
2958  pub fn test_margin() {
2959    test(
2960      r#"
2961      .foo {
2962        margin-left: 10px;
2963        margin-right: 10px;
2964        margin-top: 20px;
2965        margin-bottom: 20px;
2966      }
2967    "#,
2968      indoc! {r#"
2969      .foo {
2970        margin: 20px 10px;
2971      }
2972    "#
2973      },
2974    );
2975
2976    test(
2977      r#"
2978      .foo {
2979        margin-block-start: 15px;
2980        margin-block-end: 15px;
2981      }
2982    "#,
2983      indoc! {r#"
2984      .foo {
2985        margin-block: 15px;
2986      }
2987    "#
2988      },
2989    );
2990
2991    test(
2992      r#"
2993      .foo {
2994        margin-left: 10px;
2995        margin-right: 10px;
2996        margin-inline-start: 15px;
2997        margin-inline-end: 15px;
2998        margin-top: 20px;
2999        margin-bottom: 20px;
3000
3001      }
3002    "#,
3003      indoc! {r#"
3004      .foo {
3005        margin-left: 10px;
3006        margin-right: 10px;
3007        margin-inline: 15px;
3008        margin-top: 20px;
3009        margin-bottom: 20px;
3010      }
3011    "#
3012      },
3013    );
3014
3015    test(
3016      r#"
3017      .foo {
3018        margin: 10px;
3019        margin-top: 20px;
3020      }
3021    "#,
3022      indoc! {r#"
3023      .foo {
3024        margin: 20px 10px 10px;
3025      }
3026    "#
3027      },
3028    );
3029
3030    test(
3031      r#"
3032      .foo {
3033        margin: 10px;
3034        margin-top: var(--top);
3035      }
3036    "#,
3037      indoc! {r#"
3038      .foo {
3039        margin: 10px;
3040        margin-top: var(--top);
3041      }
3042    "#
3043      },
3044    );
3045
3046    prefix_test(
3047      r#"
3048      .foo {
3049        margin-inline-start: 2px;
3050      }
3051    "#,
3052      indoc! {r#"
3053      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
3054        margin-left: 2px;
3055      }
3056
3057      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
3058        margin-left: 2px;
3059      }
3060
3061      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
3062        margin-right: 2px;
3063      }
3064
3065      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
3066        margin-right: 2px;
3067      }
3068    "#
3069      },
3070      Browsers {
3071        safari: Some(8 << 16),
3072        ..Browsers::default()
3073      },
3074    );
3075
3076    prefix_test(
3077      r#"
3078      .foo {
3079        margin-inline-start: 2px;
3080        margin-inline-end: 4px;
3081      }
3082    "#,
3083      indoc! {r#"
3084      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
3085        margin-left: 2px;
3086        margin-right: 4px;
3087      }
3088
3089      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
3090        margin-left: 2px;
3091        margin-right: 4px;
3092      }
3093
3094      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
3095        margin-left: 4px;
3096        margin-right: 2px;
3097      }
3098
3099      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
3100        margin-left: 4px;
3101        margin-right: 2px;
3102      }
3103    "#
3104      },
3105      Browsers {
3106        safari: Some(8 << 16),
3107        ..Browsers::default()
3108      },
3109    );
3110
3111    prefix_test(
3112      r#"
3113      .foo {
3114        margin-inline: 2px;
3115      }
3116    "#,
3117      indoc! {r#"
3118      .foo {
3119        margin-left: 2px;
3120        margin-right: 2px;
3121      }
3122    "#
3123      },
3124      Browsers {
3125        safari: Some(8 << 16),
3126        ..Browsers::default()
3127      },
3128    );
3129
3130    prefix_test(
3131      r#"
3132      .foo {
3133        margin-block-start: 2px;
3134      }
3135    "#,
3136      indoc! {r#"
3137      .foo {
3138        margin-top: 2px;
3139      }
3140    "#
3141      },
3142      Browsers {
3143        safari: Some(8 << 16),
3144        ..Browsers::default()
3145      },
3146    );
3147
3148    prefix_test(
3149      r#"
3150      .foo {
3151        margin-block-end: 2px;
3152      }
3153    "#,
3154      indoc! {r#"
3155      .foo {
3156        margin-bottom: 2px;
3157      }
3158    "#
3159      },
3160      Browsers {
3161        safari: Some(8 << 16),
3162        ..Browsers::default()
3163      },
3164    );
3165
3166    prefix_test(
3167      r#"
3168      .foo {
3169        margin-inline-start: 2px;
3170        margin-inline-end: 2px;
3171      }
3172    "#,
3173      indoc! {r#"
3174      .foo {
3175        margin-inline-start: 2px;
3176        margin-inline-end: 2px;
3177      }
3178    "#
3179      },
3180      Browsers {
3181        safari: Some(13 << 16),
3182        ..Browsers::default()
3183      },
3184    );
3185
3186    prefix_test(
3187      r#"
3188      .foo {
3189        margin-inline: 2px;
3190      }
3191    "#,
3192      indoc! {r#"
3193      .foo {
3194        margin-inline-start: 2px;
3195        margin-inline-end: 2px;
3196      }
3197    "#
3198      },
3199      Browsers {
3200        safari: Some(13 << 16),
3201        ..Browsers::default()
3202      },
3203    );
3204
3205    prefix_test(
3206      r#"
3207      .foo {
3208        margin-inline-start: 2px;
3209        margin-inline-end: 2px;
3210      }
3211    "#,
3212      indoc! {r#"
3213      .foo {
3214        margin-inline: 2px;
3215      }
3216    "#
3217      },
3218      Browsers {
3219        safari: Some(15 << 16),
3220        ..Browsers::default()
3221      },
3222    );
3223
3224    prefix_test(
3225      r#"
3226      .foo {
3227        margin-inline: 2px;
3228      }
3229    "#,
3230      indoc! {r#"
3231      .foo {
3232        margin-inline: 2px;
3233      }
3234    "#
3235      },
3236      Browsers {
3237        safari: Some(15 << 16),
3238        ..Browsers::default()
3239      },
3240    );
3241  }
3242
3243  #[test]
3244  fn test_length() {
3245    for prop in &[
3246      "margin-right",
3247      "margin",
3248      "padding-right",
3249      "padding",
3250      "width",
3251      "height",
3252      "min-height",
3253      "max-height",
3254      "line-height",
3255      "border-radius",
3256    ] {
3257      prefix_test(
3258        &format!(
3259          r#"
3260        .foo {{
3261          {}: 22px;
3262          {}: max(4%, 22px);
3263        }}
3264      "#,
3265          prop, prop
3266        ),
3267        &format!(
3268          indoc! {r#"
3269        .foo {{
3270          {}: 22px;
3271          {}: max(4%, 22px);
3272        }}
3273      "#
3274          },
3275          prop, prop
3276        ),
3277        Browsers {
3278          safari: Some(10 << 16),
3279          ..Browsers::default()
3280        },
3281      );
3282
3283      prefix_test(
3284        &format!(
3285          r#"
3286        .foo {{
3287          {}: 22px;
3288          {}: max(4%, 22px);
3289        }}
3290      "#,
3291          prop, prop
3292        ),
3293        &format!(
3294          indoc! {r#"
3295        .foo {{
3296          {}: max(4%, 22px);
3297        }}
3298      "#
3299          },
3300          prop
3301        ),
3302        Browsers {
3303          safari: Some(14 << 16),
3304          ..Browsers::default()
3305        },
3306      );
3307
3308      prefix_test(
3309        &format!(
3310          r#"
3311        .foo {{
3312          {}: 22px;
3313          {}: max(2cqw, 22px);
3314        }}
3315      "#,
3316          prop, prop
3317        ),
3318        &format!(
3319          indoc! {r#"
3320        .foo {{
3321          {}: 22px;
3322          {}: max(2cqw, 22px);
3323        }}
3324      "#
3325          },
3326          prop, prop
3327        ),
3328        Browsers {
3329          safari: Some(14 << 16),
3330          ..Browsers::default()
3331        },
3332      );
3333      prefix_test(
3334        &format!(
3335          r#"
3336        .foo {{
3337          {}: 22px;
3338          {}: max(2cqw, 22px);
3339        }}
3340      "#,
3341          prop, prop
3342        ),
3343        &format!(
3344          indoc! {r#"
3345        .foo {{
3346          {}: max(2cqw, 22px);
3347        }}
3348      "#
3349          },
3350          prop
3351        ),
3352        Browsers {
3353          safari: Some(16 << 16),
3354          ..Browsers::default()
3355        },
3356      );
3357    }
3358  }
3359
3360  #[test]
3361  pub fn test_padding() {
3362    test(
3363      r#"
3364      .foo {
3365        padding-left: 10px;
3366        padding-right: 10px;
3367        padding-top: 20px;
3368        padding-bottom: 20px;
3369      }
3370    "#,
3371      indoc! {r#"
3372      .foo {
3373        padding: 20px 10px;
3374      }
3375    "#
3376      },
3377    );
3378
3379    test(
3380      r#"
3381      .foo {
3382        padding-block-start: 15px;
3383        padding-block-end: 15px;
3384      }
3385    "#,
3386      indoc! {r#"
3387      .foo {
3388        padding-block: 15px;
3389      }
3390    "#
3391      },
3392    );
3393
3394    test(
3395      r#"
3396      .foo {
3397        padding-left: 10px;
3398        padding-right: 10px;
3399        padding-inline-start: 15px;
3400        padding-inline-end: 15px;
3401        padding-top: 20px;
3402        padding-bottom: 20px;
3403
3404      }
3405    "#,
3406      indoc! {r#"
3407      .foo {
3408        padding-left: 10px;
3409        padding-right: 10px;
3410        padding-inline: 15px;
3411        padding-top: 20px;
3412        padding-bottom: 20px;
3413      }
3414    "#
3415      },
3416    );
3417
3418    prefix_test(
3419      r#"
3420      .foo {
3421        padding-inline-start: 2px;
3422      }
3423    "#,
3424      indoc! {r#"
3425      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
3426        padding-left: 2px;
3427      }
3428
3429      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
3430        padding-left: 2px;
3431      }
3432
3433      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
3434        padding-right: 2px;
3435      }
3436
3437      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
3438        padding-right: 2px;
3439      }
3440    "#
3441      },
3442      Browsers {
3443        safari: Some(8 << 16),
3444        ..Browsers::default()
3445      },
3446    );
3447
3448    prefix_test(
3449      r#"
3450      .foo {
3451        padding-inline-start: 2px;
3452        padding-inline-end: 4px;
3453      }
3454    "#,
3455      indoc! {r#"
3456      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
3457        padding-left: 2px;
3458        padding-right: 4px;
3459      }
3460
3461      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
3462        padding-left: 2px;
3463        padding-right: 4px;
3464      }
3465
3466      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
3467        padding-left: 4px;
3468        padding-right: 2px;
3469      }
3470
3471      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
3472        padding-left: 4px;
3473        padding-right: 2px;
3474      }
3475    "#
3476      },
3477      Browsers {
3478        safari: Some(8 << 16),
3479        ..Browsers::default()
3480      },
3481    );
3482
3483    prefix_test(
3484      r#"
3485      .foo {
3486        padding-inline-start: var(--padding);
3487      }
3488    "#,
3489      indoc! {r#"
3490      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
3491        padding-left: var(--padding);
3492      }
3493
3494      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
3495        padding-left: var(--padding);
3496      }
3497
3498      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
3499        padding-right: var(--padding);
3500      }
3501
3502      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
3503        padding-right: var(--padding);
3504      }
3505    "#
3506      },
3507      Browsers {
3508        safari: Some(8 << 16),
3509        ..Browsers::default()
3510      },
3511    );
3512
3513    prefix_test(
3514      r#"
3515      .foo {
3516        padding-inline: 2px;
3517      }
3518    "#,
3519      indoc! {r#"
3520      .foo {
3521        padding-left: 2px;
3522        padding-right: 2px;
3523      }
3524    "#
3525      },
3526      Browsers {
3527        safari: Some(8 << 16),
3528        ..Browsers::default()
3529      },
3530    );
3531
3532    prefix_test(
3533      r#"
3534      .foo {
3535        padding-block-start: 2px;
3536      }
3537    "#,
3538      indoc! {r#"
3539      .foo {
3540        padding-top: 2px;
3541      }
3542    "#
3543      },
3544      Browsers {
3545        safari: Some(8 << 16),
3546        ..Browsers::default()
3547      },
3548    );
3549
3550    prefix_test(
3551      r#"
3552      .foo {
3553        padding-block-end: 2px;
3554      }
3555    "#,
3556      indoc! {r#"
3557      .foo {
3558        padding-bottom: 2px;
3559      }
3560    "#
3561      },
3562      Browsers {
3563        safari: Some(8 << 16),
3564        ..Browsers::default()
3565      },
3566    );
3567
3568    prefix_test(
3569      r#"
3570      .foo {
3571        padding-top: 1px;
3572        padding-left: 2px;
3573        padding-bottom: 3px;
3574        padding-right: 4px;
3575      }
3576    "#,
3577      indoc! {r#"
3578      .foo {
3579        padding: 1px 4px 3px 2px;
3580      }
3581    "#},
3582      Browsers {
3583        safari: Some(8 << 16),
3584        ..Browsers::default()
3585      },
3586    );
3587
3588    prefix_test(
3589      r#"
3590      .foo {
3591        padding-inline-start: 2px;
3592        padding-inline-end: 2px;
3593      }
3594    "#,
3595      indoc! {r#"
3596      .foo {
3597        padding-inline-start: 2px;
3598        padding-inline-end: 2px;
3599      }
3600    "#
3601      },
3602      Browsers {
3603        safari: Some(13 << 16),
3604        ..Browsers::default()
3605      },
3606    );
3607
3608    prefix_test(
3609      r#"
3610      .foo {
3611        padding-inline-start: 2px;
3612        padding-inline-end: 2px;
3613      }
3614    "#,
3615      indoc! {r#"
3616      .foo {
3617        padding-inline: 2px;
3618      }
3619    "#
3620      },
3621      Browsers {
3622        safari: Some(15 << 16),
3623        ..Browsers::default()
3624      },
3625    );
3626  }
3627
3628  #[test]
3629  fn test_scroll_padding() {
3630    prefix_test(
3631      r#"
3632      .foo {
3633        scroll-padding-inline: 2px;
3634      }
3635    "#,
3636      indoc! {r#"
3637      .foo {
3638        scroll-padding-inline: 2px;
3639      }
3640    "#
3641      },
3642      Browsers {
3643        safari: Some(8 << 16),
3644        ..Browsers::default()
3645      },
3646    );
3647  }
3648
3649  #[test]
3650  fn test_size() {
3651    prefix_test(
3652      r#"
3653      .foo {
3654        block-size: 25px;
3655        inline-size: 25px;
3656        min-block-size: 25px;
3657        min-inline-size: 25px;
3658      }
3659    "#,
3660      indoc! {r#"
3661      .foo {
3662        height: 25px;
3663        min-height: 25px;
3664        width: 25px;
3665        min-width: 25px;
3666      }
3667    "#},
3668      Browsers {
3669        safari: Some(8 << 16),
3670        ..Browsers::default()
3671      },
3672    );
3673
3674    prefix_test(
3675      r#"
3676      .foo {
3677        block-size: 25px;
3678        min-block-size: 25px;
3679        inline-size: 25px;
3680        min-inline-size: 25px;
3681      }
3682    "#,
3683      indoc! {r#"
3684      .foo {
3685        block-size: 25px;
3686        min-block-size: 25px;
3687        inline-size: 25px;
3688        min-inline-size: 25px;
3689      }
3690    "#},
3691      Browsers {
3692        safari: Some(14 << 16),
3693        ..Browsers::default()
3694      },
3695    );
3696
3697    prefix_test(
3698      r#"
3699      .foo {
3700        block-size: var(--size);
3701        min-block-size: var(--size);
3702        inline-size: var(--size);
3703        min-inline-size: var(--size);
3704      }
3705    "#,
3706      indoc! {r#"
3707      .foo {
3708        height: var(--size);
3709        min-height: var(--size);
3710        width: var(--size);
3711        min-width: var(--size);
3712      }
3713    "#},
3714      Browsers {
3715        safari: Some(8 << 16),
3716        ..Browsers::default()
3717      },
3718    );
3719
3720    for (in_prop, out_prop) in [
3721      ("width", "width"),
3722      ("height", "height"),
3723      ("block-size", "height"),
3724      ("inline-size", "width"),
3725      ("min-width", "min-width"),
3726      ("min-height", "min-height"),
3727      ("min-block-size", "min-height"),
3728      ("min-inline-size", "min-width"),
3729      ("max-width", "max-width"),
3730      ("max-height", "max-height"),
3731      ("max-block-size", "max-height"),
3732      ("max-inline-size", "max-width"),
3733    ] {
3734      prefix_test(
3735        &format!(
3736          r#"
3737        .foo {{
3738          {}: stretch;
3739        }}
3740      "#,
3741          in_prop
3742        ),
3743        &format!(
3744          indoc! {r#"
3745        .foo {{
3746          {}: -webkit-fill-available;
3747          {}: -moz-available;
3748          {}: stretch;
3749        }}
3750      "#},
3751          out_prop, out_prop, out_prop
3752        ),
3753        Browsers {
3754          safari: Some(8 << 16),
3755          firefox: Some(4 << 16),
3756          ..Browsers::default()
3757        },
3758      );
3759
3760      prefix_test(
3761        &format!(
3762          r#"
3763        .foo {{
3764          {}: -webkit-fill-available;
3765        }}
3766      "#,
3767          in_prop
3768        ),
3769        &format!(
3770          indoc! {r#"
3771        .foo {{
3772          {}: -webkit-fill-available;
3773        }}
3774      "#},
3775          out_prop
3776        ),
3777        Browsers {
3778          safari: Some(8 << 16),
3779          firefox: Some(4 << 16),
3780          ..Browsers::default()
3781        },
3782      );
3783
3784      prefix_test(
3785        &format!(
3786          r#"
3787        .foo {{
3788          {}: 100vw;
3789          {}: -webkit-fill-available;
3790        }}
3791      "#,
3792          in_prop, in_prop
3793        ),
3794        &format!(
3795          indoc! {r#"
3796        .foo {{
3797          {}: 100vw;
3798          {}: -webkit-fill-available;
3799        }}
3800      "#},
3801          out_prop, out_prop
3802        ),
3803        Browsers {
3804          safari: Some(8 << 16),
3805          firefox: Some(4 << 16),
3806          ..Browsers::default()
3807        },
3808      );
3809
3810      prefix_test(
3811        &format!(
3812          r#"
3813        .foo {{
3814          {}: fit-content;
3815        }}
3816      "#,
3817          in_prop
3818        ),
3819        &format!(
3820          indoc! {r#"
3821        .foo {{
3822          {}: -webkit-fit-content;
3823          {}: -moz-fit-content;
3824          {}: fit-content;
3825        }}
3826      "#},
3827          out_prop, out_prop, out_prop
3828        ),
3829        Browsers {
3830          safari: Some(8 << 16),
3831          firefox: Some(4 << 16),
3832          ..Browsers::default()
3833        },
3834      );
3835
3836      prefix_test(
3837        &format!(
3838          r#"
3839        .foo {{
3840          {}: fit-content(50%);
3841        }}
3842      "#,
3843          in_prop
3844        ),
3845        &format!(
3846          indoc! {r#"
3847        .foo {{
3848          {}: fit-content(50%);
3849        }}
3850      "#},
3851          out_prop
3852        ),
3853        Browsers {
3854          safari: Some(8 << 16),
3855          firefox: Some(4 << 16),
3856          ..Browsers::default()
3857        },
3858      );
3859
3860      prefix_test(
3861        &format!(
3862          r#"
3863        .foo {{
3864          {}: min-content;
3865        }}
3866      "#,
3867          in_prop
3868        ),
3869        &format!(
3870          indoc! {r#"
3871        .foo {{
3872          {}: -webkit-min-content;
3873          {}: -moz-min-content;
3874          {}: min-content;
3875        }}
3876      "#},
3877          out_prop, out_prop, out_prop
3878        ),
3879        Browsers {
3880          safari: Some(8 << 16),
3881          firefox: Some(4 << 16),
3882          ..Browsers::default()
3883        },
3884      );
3885
3886      prefix_test(
3887        &format!(
3888          r#"
3889        .foo {{
3890          {}: max-content;
3891        }}
3892      "#,
3893          in_prop
3894        ),
3895        &format!(
3896          indoc! {r#"
3897        .foo {{
3898          {}: -webkit-max-content;
3899          {}: -moz-max-content;
3900          {}: max-content;
3901        }}
3902      "#},
3903          out_prop, out_prop, out_prop
3904        ),
3905        Browsers {
3906          safari: Some(8 << 16),
3907          firefox: Some(4 << 16),
3908          ..Browsers::default()
3909        },
3910      );
3911
3912      prefix_test(
3913        &format!(
3914          r#"
3915        .foo {{
3916          {}: 100%;
3917          {}: max-content;
3918        }}
3919      "#,
3920          in_prop, in_prop
3921        ),
3922        &format!(
3923          indoc! {r#"
3924        .foo {{
3925          {}: 100%;
3926          {}: max-content;
3927        }}
3928      "#},
3929          out_prop, out_prop
3930        ),
3931        Browsers {
3932          safari: Some(8 << 16),
3933          firefox: Some(4 << 16),
3934          ..Browsers::default()
3935        },
3936      );
3937
3938      prefix_test(
3939        &format!(
3940          r#"
3941        .foo {{
3942          {}: var(--fallback);
3943          {}: max-content;
3944        }}
3945      "#,
3946          in_prop, in_prop
3947        ),
3948        &format!(
3949          indoc! {r#"
3950        .foo {{
3951          {}: var(--fallback);
3952          {}: max-content;
3953        }}
3954      "#},
3955          out_prop, out_prop
3956        ),
3957        Browsers {
3958          safari: Some(8 << 16),
3959          firefox: Some(4 << 16),
3960          ..Browsers::default()
3961        },
3962      );
3963    }
3964
3965    minify_test(".foo { aspect-ratio: auto }", ".foo{aspect-ratio:auto}");
3966    minify_test(".foo { aspect-ratio: 2 / 3 }", ".foo{aspect-ratio:2/3}");
3967    minify_test(".foo { aspect-ratio: auto 2 / 3 }", ".foo{aspect-ratio:auto 2/3}");
3968    minify_test(".foo { aspect-ratio: 2 / 3 auto }", ".foo{aspect-ratio:auto 2/3}");
3969    minify_test(
3970      ".foo { width: 100%; width: calc(100% - constant(safe-area-inset-left)); width: calc(100% - env(safe-area-inset-left));}",
3971      ".foo{width:calc(100% - env(safe-area-inset-left))}"
3972    );
3973  }
3974
3975  #[test]
3976  pub fn test_background() {
3977    test(
3978      r#"
3979      .foo {
3980        background: url(img.png);
3981        background-position-x: 20px;
3982        background-position-y: 10px;
3983        background-size: 50px 100px;
3984        background-repeat: repeat no-repeat;
3985      }
3986    "#,
3987      indoc! {r#"
3988      .foo {
3989        background: url("img.png") 20px 10px / 50px 100px repeat-x;
3990      }
3991    "#
3992      },
3993    );
3994
3995    test(
3996      r#"
3997      .foo {
3998        background-color: red;
3999        background-position: 0% 0%;
4000        background-size: auto;
4001        background-repeat: repeat;
4002        background-clip: border-box;
4003        background-origin: padding-box;
4004        background-attachment: scroll;
4005        background-image: none
4006      }
4007    "#,
4008      indoc! {r#"
4009      .foo {
4010        background: red;
4011      }
4012    "#
4013      },
4014    );
4015
4016    test(
4017      r#"
4018      .foo {
4019        background-color: gray;
4020        background-position: 40% 50%;
4021        background-size: 10em auto;
4022        background-repeat: round;
4023        background-clip: border-box;
4024        background-origin: border-box;
4025        background-attachment: fixed;
4026        background-image: url('chess.png');
4027      }
4028    "#,
4029      indoc! {r#"
4030      .foo {
4031        background: gray url("chess.png") 40% / 10em round fixed border-box;
4032      }
4033    "#
4034      },
4035    );
4036
4037    test(
4038      r#"
4039      .foo {
4040        background: url(img.png), url(test.jpg) gray;
4041        background-position-x: right 20px, 10px;
4042        background-position-y: top 20px, 15px;
4043        background-size: 50px 50px, auto;
4044        background-repeat: repeat no-repeat, no-repeat;
4045      }
4046    "#,
4047      indoc! {r#"
4048      .foo {
4049        background: url("img.png") right 20px top 20px / 50px 50px repeat-x, gray url("test.jpg") 10px 15px no-repeat;
4050      }
4051    "#
4052      },
4053    );
4054
4055    minify_test(
4056      r#"
4057      .foo {
4058        background-position: center center;
4059      }
4060    "#,
4061      indoc! {".foo{background-position:50%}"
4062      },
4063    );
4064
4065    test(
4066      r#"
4067      .foo {
4068        background: url(img.png) gray;
4069        background-clip: content-box;
4070        -webkit-background-clip: text;
4071      }
4072    "#,
4073      indoc! {r#"
4074      .foo {
4075        background: gray url("img.png") padding-box content-box;
4076        -webkit-background-clip: text;
4077      }
4078    "#
4079      },
4080    );
4081
4082    test(
4083      r#"
4084      .foo {
4085        background: url(img.png) gray;
4086        -webkit-background-clip: text;
4087        background-clip: content-box;
4088      }
4089    "#,
4090      indoc! {r#"
4091      .foo {
4092        background: gray url("img.png");
4093        -webkit-background-clip: text;
4094        background-clip: content-box;
4095      }
4096    "#
4097      },
4098    );
4099
4100    test(
4101      r#"
4102      .foo {
4103        background: url(img.png) gray;
4104        background-position: var(--pos);
4105      }
4106    "#,
4107      indoc! {r#"
4108      .foo {
4109        background: gray url("img.png");
4110        background-position: var(--pos);
4111      }
4112    "#
4113      },
4114    );
4115
4116    minify_test(
4117      ".foo { background-position: bottom left }",
4118      ".foo{background-position:0 100%}",
4119    );
4120    minify_test(
4121      ".foo { background-position: left 10px center }",
4122      ".foo{background-position:10px 50%}",
4123    );
4124    minify_test(
4125      ".foo { background-position: right 10px center }",
4126      ".foo{background-position:right 10px center}",
4127    );
4128    minify_test(
4129      ".foo { background-position: right 10px top 20px }",
4130      ".foo{background-position:right 10px top 20px}",
4131    );
4132    minify_test(
4133      ".foo { background-position: left 10px top 20px }",
4134      ".foo{background-position:10px 20px}",
4135    );
4136    minify_test(
4137      ".foo { background-position: left 10px bottom 20px }",
4138      ".foo{background-position:left 10px bottom 20px}",
4139    );
4140    minify_test(
4141      ".foo { background-position: left 10px top }",
4142      ".foo{background-position:10px 0}",
4143    );
4144    minify_test(
4145      ".foo { background-position: bottom right }",
4146      ".foo{background-position:100% 100%}",
4147    );
4148
4149    minify_test(
4150      ".foo { background: url('img-sprite.png') no-repeat bottom right }",
4151      ".foo{background:url(img-sprite.png) 100% 100% no-repeat}",
4152    );
4153    minify_test(".foo { background: transparent }", ".foo{background:0 0}");
4154
4155    minify_test(".foo { background: url(\"data:image/svg+xml,%3Csvg width='168' height='24' xmlns='http://www.w3.org/2000/svg'%3E%3C/svg%3E\") }", ".foo{background:url(\"data:image/svg+xml,%3Csvg width='168' height='24' xmlns='http://www.w3.org/2000/svg'%3E%3C/svg%3E\")}");
4156
4157    test(
4158      r#"
4159      .foo {
4160        background: url(img.png);
4161        background-clip: text;
4162      }
4163    "#,
4164      indoc! {r#"
4165      .foo {
4166        background: url("img.png") text;
4167      }
4168    "#
4169      },
4170    );
4171
4172    prefix_test(
4173      r#"
4174      .foo {
4175        background: url(img.png);
4176        background-clip: text;
4177      }
4178    "#,
4179      indoc! {r#"
4180      .foo {
4181        background: url("img.png");
4182        -webkit-background-clip: text;
4183        background-clip: text;
4184      }
4185    "#
4186      },
4187      Browsers {
4188        safari: Some(8 << 16),
4189        ..Browsers::default()
4190      },
4191    );
4192
4193    prefix_test(
4194      r#"
4195      .foo {
4196        background: url(img.png);
4197        background-clip: text;
4198      }
4199    "#,
4200      indoc! {r#"
4201      .foo {
4202        background: url("img.png") text;
4203      }
4204    "#
4205      },
4206      Browsers {
4207        safari: Some(14 << 16),
4208        ..Browsers::default()
4209      },
4210    );
4211
4212    prefix_test(
4213      r#"
4214      .foo {
4215        background: url(img.png) text;
4216      }
4217    "#,
4218      indoc! {r#"
4219      .foo {
4220        background: url("img.png");
4221        -webkit-background-clip: text;
4222        background-clip: text;
4223      }
4224    "#
4225      },
4226      Browsers {
4227        chrome: Some(45 << 16),
4228        ..Browsers::default()
4229      },
4230    );
4231
4232    prefix_test(
4233      r#"
4234      .foo {
4235        background: url(img.png);
4236        -webkit-background-clip: text;
4237      }
4238    "#,
4239      indoc! {r#"
4240      .foo {
4241        background: url("img.png");
4242        -webkit-background-clip: text;
4243      }
4244    "#
4245      },
4246      Browsers {
4247        chrome: Some(45 << 16),
4248        ..Browsers::default()
4249      },
4250    );
4251
4252    prefix_test(
4253      r#"
4254      .foo {
4255        background: url(img.png);
4256        background-clip: text;
4257      }
4258    "#,
4259      indoc! {r#"
4260      .foo {
4261        background: url("img.png");
4262        -webkit-background-clip: text;
4263        background-clip: text;
4264      }
4265    "#
4266      },
4267      Browsers {
4268        safari: Some(14 << 16),
4269        chrome: Some(95 << 16),
4270        ..Browsers::default()
4271      },
4272    );
4273
4274    prefix_test(
4275      r#"
4276      .foo {
4277        background-image: url(img.png);
4278        background-clip: text;
4279      }
4280    "#,
4281      indoc! {r#"
4282      .foo {
4283        background-image: url("img.png");
4284        -webkit-background-clip: text;
4285        background-clip: text;
4286      }
4287    "#
4288      },
4289      Browsers {
4290        safari: Some(8 << 16),
4291        ..Browsers::default()
4292      },
4293    );
4294
4295    prefix_test(
4296      r#"
4297      .foo {
4298        -webkit-background-clip: text;
4299        background-clip: text;
4300      }
4301    "#,
4302      indoc! {r#"
4303      .foo {
4304        -webkit-background-clip: text;
4305        background-clip: text;
4306      }
4307    "#
4308      },
4309      Browsers {
4310        chrome: Some(45 << 16),
4311        ..Browsers::default()
4312      },
4313    );
4314
4315    prefix_test(
4316      r#"
4317      .foo {
4318        background-image: url(img.png);
4319        background-clip: text;
4320      }
4321    "#,
4322      indoc! {r#"
4323      .foo {
4324        background-image: url("img.png");
4325        background-clip: text;
4326      }
4327    "#
4328      },
4329      Browsers {
4330        safari: Some(14 << 16),
4331        ..Browsers::default()
4332      },
4333    );
4334
4335    minify_test(".foo { background: none center }", ".foo{background:50%}");
4336    minify_test(".foo { background: none }", ".foo{background:0 0}");
4337
4338    prefix_test(
4339      r#"
4340      .foo {
4341        background: lab(51.5117% 43.3777 -29.0443);
4342      }
4343    "#,
4344      indoc! {r#"
4345      .foo {
4346        background: #af5cae;
4347        background: lab(51.5117% 43.3777 -29.0443);
4348      }
4349    "#
4350      },
4351      Browsers {
4352        chrome: Some(95 << 16),
4353        safari: Some(15 << 16),
4354        ..Browsers::default()
4355      },
4356    );
4357
4358    prefix_test(
4359      r#"
4360      .foo {
4361        background: lab(51.5117% 43.3777 -29.0443) url(foo.png);
4362      }
4363    "#,
4364      indoc! {r#"
4365      .foo {
4366        background: #af5cae url("foo.png");
4367        background: lab(51.5117% 43.3777 -29.0443) url("foo.png");
4368      }
4369    "#
4370      },
4371      Browsers {
4372        chrome: Some(95 << 16),
4373        safari: Some(15 << 16),
4374        ..Browsers::default()
4375      },
4376    );
4377
4378    prefix_test(
4379      r#"
4380      .foo {
4381        background: lab(51.5117% 43.3777 -29.0443) linear-gradient(lab(52.2319% 40.1449 59.9171), lab(47.7776% -34.2947 -7.65904));
4382      }
4383    "#,
4384      indoc! {r#"
4385      .foo {
4386        background: #af5cae linear-gradient(#c65d07, #00807c);
4387        background: lab(51.5117% 43.3777 -29.0443) linear-gradient(lab(52.2319% 40.1449 59.9171), lab(47.7776% -34.2947 -7.65904));
4388      }
4389    "#
4390      },
4391      Browsers {
4392        chrome: Some(95 << 16),
4393        safari: Some(15 << 16),
4394        ..Browsers::default()
4395      },
4396    );
4397
4398    test(
4399      ".foo { background: calc(var(--v) / 0.3)",
4400      indoc! {r#"
4401      .foo {
4402        background: calc(var(--v) / .3);
4403      }
4404    "#},
4405    );
4406
4407    prefix_test(
4408      r#"
4409      .foo {
4410        background-color: #4263eb;
4411        background-color: color(display-p3 0 .5 1);
4412      }
4413    "#,
4414      indoc! {r#"
4415      .foo {
4416        background-color: #4263eb;
4417        background-color: color(display-p3 0 .5 1);
4418      }
4419    "#
4420      },
4421      Browsers {
4422        chrome: Some(99 << 16),
4423        ..Browsers::default()
4424      },
4425    );
4426    prefix_test(
4427      r#"
4428      .foo {
4429        background-color: #4263eb;
4430        background-color: color(display-p3 0 .5 1);
4431      }
4432    "#,
4433      indoc! {r#"
4434      .foo {
4435        background-color: color(display-p3 0 .5 1);
4436      }
4437    "#
4438      },
4439      Browsers {
4440        safari: Some(16 << 16),
4441        ..Browsers::default()
4442      },
4443    );
4444    prefix_test(
4445      r#"
4446      .foo {
4447        background-image: linear-gradient(red, green);
4448        background-image: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4449      }
4450    "#,
4451      indoc! {r#"
4452      .foo {
4453        background-image: linear-gradient(red, green);
4454        background-image: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4455      }
4456    "#
4457      },
4458      Browsers {
4459        chrome: Some(99 << 16),
4460        ..Browsers::default()
4461      },
4462    );
4463    prefix_test(
4464      r#"
4465      .foo {
4466        background-image: linear-gradient(red, green);
4467        background-image: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4468      }
4469    "#,
4470      indoc! {r#"
4471      .foo {
4472        background-image: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4473      }
4474    "#
4475      },
4476      Browsers {
4477        safari: Some(16 << 16),
4478        ..Browsers::default()
4479      },
4480    );
4481    prefix_test(
4482      r#"
4483      .foo {
4484        background: #4263eb;
4485        background: color(display-p3 0 .5 1);
4486      }
4487    "#,
4488      indoc! {r#"
4489      .foo {
4490        background: #4263eb;
4491        background: color(display-p3 0 .5 1);
4492      }
4493    "#
4494      },
4495      Browsers {
4496        chrome: Some(99 << 16),
4497        ..Browsers::default()
4498      },
4499    );
4500    prefix_test(
4501      r#"
4502      .foo {
4503        background: #4263eb;
4504        background: color(display-p3 0 .5 1);
4505      }
4506    "#,
4507      indoc! {r#"
4508      .foo {
4509        background: color(display-p3 0 .5 1);
4510      }
4511    "#
4512      },
4513      Browsers {
4514        safari: Some(16 << 16),
4515        ..Browsers::default()
4516      },
4517    );
4518    prefix_test(
4519      r#"
4520      .foo {
4521        background: linear-gradient(red, green);
4522        background: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4523      }
4524    "#,
4525      indoc! {r#"
4526      .foo {
4527        background: linear-gradient(red, green);
4528        background: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4529      }
4530    "#
4531      },
4532      Browsers {
4533        chrome: Some(99 << 16),
4534        ..Browsers::default()
4535      },
4536    );
4537    prefix_test(
4538      r#"
4539      .foo {
4540        background: red;
4541        background: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4542      }
4543    "#,
4544      indoc! {r#"
4545      .foo {
4546        background: red;
4547        background: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4548      }
4549    "#
4550      },
4551      Browsers {
4552        chrome: Some(99 << 16),
4553        ..Browsers::default()
4554      },
4555    );
4556    prefix_test(
4557      r#"
4558      .foo {
4559        background: linear-gradient(red, green);
4560        background: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4561      }
4562    "#,
4563      indoc! {r#"
4564      .foo {
4565        background: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4566      }
4567    "#
4568      },
4569      Browsers {
4570        safari: Some(16 << 16),
4571        ..Browsers::default()
4572      },
4573    );
4574    prefix_test(
4575      r#"
4576      .foo {
4577        background: var(--fallback);
4578        background: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4579      }
4580    "#,
4581      indoc! {r#"
4582      .foo {
4583        background: var(--fallback);
4584        background: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4585      }
4586    "#
4587      },
4588      Browsers {
4589        chrome: Some(99 << 16),
4590        ..Browsers::default()
4591      },
4592    );
4593    prefix_test(
4594      r#"
4595      .foo {
4596        background: red url(foo.png);
4597        background: lch(50% 132 50) url(foo.png);
4598      }
4599    "#,
4600      indoc! {r#"
4601      .foo {
4602        background: red url("foo.png");
4603        background: lch(50% 132 50) url("foo.png");
4604      }
4605    "#
4606      },
4607      Browsers {
4608        chrome: Some(99 << 16),
4609        ..Browsers::default()
4610      },
4611    );
4612  }
4613
4614  #[test]
4615  pub fn test_flex() {
4616    test(
4617      r#"
4618      .foo {
4619        flex-direction: column;
4620        flex-wrap: wrap;
4621      }
4622    "#,
4623      indoc! {r#"
4624      .foo {
4625        flex-flow: column wrap;
4626      }
4627    "#
4628      },
4629    );
4630
4631    test(
4632      r#"
4633      .foo {
4634        flex-direction: row;
4635        flex-wrap: wrap;
4636      }
4637    "#,
4638      indoc! {r#"
4639      .foo {
4640        flex-flow: wrap;
4641      }
4642    "#
4643      },
4644    );
4645
4646    test(
4647      r#"
4648      .foo {
4649        flex-direction: row;
4650        flex-wrap: nowrap;
4651      }
4652    "#,
4653      indoc! {r#"
4654      .foo {
4655        flex-flow: row;
4656      }
4657    "#
4658      },
4659    );
4660
4661    test(
4662      r#"
4663      .foo {
4664        flex-direction: column;
4665        flex-wrap: nowrap;
4666      }
4667    "#,
4668      indoc! {r#"
4669      .foo {
4670        flex-flow: column;
4671      }
4672    "#
4673      },
4674    );
4675
4676    test(
4677      r#"
4678      .foo {
4679        flex-grow: 1;
4680        flex-shrink: 1;
4681        flex-basis: 0%;
4682      }
4683    "#,
4684      indoc! {r#"
4685      .foo {
4686        flex: 1;
4687      }
4688    "#
4689      },
4690    );
4691
4692    test(
4693      r#"
4694      .foo {
4695        flex-grow: 1;
4696        flex-shrink: 1;
4697        flex-basis: 0;
4698      }
4699    "#,
4700      indoc! {r#"
4701      .foo {
4702        flex: 1 1 0;
4703      }
4704    "#
4705      },
4706    );
4707
4708    test(
4709      r#"
4710      .foo {
4711        flex-grow: 1;
4712        flex-shrink: 1;
4713        flex-basis: 0px;
4714      }
4715    "#,
4716      indoc! {r#"
4717      .foo {
4718        flex: 1 1 0;
4719      }
4720    "#
4721      },
4722    );
4723
4724    test(
4725      r#"
4726      .foo {
4727        flex-grow: 1;
4728        flex-shrink: 2;
4729        flex-basis: 0%;
4730      }
4731    "#,
4732      indoc! {r#"
4733      .foo {
4734        flex: 1 2;
4735      }
4736    "#
4737      },
4738    );
4739
4740    test(
4741      r#"
4742      .foo {
4743        flex-grow: 2;
4744        flex-shrink: 1;
4745        flex-basis: 0%;
4746      }
4747    "#,
4748      indoc! {r#"
4749      .foo {
4750        flex: 2;
4751      }
4752    "#
4753      },
4754    );
4755
4756    test(
4757      r#"
4758      .foo {
4759        flex-grow: 2;
4760        flex-shrink: 2;
4761        flex-basis: 0%;
4762      }
4763    "#,
4764      indoc! {r#"
4765      .foo {
4766        flex: 2 2;
4767      }
4768    "#
4769      },
4770    );
4771
4772    test(
4773      r#"
4774      .foo {
4775        flex-grow: 1;
4776        flex-shrink: 1;
4777        flex-basis: 10px;
4778      }
4779    "#,
4780      indoc! {r#"
4781      .foo {
4782        flex: 10px;
4783      }
4784    "#
4785      },
4786    );
4787
4788    test(
4789      r#"
4790      .foo {
4791        flex-grow: 2;
4792        flex-shrink: 1;
4793        flex-basis: 10px;
4794      }
4795    "#,
4796      indoc! {r#"
4797      .foo {
4798        flex: 2 10px;
4799      }
4800    "#
4801      },
4802    );
4803
4804    test(
4805      r#"
4806      .foo {
4807        flex-grow: 1;
4808        flex-shrink: 0;
4809        flex-basis: 0%;
4810      }
4811    "#,
4812      indoc! {r#"
4813      .foo {
4814        flex: 1 0;
4815      }
4816    "#
4817      },
4818    );
4819
4820    test(
4821      r#"
4822      .foo {
4823        flex-grow: 1;
4824        flex-shrink: 0;
4825        flex-basis: auto;
4826      }
4827    "#,
4828      indoc! {r#"
4829      .foo {
4830        flex: 1 0 auto;
4831      }
4832    "#
4833      },
4834    );
4835
4836    test(
4837      r#"
4838      .foo {
4839        flex-grow: 1;
4840        flex-shrink: 1;
4841        flex-basis: auto;
4842      }
4843    "#,
4844      indoc! {r#"
4845      .foo {
4846        flex: auto;
4847      }
4848    "#
4849      },
4850    );
4851
4852    test(
4853      r#"
4854      .foo {
4855        flex: 0 0;
4856        flex-grow: 1;
4857      }
4858    "#,
4859      indoc! {r#"
4860      .foo {
4861        flex: 1 0;
4862      }
4863    "#
4864      },
4865    );
4866
4867    test(
4868      r#"
4869      .foo {
4870        flex: 0 0;
4871        flex-grow: var(--grow);
4872      }
4873    "#,
4874      indoc! {r#"
4875      .foo {
4876        flex: 0 0;
4877        flex-grow: var(--grow);
4878      }
4879    "#
4880      },
4881    );
4882
4883    test(
4884      r#"
4885      .foo {
4886        align-content: center;
4887        justify-content: center;
4888      }
4889    "#,
4890      indoc! {r#"
4891      .foo {
4892        place-content: center;
4893      }
4894    "#
4895      },
4896    );
4897
4898    test(
4899      r#"
4900      .foo {
4901        align-content: first baseline;
4902        justify-content: safe right;
4903      }
4904    "#,
4905      indoc! {r#"
4906      .foo {
4907        place-content: baseline safe right;
4908      }
4909    "#
4910      },
4911    );
4912
4913    test(
4914      r#"
4915      .foo {
4916        place-content: first baseline unsafe left;
4917      }
4918    "#,
4919      indoc! {r#"
4920      .foo {
4921        place-content: baseline unsafe left;
4922      }
4923    "#
4924      },
4925    );
4926
4927    test(
4928      r#"
4929      .foo {
4930        place-content: center center;
4931      }
4932    "#,
4933      indoc! {r#"
4934      .foo {
4935        place-content: center;
4936      }
4937    "#
4938      },
4939    );
4940
4941    test(
4942      r#"
4943      .foo {
4944        align-self: center;
4945        justify-self: center;
4946      }
4947    "#,
4948      indoc! {r#"
4949      .foo {
4950        place-self: center;
4951      }
4952    "#
4953      },
4954    );
4955
4956    test(
4957      r#"
4958      .foo {
4959        align-self: center;
4960        justify-self: unsafe left;
4961      }
4962    "#,
4963      indoc! {r#"
4964      .foo {
4965        place-self: center unsafe left;
4966      }
4967    "#
4968      },
4969    );
4970
4971    test(
4972      r#"
4973      .foo {
4974        align-items: center;
4975        justify-items: center;
4976      }
4977    "#,
4978      indoc! {r#"
4979      .foo {
4980        place-items: center;
4981      }
4982    "#
4983      },
4984    );
4985
4986    test(
4987      r#"
4988      .foo {
4989        align-items: center;
4990        justify-items: legacy left;
4991      }
4992    "#,
4993      indoc! {r#"
4994      .foo {
4995        place-items: center legacy left;
4996      }
4997    "#
4998      },
4999    );
5000
5001    test(
5002      r#"
5003      .foo {
5004        place-items: center;
5005        justify-items: var(--justify);
5006      }
5007    "#,
5008      indoc! {r#"
5009      .foo {
5010        place-items: center;
5011        justify-items: var(--justify);
5012      }
5013    "#
5014      },
5015    );
5016
5017    test(
5018      r#"
5019      .foo {
5020        row-gap: 10px;
5021        column-gap: 20px;
5022      }
5023    "#,
5024      indoc! {r#"
5025      .foo {
5026        gap: 10px 20px;
5027      }
5028    "#
5029      },
5030    );
5031
5032    test(
5033      r#"
5034      .foo {
5035        row-gap: 10px;
5036        column-gap: 10px;
5037      }
5038    "#,
5039      indoc! {r#"
5040      .foo {
5041        gap: 10px;
5042      }
5043    "#
5044      },
5045    );
5046
5047    test(
5048      r#"
5049      .foo {
5050        gap: 10px;
5051        column-gap: 20px;
5052      }
5053    "#,
5054      indoc! {r#"
5055      .foo {
5056        gap: 10px 20px;
5057      }
5058    "#
5059      },
5060    );
5061
5062    test(
5063      r#"
5064      .foo {
5065        column-gap: 20px;
5066        gap: 10px;
5067      }
5068    "#,
5069      indoc! {r#"
5070      .foo {
5071        gap: 10px;
5072      }
5073    "#
5074      },
5075    );
5076
5077    test(
5078      r#"
5079      .foo {
5080        row-gap: normal;
5081        column-gap: 20px;
5082      }
5083    "#,
5084      indoc! {r#"
5085      .foo {
5086        gap: normal 20px;
5087      }
5088    "#
5089      },
5090    );
5091
5092    test(
5093      r#"
5094      .foo {
5095        -webkit-flex-grow: 1;
5096        -webkit-flex-shrink: 1;
5097        -webkit-flex-basis: auto;
5098      }
5099    "#,
5100      indoc! {r#"
5101      .foo {
5102        -webkit-flex: auto;
5103      }
5104    "#
5105      },
5106    );
5107    test(
5108      r#"
5109      .foo {
5110        -webkit-flex-grow: 1;
5111        -webkit-flex-shrink: 1;
5112        -webkit-flex-basis: auto;
5113        flex-grow: 1;
5114        flex-shrink: 1;
5115        flex-basis: auto;
5116      }
5117    "#,
5118      indoc! {r#"
5119      .foo {
5120        -webkit-flex: auto;
5121        flex: auto;
5122      }
5123    "#
5124      },
5125    );
5126    prefix_test(
5127      r#"
5128      .foo {
5129        -webkit-box-orient: horizontal;
5130        -webkit-box-direction: normal;
5131        flex-direction: row;
5132      }
5133    "#,
5134      indoc! {r#"
5135      .foo {
5136        -webkit-box-orient: horizontal;
5137        -webkit-box-direction: normal;
5138        -webkit-flex-direction: row;
5139        flex-direction: row;
5140      }
5141    "#},
5142      Browsers {
5143        safari: Some(4 << 16),
5144        ..Browsers::default()
5145      },
5146    );
5147    prefix_test(
5148      r#"
5149      .foo {
5150        flex-direction: row;
5151      }
5152    "#,
5153      indoc! {r#"
5154      .foo {
5155        -webkit-box-orient: horizontal;
5156        -moz-box-orient: horizontal;
5157        -webkit-box-direction: normal;
5158        -moz-box-direction: normal;
5159        -webkit-flex-direction: row;
5160        -ms-flex-direction: row;
5161        flex-direction: row;
5162      }
5163    "#},
5164      Browsers {
5165        safari: Some(4 << 16),
5166        firefox: Some(4 << 16),
5167        ie: Some(10 << 16),
5168        ..Browsers::default()
5169      },
5170    );
5171    prefix_test(
5172      r#"
5173      .foo {
5174        -webkit-box-orient: horizontal;
5175        -webkit-box-direction: normal;
5176        -moz-box-orient: horizontal;
5177        -moz-box-direction: normal;
5178        -webkit-flex-direction: row;
5179        -ms-flex-direction: row;
5180        flex-direction: row;
5181      }
5182    "#,
5183      indoc! {r#"
5184      .foo {
5185        flex-direction: row;
5186      }
5187    "#},
5188      Browsers {
5189        safari: Some(14 << 16),
5190        ..Browsers::default()
5191      },
5192    );
5193    prefix_test(
5194      r#"
5195      .foo {
5196        flex-wrap: wrap;
5197      }
5198    "#,
5199      indoc! {r#"
5200      .foo {
5201        -webkit-box-lines: multiple;
5202        -moz-box-lines: multiple;
5203        -webkit-flex-wrap: wrap;
5204        -ms-flex-wrap: wrap;
5205        flex-wrap: wrap;
5206      }
5207    "#},
5208      Browsers {
5209        safari: Some(4 << 16),
5210        firefox: Some(4 << 16),
5211        ie: Some(10 << 16),
5212        ..Browsers::default()
5213      },
5214    );
5215    prefix_test(
5216      r#"
5217      .foo {
5218        -webkit-box-lines: multiple;
5219        -moz-box-lines: multiple;
5220        -webkit-flex-wrap: wrap;
5221        -ms-flex-wrap: wrap;
5222        flex-wrap: wrap;
5223      }
5224    "#,
5225      indoc! {r#"
5226      .foo {
5227        flex-wrap: wrap;
5228      }
5229    "#},
5230      Browsers {
5231        safari: Some(11 << 16),
5232        ..Browsers::default()
5233      },
5234    );
5235    prefix_test(
5236      r#"
5237      .foo {
5238        flex-flow: row wrap;
5239      }
5240    "#,
5241      indoc! {r#"
5242      .foo {
5243        -webkit-box-orient: horizontal;
5244        -moz-box-orient: horizontal;
5245        -webkit-box-direction: normal;
5246        -moz-box-direction: normal;
5247        -webkit-flex-flow: wrap;
5248        -ms-flex-flow: wrap;
5249        flex-flow: wrap;
5250      }
5251    "#},
5252      Browsers {
5253        safari: Some(4 << 16),
5254        firefox: Some(4 << 16),
5255        ie: Some(10 << 16),
5256        ..Browsers::default()
5257      },
5258    );
5259    prefix_test(
5260      r#"
5261      .foo {
5262        -webkit-box-orient: horizontal;
5263        -moz-box-orient: horizontal;
5264        -webkit-box-direction: normal;
5265        -moz-box-direction: normal;
5266        -webkit-flex-flow: wrap;
5267        -ms-flex-flow: wrap;
5268        flex-flow: wrap;
5269      }
5270    "#,
5271      indoc! {r#"
5272      .foo {
5273        flex-flow: wrap;
5274      }
5275    "#},
5276      Browsers {
5277        safari: Some(11 << 16),
5278        ..Browsers::default()
5279      },
5280    );
5281    prefix_test(
5282      r#"
5283      .foo {
5284        flex-grow: 1;
5285      }
5286    "#,
5287      indoc! {r#"
5288      .foo {
5289        -webkit-box-flex: 1;
5290        -moz-box-flex: 1;
5291        -ms-flex-positive: 1;
5292        -webkit-flex-grow: 1;
5293        flex-grow: 1;
5294      }
5295    "#},
5296      Browsers {
5297        safari: Some(4 << 16),
5298        firefox: Some(4 << 16),
5299        ie: Some(10 << 16),
5300        ..Browsers::default()
5301      },
5302    );
5303    prefix_test(
5304      r#"
5305      .foo {
5306        -webkit-box-flex: 1;
5307        -moz-box-flex: 1;
5308        -ms-flex-positive: 1;
5309        -webkit-flex-grow: 1;
5310        flex-grow: 1;
5311      }
5312    "#,
5313      indoc! {r#"
5314      .foo {
5315        flex-grow: 1;
5316      }
5317    "#},
5318      Browsers {
5319        safari: Some(11 << 16),
5320        ..Browsers::default()
5321      },
5322    );
5323    prefix_test(
5324      r#"
5325      .foo {
5326        flex-shrink: 1;
5327      }
5328    "#,
5329      indoc! {r#"
5330      .foo {
5331        -ms-flex-negative: 1;
5332        -webkit-flex-shrink: 1;
5333        flex-shrink: 1;
5334      }
5335    "#},
5336      Browsers {
5337        safari: Some(4 << 16),
5338        firefox: Some(4 << 16),
5339        ie: Some(10 << 16),
5340        ..Browsers::default()
5341      },
5342    );
5343    prefix_test(
5344      r#"
5345      .foo {
5346        -ms-flex-negative: 1;
5347        -webkit-flex-shrink: 1;
5348        flex-shrink: 1;
5349      }
5350    "#,
5351      indoc! {r#"
5352      .foo {
5353        flex-shrink: 1;
5354      }
5355    "#},
5356      Browsers {
5357        safari: Some(11 << 16),
5358        ..Browsers::default()
5359      },
5360    );
5361    prefix_test(
5362      r#"
5363      .foo {
5364        flex-basis: 1px;
5365      }
5366    "#,
5367      indoc! {r#"
5368      .foo {
5369        -ms-flex-preferred-size: 1px;
5370        -webkit-flex-basis: 1px;
5371        flex-basis: 1px;
5372      }
5373    "#},
5374      Browsers {
5375        safari: Some(4 << 16),
5376        firefox: Some(4 << 16),
5377        ie: Some(10 << 16),
5378        ..Browsers::default()
5379      },
5380    );
5381    prefix_test(
5382      r#"
5383      .foo {
5384        -ms-flex-preferred-size: 1px;
5385        -webkit-flex-basis: 1px;
5386        flex-basis: 1px;
5387      }
5388    "#,
5389      indoc! {r#"
5390      .foo {
5391        flex-basis: 1px;
5392      }
5393    "#},
5394      Browsers {
5395        safari: Some(11 << 16),
5396        ..Browsers::default()
5397      },
5398    );
5399    prefix_test(
5400      r#"
5401      .foo {
5402        flex: 1;
5403      }
5404    "#,
5405      indoc! {r#"
5406      .foo {
5407        -webkit-box-flex: 1;
5408        -moz-box-flex: 1;
5409        -webkit-flex: 1;
5410        -ms-flex: 1;
5411        flex: 1;
5412      }
5413    "#},
5414      Browsers {
5415        safari: Some(4 << 16),
5416        firefox: Some(4 << 16),
5417        ie: Some(10 << 16),
5418        ..Browsers::default()
5419      },
5420    );
5421    prefix_test(
5422      r#"
5423      .foo {
5424        -webkit-box-flex: 1;
5425        -moz-box-flex: 1;
5426        -webkit-flex: 1;
5427        -ms-flex: 1;
5428        flex: 1;
5429      }
5430    "#,
5431      indoc! {r#"
5432      .foo {
5433        flex: 1;
5434      }
5435    "#},
5436      Browsers {
5437        safari: Some(11 << 16),
5438        ..Browsers::default()
5439      },
5440    );
5441    prefix_test(
5442      r#"
5443      .foo {
5444        align-content: space-between;
5445      }
5446    "#,
5447      indoc! {r#"
5448      .foo {
5449        -ms-flex-line-pack: justify;
5450        -webkit-align-content: space-between;
5451        align-content: space-between;
5452      }
5453    "#},
5454      Browsers {
5455        safari: Some(4 << 16),
5456        firefox: Some(4 << 16),
5457        ie: Some(10 << 16),
5458        ..Browsers::default()
5459      },
5460    );
5461    prefix_test(
5462      r#"
5463      .foo {
5464        -ms-flex-line-pack: justify;
5465        -webkit-align-content: space-between;
5466        align-content: space-between;
5467      }
5468    "#,
5469      indoc! {r#"
5470      .foo {
5471        align-content: space-between;
5472      }
5473    "#},
5474      Browsers {
5475        safari: Some(11 << 16),
5476        ..Browsers::default()
5477      },
5478    );
5479    prefix_test(
5480      r#"
5481      .foo {
5482        justify-content: space-between;
5483      }
5484    "#,
5485      indoc! {r#"
5486      .foo {
5487        -webkit-box-pack: justify;
5488        -moz-box-pack: justify;
5489        -ms-flex-pack: justify;
5490        -webkit-justify-content: space-between;
5491        justify-content: space-between;
5492      }
5493    "#},
5494      Browsers {
5495        safari: Some(4 << 16),
5496        firefox: Some(4 << 16),
5497        ie: Some(10 << 16),
5498        ..Browsers::default()
5499      },
5500    );
5501    prefix_test(
5502      r#"
5503      .foo {
5504        -webkit-box-pack: justify;
5505        -moz-box-pack: justify;
5506        -ms-flex-pack: justify;
5507        -webkit-justify-content: space-between;
5508        justify-content: space-between;
5509      }
5510    "#,
5511      indoc! {r#"
5512      .foo {
5513        justify-content: space-between;
5514      }
5515    "#},
5516      Browsers {
5517        safari: Some(11 << 16),
5518        ..Browsers::default()
5519      },
5520    );
5521    prefix_test(
5522      r#"
5523      .foo {
5524        place-content: space-between flex-end;
5525      }
5526    "#,
5527      indoc! {r#"
5528      .foo {
5529        -ms-flex-line-pack: justify;
5530        -webkit-box-pack: end;
5531        -moz-box-pack: end;
5532        -ms-flex-pack: end;
5533        -webkit-align-content: space-between;
5534        align-content: space-between;
5535        -webkit-justify-content: flex-end;
5536        justify-content: flex-end;
5537      }
5538    "#},
5539      Browsers {
5540        safari: Some(4 << 16),
5541        firefox: Some(4 << 16),
5542        ie: Some(10 << 16),
5543        ..Browsers::default()
5544      },
5545    );
5546    prefix_test(
5547      r#"
5548      .foo {
5549        -ms-flex-line-pack: justify;
5550        -webkit-box-pack: end;
5551        -moz-box-pack: end;
5552        -ms-flex-pack: end;
5553        -webkit-align-content: space-between;
5554        -webkit-justify-content: flex-end;
5555        place-content: space-between flex-end;
5556      }
5557    "#,
5558      indoc! {r#"
5559      .foo {
5560        place-content: space-between flex-end;
5561      }
5562    "#},
5563      Browsers {
5564        safari: Some(11 << 16),
5565        ..Browsers::default()
5566      },
5567    );
5568    prefix_test(
5569      r#"
5570      .foo {
5571        place-content: space-between flex-end;
5572      }
5573    "#,
5574      indoc! {r#"
5575      .foo {
5576        align-content: space-between;
5577        justify-content: flex-end;
5578      }
5579    "#},
5580      Browsers {
5581        chrome: Some(30 << 16),
5582        ..Browsers::default()
5583      },
5584    );
5585    prefix_test(
5586      r#"
5587      .foo {
5588        place-content: space-between flex-end;
5589      }
5590    "#,
5591      indoc! {r#"
5592      .foo {
5593        place-content: space-between flex-end;
5594      }
5595    "#},
5596      Browsers {
5597        chrome: Some(60 << 16),
5598        ..Browsers::default()
5599      },
5600    );
5601    prefix_test(
5602      r#"
5603      .foo {
5604        align-self: flex-end;
5605      }
5606    "#,
5607      indoc! {r#"
5608      .foo {
5609        -ms-flex-item-align: end;
5610        -webkit-align-self: flex-end;
5611        align-self: flex-end;
5612      }
5613    "#},
5614      Browsers {
5615        safari: Some(4 << 16),
5616        firefox: Some(4 << 16),
5617        ie: Some(10 << 16),
5618        ..Browsers::default()
5619      },
5620    );
5621    prefix_test(
5622      r#"
5623      .foo {
5624        -ms-flex-item-align: end;
5625        -webkit-align-self: flex-end;
5626        align-self: flex-end;
5627      }
5628    "#,
5629      indoc! {r#"
5630      .foo {
5631        align-self: flex-end;
5632      }
5633    "#},
5634      Browsers {
5635        safari: Some(11 << 16),
5636        ..Browsers::default()
5637      },
5638    );
5639    prefix_test(
5640      r#"
5641      .foo {
5642        place-self: center flex-end;
5643      }
5644    "#,
5645      indoc! {r#"
5646      .foo {
5647        -ms-flex-item-align: center;
5648        -webkit-align-self: center;
5649        align-self: center;
5650        justify-self: flex-end;
5651      }
5652    "#},
5653      Browsers {
5654        safari: Some(4 << 16),
5655        firefox: Some(4 << 16),
5656        ie: Some(10 << 16),
5657        ..Browsers::default()
5658      },
5659    );
5660    prefix_test(
5661      r#"
5662      .foo {
5663        -ms-flex-item-align: center;
5664        -webkit-align-self: center;
5665        place-self: center flex-end;
5666      }
5667    "#,
5668      indoc! {r#"
5669      .foo {
5670        place-self: center flex-end;
5671      }
5672    "#},
5673      Browsers {
5674        safari: Some(11 << 16),
5675        ..Browsers::default()
5676      },
5677    );
5678    prefix_test(
5679      r#"
5680      .foo {
5681        place-self: center flex-end;
5682      }
5683    "#,
5684      indoc! {r#"
5685      .foo {
5686        align-self: center;
5687        justify-self: flex-end;
5688      }
5689    "#},
5690      Browsers {
5691        chrome: Some(57 << 16),
5692        ..Browsers::default()
5693      },
5694    );
5695    prefix_test(
5696      r#"
5697      .foo {
5698        place-self: center flex-end;
5699      }
5700    "#,
5701      indoc! {r#"
5702      .foo {
5703        place-self: center flex-end;
5704      }
5705    "#},
5706      Browsers {
5707        chrome: Some(59 << 16),
5708        ..Browsers::default()
5709      },
5710    );
5711    prefix_test(
5712      r#"
5713      .foo {
5714        align-items: flex-end;
5715      }
5716    "#,
5717      indoc! {r#"
5718      .foo {
5719        -webkit-box-align: end;
5720        -moz-box-align: end;
5721        -ms-flex-align: end;
5722        -webkit-align-items: flex-end;
5723        align-items: flex-end;
5724      }
5725    "#},
5726      Browsers {
5727        safari: Some(4 << 16),
5728        firefox: Some(4 << 16),
5729        ie: Some(10 << 16),
5730        ..Browsers::default()
5731      },
5732    );
5733    prefix_test(
5734      r#"
5735      .foo {
5736        -webkit-box-align: end;
5737        -moz-box-align: end;
5738        -ms-flex-align: end;
5739        -webkit-align-items: flex-end;
5740        align-items: flex-end;
5741      }
5742    "#,
5743      indoc! {r#"
5744      .foo {
5745        align-items: flex-end;
5746      }
5747    "#},
5748      Browsers {
5749        safari: Some(11 << 16),
5750        ..Browsers::default()
5751      },
5752    );
5753    prefix_test(
5754      r#"
5755      .foo {
5756        place-items: flex-end center;
5757      }
5758    "#,
5759      indoc! {r#"
5760      .foo {
5761        -webkit-box-align: end;
5762        -moz-box-align: end;
5763        -ms-flex-align: end;
5764        -webkit-align-items: flex-end;
5765        align-items: flex-end;
5766        justify-items: center;
5767      }
5768    "#},
5769      Browsers {
5770        safari: Some(4 << 16),
5771        firefox: Some(4 << 16),
5772        ie: Some(10 << 16),
5773        ..Browsers::default()
5774      },
5775    );
5776    prefix_test(
5777      r#"
5778      .foo {
5779        -webkit-box-align: end;
5780        -moz-box-align: end;
5781        -ms-flex-align: end;
5782        -webkit-align-items: flex-end;
5783        place-items: flex-end center;
5784      }
5785    "#,
5786      indoc! {r#"
5787      .foo {
5788        place-items: flex-end center;
5789      }
5790    "#},
5791      Browsers {
5792        safari: Some(11 << 16),
5793        ..Browsers::default()
5794      },
5795    );
5796    prefix_test(
5797      r#"
5798      .foo {
5799        place-items: flex-end center;
5800      }
5801    "#,
5802      indoc! {r#"
5803      .foo {
5804        align-items: flex-end;
5805        justify-items: center;
5806      }
5807    "#},
5808      Browsers {
5809        safari: Some(10 << 16),
5810        ..Browsers::default()
5811      },
5812    );
5813    prefix_test(
5814      r#"
5815      .foo {
5816        order: 1;
5817      }
5818    "#,
5819      indoc! {r#"
5820      .foo {
5821        -webkit-box-ordinal-group: 1;
5822        -moz-box-ordinal-group: 1;
5823        -ms-flex-order: 1;
5824        -webkit-order: 1;
5825        order: 1;
5826      }
5827    "#},
5828      Browsers {
5829        safari: Some(4 << 16),
5830        firefox: Some(4 << 16),
5831        ie: Some(10 << 16),
5832        ..Browsers::default()
5833      },
5834    );
5835    prefix_test(
5836      r#"
5837      .foo {
5838        -webkit-box-ordinal-group: 1;
5839        -moz-box-ordinal-group: 1;
5840        -ms-flex-order: 1;
5841        -webkit-order: 1;
5842        order: 1;
5843      }
5844    "#,
5845      indoc! {r#"
5846      .foo {
5847        order: 1;
5848      }
5849    "#},
5850      Browsers {
5851        safari: Some(11 << 16),
5852        ..Browsers::default()
5853      },
5854    );
5855    prefix_test(
5856      r#"
5857      .foo {
5858        -ms-flex: 0 0 8%;
5859        flex: 0 0 5%;
5860      }
5861    "#,
5862      indoc! {r#"
5863      .foo {
5864        -ms-flex: 0 0 8%;
5865        flex: 0 0 5%;
5866      }
5867    "#},
5868      Browsers {
5869        safari: Some(11 << 16),
5870        ..Browsers::default()
5871      },
5872    );
5873  }
5874
5875  #[test]
5876  fn test_font() {
5877    test(
5878      r#"
5879      .foo {
5880        font-family: "Helvetica", "Times New Roman", sans-serif;
5881        font-size: 12px;
5882        font-weight: bold;
5883        font-style: italic;
5884        font-stretch: expanded;
5885        font-variant-caps: small-caps;
5886        line-height: 1.2em;
5887      }
5888    "#,
5889      indoc! {r#"
5890      .foo {
5891        font: italic small-caps bold expanded 12px / 1.2em Helvetica, Times New Roman, sans-serif;
5892      }
5893    "#
5894      },
5895    );
5896
5897    minify_test(
5898      r#"
5899      .foo {
5900        font-family: "Helvetica", "Times New Roman", sans-serif;
5901        font-size: 12px;
5902        font-weight: bold;
5903        font-style: italic;
5904        font-stretch: expanded;
5905        font-variant-caps: small-caps;
5906        line-height: 1.2em;
5907      }
5908    "#,
5909      indoc! {".foo{font:italic small-caps 700 125% 12px/1.2em Helvetica,Times New Roman,sans-serif}"
5910      },
5911    );
5912
5913    test(
5914      r#"
5915      .foo {
5916        font: 12px "Helvetica", "Times New Roman", sans-serif;
5917        line-height: 1.2em;
5918      }
5919    "#,
5920      indoc! {r#"
5921      .foo {
5922        font: 12px / 1.2em Helvetica, Times New Roman, sans-serif;
5923      }
5924    "#
5925      },
5926    );
5927
5928    test(
5929      r#"
5930      .foo {
5931        font: 12px "Helvetica", "Times New Roman", sans-serif;
5932        line-height: var(--lh);
5933      }
5934    "#,
5935      indoc! {r#"
5936      .foo {
5937        font: 12px Helvetica, Times New Roman, sans-serif;
5938        line-height: var(--lh);
5939      }
5940    "#
5941      },
5942    );
5943
5944    minify_test(
5945      r#"
5946      .foo {
5947        font-family: "Helvetica", "Times New Roman", sans-serif;
5948        font-size: 12px;
5949        font-stretch: expanded;
5950      }
5951    "#,
5952      indoc! {".foo{font-family:Helvetica,Times New Roman,sans-serif;font-size:12px;font-stretch:125%}"
5953      },
5954    );
5955
5956    test(
5957      r#"
5958      .foo {
5959        font-family: "Helvetica", "Times New Roman", sans-serif;
5960        font-size: 12px;
5961        font-weight: bold;
5962        font-style: italic;
5963        font-stretch: expanded;
5964        font-variant-caps: all-small-caps;
5965        line-height: 1.2em;
5966      }
5967    "#,
5968      indoc! {r#"
5969      .foo {
5970        font: italic bold expanded 12px / 1.2em Helvetica, Times New Roman, sans-serif;
5971        font-variant-caps: all-small-caps;
5972      }
5973    "#
5974      },
5975    );
5976
5977    minify_test(
5978      ".foo { font: normal normal 600 9px/normal Charcoal; }",
5979      ".foo{font:600 9px Charcoal}",
5980    );
5981    minify_test(
5982      ".foo { font: normal normal 500 medium/normal Charcoal; }",
5983      ".foo{font:500 medium Charcoal}",
5984    );
5985    minify_test(
5986      ".foo { font: normal normal 400 medium Charcoal; }",
5987      ".foo{font:400 medium Charcoal}",
5988    );
5989    minify_test(
5990      ".foo { font: normal normal 500 medium/10px Charcoal; }",
5991      ".foo{font:500 medium/10px Charcoal}",
5992    );
5993    minify_test(
5994      ".foo { font-family: 'sans-serif'; }",
5995      ".foo{font-family:\"sans-serif\"}",
5996    );
5997    minify_test(".foo { font-family: sans-serif; }", ".foo{font-family:sans-serif}");
5998    minify_test(".foo { font-family: 'default'; }", ".foo{font-family:\"default\"}");
5999    minify_test(".foo { font-family: default; }", ".foo{font-family:default}");
6000    minify_test(".foo { font-family: 'inherit'; }", ".foo{font-family:\"inherit\"}");
6001    minify_test(".foo { font-family: inherit; }", ".foo{font-family:inherit}");
6002    minify_test(".foo { font-family: inherit test; }", ".foo{font-family:inherit test}");
6003    minify_test(
6004      ".foo { font-family: 'inherit test'; }",
6005      ".foo{font-family:inherit test}",
6006    );
6007    minify_test(".foo { font-family: revert; }", ".foo{font-family:revert}");
6008    minify_test(".foo { font-family: 'revert'; }", ".foo{font-family:\"revert\"}");
6009    minify_test(".foo { font-family: revert-layer; }", ".foo{font-family:revert-layer}");
6010    minify_test(
6011      ".foo { font-family: revert-layer, serif; }",
6012      ".foo{font-family:revert-layer,serif}",
6013    );
6014    minify_test(
6015      ".foo { font-family: 'revert', sans-serif; }",
6016      ".foo{font-family:\"revert\",sans-serif}",
6017    );
6018    minify_test(
6019      ".foo { font-family: 'revert', foo, sans-serif; }",
6020      ".foo{font-family:\"revert\",foo,sans-serif}",
6021    );
6022    minify_test(".foo { font-family: ''; }", ".foo{font-family:\"\"}");
6023
6024    // font-family in @font-face
6025    minify_test(
6026      "@font-face { font-family: 'revert'; }",
6027      "@font-face{font-family:\"revert\"}",
6028    );
6029    minify_test(
6030      "@font-face { font-family: 'revert-layer'; }",
6031      "@font-face{font-family:\"revert-layer\"}",
6032    );
6033
6034    prefix_test(
6035      r#"
6036      .foo {
6037        font-family: Helvetica, system-ui, sans-serif;
6038      }
6039    "#,
6040      indoc! {r#"
6041      .foo {
6042        font-family: Helvetica, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Noto Sans, Ubuntu, Cantarell, Helvetica Neue, sans-serif;
6043      }
6044    "#
6045      },
6046      Browsers {
6047        safari: Some(8 << 16),
6048        ..Browsers::default()
6049      },
6050    );
6051
6052    prefix_test(
6053      r#"
6054      .foo {
6055        font: 100%/1.5 Helvetica, system-ui, sans-serif;
6056      }
6057    "#,
6058      indoc! {r#"
6059      .foo {
6060        font: 100% / 1.5 Helvetica, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Noto Sans, Ubuntu, Cantarell, Helvetica Neue, sans-serif;
6061      }
6062    "#
6063      },
6064      Browsers {
6065        safari: Some(8 << 16),
6066        ..Browsers::default()
6067      },
6068    );
6069
6070    prefix_test(
6071      r#"
6072      .foo {
6073        font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
6074      }
6075    "#,
6076      indoc! {r#"
6077      .foo {
6078        font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Noto Sans, Ubuntu, Cantarell, Helvetica Neue, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
6079      }
6080    "#
6081      },
6082      Browsers {
6083        firefox: Some(91 << 16),
6084        ..Browsers::default()
6085      },
6086    );
6087
6088    prefix_test(
6089      r#"
6090      .foo {
6091        font-size: 22px;
6092        font-size: max(2cqw, 22px);
6093      }
6094    "#,
6095      indoc! {r#"
6096      .foo {
6097        font-size: 22px;
6098        font-size: max(2cqw, 22px);
6099      }
6100    "#
6101      },
6102      Browsers {
6103        safari: Some(14 << 16),
6104        ..Browsers::default()
6105      },
6106    );
6107    prefix_test(
6108      r#"
6109      .foo {
6110        font-size: 22px;
6111        font-size: max(2cqw, 22px);
6112      }
6113    "#,
6114      indoc! {r#"
6115      .foo {
6116        font-size: max(2cqw, 22px);
6117      }
6118    "#
6119      },
6120      Browsers {
6121        safari: Some(16 << 16),
6122        ..Browsers::default()
6123      },
6124    );
6125
6126    prefix_test(
6127      r#"
6128      .foo {
6129        font-size: 22px;
6130        font-size: xxx-large;
6131      }
6132    "#,
6133      indoc! {r#"
6134      .foo {
6135        font-size: 22px;
6136        font-size: xxx-large;
6137      }
6138    "#
6139      },
6140      Browsers {
6141        chrome: Some(70 << 16),
6142        ..Browsers::default()
6143      },
6144    );
6145    prefix_test(
6146      r#"
6147      .foo {
6148        font-size: 22px;
6149        font-size: xxx-large;
6150      }
6151    "#,
6152      indoc! {r#"
6153      .foo {
6154        font-size: xxx-large;
6155      }
6156    "#
6157      },
6158      Browsers {
6159        chrome: Some(80 << 16),
6160        ..Browsers::default()
6161      },
6162    );
6163
6164    prefix_test(
6165      r#"
6166      .foo {
6167        font-weight: 700;
6168        font-weight: 789;
6169      }
6170    "#,
6171      indoc! {r#"
6172      .foo {
6173        font-weight: 700;
6174        font-weight: 789;
6175      }
6176    "#
6177      },
6178      Browsers {
6179        chrome: Some(60 << 16),
6180        ..Browsers::default()
6181      },
6182    );
6183    prefix_test(
6184      r#"
6185      .foo {
6186        font-weight: 700;
6187        font-weight: 789;
6188      }
6189    "#,
6190      indoc! {r#"
6191      .foo {
6192        font-weight: 789;
6193      }
6194    "#
6195      },
6196      Browsers {
6197        chrome: Some(80 << 16),
6198        ..Browsers::default()
6199      },
6200    );
6201
6202    prefix_test(
6203      r#"
6204      .foo {
6205        font-family: Helvetica;
6206        font-family: system-ui;
6207      }
6208    "#,
6209      indoc! {r#"
6210      .foo {
6211        font-family: Helvetica;
6212        font-family: system-ui;
6213      }
6214    "#
6215      },
6216      Browsers {
6217        chrome: Some(50 << 16),
6218        ..Browsers::default()
6219      },
6220    );
6221    prefix_test(
6222      r#"
6223      .foo {
6224        font-family: Helvetica;
6225        font-family: system-ui;
6226      }
6227    "#,
6228      indoc! {r#"
6229      .foo {
6230        font-family: system-ui;
6231      }
6232    "#
6233      },
6234      Browsers {
6235        chrome: Some(80 << 16),
6236        ..Browsers::default()
6237      },
6238    );
6239
6240    prefix_test(
6241      r#"
6242      .foo {
6243        font-style: oblique;
6244        font-style: oblique 40deg;
6245      }
6246    "#,
6247      indoc! {r#"
6248      .foo {
6249        font-style: oblique;
6250        font-style: oblique 40deg;
6251      }
6252    "#
6253      },
6254      Browsers {
6255        firefox: Some(50 << 16),
6256        ..Browsers::default()
6257      },
6258    );
6259    prefix_test(
6260      r#"
6261      .foo {
6262        font-style: oblique;
6263        font-style: oblique 40deg;
6264      }
6265    "#,
6266      indoc! {r#"
6267      .foo {
6268        font-style: oblique 40deg;
6269      }
6270    "#
6271      },
6272      Browsers {
6273        firefox: Some(80 << 16),
6274        ..Browsers::default()
6275      },
6276    );
6277
6278    prefix_test(
6279      r#"
6280      .foo {
6281        font: 22px Helvetica;
6282        font: xxx-large system-ui;
6283      }
6284    "#,
6285      indoc! {r#"
6286      .foo {
6287        font: 22px Helvetica;
6288        font: xxx-large system-ui;
6289      }
6290    "#
6291      },
6292      Browsers {
6293        chrome: Some(70 << 16),
6294        ..Browsers::default()
6295      },
6296    );
6297    prefix_test(
6298      r#"
6299      .foo {
6300        font: 22px Helvetica;
6301        font: xxx-large system-ui;
6302      }
6303    "#,
6304      indoc! {r#"
6305      .foo {
6306        font: xxx-large system-ui;
6307      }
6308    "#
6309      },
6310      Browsers {
6311        chrome: Some(80 << 16),
6312        ..Browsers::default()
6313      },
6314    );
6315
6316    prefix_test(
6317      r#"
6318      .foo {
6319        font: var(--fallback);
6320        font: xxx-large system-ui;
6321      }
6322    "#,
6323      indoc! {r#"
6324      .foo {
6325        font: var(--fallback);
6326        font: xxx-large system-ui;
6327      }
6328    "#
6329      },
6330      Browsers {
6331        chrome: Some(50 << 16),
6332        ..Browsers::default()
6333      },
6334    );
6335  }
6336
6337  #[test]
6338  fn test_vertical_align() {
6339    minify_test(".foo { vertical-align: middle }", ".foo{vertical-align:middle}");
6340    minify_test(".foo { vertical-align: 0.3em }", ".foo{vertical-align:.3em}");
6341  }
6342
6343  #[test]
6344  fn test_selectors() {
6345    minify_test(":nth-col(2n) {width: 20px}", ":nth-col(2n){width:20px}");
6346    minify_test(":nth-col(10n-1) {width: 20px}", ":nth-col(10n-1){width:20px}");
6347    minify_test(":nth-col(-n+2) {width: 20px}", ":nth-col(-n+2){width:20px}");
6348    minify_test(":nth-col(even) {width: 20px}", ":nth-col(2n){width:20px}");
6349    minify_test(":nth-col(odd) {width: 20px}", ":nth-col(odd){width:20px}");
6350    minify_test(":nth-last-col(2n) {width: 20px}", ":nth-last-col(2n){width:20px}");
6351    minify_test(":nth-last-col(10n-1) {width: 20px}", ":nth-last-col(10n-1){width:20px}");
6352    minify_test(":nth-last-col(-n+2) {width: 20px}", ":nth-last-col(-n+2){width:20px}");
6353    minify_test(":nth-last-col(even) {width: 20px}", ":nth-last-col(2n){width:20px}");
6354    minify_test(":nth-last-col(odd) {width: 20px}", ":nth-last-col(odd){width:20px}");
6355    minify_test(":nth-child(odd) {width: 20px}", ":nth-child(odd){width:20px}");
6356    minify_test(":nth-child(2n) {width: 20px}", ":nth-child(2n){width:20px}");
6357    minify_test(":nth-child(2n+1) {width: 20px}", ":nth-child(odd){width:20px}");
6358    minify_test(":first-child {width: 20px}", ":first-child{width:20px}");
6359    minify_test(":nth-child(1) {width: 20px}", ":first-child{width:20px}");
6360    minify_test(":nth-last-child(1) {width: 20px}", ":last-child{width:20px}");
6361    minify_test(":nth-of-type(1) {width: 20px}", ":first-of-type{width:20px}");
6362    minify_test(":nth-last-of-type(1) {width: 20px}", ":last-of-type{width:20px}");
6363    minify_test(
6364      ":nth-child(even of li.important) {width: 20px}",
6365      ":nth-child(2n of li.important){width:20px}",
6366    );
6367    minify_test(
6368      ":nth-child(1 of li.important) {width: 20px}",
6369      ":nth-child(1 of li.important){width:20px}",
6370    );
6371    minify_test(
6372      ":nth-last-child(even of li.important) {width: 20px}",
6373      ":nth-last-child(2n of li.important){width:20px}",
6374    );
6375    minify_test(
6376      ":nth-last-child(1 of li.important) {width: 20px}",
6377      ":nth-last-child(1 of li.important){width:20px}",
6378    );
6379    minify_test(
6380      ":nth-last-child(1 of.important) {width: 20px}",
6381      ":nth-last-child(1 of .important){width:20px}",
6382    );
6383
6384    minify_test("[foo=\"baz\"] {color:red}", "[foo=baz]{color:red}");
6385    minify_test("[foo=\"foo bar\"] {color:red}", "[foo=foo\\ bar]{color:red}");
6386    minify_test("[foo=\"foo bar baz\"] {color:red}", "[foo=\"foo bar baz\"]{color:red}");
6387    minify_test("[foo=\"\"] {color:red}", "[foo=\"\"]{color:red}");
6388    minify_test(
6389      ".test:not([foo=\"bar\"]) {color:red}",
6390      ".test:not([foo=bar]){color:red}",
6391    );
6392    minify_test(".test + .foo {color:red}", ".test+.foo{color:red}");
6393    minify_test(".test ~ .foo {color:red}", ".test~.foo{color:red}");
6394    minify_test(".test .foo {color:red}", ".test .foo{color:red}");
6395    minify_test(
6396      ".custom-range::-webkit-slider-thumb:active {color:red}",
6397      ".custom-range::-webkit-slider-thumb:active{color:red}",
6398    );
6399    minify_test(".test:not(.foo, .bar) {color:red}", ".test:not(.foo,.bar){color:red}");
6400    minify_test(".test:is(.foo, .bar) {color:red}", ".test:is(.foo,.bar){color:red}");
6401    minify_test(
6402      ".test:where(.foo, .bar) {color:red}",
6403      ".test:where(.foo,.bar){color:red}",
6404    );
6405    minify_test(
6406      ".test:where(.foo, .bar) {color:red}",
6407      ".test:where(.foo,.bar){color:red}",
6408    );
6409    minify_test(":host {color:red}", ":host{color:red}");
6410    minify_test(":host(.foo) {color:red}", ":host(.foo){color:red}");
6411    minify_test("::slotted(span) {color:red", "::slotted(span){color:red}");
6412    minify_test(
6413      "custom-element::part(foo) {color:red}",
6414      "custom-element::part(foo){color:red}",
6415    );
6416    minify_test(".sm\\:text-5xl { font-size: 3rem }", ".sm\\:text-5xl{font-size:3rem}");
6417    minify_test("a:has(> img) {color:red}", "a:has(>img){color:red}");
6418    minify_test("dt:has(+ dt) {color:red}", "dt:has(+dt){color:red}");
6419    minify_test(
6420      "section:not(:has(h1, h2, h3, h4, h5, h6)) {color:red}",
6421      "section:not(:has(h1,h2,h3,h4,h5,h6)){color:red}",
6422    );
6423    minify_test(
6424      ":has(.sibling ~ .target) {color:red}",
6425      ":has(.sibling~.target){color:red}",
6426    );
6427    minify_test(".x:has(> .a > .b) {color:red}", ".x:has(>.a>.b){color:red}");
6428    minify_test(".x:has(.bar, #foo) {color:red}", ".x:has(.bar,#foo){color:red}");
6429    minify_test(".x:has(span + span) {color:red}", ".x:has(span+span){color:red}");
6430    minify_test("a:has(:visited) {color:red}", "a:has(:visited){color:red}");
6431    for element in [
6432      "-webkit-scrollbar",
6433      "-webkit-scrollbar-button",
6434      "-webkit-scrollbar-track",
6435      "-webkit-scrollbar-track-piece",
6436      "-webkit-scrollbar-thumb",
6437      "-webkit-scrollbar-corner",
6438      "-webkit-resizer",
6439    ] {
6440      for class in [
6441        "enabled",
6442        "disabled",
6443        "hover",
6444        "active",
6445        "horizontal",
6446        "vertical",
6447        "decrement",
6448        "increment",
6449        "start",
6450        "end",
6451        "double-button",
6452        "single-button",
6453        "no-button",
6454        "corner-present",
6455        "window-inactive",
6456      ] {
6457        minify_test(
6458          &format!("::{}:{} {{color:red}}", element, class),
6459          &format!("::{}:{}{{color:red}}", element, class),
6460        );
6461      }
6462    }
6463    for class in [
6464      "horizontal",
6465      "vertical",
6466      "decrement",
6467      "increment",
6468      "start",
6469      "end",
6470      "double-button",
6471      "single-button",
6472      "no-button",
6473      "corner-present",
6474      "window-inactive",
6475    ] {
6476      error_test(
6477        &format!(":{} {{color:red}}", class),
6478        ParserError::SelectorError(SelectorError::InvalidPseudoClassBeforeWebKitScrollbar),
6479      );
6480    }
6481    for element in [
6482      "-webkit-scrollbar",
6483      "-webkit-scrollbar-button",
6484      "-webkit-scrollbar-track",
6485      "-webkit-scrollbar-track-piece",
6486      "-webkit-scrollbar-thumb",
6487      "-webkit-scrollbar-corner",
6488      "-webkit-resizer",
6489    ] {
6490      error_test(
6491        &format!("::{}:focus {{color:red}}", element),
6492        ParserError::SelectorError(SelectorError::InvalidPseudoClassAfterWebKitScrollbar),
6493      );
6494    }
6495
6496    error_test(
6497      "a::first-letter:last-child {color:red}",
6498      ParserError::SelectorError(SelectorError::InvalidPseudoClassAfterPseudoElement),
6499    );
6500    minify_test(
6501      "a:last-child::first-letter {color:red}",
6502      "a:last-child:first-letter{color:red}",
6503    );
6504
6505    prefix_test(
6506      ".test:not(.foo, .bar) {color:red}",
6507      indoc! {r#"
6508      .test:not(:-webkit-any(.foo, .bar)) {
6509        color: red;
6510      }
6511
6512      .test:not(:is(.foo, .bar)) {
6513        color: red;
6514      }
6515      "#},
6516      Browsers {
6517        safari: Some(8 << 16),
6518        ..Browsers::default()
6519      },
6520    );
6521    prefix_test(
6522      ".test:not(.foo, .bar) {color:red}",
6523      indoc! {r#"
6524      .test:not(.foo, .bar) {
6525        color: red;
6526      }
6527      "#},
6528      Browsers {
6529        safari: Some(11 << 16),
6530        ..Browsers::default()
6531      },
6532    );
6533
6534    minify_test("a:lang(en) {color:red}", "a:lang(en){color:red}");
6535    minify_test("a:lang(en, fr) {color:red}", "a:lang(en,fr){color:red}");
6536    minify_test("a:lang('en') {color:red}", "a:lang(en){color:red}");
6537    minify_test(
6538      "a:-webkit-any(.foo, .bar) {color:red}",
6539      "a:-webkit-any(.foo,.bar){color:red}",
6540    );
6541    minify_test("a:-moz-any(.foo, .bar) {color:red}", "a:-moz-any(.foo,.bar){color:red}");
6542
6543    prefix_test(
6544      "a:is(.foo, .bar) {color:red}",
6545      indoc! {r#"
6546      a:-webkit-any(.foo, .bar) {
6547        color: red;
6548      }
6549
6550      a:-moz-any(.foo, .bar) {
6551        color: red;
6552      }
6553
6554      a:is(.foo, .bar) {
6555        color: red;
6556      }
6557      "#},
6558      Browsers {
6559        safari: Some(11 << 16),
6560        firefox: Some(50 << 16),
6561        ..Browsers::default()
6562      },
6563    );
6564
6565    prefix_test(
6566      "a:is(.foo > .bar) {color:red}",
6567      indoc! {r#"
6568      a:is(.foo > .bar) {
6569        color: red;
6570      }
6571      "#},
6572      Browsers {
6573        safari: Some(11 << 16),
6574        firefox: Some(50 << 16),
6575        ..Browsers::default()
6576      },
6577    );
6578
6579    prefix_test(
6580      "a:lang(en, fr) {color:red}",
6581      indoc! {r#"
6582      a:-webkit-any(:lang(en), :lang(fr)) {
6583        color: red;
6584      }
6585
6586      a:-moz-any(:lang(en), :lang(fr)) {
6587        color: red;
6588      }
6589
6590      a:is(:lang(en), :lang(fr)) {
6591        color: red;
6592      }
6593      "#},
6594      Browsers {
6595        safari: Some(11 << 16),
6596        firefox: Some(50 << 16),
6597        ..Browsers::default()
6598      },
6599    );
6600
6601    prefix_test(
6602      "a:lang(en, fr) {color:red}",
6603      indoc! {r#"
6604      a:is(:lang(en), :lang(fr)) {
6605        color: red;
6606      }
6607      "#},
6608      Browsers {
6609        safari: Some(14 << 16),
6610        firefox: Some(88 << 16),
6611        ..Browsers::default()
6612      },
6613    );
6614
6615    prefix_test(
6616      "a:lang(en, fr) {color:red}",
6617      indoc! {r#"
6618      a:lang(en, fr) {
6619        color: red;
6620      }
6621      "#},
6622      Browsers {
6623        safari: Some(14 << 16),
6624        ..Browsers::default()
6625      },
6626    );
6627
6628    prefix_test(
6629      "a:dir(rtl) {color:red}",
6630      indoc! {r#"
6631      a:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
6632        color: red;
6633      }
6634
6635      a:-moz-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
6636        color: red;
6637      }
6638
6639      a:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
6640        color: red;
6641      }
6642      "#},
6643      Browsers {
6644        safari: Some(11 << 16),
6645        firefox: Some(50 << 16),
6646        ..Browsers::default()
6647      },
6648    );
6649
6650    prefix_test(
6651      "a:dir(ltr) {color:red}",
6652      indoc! {r#"
6653      a:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
6654        color: red;
6655      }
6656
6657      a:not(:-moz-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
6658        color: red;
6659      }
6660
6661      a:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
6662        color: red;
6663      }
6664      "#},
6665      Browsers {
6666        safari: Some(11 << 16),
6667        firefox: Some(50 << 16),
6668        ..Browsers::default()
6669      },
6670    );
6671
6672    prefix_test(
6673      "a:dir(rtl) {color:red}",
6674      indoc! {r#"
6675      a:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
6676        color: red;
6677      }
6678      "#},
6679      Browsers {
6680        safari: Some(14 << 16),
6681        firefox: Some(88 << 16),
6682        ..Browsers::default()
6683      },
6684    );
6685
6686    prefix_test(
6687      "a:dir(ltr) {color:red}",
6688      indoc! {r#"
6689      a:not(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
6690        color: red;
6691      }
6692      "#},
6693      Browsers {
6694        safari: Some(14 << 16),
6695        firefox: Some(88 << 16),
6696        ..Browsers::default()
6697      },
6698    );
6699
6700    prefix_test(
6701      "a:dir(rtl) {color:red}",
6702      indoc! {r#"
6703      a:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
6704        color: red;
6705      }
6706      "#},
6707      Browsers {
6708        safari: Some(14 << 16),
6709        ..Browsers::default()
6710      },
6711    );
6712
6713    prefix_test(
6714      "a:dir(ltr) {color:red}",
6715      indoc! {r#"
6716      a:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
6717        color: red;
6718      }
6719      "#},
6720      Browsers {
6721        safari: Some(14 << 16),
6722        ..Browsers::default()
6723      },
6724    );
6725
6726    prefix_test(
6727      "a:is(:dir(rtl)) {color:red}",
6728      indoc! {r#"
6729      a:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
6730        color: red;
6731      }
6732      "#},
6733      Browsers {
6734        safari: Some(14 << 16),
6735        ..Browsers::default()
6736      },
6737    );
6738
6739    prefix_test(
6740      "a:where(:dir(rtl)) {color:red}",
6741      indoc! {r#"
6742      a:where(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
6743        color: red;
6744      }
6745      "#},
6746      Browsers {
6747        safari: Some(14 << 16),
6748        ..Browsers::default()
6749      },
6750    );
6751
6752    prefix_test(
6753      "a:has(:dir(rtl)) {color:red}",
6754      indoc! {r#"
6755      a:has(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
6756        color: red;
6757      }
6758      "#},
6759      Browsers {
6760        safari: Some(14 << 16),
6761        ..Browsers::default()
6762      },
6763    );
6764
6765    prefix_test(
6766      "a:not(:dir(rtl)) {color:red}",
6767      indoc! {r#"
6768      a:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
6769        color: red;
6770      }
6771      "#},
6772      Browsers {
6773        safari: Some(14 << 16),
6774        ..Browsers::default()
6775      },
6776    );
6777
6778    prefix_test(
6779      "a:dir(rtl)::after {color:red}",
6780      indoc! {r#"
6781      a:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi):after {
6782        color: red;
6783      }
6784      "#},
6785      Browsers {
6786        safari: Some(14 << 16),
6787        ..Browsers::default()
6788      },
6789    );
6790
6791    prefix_test(
6792      "a:dir(rtl) div {color:red}",
6793      indoc! {r#"
6794      a:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) div {
6795        color: red;
6796      }
6797      "#},
6798      Browsers {
6799        safari: Some(14 << 16),
6800        ..Browsers::default()
6801      },
6802    );
6803
6804    minify_test(".foo::cue {color: red}", ".foo::cue{color:red}");
6805    minify_test(".foo::cue-region {color: red}", ".foo::cue-region{color:red}");
6806    minify_test(".foo::cue(b) {color: red}", ".foo::cue(b){color:red}");
6807    minify_test(".foo::cue-region(b) {color: red}", ".foo::cue-region(b){color:red}");
6808    minify_test(
6809      "::cue(v[voice='active']) {color: yellow;}",
6810      "::cue(v[voice=active]){color:#ff0}",
6811    );
6812    minify_test(":foo(bar) { color: yellow }", ":foo(bar){color:#ff0}");
6813    minify_test("::foo(bar) { color: yellow }", "::foo(bar){color:#ff0}");
6814    minify_test("::foo(*) { color: yellow }", "::foo(*){color:#ff0}");
6815
6816    minify_test(":is(.foo) { color: yellow }", ".foo{color:#ff0}");
6817    minify_test(":is(#foo) { color: yellow }", "#foo{color:#ff0}");
6818    minify_test("a:is(.foo) { color: yellow }", "a.foo{color:#ff0}");
6819    minify_test("a:is([data-test]) { color: yellow }", "a[data-test]{color:#ff0}");
6820    minify_test(".foo:is(a) { color: yellow }", ".foo:is(a){color:#ff0}");
6821    minify_test(".foo:is(*|a) { color: yellow }", ".foo:is(*|a){color:#ff0}");
6822    minify_test(".foo:is(*) { color: yellow }", ".foo:is(*){color:#ff0}");
6823    minify_test(
6824      "@namespace svg url(http://www.w3.org/2000/svg); .foo:is(svg|a) { color: yellow }",
6825      "@namespace svg \"http://www.w3.org/2000/svg\";.foo:is(svg|a){color:#ff0}",
6826    );
6827    minify_test("a:is(.foo .bar) { color: yellow }", "a:is(.foo .bar){color:#ff0}");
6828    minify_test(":is(.foo, .bar) { color: yellow }", ":is(.foo,.bar){color:#ff0}");
6829    minify_test("a:is(:not(.foo)) { color: yellow }", "a:not(.foo){color:#ff0}");
6830    minify_test("a:is(:first-child) { color: yellow }", "a:first-child{color:#ff0}");
6831    minify_test("a:is(:has(.foo)) { color: yellow }", "a:has(.foo){color:#ff0}");
6832    minify_test("a:is(:is(.foo)) { color: yellow }", "a.foo{color:#ff0}");
6833    minify_test(":host(:hover) {color: red}", ":host(:hover){color:red}");
6834    minify_test("::slotted(:hover) {color: red}", "::slotted(:hover){color:red}");
6835
6836    minify_test(
6837      ":root::view-transition {position: fixed}",
6838      ":root::view-transition{position:fixed}",
6839    );
6840    for name in &[
6841      "view-transition-group",
6842      "view-transition-image-pair",
6843      "view-transition-new",
6844      "view-transition-old",
6845    ] {
6846      minify_test(
6847        &format!(":root::{}(*) {{position: fixed}}", name),
6848        &format!(":root::{}(*){{position:fixed}}", name),
6849      );
6850      minify_test(
6851        &format!(":root::{}(foo) {{position: fixed}}", name),
6852        &format!(":root::{}(foo){{position:fixed}}", name),
6853      );
6854      minify_test(
6855        &format!(":root::{}(foo):only-child {{position: fixed}}", name),
6856        &format!(":root::{}(foo):only-child{{position:fixed}}", name),
6857      );
6858      error_test(
6859        &format!(":root::{}(foo):first-child {{position: fixed}}", name),
6860        ParserError::SelectorError(SelectorError::InvalidPseudoClassAfterPseudoElement),
6861      );
6862      error_test(
6863        &format!(":root::{}(foo)::before {{position: fixed}}", name),
6864        ParserError::SelectorError(SelectorError::InvalidState),
6865      );
6866    }
6867
6868    minify_test(".foo ::deep .bar {width: 20px}", ".foo ::deep .bar{width:20px}");
6869    minify_test(".foo::deep .bar {width: 20px}", ".foo::deep .bar{width:20px}");
6870    minify_test(".foo ::deep.bar {width: 20px}", ".foo ::deep.bar{width:20px}");
6871    minify_test(".foo ::unknown .bar {width: 20px}", ".foo ::unknown .bar{width:20px}");
6872    minify_test(
6873      ".foo ::unknown(foo) .bar {width: 20px}",
6874      ".foo ::unknown(foo) .bar{width:20px}",
6875    );
6876    minify_test(
6877      ".foo ::unknown:only-child {width: 20px}",
6878      ".foo ::unknown:only-child{width:20px}",
6879    );
6880    minify_test(
6881      ".foo ::unknown(.foo) .bar {width: 20px}",
6882      ".foo ::unknown(.foo) .bar{width:20px}",
6883    );
6884    minify_test(
6885      ".foo ::unknown(.foo .bar / .baz) .bar {width: 20px}",
6886      ".foo ::unknown(.foo .bar / .baz) .bar{width:20px}",
6887    );
6888    minify_test(
6889      ".foo ::unknown(something(foo)) .bar {width: 20px}",
6890      ".foo ::unknown(something(foo)) .bar{width:20px}",
6891    );
6892    minify_test(
6893      ".foo ::unknown([abc]) .bar {width: 20px}",
6894      ".foo ::unknown([abc]) .bar{width:20px}",
6895    );
6896
6897    let deep_options = ParserOptions {
6898      flags: ParserFlags::DEEP_SELECTOR_COMBINATOR,
6899      ..ParserOptions::default()
6900    };
6901
6902    error_test(
6903      ".foo >>> .bar {width: 20px}",
6904      ParserError::SelectorError(SelectorError::DanglingCombinator),
6905    );
6906    error_test(
6907      ".foo /deep/ .bar {width: 20px}",
6908      ParserError::SelectorError(SelectorError::DanglingCombinator),
6909    );
6910    minify_test_with_options(
6911      ".foo >>> .bar {width: 20px}",
6912      ".foo>>>.bar{width:20px}",
6913      deep_options.clone(),
6914    );
6915    minify_test_with_options(
6916      ".foo /deep/ .bar {width: 20px}",
6917      ".foo /deep/ .bar{width:20px}",
6918      deep_options.clone(),
6919    );
6920
6921    let pure_css_module_options = ParserOptions {
6922      css_modules: Some(crate::css_modules::Config {
6923        pure: true,
6924        ..Default::default()
6925      }),
6926      ..ParserOptions::default()
6927    };
6928
6929    minify_error_test_with_options(
6930      "div {width: 20px}",
6931      MinifyErrorKind::ImpureCSSModuleSelector,
6932      pure_css_module_options.clone(),
6933    );
6934    minify_error_test_with_options(
6935      ":global(.foo) {width: 20px}",
6936      MinifyErrorKind::ImpureCSSModuleSelector,
6937      pure_css_module_options.clone(),
6938    );
6939    minify_error_test_with_options(
6940      "[foo=bar] {width: 20px}",
6941      MinifyErrorKind::ImpureCSSModuleSelector,
6942      pure_css_module_options.clone(),
6943    );
6944    minify_error_test_with_options(
6945      "div, .foo {width: 20px}",
6946      MinifyErrorKind::ImpureCSSModuleSelector,
6947      pure_css_module_options.clone(),
6948    );
6949    minify_test_with_options(
6950      ":local(.foo) {width: 20px}",
6951      "._8Z4fiW_foo{width:20px}",
6952      pure_css_module_options.clone(),
6953    );
6954    minify_test_with_options(
6955      "div.my-class {color: red;}",
6956      "div._8Z4fiW_my-class{color:red}",
6957      pure_css_module_options.clone(),
6958    );
6959    minify_test_with_options(
6960      "#id {color: red;}",
6961      "#_8Z4fiW_id{color:red}",
6962      pure_css_module_options.clone(),
6963    );
6964    minify_test_with_options(
6965      "a .my-class{color: red;}",
6966      "a ._8Z4fiW_my-class{color:red}",
6967      pure_css_module_options.clone(),
6968    );
6969    minify_test_with_options(
6970      ".my-class a {color: red;}",
6971      "._8Z4fiW_my-class a{color:red}",
6972      pure_css_module_options.clone(),
6973    );
6974    minify_test_with_options(
6975      ".my-class:is(a) {color: red;}",
6976      "._8Z4fiW_my-class:is(a){color:red}",
6977      pure_css_module_options.clone(),
6978    );
6979    minify_test_with_options(
6980      "div:has(.my-class) {color: red;}",
6981      "div:has(._8Z4fiW_my-class){color:red}",
6982      pure_css_module_options.clone(),
6983    );
6984    minify_test_with_options(
6985      ".foo { html &:hover { a_value: some-value; } }",
6986      "._8Z4fiW_foo{html &:hover{a_value:some-value}}",
6987      pure_css_module_options.clone(),
6988    );
6989    minify_test_with_options(
6990      ".foo { span { color: red; } }",
6991      "._8Z4fiW_foo{& span{color:red}}",
6992      pure_css_module_options.clone(),
6993    );
6994    minify_error_test_with_options(
6995      "html { .foo { span { color: red; } } }",
6996      MinifyErrorKind::ImpureCSSModuleSelector,
6997      pure_css_module_options.clone(),
6998    );
6999    minify_test_with_options(
7000      ".foo { div { span { color: red; } } }",
7001      "._8Z4fiW_foo{& div{& span{color:red}}}",
7002      pure_css_module_options.clone(),
7003    );
7004    minify_error_test_with_options(
7005      "@scope (div) { .foo { color: red } }",
7006      MinifyErrorKind::ImpureCSSModuleSelector,
7007      pure_css_module_options.clone(),
7008    );
7009    minify_error_test_with_options(
7010      "@scope (.a) to (div) { .foo { color: red } }",
7011      MinifyErrorKind::ImpureCSSModuleSelector,
7012      pure_css_module_options.clone(),
7013    );
7014    minify_error_test_with_options(
7015      "@scope (.a) to (.b) { div { color: red } }",
7016      MinifyErrorKind::ImpureCSSModuleSelector,
7017      pure_css_module_options.clone(),
7018    );
7019    minify_test_with_options(
7020      "@scope (.a) to (.b) { .foo { color: red } }",
7021      "@scope(._8Z4fiW_a) to (._8Z4fiW_b){._8Z4fiW_foo{color:red}}",
7022      pure_css_module_options.clone(),
7023    );
7024
7025    error_test(
7026      "input.defaultCheckbox::before h1 {width: 20px}",
7027      ParserError::SelectorError(SelectorError::UnexpectedSelectorAfterPseudoElement(Token::Ident(
7028        "h1".into(),
7029      ))),
7030    );
7031    error_test(
7032      "input.defaultCheckbox::before .my-class {width: 20px}",
7033      ParserError::SelectorError(SelectorError::UnexpectedSelectorAfterPseudoElement(Token::Delim('.'))),
7034    );
7035    error_test(
7036      "input.defaultCheckbox::before.my-class {width: 20px}",
7037      ParserError::SelectorError(SelectorError::UnexpectedSelectorAfterPseudoElement(Token::Delim('.'))),
7038    );
7039    error_test(
7040      "input.defaultCheckbox::before #id {width: 20px}",
7041      ParserError::SelectorError(SelectorError::UnexpectedSelectorAfterPseudoElement(Token::IDHash(
7042        "id".into(),
7043      ))),
7044    );
7045    error_test(
7046      "input.defaultCheckbox::before#id {width: 20px}",
7047      ParserError::SelectorError(SelectorError::UnexpectedSelectorAfterPseudoElement(Token::IDHash(
7048        "id".into(),
7049      ))),
7050    );
7051    error_test(
7052      "input.defaultCheckbox::before [attr] {width: 20px}",
7053      ParserError::SelectorError(SelectorError::UnexpectedSelectorAfterPseudoElement(
7054        Token::SquareBracketBlock,
7055      )),
7056    );
7057    error_test(
7058      "input.defaultCheckbox::before[attr] {width: 20px}",
7059      ParserError::SelectorError(SelectorError::UnexpectedSelectorAfterPseudoElement(
7060        Token::SquareBracketBlock,
7061      )),
7062    );
7063  }
7064
7065  #[test]
7066  fn test_keyframes() {
7067    minify_test(
7068      r#"
7069      @keyframes "test" {
7070        100% {
7071          background: blue
7072        }
7073      }
7074    "#,
7075      "@keyframes test{to{background:#00f}}",
7076    );
7077    minify_test(
7078      r#"
7079      @keyframes test {
7080        100% {
7081          background: blue
7082        }
7083      }
7084    "#,
7085      "@keyframes test{to{background:#00f}}",
7086    );
7087
7088    // named animation range percentages
7089    minify_test(
7090      r#"
7091      @keyframes test {
7092        entry 0% {
7093          background: blue
7094        }
7095        exit 100% {
7096          background: green
7097        }
7098      }
7099    "#,
7100      "@keyframes test{entry 0%{background:#00f}exit 100%{background:green}}",
7101    );
7102
7103    // CSS-wide keywords and `none` cannot remove quotes.
7104    minify_test(
7105      r#"
7106      @keyframes "revert" {
7107        from {
7108          background: green;
7109        }
7110      }
7111    "#,
7112      "@keyframes \"revert\"{0%{background:green}}",
7113    );
7114
7115    minify_test(
7116      r#"
7117      @keyframes "none" {
7118        from {
7119          background: green;
7120        }
7121      }
7122    "#,
7123      "@keyframes \"none\"{0%{background:green}}",
7124    );
7125
7126    // named animation ranges cannot be used with to or from
7127    minify_test(
7128      r#"
7129      @keyframes test {
7130        entry to {
7131          background: blue
7132        }
7133      }
7134    "#,
7135      "@keyframes test{}",
7136    );
7137
7138    // CSS-wide keywords without quotes throws an error.
7139    error_test(
7140      r#"
7141      @keyframes revert {}
7142    "#,
7143      ParserError::UnexpectedToken(Token::Ident("revert".into())),
7144    );
7145
7146    error_test(
7147      r#"
7148      @keyframes revert-layer {}
7149    "#,
7150      ParserError::UnexpectedToken(Token::Ident("revert-layer".into())),
7151    );
7152
7153    error_test(
7154      r#"
7155      @keyframes none {}
7156    "#,
7157      ParserError::UnexpectedToken(Token::Ident("none".into())),
7158    );
7159
7160    error_test(
7161      r#"
7162      @keyframes NONE {}
7163    "#,
7164      ParserError::UnexpectedToken(Token::Ident("NONE".into())),
7165    );
7166
7167    minify_test(
7168      r#"
7169      @-webkit-keyframes test {
7170        from {
7171          background: green;
7172          background-color: red;
7173        }
7174
7175        100% {
7176          background: blue
7177        }
7178      }
7179    "#,
7180      "@-webkit-keyframes test{0%{background:red}to{background:#00f}}",
7181    );
7182    minify_test(
7183      r#"
7184      @-moz-keyframes test {
7185        from {
7186          background: green;
7187          background-color: red;
7188        }
7189
7190        100% {
7191          background: blue
7192        }
7193      }
7194    "#,
7195      "@-moz-keyframes test{0%{background:red}to{background:#00f}}",
7196    );
7197    minify_test(r#"
7198      @-webkit-keyframes test {
7199        from {
7200          background: green;
7201          background-color: red;
7202        }
7203
7204        100% {
7205          background: blue
7206        }
7207      }
7208      @-moz-keyframes test {
7209        from {
7210          background: green;
7211          background-color: red;
7212        }
7213
7214        100% {
7215          background: blue
7216        }
7217      }
7218    "#, "@-webkit-keyframes test{0%{background:red}to{background:#00f}}@-moz-keyframes test{0%{background:red}to{background:#00f}}");
7219
7220    prefix_test(
7221      r#"
7222      @keyframes test {
7223        from {
7224          background: green;
7225        }
7226        to {
7227          background: blue
7228        }
7229      }
7230    "#,
7231      indoc! { r#"
7232      @-webkit-keyframes test {
7233        from {
7234          background: green;
7235        }
7236
7237        to {
7238          background: #00f;
7239        }
7240      }
7241
7242      @-moz-keyframes test {
7243        from {
7244          background: green;
7245        }
7246
7247        to {
7248          background: #00f;
7249        }
7250      }
7251
7252      @keyframes test {
7253        from {
7254          background: green;
7255        }
7256
7257        to {
7258          background: #00f;
7259        }
7260      }
7261    "#},
7262      Browsers {
7263        safari: Some(5 << 16),
7264        firefox: Some(6 << 16),
7265        ..Browsers::default()
7266      },
7267    );
7268    prefix_test(
7269      r#"
7270      @-webkit-keyframes test {
7271        from {
7272          background: green;
7273        }
7274
7275        to {
7276          background: blue;
7277        }
7278      }
7279      @-moz-keyframes test {
7280        from {
7281          background: green;
7282        }
7283
7284        to {
7285          background: blue;
7286        }
7287      }
7288      @keyframes test {
7289        from {
7290          background: green;
7291        }
7292        to {
7293          background: blue
7294        }
7295      }
7296    "#,
7297      indoc! { r#"
7298      @keyframes test {
7299        from {
7300          background: green;
7301        }
7302
7303        to {
7304          background: #00f;
7305        }
7306      }
7307    "#},
7308      Browsers {
7309        safari: Some(10 << 16),
7310        firefox: Some(17 << 16),
7311        ..Browsers::default()
7312      },
7313    );
7314    prefix_test(
7315      r#"
7316      @-webkit-keyframes test1 {
7317        from {
7318          background: green;
7319        }
7320
7321        to {
7322          background: blue;
7323        }
7324      }
7325
7326      @-moz-keyframes test2 {
7327        from {
7328          background: green;
7329        }
7330
7331        to {
7332          background: blue;
7333        }
7334      }
7335
7336      @keyframes test3 {
7337        from {
7338          background: green;
7339        }
7340        to {
7341          background: blue
7342        }
7343      }
7344    "#,
7345      indoc! { r#"
7346      @-webkit-keyframes test1 {
7347        from {
7348          background: green;
7349        }
7350
7351        to {
7352          background: #00f;
7353        }
7354      }
7355
7356      @-moz-keyframes test2 {
7357        from {
7358          background: green;
7359        }
7360
7361        to {
7362          background: #00f;
7363        }
7364      }
7365
7366      @keyframes test3 {
7367        from {
7368          background: green;
7369        }
7370
7371        to {
7372          background: #00f;
7373        }
7374      }
7375    "#},
7376      Browsers {
7377        safari: Some(10 << 16),
7378        firefox: Some(17 << 16),
7379        ..Browsers::default()
7380      },
7381    );
7382    prefix_test(
7383      r#"
7384      @-webkit-keyframes test {
7385        from {
7386          background: green;
7387        }
7388
7389        to {
7390          background: red;
7391        }
7392      }
7393      @-moz-keyframes test {
7394        from {
7395          background: green;
7396        }
7397
7398        to {
7399          background: pink;
7400        }
7401      }
7402      @keyframes test {
7403        from {
7404          background: green;
7405        }
7406        to {
7407          background: blue
7408        }
7409      }
7410    "#,
7411      indoc! { r#"
7412      @-webkit-keyframes test {
7413        from {
7414          background: green;
7415        }
7416
7417        to {
7418          background: red;
7419        }
7420      }
7421
7422      @-moz-keyframes test {
7423        from {
7424          background: green;
7425        }
7426
7427        to {
7428          background: pink;
7429        }
7430      }
7431
7432      @keyframes test {
7433        from {
7434          background: green;
7435        }
7436
7437        to {
7438          background: #00f;
7439        }
7440      }
7441    "#},
7442      Browsers {
7443        safari: Some(10 << 16),
7444        firefox: Some(17 << 16),
7445        ..Browsers::default()
7446      },
7447    );
7448
7449    minify_test(
7450      r#"
7451      @keyframes test {
7452        100% {
7453          background: blue
7454        }
7455      }
7456
7457      @keyframes test {
7458        100% {
7459          background: red
7460        }
7461      }
7462    "#,
7463      "@keyframes test{to{background:red}}",
7464    );
7465    minify_test(
7466      r#"
7467      @keyframes test {
7468        100% {
7469          background: blue
7470        }
7471      }
7472
7473      @-webkit-keyframes test {
7474        100% {
7475          background: red
7476        }
7477      }
7478    "#,
7479      "@keyframes test{to{background:#00f}}@-webkit-keyframes test{to{background:red}}",
7480    );
7481  }
7482
7483  #[test]
7484  fn test_important() {
7485    test(
7486      r#"
7487      .foo {
7488        align-items: center;
7489        justify-items: center !important;
7490      }
7491    "#,
7492      indoc! {r#"
7493      .foo {
7494        align-items: center;
7495        justify-items: center !important;
7496      }
7497    "#},
7498    );
7499
7500    test(
7501      r#"
7502      .foo {
7503        justify-items: center !important;
7504        align-items: center;
7505      }
7506    "#,
7507      indoc! {r#"
7508      .foo {
7509        align-items: center;
7510        justify-items: center !important;
7511      }
7512    "#},
7513    );
7514
7515    minify_test(
7516      r#"
7517      .foo {
7518        font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !important;
7519      }
7520    "#,
7521      ".foo{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important}",
7522    );
7523  }
7524
7525  #[test]
7526  fn test_calc() {
7527    minify_test(".foo { width: calc(20px * 2) }", ".foo{width:40px}");
7528    minify_test(".foo { font-size: calc(100vw / 35) }", ".foo{font-size:2.85714vw}");
7529    minify_test(".foo { width: calc(20px * 2 * 3) }", ".foo{width:120px}");
7530    minify_test(".foo { width: calc(20px + 30px) }", ".foo{width:50px}");
7531    minify_test(".foo { width: calc(20px + 30px + 40px) }", ".foo{width:90px}");
7532    minify_test(".foo { width: calc(100% - 30px) }", ".foo{width:calc(100% - 30px)}");
7533    minify_test(
7534      ".foo { width: calc(100% - 30px + 20px) }",
7535      ".foo{width:calc(100% - 10px)}",
7536    );
7537    minify_test(
7538      ".foo { width: calc(20px + 100% - 30px) }",
7539      ".foo{width:calc(100% - 10px)}",
7540    );
7541    minify_test(
7542      ".foo { width: calc(20px + 100% + 10vw - 30px) }",
7543      ".foo{width:calc(100% - 10px + 10vw)}",
7544    );
7545    minify_test(
7546      ".foo { width: calc(20px + 100% - 30px) }",
7547      ".foo{width:calc(100% - 10px)}",
7548    );
7549    minify_test(
7550      ".foo { width: calc(2 * (100% - 20px)) }",
7551      ".foo{width:calc(200% - 40px)}",
7552    );
7553    minify_test(
7554      ".foo { width: calc((100% - 20px) * 2) }",
7555      ".foo{width:calc(200% - 40px)}",
7556    );
7557    minify_test(".foo { width: calc(100% - 20px * 2) }", ".foo{width:calc(100% - 40px)}");
7558    minify_test(".foo { width: calc(1px + 1px) }", ".foo{width:2px}");
7559    minify_test(".foo { width: calc(100vw / 2) }", ".foo{width:50vw}");
7560    minify_test(".foo { width: calc(50px - (20px - 30px)) }", ".foo{width:60px}");
7561    minify_test(".foo { width: calc(100px - (100px - 100%)) }", ".foo{width:100%}");
7562    minify_test(
7563      ".foo { width: calc(100px + (100px - 100%)) }",
7564      ".foo{width:calc(200px - 100%)}",
7565    );
7566    minify_test(
7567      ".foo { width: calc(1px - (2em + 3%)) }",
7568      ".foo{width:calc(1px + -2em - 3%)}",
7569    ); // TODO: fix sign
7570    minify_test(
7571      ".foo { width: calc((100vw - 50em) / 2) }",
7572      ".foo{width:calc(50vw - 25em)}",
7573    );
7574    minify_test(
7575      ".foo { width: calc(1px - (2em + 4vh + 3%)) }",
7576      ".foo{width:calc(1px + -2em - 4vh - 3%)}",
7577    ); // TODO
7578    minify_test(
7579      ".foo { width: calc(1px + (2em + (3vh + 4px))) }",
7580      ".foo{width:calc(2em + 3vh + 5px)}",
7581    );
7582    minify_test(
7583      ".foo { width: calc(1px - (2em + 4px - 6vh) / 2) }",
7584      ".foo{width:calc(-1em - 1px + 3vh)}",
7585    );
7586    minify_test(
7587      ".foo { width: calc(100% - calc(50% + 25px)) }",
7588      ".foo{width:calc(50% - 25px)}",
7589    );
7590    minify_test(".foo { width: calc(1px/100) }", ".foo{width:.01px}");
7591    minify_test(
7592      ".foo { width: calc(100vw / 2 - 6px + 0px) }",
7593      ".foo{width:calc(50vw - 6px)}",
7594    );
7595    minify_test(".foo { width: calc(1px + 1) }", ".foo{width:calc(1px + 1)}");
7596    minify_test(
7597      ".foo { width: calc( (1em - calc( 10px + 1em)) / 2) }",
7598      ".foo{width:-5px}",
7599    );
7600    minify_test(
7601      ".foo { width: calc((100px - 1em) + (-50px + 1em)) }",
7602      ".foo{width:50px}",
7603    );
7604    minify_test(
7605      ".foo { width: calc(100% + (2 * 100px) - ((75.37% - 63.5px) - 900px)) }",
7606      ".foo{width:calc(24.63% + 1163.5px)}",
7607    );
7608    minify_test(
7609      ".foo { width: calc(((((100% + (2 * 30px) + 63.5px) / 0.7537) - (100vw - 60px)) / 2) + 30px) }",
7610      ".foo{width:calc(66.3394% + 141.929px - 50vw)}",
7611    );
7612    minify_test(
7613      ".foo { width: calc(((75.37% - 63.5px) - 900px) + (2 * 100px)) }",
7614      ".foo{width:calc(75.37% - 763.5px)}",
7615    );
7616    minify_test(
7617      ".foo { width: calc((900px - (10% - 63.5px)) + (2 * 100px)) }",
7618      ".foo{width:calc(1163.5px - 10%)}",
7619    );
7620    minify_test(".foo { width: calc(500px/0) }", ".foo{width:calc(500px/0)}");
7621    minify_test(".foo { width: calc(500px/2px) }", ".foo{width:calc(500px/2px)}");
7622    minify_test(".foo { width: calc(100% / 3 * 3) }", ".foo{width:100%}");
7623    minify_test(".foo { width: calc(+100px + +100px) }", ".foo{width:200px}");
7624    minify_test(".foo { width: calc(+100px - +100px) }", ".foo{width:0}");
7625    minify_test(".foo { width: calc(200px * +1) }", ".foo{width:200px}");
7626    minify_test(".foo { width: calc(200px / +1) }", ".foo{width:200px}");
7627    minify_test(".foo { width: calc(1.1e+1px + 1.1e+1px) }", ".foo{width:22px}");
7628    minify_test(".foo { border-width: calc(1px + 2px) }", ".foo{border-width:3px}");
7629    minify_test(
7630      ".foo { border-width: calc(1em + 2px + 2em + 3px) }",
7631      ".foo{border-width:calc(3em + 5px)}",
7632    );
7633
7634    minify_test(
7635      ".foo { border-width: min(1em, 2px) }",
7636      ".foo{border-width:min(1em,2px)}",
7637    );
7638    minify_test(
7639      ".foo { border-width: min(1em + 2em, 2px + 2px) }",
7640      ".foo{border-width:min(3em,4px)}",
7641    );
7642    minify_test(
7643      ".foo { border-width: min(1em + 2px, 2px + 1em) }",
7644      ".foo{border-width:min(1em + 2px,2px + 1em)}",
7645    );
7646    minify_test(
7647      ".foo { border-width: min(1em + 2px + 2px, 2px + 1em + 1px) }",
7648      ".foo{border-width:min(1em + 4px,3px + 1em)}",
7649    );
7650    minify_test(
7651      ".foo { border-width: min(2px + 1px, 3px + 4px) }",
7652      ".foo{border-width:3px}",
7653    );
7654    minify_test(
7655      ".foo { border-width: min(1px, 1em, 2px, 3in) }",
7656      ".foo{border-width:min(1px,1em)}",
7657    );
7658
7659    minify_test(
7660      ".foo { border-width: max(1em, 2px) }",
7661      ".foo{border-width:max(1em,2px)}",
7662    );
7663    minify_test(
7664      ".foo { border-width: max(1em + 2em, 2px + 2px) }",
7665      ".foo{border-width:max(3em,4px)}",
7666    );
7667    minify_test(
7668      ".foo { border-width: max(1em + 2px, 2px + 1em) }",
7669      ".foo{border-width:max(1em + 2px,2px + 1em)}",
7670    );
7671    minify_test(
7672      ".foo { border-width: max(1em + 2px + 2px, 2px + 1em + 1px) }",
7673      ".foo{border-width:max(1em + 4px,3px + 1em)}",
7674    );
7675    minify_test(
7676      ".foo { border-width: max(2px + 1px, 3px + 4px) }",
7677      ".foo{border-width:7px}",
7678    );
7679    minify_test(
7680      ".foo { border-width: max(1px, 1em, 2px, 3in) }",
7681      ".foo{border-width:max(3in,1em)}",
7682    );
7683
7684    minify_test(".foo { border-width: clamp(1px, 2px, 3px) }", ".foo{border-width:2px}");
7685    minify_test(".foo { border-width: clamp(1px, 10px, 3px) }", ".foo{border-width:3px}");
7686    minify_test(".foo { border-width: clamp(5px, 2px, 10px) }", ".foo{border-width:5px}");
7687    minify_test(
7688      ".foo { border-width: clamp(100px, 2px, 10px) }",
7689      ".foo{border-width:100px}",
7690    );
7691    minify_test(
7692      ".foo { border-width: clamp(5px + 5px, 5px + 7px, 10px + 20px) }",
7693      ".foo{border-width:12px}",
7694    );
7695
7696    minify_test(
7697      ".foo { border-width: clamp(1em, 2px, 4vh) }",
7698      ".foo{border-width:clamp(1em,2px,4vh)}",
7699    );
7700    minify_test(
7701      ".foo { border-width: clamp(1em, 2em, 4vh) }",
7702      ".foo{border-width:min(2em,4vh)}",
7703    );
7704    minify_test(
7705      ".foo { border-width: clamp(1em, 2vh, 4vh) }",
7706      ".foo{border-width:max(1em,2vh)}",
7707    );
7708    minify_test(
7709      ".foo { border-width: clamp(1px, 1px + 2em, 4px) }",
7710      ".foo{border-width:clamp(1px,1px + 2em,4px)}",
7711    );
7712    minify_test(".foo { border-width: clamp(1px, 2pt, 1in) }", ".foo{border-width:2pt}");
7713
7714    minify_test(
7715      ".foo { top: calc(-1 * clamp(1.75rem, 8vw, 4rem)) }",
7716      ".foo{top:calc(-1*clamp(1.75rem,8vw,4rem))}",
7717    );
7718    minify_test(
7719      ".foo { top: calc(-1 * min(1.75rem, 8vw, 4rem)) }",
7720      ".foo{top:calc(-1*min(1.75rem,8vw))}",
7721    );
7722    minify_test(
7723      ".foo { top: calc(-1 * max(1.75rem, 8vw, 4rem)) }",
7724      ".foo{top:calc(-1*max(4rem,8vw))}",
7725    );
7726    minify_test(
7727      ".foo { top: calc(clamp(1.75rem, 8vw, 4rem) * -1) }",
7728      ".foo{top:calc(-1*clamp(1.75rem,8vw,4rem))}",
7729    );
7730    minify_test(
7731      ".foo { top: calc(min(1.75rem, 8vw, 4rem) * -1) }",
7732      ".foo{top:calc(-1*min(1.75rem,8vw))}",
7733    );
7734    minify_test(
7735      ".foo { top: calc(max(1.75rem, 8vw, 4rem) * -1) }",
7736      ".foo{top:calc(-1*max(4rem,8vw))}",
7737    );
7738    minify_test(
7739      ".foo { top: calc(clamp(1.75rem, 8vw, 4rem) / 2) }",
7740      ".foo{top:calc(clamp(1.75rem,8vw,4rem)/2)}",
7741    );
7742    minify_test(
7743      ".foo { top: calc(min(1.75rem, 8vw, 4rem) / 2) }",
7744      ".foo{top:calc(min(1.75rem,8vw)/2)}",
7745    );
7746    minify_test(
7747      ".foo { top: calc(max(1.75rem, 8vw, 4rem) / 2) }",
7748      ".foo{top:calc(max(4rem,8vw)/2)}",
7749    );
7750    minify_test(
7751      ".foo { top: calc(0.5 * clamp(1.75rem, 8vw, 4rem)) }",
7752      ".foo{top:calc(clamp(1.75rem,8vw,4rem)/2)}",
7753    );
7754    minify_test(
7755      ".foo { top: calc(1 * clamp(1.75rem, 8vw, 4rem)) }",
7756      ".foo{top:calc(clamp(1.75rem,8vw,4rem))}",
7757    );
7758    minify_test(
7759      ".foo { top: calc(2 * clamp(1.75rem, 8vw, 4rem) / 2) }",
7760      ".foo{top:calc(clamp(1.75rem,8vw,4rem))}",
7761    );
7762
7763    minify_test(".foo { width: max(0px, 1vw) }", ".foo{width:max(0px,1vw)}");
7764
7765    prefix_test(
7766      ".foo { border-width: clamp(1em, 2px, 4vh) }",
7767      indoc! { r#"
7768        .foo {
7769          border-width: max(1em, min(2px, 4vh));
7770        }
7771      "#},
7772      Browsers {
7773        safari: Some(12 << 16),
7774        ..Browsers::default()
7775      },
7776    );
7777
7778    prefix_test(
7779      ".foo { border-width: clamp(1em, 2px, 4vh) }",
7780      indoc! { r#"
7781        .foo {
7782          border-width: clamp(1em, 2px, 4vh);
7783        }
7784      "#},
7785      Browsers {
7786        safari: Some(14 << 16),
7787        ..Browsers::default()
7788      },
7789    );
7790
7791    minify_test(".foo { width: calc(1vh + 2vh) }", ".foo{width:3vh}");
7792    minify_test(".foo { width: calc(1dvh + 2dvh) }", ".foo{width:3dvh}");
7793    minify_test(".foo { width: calc(1lvh + 2lvh) }", ".foo{width:3lvh}");
7794    minify_test(".foo { width: calc(1svh + 2svh) }", ".foo{width:3svh}");
7795    minify_test(".foo { width: calc(1sVmin + 2Svmin) }", ".foo{width:3svmin}");
7796    minify_test(".foo { width: calc(1ic + 2ic) }", ".foo{width:3ic}");
7797    minify_test(".foo { width: calc(1ric + 2ric) }", ".foo{width:3ric}");
7798    minify_test(".foo { width: calc(1cap + 2cap) }", ".foo{width:3cap}");
7799    minify_test(".foo { width: calc(1lh + 2lh) }", ".foo{width:3lh}");
7800    minify_test(".foo { width: calc(1x + 2x) }", ".foo{width:calc(1x + 2x)}");
7801    minify_test(
7802      ".foo { left: calc(50% - 100px + clamp(0px, calc(50vw - 50px), 100px)) }",
7803      ".foo{left:calc(50% - 100px + clamp(0px,50vw - 50px,100px))}",
7804    );
7805    minify_test(
7806      ".foo { left: calc(10px + min(10px, 1rem) + max(2px, 1vw)) }",
7807      ".foo{left:calc(10px + min(10px,1rem) + max(2px,1vw))}",
7808    );
7809    minify_test(".foo { width: round(22px, 5px) }", ".foo{width:20px}");
7810    minify_test(".foo { width: round(nearest, 22px, 5px) }", ".foo{width:20px}");
7811    minify_test(".foo { width: round(down, 22px, 5px) }", ".foo{width:20px}");
7812    minify_test(".foo { width: round(to-zero, 22px, 5px) }", ".foo{width:20px}");
7813    minify_test(".foo { width: round(up, 22px, 5px) }", ".foo{width:25px}");
7814    minify_test(".foo { width: round(23px, 5px) }", ".foo{width:25px}");
7815    minify_test(".foo { width: round(nearest, 23px, 5px) }", ".foo{width:25px}");
7816    minify_test(".foo { width: round(down, 23px, 5px) }", ".foo{width:20px}");
7817    minify_test(".foo { width: round(to-zero, 23px, 5px) }", ".foo{width:20px}");
7818    minify_test(".foo { width: round(up, 23px, 5px) }", ".foo{width:25px}");
7819    minify_test(".foo { width: round(22px, 5vw) }", ".foo{width:round(22px,5vw)}");
7820    minify_test(".foo { rotate: round(22deg, 5deg) }", ".foo{rotate:20deg}");
7821    minify_test(".foo { rotate: round(22deg, 5deg) }", ".foo{rotate:20deg}");
7822    minify_test(
7823      ".foo { transition-duration: round(22ms, 5ms) }",
7824      ".foo{transition-duration:20ms}",
7825    );
7826    minify_test(".foo { margin: round(to-zero, -23px, 5px) }", ".foo{margin:-20px}");
7827    minify_test(".foo { margin: round(nearest, -23px, 5px) }", ".foo{margin:-25px}");
7828    minify_test(".foo { margin: calc(10px * round(22, 5)) }", ".foo{margin:200px}");
7829    minify_test(".foo { width: rem(18px, 5px) }", ".foo{width:3px}");
7830    minify_test(".foo { width: rem(-18px, 5px) }", ".foo{width:-3px}");
7831    minify_test(".foo { width: rem(18px, 5vw) }", ".foo{width:rem(18px,5vw)}");
7832    minify_test(".foo { rotate: rem(-140deg, -90deg) }", ".foo{rotate:-50deg}");
7833    minify_test(".foo { rotate: rem(140deg, -90deg) }", ".foo{rotate:50deg}");
7834    minify_test(".foo { width: calc(10px * rem(18, 5)) }", ".foo{width:30px}");
7835    minify_test(".foo { width: mod(18px, 5px) }", ".foo{width:3px}");
7836    minify_test(".foo { width: mod(-18px, 5px) }", ".foo{width:2px}");
7837    minify_test(".foo { rotate: mod(-140deg, -90deg) }", ".foo{rotate:-50deg}");
7838    minify_test(".foo { rotate: mod(140deg, -90deg) }", ".foo{rotate:-40deg}");
7839    minify_test(".foo { width: mod(18px, 5vw) }", ".foo{width:mod(18px,5vw)}");
7840    minify_test(
7841      ".foo { transform: rotateX(mod(140deg, -90deg)) rotateY(rem(140deg, -90deg)) }",
7842      ".foo{transform:rotateX(-40deg)rotateY(50deg)}",
7843    );
7844    minify_test(".foo { width: calc(10px * mod(18, 5)) }", ".foo{width:30px}");
7845  }
7846
7847  #[test]
7848  fn test_trig() {
7849    minify_test(".foo { width: calc(2px * pi); }", ".foo{width:6.28319px}");
7850    minify_test(".foo { width: calc(2px / pi); }", ".foo{width:.63662px}");
7851    // minify_test(
7852    //   ".foo { width: calc(2px * infinity); }",
7853    //   ".foo{width:calc(2px*infinity)}",
7854    // );
7855    // minify_test(
7856    //   ".foo { width: calc(2px * -infinity); }",
7857    //   ".foo{width:calc(2px*-infinity)}",
7858    // );
7859    minify_test(".foo { width: calc(100px * sin(45deg))", ".foo{width:70.7107px}");
7860    minify_test(".foo { width: calc(100px * sin(.125turn))", ".foo{width:70.7107px}");
7861    minify_test(
7862      ".foo { width: calc(100px * sin(3.14159265 / 4))",
7863      ".foo{width:70.7107px}",
7864    );
7865    minify_test(".foo { width: calc(100px * sin(pi / 4))", ".foo{width:70.7107px}");
7866    minify_test(
7867      ".foo { width: calc(100px * sin(22deg + 23deg))",
7868      ".foo{width:70.7107px}",
7869    );
7870
7871    minify_test(".foo { width: calc(2px * cos(45deg))", ".foo{width:1.41421px}");
7872    minify_test(".foo { width: calc(2px * tan(45deg))", ".foo{width:2px}");
7873
7874    minify_test(".foo { rotate: asin(sin(45deg))", ".foo{rotate:45deg}");
7875    minify_test(".foo { rotate: asin(1)", ".foo{rotate:90deg}");
7876    minify_test(".foo { rotate: asin(-1)", ".foo{rotate:-90deg}");
7877    minify_test(".foo { rotate: asin(0.5)", ".foo{rotate:30deg}");
7878    minify_test(".foo { rotate: asin(45deg)", ".foo{rotate:asin(45deg)}"); // invalid
7879    minify_test(".foo { rotate: asin(-20)", ".foo{rotate:asin(-20)}"); // evaluates to NaN
7880    minify_test(".foo { width: asin(sin(45deg))", ".foo{width:asin(sin(45deg))}"); // invalid
7881
7882    minify_test(".foo { rotate: acos(cos(45deg))", ".foo{rotate:45deg}");
7883    minify_test(".foo { rotate: acos(-1)", ".foo{rotate:180deg}");
7884    minify_test(".foo { rotate: acos(0)", ".foo{rotate:90deg}");
7885    minify_test(".foo { rotate: acos(1)", ".foo{rotate:none}");
7886    minify_test(".foo { rotate: acos(45deg)", ".foo{rotate:acos(45deg)}"); // invalid
7887    minify_test(".foo { rotate: acos(-20)", ".foo{rotate:acos(-20)}"); // evaluates to NaN
7888
7889    minify_test(".foo { rotate: atan(tan(45deg))", ".foo{rotate:45deg}");
7890    minify_test(".foo { rotate: atan(1)", ".foo{rotate:45deg}");
7891    minify_test(".foo { rotate: atan(0)", ".foo{rotate:none}");
7892    minify_test(".foo { rotate: atan(45deg)", ".foo{rotate:atan(45deg)}"); // invalid
7893
7894    minify_test(".foo { rotate: atan2(1px, -1px)", ".foo{rotate:135deg}");
7895    minify_test(".foo { rotate: atan2(1vw, -1vw)", ".foo{rotate:135deg}");
7896    minify_test(".foo { rotate: atan2(1, -1)", ".foo{rotate:135deg}");
7897    minify_test(".foo { rotate: atan2(1ms, -1ms)", ".foo{rotate:135deg}");
7898    minify_test(".foo { rotate: atan2(1%, -1%)", ".foo{rotate:135deg}");
7899    minify_test(".foo { rotate: atan2(1deg, -1deg)", ".foo{rotate:135deg}");
7900    minify_test(".foo { rotate: atan2(1cm, 1mm)", ".foo{rotate:84.2894deg}");
7901    minify_test(".foo { rotate: atan2(0, -1)", ".foo{rotate:180deg}");
7902    minify_test(".foo { rotate: atan2(-1, 1)", ".foo{rotate:-45deg}");
7903    // incompatible units
7904    minify_test(".foo { rotate: atan2(1px, -1vw)", ".foo{rotate:atan2(1px,-1vw)}");
7905  }
7906
7907  #[test]
7908  fn test_exp() {
7909    minify_test(".foo { width: hypot()", ".foo{width:hypot()}");
7910    minify_test(".foo { width: hypot(1px)", ".foo{width:1px}");
7911    minify_test(".foo { width: hypot(1px, 2px)", ".foo{width:2.23607px}");
7912    minify_test(".foo { width: hypot(1px, 2px, 3px)", ".foo{width:3.74166px}");
7913    minify_test(".foo { width: hypot(1px, 2vw)", ".foo{width:hypot(1px,2vw)}");
7914    minify_test(".foo { width: hypot(1px, 2px, 3vw)", ".foo{width:hypot(1px,2px,3vw)}");
7915    minify_test(".foo { width: calc(100px * hypot(3, 4))", ".foo{width:500px}");
7916    minify_test(".foo { width: calc(1px * pow(2, sqrt(100))", ".foo{width:1024px}");
7917    minify_test(".foo { width: calc(100px * pow(2, pow(2, 2)", ".foo{width:1600px}");
7918    minify_test(".foo { width: calc(1px * log(1))", ".foo{width:0}");
7919    minify_test(".foo { width: calc(1px * log(10, 10))", ".foo{width:1px}");
7920    minify_test(".foo { width: calc(1px * exp(0))", ".foo{width:1px}");
7921    minify_test(".foo { width: calc(1px * log(e))", ".foo{width:1px}");
7922    minify_test(".foo { width: calc(1px * (e - exp(1)))", ".foo{width:0}");
7923    minify_test(
7924      ".foo { width: calc(1px * (exp(log(1) + exp(0)*2))",
7925      ".foo{width:7.38906px}",
7926    );
7927  }
7928
7929  #[test]
7930  fn test_sign() {
7931    minify_test(".foo { width: abs(1px)", ".foo{width:1px}");
7932    minify_test(".foo { width: abs(-1px)", ".foo{width:1px}");
7933    minify_test(".foo { width: abs(1%)", ".foo{width:abs(1%)}"); // spec says percentages must be against resolved value
7934
7935    minify_test(".foo { width: calc(10px * sign(-1vw)", ".foo{width:-10px}");
7936    minify_test(".foo { width: calc(10px * sign(1%)", ".foo{width:calc(10px*sign(1%))}");
7937  }
7938
7939  #[test]
7940  fn test_box_shadow() {
7941    minify_test(
7942      ".foo { box-shadow: 64px 64px 12px 40px rgba(0,0,0,0.4) }",
7943      ".foo{box-shadow:64px 64px 12px 40px #0006}",
7944    );
7945    minify_test(
7946      ".foo { box-shadow: 12px 12px 0px 8px rgba(0,0,0,0.4) inset }",
7947      ".foo{box-shadow:inset 12px 12px 0 8px #0006}",
7948    );
7949    minify_test(
7950      ".foo { box-shadow: inset 12px 12px 0px 8px rgba(0,0,0,0.4) }",
7951      ".foo{box-shadow:inset 12px 12px 0 8px #0006}",
7952    );
7953    minify_test(
7954      ".foo { box-shadow: 12px 12px 8px 0px rgba(0,0,0,0.4) }",
7955      ".foo{box-shadow:12px 12px 8px #0006}",
7956    );
7957    minify_test(
7958      ".foo { box-shadow: 12px 12px 0px 0px rgba(0,0,0,0.4) }",
7959      ".foo{box-shadow:12px 12px #0006}",
7960    );
7961    minify_test(
7962      ".foo { box-shadow: 64px 64px 12px 40px rgba(0,0,0,0.4), 12px 12px 0px 8px rgba(0,0,0,0.4) inset }",
7963      ".foo{box-shadow:64px 64px 12px 40px #0006,inset 12px 12px 0 8px #0006}",
7964    );
7965
7966    prefix_test(
7967      ".foo { box-shadow: 12px 12px lab(40% 56.6 39) }",
7968      indoc! { r#"
7969        .foo {
7970          box-shadow: 12px 12px #b32323;
7971          box-shadow: 12px 12px lab(40% 56.6 39);
7972        }
7973      "#},
7974      Browsers {
7975        chrome: Some(90 << 16),
7976        ..Browsers::default()
7977      },
7978    );
7979
7980    prefix_test(
7981      ".foo { box-shadow: 12px 12px lab(40% 56.6 39) }",
7982      indoc! { r#"
7983        .foo {
7984          -webkit-box-shadow: 12px 12px #b32323;
7985          box-shadow: 12px 12px #b32323;
7986          box-shadow: 12px 12px lab(40% 56.6 39);
7987        }
7988      "#},
7989      Browsers {
7990        chrome: Some(4 << 16),
7991        ..Browsers::default()
7992      },
7993    );
7994
7995    prefix_test(
7996      ".foo { box-shadow: 12px 12px lab(40% 56.6 39), 12px 12px yellow }",
7997      indoc! { r#"
7998        .foo {
7999          -webkit-box-shadow: 12px 12px #b32323, 12px 12px #ff0;
8000          box-shadow: 12px 12px #b32323, 12px 12px #ff0;
8001          box-shadow: 12px 12px lab(40% 56.6 39), 12px 12px #ff0;
8002        }
8003      "#},
8004      Browsers {
8005        chrome: Some(4 << 16),
8006        ..Browsers::default()
8007      },
8008    );
8009
8010    prefix_test(
8011      ".foo { -webkit-box-shadow: 12px 12px #0006 }",
8012      indoc! { r#"
8013        .foo {
8014          -webkit-box-shadow: 12px 12px rgba(0, 0, 0, .4);
8015        }
8016      "#},
8017      Browsers {
8018        chrome: Some(4 << 16),
8019        ..Browsers::default()
8020      },
8021    );
8022
8023    prefix_test(
8024      ".foo {
8025        -webkit-box-shadow: 12px 12px #0006;
8026        -moz-box-shadow: 12px 12px #0009;
8027      }",
8028      indoc! { r#"
8029        .foo {
8030          -webkit-box-shadow: 12px 12px rgba(0, 0, 0, .4);
8031          -moz-box-shadow: 12px 12px rgba(0, 0, 0, .6);
8032        }
8033      "#},
8034      Browsers {
8035        chrome: Some(4 << 16),
8036        ..Browsers::default()
8037      },
8038    );
8039
8040    prefix_test(
8041      ".foo {
8042        -webkit-box-shadow: 12px 12px #0006;
8043        -moz-box-shadow: 12px 12px #0006;
8044        box-shadow: 12px 12px #0006;
8045      }",
8046      indoc! { r#"
8047        .foo {
8048          box-shadow: 12px 12px #0006;
8049        }
8050      "#},
8051      Browsers {
8052        chrome: Some(95 << 16),
8053        ..Browsers::default()
8054      },
8055    );
8056
8057    prefix_test(
8058      ".foo { box-shadow: var(--foo) 12px lab(40% 56.6 39) }",
8059      indoc! { r#"
8060        .foo {
8061          box-shadow: var(--foo) 12px #b32323;
8062        }
8063
8064        @supports (color: lab(0% 0 0)) {
8065          .foo {
8066            box-shadow: var(--foo) 12px lab(40% 56.6 39);
8067          }
8068        }
8069      "#},
8070      Browsers {
8071        chrome: Some(90 << 16),
8072        ..Browsers::default()
8073      },
8074    );
8075
8076    prefix_test(
8077      r#"
8078      .foo {
8079        box-shadow: 0px 0px 22px red;
8080        box-shadow: 0px 0px max(2cqw, 22px) red;
8081      }
8082    "#,
8083      indoc! {r#"
8084      .foo {
8085        box-shadow: 0 0 22px red;
8086        box-shadow: 0 0 max(2cqw, 22px) red;
8087      }
8088    "#
8089      },
8090      Browsers {
8091        safari: Some(14 << 16),
8092        ..Browsers::default()
8093      },
8094    );
8095    prefix_test(
8096      r#"
8097      .foo {
8098        box-shadow: 0px 0px 22px red;
8099        box-shadow: 0px 0px max(2cqw, 22px) red;
8100      }
8101    "#,
8102      indoc! {r#"
8103      .foo {
8104        box-shadow: 0 0 max(2cqw, 22px) red;
8105      }
8106    "#
8107      },
8108      Browsers {
8109        safari: Some(16 << 16),
8110        ..Browsers::default()
8111      },
8112    );
8113
8114    prefix_test(
8115      r#"
8116      .foo {
8117        box-shadow: 0px 0px 22px red;
8118        box-shadow: 0px 0px 22px lab(40% 56.6 39);
8119      }
8120    "#,
8121      indoc! {r#"
8122      .foo {
8123        box-shadow: 0 0 22px red;
8124        box-shadow: 0 0 22px lab(40% 56.6 39);
8125      }
8126    "#
8127      },
8128      Browsers {
8129        safari: Some(14 << 16),
8130        ..Browsers::default()
8131      },
8132    );
8133    prefix_test(
8134      r#"
8135      .foo {
8136        box-shadow: 0px 0px 22px red;
8137        box-shadow: 0px 0px 22px lab(40% 56.6 39);
8138      }
8139    "#,
8140      indoc! {r#"
8141      .foo {
8142        box-shadow: 0 0 22px lab(40% 56.6 39);
8143      }
8144    "#
8145      },
8146      Browsers {
8147        safari: Some(16 << 16),
8148        ..Browsers::default()
8149      },
8150    );
8151
8152    prefix_test(
8153      r#"
8154      .foo {
8155        box-shadow: var(--fallback);
8156        box-shadow: 0px 0px 22px lab(40% 56.6 39);
8157      }
8158    "#,
8159      indoc! {r#"
8160      .foo {
8161        box-shadow: var(--fallback);
8162        box-shadow: 0 0 22px lab(40% 56.6 39);
8163      }
8164    "#
8165      },
8166      Browsers {
8167        safari: Some(16 << 16),
8168        ..Browsers::default()
8169      },
8170    );
8171  }
8172
8173  #[test]
8174  fn test_media() {
8175    minify_test(
8176      "@media (min-width: 240px) { .foo { color: chartreuse }}",
8177      "@media (width>=240px){.foo{color:#7fff00}}",
8178    );
8179    minify_test(
8180      "@media (width < 240px) { .foo { color: chartreuse }}",
8181      "@media (width<240px){.foo{color:#7fff00}}",
8182    );
8183    minify_test(
8184      "@media (width <= 240px) { .foo { color: chartreuse }}",
8185      "@media (width<=240px){.foo{color:#7fff00}}",
8186    );
8187    minify_test(
8188      "@media (width > 240px) { .foo { color: chartreuse }}",
8189      "@media (width>240px){.foo{color:#7fff00}}",
8190    );
8191    minify_test(
8192      "@media (width >= 240px) { .foo { color: chartreuse }}",
8193      "@media (width>=240px){.foo{color:#7fff00}}",
8194    );
8195    minify_test(
8196      "@media (240px < width) { .foo { color: chartreuse }}",
8197      "@media (width>240px){.foo{color:#7fff00}}",
8198    );
8199    minify_test(
8200      "@media (240px <= width) { .foo { color: chartreuse }}",
8201      "@media (width>=240px){.foo{color:#7fff00}}",
8202    );
8203    minify_test(
8204      "@media (240px > width) { .foo { color: chartreuse }}",
8205      "@media (width<240px){.foo{color:#7fff00}}",
8206    );
8207    minify_test(
8208      "@media (240px >= width) { .foo { color: chartreuse }}",
8209      "@media (width<=240px){.foo{color:#7fff00}}",
8210    );
8211    minify_test(
8212      "@media (100px < width < 200px) { .foo { color: chartreuse }}",
8213      "@media (100px<width<200px){.foo{color:#7fff00}}",
8214    );
8215    minify_test(
8216      "@media (100px <= width <= 200px) { .foo { color: chartreuse }}",
8217      "@media (100px<=width<=200px){.foo{color:#7fff00}}",
8218    );
8219    minify_test(
8220      "@media (min-width: 30em) and (max-width: 50em) { .foo { color: chartreuse }}",
8221      "@media (width>=30em) and (width<=50em){.foo{color:#7fff00}}",
8222    );
8223    minify_test(
8224      "@media screen, print { .foo { color: chartreuse }}",
8225      "@media screen,print{.foo{color:#7fff00}}",
8226    );
8227    minify_test(
8228      "@media (hover: hover) { .foo { color: chartreuse }}",
8229      "@media (hover:hover){.foo{color:#7fff00}}",
8230    );
8231    minify_test(
8232      "@media (hover) { .foo { color: chartreuse }}",
8233      "@media (hover){.foo{color:#7fff00}}",
8234    );
8235    minify_test(
8236      "@media (aspect-ratio: 11/5) { .foo { color: chartreuse }}",
8237      "@media (aspect-ratio:11/5){.foo{color:#7fff00}}",
8238    );
8239    minify_test(
8240      "@media (aspect-ratio: 2/1) { .foo { color: chartreuse }}",
8241      "@media (aspect-ratio:2){.foo{color:#7fff00}}",
8242    );
8243    minify_test(
8244      "@media (aspect-ratio: 2) { .foo { color: chartreuse }}",
8245      "@media (aspect-ratio:2){.foo{color:#7fff00}}",
8246    );
8247    minify_test(
8248      "@media not screen and (color) { .foo { color: chartreuse }}",
8249      "@media not screen and (color){.foo{color:#7fff00}}",
8250    );
8251    minify_test(
8252      "@media only screen and (color) { .foo { color: chartreuse }}",
8253      "@media only screen and (color){.foo{color:#7fff00}}",
8254    );
8255    minify_test(
8256      "@media (update: slow) or (hover: none) { .foo { color: chartreuse }}",
8257      "@media (update:slow) or (hover:none){.foo{color:#7fff00}}",
8258    );
8259    minify_test(
8260      "@media (width < 600px) and (height < 600px) { .foo { color: chartreuse }}",
8261      "@media (width<600px) and (height<600px){.foo{color:#7fff00}}",
8262    );
8263    minify_test(
8264      "@media (not (color)) or (hover) { .foo { color: chartreuse }}",
8265      "@media (not (color)) or (hover){.foo{color:#7fff00}}",
8266    );
8267    error_test(
8268      "@media (example, all,), speech { .foo { color: chartreuse }}",
8269      ParserError::UnexpectedToken(Token::Comma),
8270    );
8271    error_test(
8272      "@media &test, speech { .foo { color: chartreuse }}",
8273      ParserError::UnexpectedToken(Token::Delim('&')),
8274    );
8275    error_test(
8276      "@media &test { .foo { color: chartreuse }}",
8277      ParserError::UnexpectedToken(Token::Delim('&')),
8278    );
8279    minify_test(
8280      "@media (min-width: calc(200px + 40px)) { .foo { color: chartreuse }}",
8281      "@media (width>=240px){.foo{color:#7fff00}}",
8282    );
8283    minify_test(
8284      "@media (min-width: calc(1em + 5px)) { .foo { color: chartreuse }}",
8285      "@media (width>=calc(1em + 5px)){.foo{color:#7fff00}}",
8286    );
8287    minify_test("@media { .foo { color: chartreuse }}", ".foo{color:#7fff00}");
8288    minify_test("@media all { .foo { color: chartreuse }}", ".foo{color:#7fff00}");
8289    minify_test(
8290      "@media not (((color) or (hover))) { .foo { color: chartreuse }}",
8291      "@media not ((color) or (hover)){.foo{color:#7fff00}}",
8292    );
8293    minify_test(
8294      "@media (hover) and ((color) and (test)) { .foo { color: chartreuse }}",
8295      "@media (hover) and (color) and (test){.foo{color:#7fff00}}",
8296    );
8297    minify_test(
8298      "@media (grid: 1) { .foo { color: chartreuse }}",
8299      "@media (grid:1){.foo{color:#7fff00}}",
8300    );
8301    minify_test(
8302      "@media (width >= calc(2px + 4px)) { .foo { color: chartreuse }}",
8303      "@media (width>=6px){.foo{color:#7fff00}}",
8304    );
8305
8306    prefix_test(
8307      r#"
8308        @media (width >= 240px) {
8309          .foo {
8310            color: chartreuse;
8311          }
8312        }
8313      "#,
8314      indoc! { r#"
8315        @media (min-width: 240px) {
8316          .foo {
8317            color: #7fff00;
8318          }
8319        }
8320      "#},
8321      Browsers {
8322        firefox: Some(60 << 16),
8323        ..Browsers::default()
8324      },
8325    );
8326
8327    prefix_test(
8328      r#"
8329        @media (width >= 240px) {
8330          .foo {
8331            color: chartreuse;
8332          }
8333        }
8334      "#,
8335      indoc! { r#"
8336        @media (width >= 240px) {
8337          .foo {
8338            color: #7fff00;
8339          }
8340        }
8341      "#},
8342      Browsers {
8343        firefox: Some(64 << 16),
8344        ..Browsers::default()
8345      },
8346    );
8347
8348    prefix_test(
8349      r#"
8350        @media (color > 2) {
8351          .foo {
8352            color: chartreuse;
8353          }
8354        }
8355      "#,
8356      indoc! { r#"
8357        @media (min-color: 3) {
8358          .foo {
8359            color: #7fff00;
8360          }
8361        }
8362      "#},
8363      Browsers {
8364        firefox: Some(60 << 16),
8365        ..Browsers::default()
8366      },
8367    );
8368
8369    prefix_test(
8370      r#"
8371        @media (color < 2) {
8372          .foo {
8373            color: chartreuse;
8374          }
8375        }
8376      "#,
8377      indoc! { r#"
8378        @media (max-color: 1) {
8379          .foo {
8380            color: #7fff00;
8381          }
8382        }
8383      "#},
8384      Browsers {
8385        firefox: Some(60 << 16),
8386        ..Browsers::default()
8387      },
8388    );
8389
8390    prefix_test(
8391      r#"
8392        @media (width > 240px) {
8393          .foo {
8394            color: chartreuse;
8395          }
8396        }
8397      "#,
8398      indoc! { r#"
8399        @media (min-width: 240.001px) {
8400          .foo {
8401            color: #7fff00;
8402          }
8403        }
8404      "#},
8405      Browsers {
8406        firefox: Some(60 << 16),
8407        ..Browsers::default()
8408      },
8409    );
8410
8411    prefix_test(
8412      r#"
8413        @media (width <= 240px) {
8414          .foo {
8415            color: chartreuse;
8416          }
8417        }
8418      "#,
8419      indoc! { r#"
8420        @media (max-width: 240px) {
8421          .foo {
8422            color: #7fff00;
8423          }
8424        }
8425      "#},
8426      Browsers {
8427        firefox: Some(60 << 16),
8428        ..Browsers::default()
8429      },
8430    );
8431
8432    prefix_test(
8433      r#"
8434        @media (width <= 240px) {
8435          .foo {
8436            color: chartreuse;
8437          }
8438        }
8439      "#,
8440      indoc! { r#"
8441        @media (width <= 240px) {
8442          .foo {
8443            color: #7fff00;
8444          }
8445        }
8446      "#},
8447      Browsers {
8448        firefox: Some(64 << 16),
8449        ..Browsers::default()
8450      },
8451    );
8452
8453    prefix_test(
8454      r#"
8455        @media (width < 240px) {
8456          .foo {
8457            color: chartreuse;
8458          }
8459        }
8460      "#,
8461      indoc! { r#"
8462        @media (max-width: 239.999px) {
8463          .foo {
8464            color: #7fff00;
8465          }
8466        }
8467      "#},
8468      Browsers {
8469        firefox: Some(60 << 16),
8470        ..Browsers::default()
8471      },
8472    );
8473
8474    prefix_test(
8475      r#"
8476        @media (100px <= width <= 200px) {
8477          .foo {
8478            color: chartreuse;
8479          }
8480        }
8481      "#,
8482      indoc! { r#"
8483        @media (min-width: 100px) and (max-width: 200px) {
8484          .foo {
8485            color: #7fff00;
8486          }
8487        }
8488      "#},
8489      Browsers {
8490        firefox: Some(85 << 16),
8491        ..Browsers::default()
8492      },
8493    );
8494
8495    prefix_test(
8496      r#"
8497        @media not (100px <= width <= 200px) {
8498          .foo {
8499            color: chartreuse;
8500          }
8501        }
8502      "#,
8503      indoc! { r#"
8504        @media not ((min-width: 100px) and (max-width: 200px)) {
8505          .foo {
8506            color: #7fff00;
8507          }
8508        }
8509      "#},
8510      Browsers {
8511        firefox: Some(85 << 16),
8512        ..Browsers::default()
8513      },
8514    );
8515
8516    prefix_test(
8517      r#"
8518        @media (hover) and (100px <= width <= 200px) {
8519          .foo {
8520            color: chartreuse;
8521          }
8522        }
8523      "#,
8524      indoc! { r#"
8525        @media (hover) and (min-width: 100px) and (max-width: 200px) {
8526          .foo {
8527            color: #7fff00;
8528          }
8529        }
8530      "#},
8531      Browsers {
8532        firefox: Some(85 << 16),
8533        ..Browsers::default()
8534      },
8535    );
8536
8537    prefix_test(
8538      r#"
8539        @media (hover) or (100px <= width <= 200px) {
8540          .foo {
8541            color: chartreuse;
8542          }
8543        }
8544      "#,
8545      indoc! { r#"
8546        @media (hover) or ((min-width: 100px) and (max-width: 200px)) {
8547          .foo {
8548            color: #7fff00;
8549          }
8550        }
8551      "#},
8552      Browsers {
8553        firefox: Some(85 << 16),
8554        ..Browsers::default()
8555      },
8556    );
8557
8558    prefix_test(
8559      r#"
8560        @media (100px < width < 200px) {
8561          .foo {
8562            color: chartreuse;
8563          }
8564        }
8565      "#,
8566      indoc! { r#"
8567        @media (min-width: 100.001px) and (max-width: 199.999px) {
8568          .foo {
8569            color: #7fff00;
8570          }
8571        }
8572      "#},
8573      Browsers {
8574        firefox: Some(85 << 16),
8575        ..Browsers::default()
8576      },
8577    );
8578
8579    prefix_test(
8580      r#"
8581        @media (200px >= width >= 100px) {
8582          .foo {
8583            color: chartreuse;
8584          }
8585        }
8586      "#,
8587      indoc! { r#"
8588        @media (max-width: 200px) and (min-width: 100px) {
8589          .foo {
8590            color: #7fff00;
8591          }
8592        }
8593      "#},
8594      Browsers {
8595        firefox: Some(85 << 16),
8596        ..Browsers::default()
8597      },
8598    );
8599
8600    test(
8601      r#"
8602      @media not all {
8603        .a {
8604          color: green;
8605        }
8606      }
8607      "#,
8608      "\n",
8609    );
8610
8611    prefix_test(
8612      r#"
8613      @media (width > calc(1px + 1rem)) {
8614        .foo { color: yellow; }
8615      }
8616      "#,
8617      indoc! { r#"
8618        @media (min-width: calc(1.001px + 1rem)) {
8619          .foo {
8620            color: #ff0;
8621          }
8622        }
8623      "#},
8624      Browsers {
8625        chrome: Some(85 << 16),
8626        ..Browsers::default()
8627      },
8628    );
8629    prefix_test(
8630      r#"
8631      @media (width > max(10px, 1rem)) {
8632        .foo { color: yellow; }
8633      }
8634      "#,
8635      indoc! { r#"
8636        @media (min-width: calc(max(10px, 1rem) + .001px)) {
8637          .foo {
8638            color: #ff0;
8639          }
8640        }
8641      "#},
8642      Browsers {
8643        chrome: Some(85 << 16),
8644        ..Browsers::default()
8645      },
8646    );
8647    prefix_test(
8648      r#"
8649      @media (width > 0) {
8650        .foo { color: yellow; }
8651      }
8652      "#,
8653      indoc! { r#"
8654        @media (min-width: .001px) {
8655          .foo {
8656            color: #ff0;
8657          }
8658        }
8659      "#},
8660      Browsers {
8661        chrome: Some(85 << 16),
8662        ..Browsers::default()
8663      },
8664    );
8665    prefix_test(
8666      r#"
8667      @media (min-resolution: 2dppx) {
8668        .foo { color: yellow; }
8669      }
8670      "#,
8671      indoc! { r#"
8672        @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 2dppx) {
8673          .foo {
8674            color: #ff0;
8675          }
8676        }
8677      "#},
8678      Browsers {
8679        safari: Some(15 << 16),
8680        ..Browsers::default()
8681      },
8682    );
8683    prefix_test(
8684      r#"
8685      @media (min-resolution: 2dppx) {
8686        .foo { color: yellow; }
8687      }
8688      "#,
8689      indoc! { r#"
8690        @media (min--moz-device-pixel-ratio: 2), (min-resolution: 2dppx) {
8691          .foo {
8692            color: #ff0;
8693          }
8694        }
8695      "#},
8696      Browsers {
8697        firefox: Some(10 << 16),
8698        ..Browsers::default()
8699      },
8700    );
8701    prefix_test(
8702      r#"
8703      @media (resolution > 2dppx) {
8704        .foo { color: yellow; }
8705      }
8706      "#,
8707      indoc! { r#"
8708        @media (-webkit-min-device-pixel-ratio: 2.001), (min-resolution: 2.001dppx) {
8709          .foo {
8710            color: #ff0;
8711          }
8712        }
8713      "#},
8714      Browsers {
8715        safari: Some(15 << 16),
8716        ..Browsers::default()
8717      },
8718    );
8719    prefix_test(
8720      r#"
8721      @media (resolution >= 300dpi) {
8722        .foo { color: yellow; }
8723      }
8724      "#,
8725      indoc! { r#"
8726        @media (-webkit-min-device-pixel-ratio: 3.125), (min-resolution: 300dpi) {
8727          .foo {
8728            color: #ff0;
8729          }
8730        }
8731      "#},
8732      Browsers {
8733        safari: Some(15 << 16),
8734        ..Browsers::default()
8735      },
8736    );
8737    prefix_test(
8738      r#"
8739      @media (min-resolution: 113.38dpcm) {
8740        .foo { color: yellow; }
8741      }
8742      "#,
8743      indoc! { r#"
8744        @media (-webkit-min-device-pixel-ratio: 2.99985), (min--moz-device-pixel-ratio: 2.99985), (min-resolution: 113.38dpcm) {
8745          .foo {
8746            color: #ff0;
8747          }
8748        }
8749      "#},
8750      Browsers {
8751        safari: Some(15 << 16),
8752        firefox: Some(10 << 16),
8753        ..Browsers::default()
8754      },
8755    );
8756    prefix_test(
8757      r#"
8758      @media (color) and (min-resolution: 2dppx) {
8759        .foo { color: yellow; }
8760      }
8761      "#,
8762      indoc! { r#"
8763        @media (color) and (-webkit-min-device-pixel-ratio: 2), (color) and (min-resolution: 2dppx) {
8764          .foo {
8765            color: #ff0;
8766          }
8767        }
8768      "#},
8769      Browsers {
8770        safari: Some(15 << 16),
8771        ..Browsers::default()
8772      },
8773    );
8774    prefix_test(
8775      r#"
8776      @media (min-resolution: 2dppx),
8777             (min-resolution: 192dpi) {
8778        .foo { color: yellow; }
8779      }
8780      "#,
8781      indoc! { r#"
8782        @media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (min-resolution: 2dppx), (min-resolution: 192dpi) {
8783          .foo {
8784            color: #ff0;
8785          }
8786        }
8787      "#},
8788      Browsers {
8789        safari: Some(15 << 16),
8790        firefox: Some(10 << 16),
8791        ..Browsers::default()
8792      },
8793    );
8794    prefix_test(
8795      r#"
8796      @media only screen and (min-resolution: 124.8dpi) {
8797        .foo { color: yellow; }
8798      }
8799      "#,
8800      indoc! { r#"
8801        @media only screen and (-webkit-min-device-pixel-ratio: 1.3), only screen and (min--moz-device-pixel-ratio: 1.3), only screen and (min-resolution: 124.8dpi) {
8802          .foo {
8803            color: #ff0;
8804          }
8805        }
8806      "#},
8807      Browsers {
8808        safari: Some(15 << 16),
8809        firefox: Some(10 << 16),
8810        ..Browsers::default()
8811      },
8812    );
8813
8814    error_test(
8815      "@media (min-width: hi) { .foo { color: chartreuse }}",
8816      ParserError::InvalidMediaQuery,
8817    );
8818    error_test(
8819      "@media (width >= hi) { .foo { color: chartreuse }}",
8820      ParserError::InvalidMediaQuery,
8821    );
8822    error_test(
8823      "@media (width >= 2/1) { .foo { color: chartreuse }}",
8824      ParserError::UnexpectedToken(Token::Delim('/')),
8825    );
8826    error_test(
8827      "@media (600px <= min-height) { .foo { color: chartreuse }}",
8828      ParserError::InvalidMediaQuery,
8829    );
8830    error_test(
8831      "@media (scan >= 1) { .foo { color: chartreuse }}",
8832      ParserError::InvalidMediaQuery,
8833    );
8834    error_test(
8835      "@media (min-scan: interlace) { .foo { color: chartreuse }}",
8836      ParserError::InvalidMediaQuery,
8837    );
8838    error_test(
8839      "@media (1px <= width <= bar) { .foo { color: chartreuse }}",
8840      ParserError::InvalidMediaQuery,
8841    );
8842    error_test(
8843      "@media (1px <= min-width <= 2px) { .foo { color: chartreuse }}",
8844      ParserError::InvalidMediaQuery,
8845    );
8846    error_test(
8847      "@media (1px <= scan <= 2px) { .foo { color: chartreuse }}",
8848      ParserError::InvalidMediaQuery,
8849    );
8850    error_test(
8851      "@media (grid: 10) { .foo { color: chartreuse }}",
8852      ParserError::InvalidMediaQuery,
8853    );
8854    error_test(
8855      "@media (prefers-color-scheme = dark) { .foo { color: chartreuse }}",
8856      ParserError::InvalidMediaQuery,
8857    );
8858  }
8859
8860  #[test]
8861  fn test_merge_layers() {
8862    test(
8863      r#"
8864      @layer foo {
8865        .foo {
8866          color: red;
8867        }
8868      }
8869      @layer foo {
8870        .foo {
8871          background: #fff;
8872        }
8873
8874        .baz {
8875          color: #fff;
8876        }
8877      }
8878      "#,
8879      indoc! {r#"
8880      @layer foo {
8881        .foo {
8882          color: red;
8883          background: #fff;
8884        }
8885
8886        .baz {
8887          color: #fff;
8888        }
8889      }
8890    "#},
8891    );
8892    test(
8893      r#"
8894      @layer a {}
8895      @layer b {}
8896
8897      @layer b {
8898        foo {
8899          color: red;
8900        }
8901      }
8902
8903      @layer a {
8904        bar {
8905          color: yellow;
8906        }
8907      }
8908      "#,
8909      indoc! {r#"
8910      @layer a {
8911        bar {
8912          color: #ff0;
8913        }
8914      }
8915
8916      @layer b {
8917        foo {
8918          color: red;
8919        }
8920      }
8921    "#},
8922    );
8923
8924    test(
8925      r#"
8926      @layer a {}
8927      @layer b {}
8928
8929      @layer b {
8930        foo {
8931          color: red;
8932        }
8933      }
8934      "#,
8935      indoc! {r#"
8936      @layer a;
8937
8938      @layer b {
8939        foo {
8940          color: red;
8941        }
8942      }
8943    "#},
8944    );
8945
8946    test(
8947      r#"
8948      @layer a;
8949      @layer b;
8950      @layer c;
8951      "#,
8952      indoc! {r#"
8953      @layer a, b, c;
8954    "#},
8955    );
8956
8957    test(
8958      r#"
8959      @layer a {}
8960      @layer b {}
8961      @layer c {}
8962      "#,
8963      indoc! {r#"
8964      @layer a, b, c;
8965    "#},
8966    );
8967
8968    test(
8969      r#"
8970      @layer a;
8971      @layer b {
8972        .foo {
8973          color: red;
8974        }
8975      }
8976      @layer c {}
8977      "#,
8978      indoc! {r#"
8979      @layer a;
8980
8981      @layer b {
8982        .foo {
8983          color: red;
8984        }
8985      }
8986
8987      @layer c;
8988    "#},
8989    );
8990
8991    test(
8992      r#"
8993      @layer a, b;
8994      @layer c {}
8995
8996      @layer d {
8997        foo {
8998          color: red;
8999        }
9000      }
9001      "#,
9002      indoc! {r#"
9003      @layer a, b, c;
9004
9005      @layer d {
9006        foo {
9007          color: red;
9008        }
9009      }
9010    "#},
9011    );
9012
9013    test(
9014      r#"
9015      @layer a;
9016      @layer b;
9017      @import "a.css" layer(x);
9018      @layer c;
9019
9020      @layer d {
9021        foo {
9022          color: red;
9023        }
9024      }
9025      "#,
9026      indoc! {r#"
9027      @layer a, b;
9028      @import "a.css" layer(x);
9029      @layer c;
9030
9031      @layer d {
9032        foo {
9033          color: red;
9034        }
9035      }
9036    "#},
9037    );
9038
9039    test(
9040      r#"
9041      @layer a, b, c;
9042
9043      @layer a {
9044        foo {
9045          color: red;
9046        }
9047      }
9048      "#,
9049      indoc! {r#"
9050      @layer a {
9051        foo {
9052          color: red;
9053        }
9054      }
9055
9056      @layer b, c;
9057    "#},
9058    );
9059  }
9060
9061  #[test]
9062  fn test_merge_rules() {
9063    test(
9064      r#"
9065      .foo {
9066        color: red;
9067      }
9068      .bar {
9069        color: red;
9070      }
9071    "#,
9072      indoc! {r#"
9073      .foo, .bar {
9074        color: red;
9075      }
9076    "#},
9077    );
9078    test(
9079      r#"
9080      .foo {
9081        color: red;
9082      }
9083      .foo {
9084        background: green;
9085      }
9086    "#,
9087      indoc! {r#"
9088      .foo {
9089        color: red;
9090        background: green;
9091      }
9092    "#},
9093    );
9094    test(
9095      r#"
9096      .foo {
9097        color: red;
9098      }
9099      .foo {
9100        background: green !important;
9101      }
9102    "#,
9103      indoc! {r#"
9104      .foo {
9105        color: red;
9106        background: green !important;
9107      }
9108    "#},
9109    );
9110    test(
9111      r#"
9112      .foo {
9113        background: red;
9114      }
9115      .foo {
9116        background: green;
9117      }
9118    "#,
9119      indoc! {r#"
9120      .foo {
9121        background: green;
9122      }
9123    "#},
9124    );
9125    test(
9126      r#"
9127      .foo {
9128        --foo: red;
9129        --foo: purple;
9130      }
9131      .foo {
9132        --foo: green;
9133      }
9134    "#,
9135      indoc! {r#"
9136      .foo {
9137        --foo: green;
9138      }
9139    "#},
9140    );
9141    test(
9142      r#"
9143      .foo {
9144        color: red;
9145      }
9146
9147      .bar {
9148        background: green;
9149      }
9150    "#,
9151      indoc! {r#"
9152      .foo {
9153        color: red;
9154      }
9155
9156      .bar {
9157        background: green;
9158      }
9159    "#},
9160    );
9161    test(
9162      r#"
9163      .foo {
9164        color: red;
9165      }
9166
9167      .baz {
9168        color: blue;
9169      }
9170
9171      .bar {
9172        color: red;
9173      }
9174    "#,
9175      indoc! {r#"
9176      .foo {
9177        color: red;
9178      }
9179
9180      .baz {
9181        color: #00f;
9182      }
9183
9184      .bar {
9185        color: red;
9186      }
9187    "#},
9188    );
9189    test(
9190      r#"
9191      .foo {
9192        background: red;
9193      }
9194      .bar {
9195        background: red;
9196      }
9197      .foo {
9198        color: green;
9199      }
9200      .bar {
9201        color: green;
9202      }
9203    "#,
9204      indoc! {r#"
9205      .foo, .bar {
9206        color: green;
9207        background: red;
9208      }
9209    "#},
9210    );
9211    test(
9212      r#"
9213      .foo, .bar {
9214        background: red;
9215      }
9216      .foo {
9217        color: green;
9218      }
9219      .bar {
9220        color: green;
9221      }
9222    "#,
9223      indoc! {r#"
9224      .foo, .bar {
9225        color: green;
9226        background: red;
9227      }
9228    "#},
9229    );
9230    test(
9231      r#"
9232      .foo {
9233        background: red;
9234      }
9235      .foo {
9236        color: green;
9237      }
9238      .bar {
9239        background: red;
9240      }
9241      .bar {
9242        color: green;
9243      }
9244    "#,
9245      indoc! {r#"
9246      .foo, .bar {
9247        color: green;
9248        background: red;
9249      }
9250    "#},
9251    );
9252    test(
9253      r#"
9254      [foo="bar"] {
9255        color: red;
9256      }
9257      .bar {
9258        color: red;
9259      }
9260    "#,
9261      indoc! {r#"
9262      [foo="bar"], .bar {
9263        color: red;
9264      }
9265    "#},
9266    );
9267    test(
9268      r#"
9269      .a {
9270        color: red;
9271      }
9272      .b {
9273        color: green;
9274      }
9275      .a {
9276        color: red;
9277      }
9278    "#,
9279      indoc! {r#"
9280      .b {
9281        color: green;
9282      }
9283
9284      .a {
9285        color: red;
9286      }
9287    "#},
9288    );
9289    test(
9290      r#"
9291      .a {
9292        color: red;
9293      }
9294      .b {
9295        color: green;
9296      }
9297      .a {
9298        color: pink;
9299      }
9300    "#,
9301      indoc! {r#"
9302      .b {
9303        color: green;
9304      }
9305
9306      .a {
9307        color: pink;
9308      }
9309    "#},
9310    );
9311    test(
9312      r#"
9313      .a:foo(#000) {
9314        color: red;
9315      }
9316      .b {
9317        color: green;
9318      }
9319      .a:foo(#ff0) {
9320        color: pink;
9321      }
9322    "#,
9323      indoc! {r#"
9324      .a:foo(#000) {
9325        color: red;
9326      }
9327
9328      .b {
9329        color: green;
9330      }
9331
9332      .a:foo(#ff0) {
9333        color: pink;
9334      }
9335    "#},
9336    );
9337    test(
9338      r#"
9339      .a {
9340        border-radius: 10px;
9341      }
9342      .b {
9343        color: green;
9344      }
9345      .a {
9346        border-radius: 10px;
9347      }
9348    "#,
9349      indoc! {r#"
9350      .b {
9351        color: green;
9352      }
9353
9354      .a {
9355        border-radius: 10px;
9356      }
9357    "#},
9358    );
9359    test(
9360      r#"
9361      .a {
9362        border-radius: 10px;
9363      }
9364      .b {
9365        color: green;
9366      }
9367      .a {
9368        -webkit-border-radius: 10px;
9369      }
9370    "#,
9371      indoc! {r#"
9372      .a {
9373        border-radius: 10px;
9374      }
9375
9376      .b {
9377        color: green;
9378      }
9379
9380      .a {
9381        -webkit-border-radius: 10px;
9382      }
9383    "#},
9384    );
9385    test(
9386      r#"
9387      .a {
9388        border-radius: 10px;
9389      }
9390      .b {
9391        color: green;
9392      }
9393      .a {
9394        border-radius: var(--foo);
9395      }
9396    "#,
9397      indoc! {r#"
9398      .b {
9399        color: green;
9400      }
9401
9402      .a {
9403        border-radius: var(--foo);
9404      }
9405    "#},
9406    );
9407    test(
9408      r#"
9409      .a {
9410        border-radius: 10px;
9411      }
9412      .b {
9413        color: green;
9414      }
9415      .c {
9416        border-radius: 20px;
9417      }
9418    "#,
9419      indoc! {r#"
9420      .a {
9421        border-radius: 10px;
9422      }
9423
9424      .b {
9425        color: green;
9426      }
9427
9428      .c {
9429        border-radius: 20px;
9430      }
9431    "#},
9432    );
9433    test(
9434      r#"
9435      @media print {
9436        .a {
9437          color: red;
9438        }
9439        .b {
9440          color: green;
9441        }
9442        .a {
9443          color: red;
9444        }
9445      }
9446    "#,
9447      indoc! {r#"
9448      @media print {
9449        .b {
9450          color: green;
9451        }
9452
9453        .a {
9454          color: red;
9455        }
9456      }
9457    "#},
9458    );
9459    test(
9460      r#"
9461      .a {
9462        border-radius: 10px;
9463      }
9464      .b {
9465        color: green;
9466      }
9467      .a {
9468        border-radius: 20px;
9469        color: pink;
9470      }
9471    "#,
9472      indoc! {r#"
9473      .a {
9474        border-radius: 10px;
9475      }
9476
9477      .b {
9478        color: green;
9479      }
9480
9481      .a {
9482        color: pink;
9483        border-radius: 20px;
9484      }
9485    "#},
9486    );
9487    test(
9488      r#"
9489      .a {
9490        color: red;
9491      }
9492      .b {
9493        color: green;
9494      }
9495      .a {
9496        color: red;
9497      }
9498      .b {
9499        color: green;
9500      }
9501    "#,
9502      indoc! {r#"
9503      .a {
9504        color: red;
9505      }
9506
9507      .b {
9508        color: green;
9509      }
9510    "#},
9511    );
9512
9513    prefix_test(
9514      r#"
9515      [foo="bar"] {
9516        color: red;
9517      }
9518      .bar {
9519        color: red;
9520      }
9521    "#,
9522      indoc! {r#"
9523      [foo="bar"] {
9524        color: red;
9525      }
9526
9527      .bar {
9528        color: red;
9529      }
9530    "#},
9531      Browsers {
9532        ie: Some(6 << 16),
9533        ..Browsers::default()
9534      },
9535    );
9536
9537    prefix_test(
9538      r#"
9539      [foo="bar"] {
9540        color: red;
9541      }
9542      .bar {
9543        color: red;
9544      }
9545    "#,
9546      indoc! {r#"
9547      [foo="bar"], .bar {
9548        color: red;
9549      }
9550    "#},
9551      Browsers {
9552        ie: Some(10 << 16),
9553        ..Browsers::default()
9554      },
9555    );
9556
9557    test(
9558      r#"
9559      .foo:-moz-read-only {
9560        color: red;
9561      }
9562    "#,
9563      indoc! {r#"
9564      .foo:-moz-read-only {
9565        color: red;
9566      }
9567    "#},
9568    );
9569
9570    test(
9571      r#"
9572      .foo:-moz-read-only {
9573        color: red;
9574      }
9575
9576      .foo:read-only {
9577        color: red;
9578      }
9579    "#,
9580      indoc! {r#"
9581      .foo:-moz-read-only {
9582        color: red;
9583      }
9584
9585      .foo:read-only {
9586        color: red;
9587      }
9588    "#},
9589    );
9590
9591    prefix_test(
9592      r#"
9593      .foo:-moz-read-only {
9594        color: red;
9595      }
9596
9597      .foo:read-only {
9598        color: red;
9599      }
9600    "#,
9601      indoc! {r#"
9602      .foo:read-only {
9603        color: red;
9604      }
9605    "#},
9606      Browsers {
9607        firefox: Some(85 << 16),
9608        ..Browsers::default()
9609      },
9610    );
9611
9612    prefix_test(
9613      r#"
9614      .foo:-moz-read-only {
9615        color: red;
9616      }
9617
9618      .bar {
9619        color: yellow;
9620      }
9621
9622      .foo:read-only {
9623        color: red;
9624      }
9625    "#,
9626      indoc! {r#"
9627      .foo:-moz-read-only {
9628        color: red;
9629      }
9630
9631      .bar {
9632        color: #ff0;
9633      }
9634
9635      .foo:read-only {
9636        color: red;
9637      }
9638    "#},
9639      Browsers {
9640        firefox: Some(85 << 16),
9641        ..Browsers::default()
9642      },
9643    );
9644
9645    prefix_test(
9646      r#"
9647      .foo:-moz-read-only {
9648        color: red;
9649      }
9650
9651      .foo:read-only {
9652        color: red;
9653      }
9654    "#,
9655      indoc! {r#"
9656      .foo:-moz-read-only {
9657        color: red;
9658      }
9659
9660      .foo:read-only {
9661        color: red;
9662      }
9663    "#},
9664      Browsers {
9665        firefox: Some(36 << 16),
9666        ..Browsers::default()
9667      },
9668    );
9669
9670    prefix_test(
9671      r#"
9672      .foo:read-only {
9673        color: red;
9674      }
9675    "#,
9676      indoc! {r#"
9677      .foo:-moz-read-only {
9678        color: red;
9679      }
9680
9681      .foo:read-only {
9682        color: red;
9683      }
9684    "#},
9685      Browsers {
9686        firefox: Some(36 << 16),
9687        ..Browsers::default()
9688      },
9689    );
9690
9691    prefix_test(
9692      r#"
9693      .foo:-webkit-full-screen {
9694        color: red;
9695      }
9696      .foo:-moz-full-screen {
9697        color: red;
9698      }
9699      .foo:-ms-fullscreen {
9700        color: red;
9701      }
9702      .foo:fullscreen {
9703        color: red;
9704      }
9705    "#,
9706      indoc! {r#"
9707      .foo:fullscreen {
9708        color: red;
9709      }
9710    "#},
9711      Browsers {
9712        chrome: Some(96 << 16),
9713        ..Browsers::default()
9714      },
9715    );
9716
9717    prefix_test(
9718      r#"
9719      .foo:fullscreen {
9720        color: red;
9721      }
9722    "#,
9723      indoc! {r#"
9724      .foo:-webkit-full-screen {
9725        color: red;
9726      }
9727
9728      .foo:-moz-full-screen {
9729        color: red;
9730      }
9731
9732      .foo:-ms-fullscreen {
9733        color: red;
9734      }
9735
9736      .foo:fullscreen {
9737        color: red;
9738      }
9739    "#},
9740      Browsers {
9741        chrome: Some(45 << 16),
9742        firefox: Some(45 << 16),
9743        ie: Some(11 << 16),
9744        ..Browsers::default()
9745      },
9746    );
9747
9748    prefix_test(
9749      r#"
9750      .foo::placeholder {
9751        color: red;
9752      }
9753    "#,
9754      indoc! {r#"
9755      .foo::-webkit-input-placeholder {
9756        color: red;
9757      }
9758
9759      .foo::-moz-placeholder {
9760        color: red;
9761      }
9762
9763      .foo::-ms-input-placeholder {
9764        color: red;
9765      }
9766
9767      .foo::placeholder {
9768        color: red;
9769      }
9770    "#},
9771      Browsers {
9772        chrome: Some(45 << 16),
9773        firefox: Some(45 << 16),
9774        ie: Some(11 << 16),
9775        ..Browsers::default()
9776      },
9777    );
9778
9779    prefix_test(
9780      r#"
9781      .foo::file-selector-button {
9782        color: red;
9783      }
9784    "#,
9785      indoc! {r#"
9786      .foo::-webkit-file-upload-button {
9787        color: red;
9788      }
9789
9790      .foo::-ms-browse {
9791        color: red;
9792      }
9793
9794      .foo::file-selector-button {
9795        color: red;
9796      }
9797    "#},
9798      Browsers {
9799        chrome: Some(84 << 16),
9800        ie: Some(10 << 16),
9801        ..Browsers::default()
9802      },
9803    );
9804
9805    prefix_test(
9806      r#"
9807      .foo::file-selector-button {
9808        margin-inline-start: 2px;
9809      }
9810    "#,
9811      indoc! {r#"
9812      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)))::-webkit-file-upload-button {
9813        margin-left: 2px;
9814      }
9815
9816      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)))::-ms-browse {
9817        margin-left: 2px;
9818      }
9819
9820      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)))::file-selector-button {
9821        margin-left: 2px;
9822      }
9823
9824      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))::-webkit-file-upload-button {
9825        margin-right: 2px;
9826      }
9827
9828      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))::-ms-browse {
9829        margin-right: 2px;
9830      }
9831
9832      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))::file-selector-button {
9833        margin-right: 2px;
9834      }
9835    "#},
9836      Browsers {
9837        chrome: Some(84 << 16),
9838        ie: Some(10 << 16),
9839        ..Browsers::default()
9840      },
9841    );
9842
9843    prefix_test(
9844      r#"
9845      .foo:placeholder-shown .bar { color: red; }
9846      .foo:autofill .baz { color: red; }
9847      "#,
9848      indoc! {r#"
9849      .foo:placeholder-shown .bar {
9850        color: red;
9851      }
9852
9853      .foo:-webkit-autofill .baz {
9854        color: red;
9855      }
9856
9857      .foo:autofill .baz {
9858        color: red;
9859      }
9860      "#},
9861      Browsers {
9862        chrome: Some(103 << 16),
9863        ..Browsers::default()
9864      },
9865    );
9866
9867    prefix_test(
9868      r#"
9869      .foo:placeholder-shown .bar,.foo:autofill .baz{color:red}
9870      "#,
9871      indoc! {r#"
9872      :-webkit-any(.foo:placeholder-shown .bar, .foo:-webkit-autofill .baz) {
9873        color: red;
9874      }
9875
9876      :is(.foo:placeholder-shown .bar, .foo:autofill .baz) {
9877        color: red;
9878      }
9879      "#},
9880      Browsers {
9881        chrome: Some(103 << 16),
9882        ..Browsers::default()
9883      },
9884    );
9885
9886    prefix_test(
9887      r#"
9888      .foo:placeholder-shown .bar, .foo:-webkit-autofill .baz {
9889        color: red;
9890      }
9891
9892      .foo:placeholder-shown .bar, .foo:autofill .baz {
9893        color: red;
9894      }
9895      "#,
9896      indoc! {r#"
9897      :-webkit-any(.foo:placeholder-shown .bar, .foo:-webkit-autofill .baz) {
9898        color: red;
9899      }
9900
9901      :is(.foo:placeholder-shown .bar, .foo:autofill .baz) {
9902        color: red;
9903      }
9904      "#},
9905      Browsers {
9906        chrome: Some(103 << 16),
9907        ..Browsers::default()
9908      },
9909    );
9910
9911    test(
9912      r#"
9913      .foo:placeholder-shown .bar, .foo:-webkit-autofill .baz {
9914        color: red;
9915      }
9916
9917      .foo:placeholder-shown .bar, .foo:autofill .baz {
9918        color: red;
9919      }
9920      "#,
9921      indoc! {r#"
9922      .foo:placeholder-shown .bar, .foo:-webkit-autofill .baz {
9923        color: red;
9924      }
9925
9926      .foo:placeholder-shown .bar, .foo:autofill .baz {
9927        color: red;
9928      }
9929      "#},
9930    );
9931
9932    prefix_test(
9933      r#"
9934      :hover, :focus-visible {
9935        color: red;
9936      }
9937      "#,
9938      indoc! {r#"
9939      :hover {
9940        color: red;
9941      }
9942
9943      :focus-visible {
9944        color: red;
9945      }
9946      "#},
9947      Browsers {
9948        safari: Some(13 << 16),
9949        ..Browsers::default()
9950      },
9951    );
9952
9953    prefix_test(
9954      r#"
9955      .foo {
9956        color: red;
9957      }
9958
9959      :hover, :focus-visible {
9960        color: red;
9961      }
9962      "#,
9963      indoc! {r#"
9964      .foo, :hover {
9965        color: red;
9966      }
9967
9968      :focus-visible {
9969        color: red;
9970      }
9971      "#},
9972      Browsers {
9973        safari: Some(13 << 16),
9974        ..Browsers::default()
9975      },
9976    );
9977
9978    prefix_test(
9979      r#"
9980      :hover, :focus-visible {
9981        margin-inline-start: 24px;
9982      }
9983      "#,
9984      indoc! {r#"
9985      :hover:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
9986        margin-left: 24px;
9987      }
9988
9989      :hover:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
9990        margin-right: 24px;
9991      }
9992
9993      :focus-visible:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
9994        margin-left: 24px;
9995      }
9996
9997      :focus-visible:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
9998        margin-right: 24px;
9999      }
10000      "#},
10001      Browsers {
10002        safari: Some(11 << 16),
10003        ..Browsers::default()
10004      },
10005    );
10006
10007    prefix_test(
10008      r#"
10009      :focus-within, :focus-visible {
10010        color: red;
10011      }
10012      "#,
10013      indoc! {r#"
10014      :focus-within {
10015        color: red;
10016      }
10017
10018      :focus-visible {
10019        color: red;
10020      }
10021      "#},
10022      Browsers {
10023        safari: Some(9 << 16),
10024        ..Browsers::default()
10025      },
10026    );
10027
10028    prefix_test(
10029      r#"
10030      :hover, :focus-visible {
10031        color: red;
10032      }
10033      "#,
10034      indoc! {r#"
10035      :is(:hover, :focus-visible) {
10036        color: red;
10037      }
10038      "#},
10039      Browsers {
10040        safari: Some(14 << 16),
10041        ..Browsers::default()
10042      },
10043    );
10044
10045    prefix_test(
10046      r#"
10047      a::after:hover, a::after:focus-visible {
10048        color: red;
10049      }
10050      "#,
10051      indoc! {r#"
10052      a:after:hover {
10053        color: red;
10054      }
10055
10056      a:after:focus-visible {
10057        color: red;
10058      }
10059      "#},
10060      Browsers {
10061        safari: Some(14 << 16),
10062        ..Browsers::default()
10063      },
10064    );
10065
10066    prefix_test(
10067      r#"
10068      a:not(:hover), a:not(:focus-visible) {
10069        color: red;
10070      }
10071      "#,
10072      indoc! {r#"
10073      :is(a:not(:hover), a:not(:focus-visible)) {
10074        color: red;
10075      }
10076      "#},
10077      Browsers {
10078        safari: Some(14 << 16),
10079        ..Browsers::default()
10080      },
10081    );
10082
10083    prefix_test(
10084      r#"
10085      a:has(:hover), a:has(:focus-visible) {
10086        color: red;
10087      }
10088      "#,
10089      indoc! {r#"
10090      :is(a:has(:hover), a:has(:focus-visible)) {
10091        color: red;
10092      }
10093      "#},
10094      Browsers {
10095        safari: Some(14 << 16),
10096        ..Browsers::default()
10097      },
10098    );
10099
10100    prefix_test(
10101      r#"
10102      .foo.foo:hover, .bar:focus-visible {
10103        color: red;
10104      }
10105      "#,
10106      indoc! {r#"
10107      .foo.foo:hover {
10108        color: red;
10109      }
10110
10111      .bar:focus-visible {
10112        color: red;
10113      }
10114      "#},
10115      Browsers {
10116        safari: Some(14 << 16),
10117        ..Browsers::default()
10118      },
10119    );
10120
10121    prefix_test(
10122      r#"
10123      a::unknown-a, a::unknown-b {
10124        color: red;
10125      }
10126      "#,
10127      indoc! {r#"
10128      a::unknown-a {
10129        color: red;
10130      }
10131
10132      a::unknown-b {
10133        color: red;
10134      }
10135      "#},
10136      Browsers {
10137        safari: Some(14 << 16),
10138        ..Browsers::default()
10139      },
10140    );
10141
10142    nesting_test_with_targets(
10143      r#"
10144      .foo {
10145        padding-inline-start: 3px;
10146
10147        .bar {
10148          padding-inline-start: 5px;
10149        }
10150      }
10151      "#,
10152      indoc! {r#"
10153      .foo:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
10154        padding-left: 3px;
10155      }
10156
10157      .foo:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
10158        padding-right: 3px;
10159      }
10160
10161      .foo .bar:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
10162        padding-left: 5px;
10163      }
10164
10165      .foo .bar:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
10166        padding-right: 5px;
10167      }
10168      "#},
10169      Browsers {
10170        safari: Some(12 << 16),
10171        ..Browsers::default()
10172      }
10173      .into(),
10174    );
10175
10176    prefix_test(
10177      r#"
10178      .foo::part(header), .foo::part(body) {
10179        display: none
10180      }
10181      "#,
10182      indoc! {r#"
10183      .foo::part(header), .foo::part(body) {
10184        display: none;
10185      }
10186      "#},
10187      Browsers {
10188        safari: Some(14 << 16),
10189        ..Browsers::default()
10190      },
10191    );
10192
10193    prefix_test(
10194      r#"
10195      .foo :is(.bar) {
10196        color: red;
10197      }
10198      "#,
10199      indoc! {r#"
10200        .foo .bar {
10201          color: red;
10202        }
10203      "#},
10204      Browsers {
10205        chrome: Some(87 << 16),
10206        ..Browsers::default()
10207      },
10208    );
10209
10210    prefix_test(
10211      r#"
10212      .foo :is(.bar), .bar :is(.baz) {
10213        color: red;
10214      }
10215      "#,
10216      indoc! {r#"
10217        .foo .bar, .bar .baz {
10218          color: red;
10219        }
10220      "#},
10221      Browsers {
10222        chrome: Some(87 << 16),
10223        ..Browsers::default()
10224      },
10225    );
10226
10227    prefix_test(
10228      r#"
10229      .foo :is(.bar:focus-visible), .bar :is(.baz:hover) {
10230        color: red;
10231      }
10232      "#,
10233      indoc! {r#"
10234        .bar .baz:hover {
10235          color: red;
10236        }
10237
10238        .foo .bar:focus-visible {
10239          color: red;
10240        }
10241      "#},
10242      Browsers {
10243        chrome: Some(85 << 16),
10244        ..Browsers::default()
10245      },
10246    );
10247
10248    prefix_test(
10249      r#"
10250      *,
10251      ::before,
10252      ::after,
10253      ::backdrop {
10254        padding: 5px;
10255      }
10256      "#,
10257      indoc! {r#"
10258        *, :before, :after {
10259          padding: 5px;
10260        }
10261
10262        ::-webkit-backdrop {
10263          padding: 5px;
10264        }
10265
10266        ::backdrop {
10267          padding: 5px;
10268        }
10269      "#},
10270      Browsers {
10271        chrome: Some(33 << 16),
10272        ..Browsers::default()
10273      },
10274    );
10275
10276    test(
10277      r#"
10278      .foo:-webkit-any(.bar, .baz):after {
10279        color: red;
10280      }
10281
10282      .foo:is(.bar, .baz):after {
10283        color: red;
10284      }
10285      "#,
10286      indoc! {r#"
10287        .foo:-webkit-any(.bar, .baz):after {
10288          color: red;
10289        }
10290
10291        .foo:is(.bar, .baz):after {
10292          color: red;
10293        }
10294      "#},
10295    );
10296
10297    prefix_test(
10298      r#"
10299      .foo:-webkit-any(.bar, .baz):after {
10300        color: red;
10301      }
10302
10303      .foo:is(.bar, .baz):after {
10304        color: red;
10305      }
10306      "#,
10307      indoc! {r#"
10308        .foo:is(.bar, .baz):after {
10309          color: red;
10310        }
10311      "#},
10312      Browsers {
10313        safari: Some(16 << 16),
10314        ..Browsers::default()
10315      },
10316    );
10317
10318    prefix_test(
10319      r#"
10320      .foo:-webkit-any(.bar):after {
10321        color: red;
10322      }
10323
10324      .foo:is(.bar, .baz):after {
10325        color: red;
10326      }
10327      "#,
10328      indoc! {r#"
10329        .foo:-webkit-any(.bar):after {
10330          color: red;
10331        }
10332
10333        .foo:is(.bar, .baz):after {
10334          color: red;
10335        }
10336      "#},
10337      Browsers {
10338        safari: Some(16 << 16),
10339        ..Browsers::default()
10340      },
10341    );
10342
10343    prefix_test(
10344      r#"
10345      .foo:-webkit-any(.bar, .baz):after {
10346        color: red;
10347      }
10348
10349      .foo:is(.bar, .baz):after {
10350        color: red;
10351      }
10352      "#,
10353      indoc! {r#"
10354        .foo:-webkit-any(.bar, .baz):after {
10355          color: red;
10356        }
10357
10358        .foo:is(.bar, .baz):after {
10359          color: red;
10360        }
10361      "#},
10362      Browsers {
10363        safari: Some(12 << 16),
10364        ..Browsers::default()
10365      },
10366    );
10367
10368    prefix_test(
10369      r#"
10370      .foo:-webkit-any(.bar, .baz):after {
10371        color: red;
10372      }
10373
10374      .foo:-moz-any(.bar, .baz):after {
10375        color: red;
10376      }
10377      "#,
10378      indoc! {r#"
10379        .foo:-webkit-any(.bar, .baz):after {
10380          color: red;
10381        }
10382
10383        .foo:-moz-any(.bar, .baz):after {
10384          color: red;
10385        }
10386      "#},
10387      Browsers {
10388        safari: Some(12 << 16),
10389        firefox: Some(67 << 16),
10390        ..Browsers::default()
10391      },
10392    );
10393
10394    prefix_test(
10395      r#"
10396      .a {
10397        padding-inline: var(--foo);
10398      }
10399
10400      .a:-webkit-any(.b, .c) {
10401        padding-inline: var(--foo);
10402      }
10403      "#,
10404      indoc! {r#"
10405        .a {
10406          padding-inline: var(--foo);
10407        }
10408
10409        .a:-webkit-any(.b, .c) {
10410          padding-inline: var(--foo);
10411        }
10412      "#},
10413      Browsers {
10414        safari: Some(12 << 16),
10415        ..Browsers::default()
10416      },
10417    );
10418  }
10419
10420  #[test]
10421  fn test_merge_media_rules() {
10422    test(
10423      r#"
10424      @media (hover) {
10425        .foo {
10426          color: red;
10427        }
10428      }
10429      @media (hover) {
10430        .foo {
10431          background: #fff;
10432        }
10433
10434        .baz {
10435          color: #fff;
10436        }
10437      }
10438      "#,
10439      indoc! {r#"
10440      @media (hover) {
10441        .foo {
10442          color: red;
10443          background: #fff;
10444        }
10445
10446        .baz {
10447          color: #fff;
10448        }
10449      }
10450    "#},
10451    );
10452
10453    test(
10454      r#"
10455      @media (hover) {
10456        .foo {
10457          color: red;
10458        }
10459      }
10460      @media (min-width: 250px) {
10461        .foo {
10462          background: #fff;
10463        }
10464
10465        .baz {
10466          color: #fff;
10467        }
10468      }
10469      "#,
10470      indoc! {r#"
10471      @media (hover) {
10472        .foo {
10473          color: red;
10474        }
10475      }
10476
10477      @media (width >= 250px) {
10478        .foo {
10479          background: #fff;
10480        }
10481
10482        .baz {
10483          color: #fff;
10484        }
10485      }
10486    "#},
10487    );
10488  }
10489
10490  #[test]
10491  fn test_merge_supports() {
10492    test(
10493      r#"
10494      @supports (flex: 1) {
10495        .foo {
10496          color: red;
10497        }
10498      }
10499      @supports (flex: 1) {
10500        .foo {
10501          background: #fff;
10502        }
10503
10504        .baz {
10505          color: #fff;
10506        }
10507      }
10508      "#,
10509      indoc! {r#"
10510      @supports (flex: 1) {
10511        .foo {
10512          color: red;
10513          background: #fff;
10514        }
10515
10516        .baz {
10517          color: #fff;
10518        }
10519      }
10520    "#},
10521    );
10522
10523    test(
10524      r#"
10525      @supports (flex: 1) {
10526        .foo {
10527          color: red;
10528        }
10529      }
10530      @supports (display: grid) {
10531        .foo {
10532          background: #fff;
10533        }
10534
10535        .baz {
10536          color: #fff;
10537        }
10538      }
10539      "#,
10540      indoc! {r#"
10541      @supports (flex: 1) {
10542        .foo {
10543          color: red;
10544        }
10545      }
10546
10547      @supports (display: grid) {
10548        .foo {
10549          background: #fff;
10550        }
10551
10552        .baz {
10553          color: #fff;
10554        }
10555      }
10556    "#},
10557    );
10558  }
10559
10560  #[test]
10561  fn test_opacity() {
10562    minify_test(".foo { opacity: 0 }", ".foo{opacity:0}");
10563    minify_test(".foo { opacity: 0% }", ".foo{opacity:0}");
10564    minify_test(".foo { opacity: 0.5 }", ".foo{opacity:.5}");
10565    minify_test(".foo { opacity: 50% }", ".foo{opacity:.5}");
10566    minify_test(".foo { opacity: 1 }", ".foo{opacity:1}");
10567    minify_test(".foo { opacity: 100% }", ".foo{opacity:1}");
10568  }
10569
10570  #[test]
10571  fn test_transitions() {
10572    minify_test(".foo { transition-duration: 500ms }", ".foo{transition-duration:.5s}");
10573    minify_test(".foo { transition-duration: .5s }", ".foo{transition-duration:.5s}");
10574    minify_test(".foo { transition-duration: 99ms }", ".foo{transition-duration:99ms}");
10575    minify_test(".foo { transition-duration: .099s }", ".foo{transition-duration:99ms}");
10576    minify_test(".foo { transition-duration: 2000ms }", ".foo{transition-duration:2s}");
10577    minify_test(".foo { transition-duration: 2s }", ".foo{transition-duration:2s}");
10578    minify_test(
10579      ".foo { transition-duration: calc(1s - 50ms) }",
10580      ".foo{transition-duration:.95s}",
10581    );
10582    minify_test(
10583      ".foo { transition-duration: calc(1s - 50ms + 2s) }",
10584      ".foo{transition-duration:2.95s}",
10585    );
10586    minify_test(
10587      ".foo { transition-duration: calc((1s - 50ms) * 2) }",
10588      ".foo{transition-duration:1.9s}",
10589    );
10590    minify_test(
10591      ".foo { transition-duration: calc(2 * (1s - 50ms)) }",
10592      ".foo{transition-duration:1.9s}",
10593    );
10594    minify_test(
10595      ".foo { transition-duration: calc((2s + 50ms) - (1s - 50ms)) }",
10596      ".foo{transition-duration:1.1s}",
10597    );
10598    minify_test(
10599      ".foo { transition-duration: 500ms, 50ms }",
10600      ".foo{transition-duration:.5s,50ms}",
10601    );
10602    minify_test(".foo { transition-delay: 500ms }", ".foo{transition-delay:.5s}");
10603    minify_test(
10604      ".foo { transition-property: background }",
10605      ".foo{transition-property:background}",
10606    );
10607    minify_test(
10608      ".foo { transition-property: background, opacity }",
10609      ".foo{transition-property:background,opacity}",
10610    );
10611    minify_test(
10612      ".foo { transition-timing-function: linear }",
10613      ".foo{transition-timing-function:linear}",
10614    );
10615    minify_test(
10616      ".foo { transition-timing-function: ease }",
10617      ".foo{transition-timing-function:ease}",
10618    );
10619    minify_test(
10620      ".foo { transition-timing-function: ease-in }",
10621      ".foo{transition-timing-function:ease-in}",
10622    );
10623    minify_test(
10624      ".foo { transition-timing-function: ease-out }",
10625      ".foo{transition-timing-function:ease-out}",
10626    );
10627    minify_test(
10628      ".foo { transition-timing-function: ease-in-out }",
10629      ".foo{transition-timing-function:ease-in-out}",
10630    );
10631    minify_test(
10632      ".foo { transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1) }",
10633      ".foo{transition-timing-function:ease}",
10634    );
10635    minify_test(
10636      ".foo { transition-timing-function: cubic-bezier(0.42, 0, 1, 1) }",
10637      ".foo{transition-timing-function:ease-in}",
10638    );
10639    minify_test(
10640      ".foo { transition-timing-function: cubic-bezier(0, 0, 0.58, 1) }",
10641      ".foo{transition-timing-function:ease-out}",
10642    );
10643    minify_test(
10644      ".foo { transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1) }",
10645      ".foo{transition-timing-function:ease-in-out}",
10646    );
10647    minify_test(
10648      ".foo { transition-timing-function: cubic-bezier(0.58, 0.2, 0.11, 1.2) }",
10649      ".foo{transition-timing-function:cubic-bezier(.58,.2,.11,1.2)}",
10650    );
10651    minify_test(
10652      ".foo { transition-timing-function: step-start }",
10653      ".foo{transition-timing-function:step-start}",
10654    );
10655    minify_test(
10656      ".foo { transition-timing-function: step-end }",
10657      ".foo{transition-timing-function:step-end}",
10658    );
10659    minify_test(
10660      ".foo { transition-timing-function: steps(1, start) }",
10661      ".foo{transition-timing-function:step-start}",
10662    );
10663    minify_test(
10664      ".foo { transition-timing-function: steps(1, jump-start) }",
10665      ".foo{transition-timing-function:step-start}",
10666    );
10667    minify_test(
10668      ".foo { transition-timing-function: steps(1, end) }",
10669      ".foo{transition-timing-function:step-end}",
10670    );
10671    minify_test(
10672      ".foo { transition-timing-function: steps(1, jump-end) }",
10673      ".foo{transition-timing-function:step-end}",
10674    );
10675    minify_test(
10676      ".foo { transition-timing-function: steps(5, jump-start) }",
10677      ".foo{transition-timing-function:steps(5,start)}",
10678    );
10679    minify_test(
10680      ".foo { transition-timing-function: steps(5, jump-end) }",
10681      ".foo{transition-timing-function:steps(5,end)}",
10682    );
10683    minify_test(
10684      ".foo { transition-timing-function: steps(5, jump-both) }",
10685      ".foo{transition-timing-function:steps(5,jump-both)}",
10686    );
10687    minify_test(
10688      ".foo { transition-timing-function: ease-in-out, cubic-bezier(0.42, 0, 1, 1) }",
10689      ".foo{transition-timing-function:ease-in-out,ease-in}",
10690    );
10691    minify_test(
10692      ".foo { transition-timing-function: cubic-bezier(0.42, 0, 1, 1), cubic-bezier(0.58, 0.2, 0.11, 1.2) }",
10693      ".foo{transition-timing-function:ease-in,cubic-bezier(.58,.2,.11,1.2)}",
10694    );
10695    minify_test(
10696      ".foo { transition-timing-function: step-start, steps(5, jump-start) }",
10697      ".foo{transition-timing-function:step-start,steps(5,start)}",
10698    );
10699    minify_test(".foo { transition: width 2s ease }", ".foo{transition:width 2s}");
10700    minify_test(
10701      ".foo { transition: width 2s ease, height 1000ms cubic-bezier(0.25, 0.1, 0.25, 1) }",
10702      ".foo{transition:width 2s,height 1s}",
10703    );
10704    minify_test(".foo { transition: width 2s 1s }", ".foo{transition:width 2s 1s}");
10705    minify_test(".foo { transition: width 2s ease 1s }", ".foo{transition:width 2s 1s}");
10706    minify_test(
10707      ".foo { transition: ease-in 1s width 4s }",
10708      ".foo{transition:width 1s ease-in 4s}",
10709    );
10710    minify_test(".foo { transition: opacity 0s .6s }", ".foo{transition:opacity 0s .6s}");
10711    test(
10712      r#"
10713      .foo {
10714        transition-property: opacity;
10715        transition-duration: 0.09s;
10716        transition-timing-function: ease-in-out;
10717        transition-delay: 500ms;
10718      }
10719    "#,
10720      indoc! {r#"
10721      .foo {
10722        transition: opacity 90ms ease-in-out .5s;
10723      }
10724    "#},
10725    );
10726    test(
10727      r#"
10728      .foo {
10729        transition: opacity 2s;
10730        transition-timing-function: ease;
10731        transition-delay: 500ms;
10732      }
10733    "#,
10734      indoc! {r#"
10735      .foo {
10736        transition: opacity 2s .5s;
10737      }
10738    "#},
10739    );
10740    test(
10741      r#"
10742      .foo {
10743        transition: opacity 500ms;
10744        transition-timing-function: var(--ease);
10745      }
10746    "#,
10747      indoc! {r#"
10748      .foo {
10749        transition: opacity .5s;
10750        transition-timing-function: var(--ease);
10751      }
10752    "#},
10753    );
10754    test(
10755      r#"
10756      .foo {
10757        transition-property: opacity;
10758        transition-duration: 0.09s;
10759        transition-timing-function: ease-in-out;
10760        transition-delay: 500ms;
10761        transition: color 2s;
10762      }
10763    "#,
10764      indoc! {r#"
10765      .foo {
10766        transition: color 2s;
10767      }
10768    "#},
10769    );
10770    test(
10771      r#"
10772      .foo {
10773        transition-property: opacity, color;
10774        transition-duration: 2s, 4s;
10775        transition-timing-function: ease-in-out, ease-in;
10776        transition-delay: 500ms, 0s;
10777      }
10778    "#,
10779      indoc! {r#"
10780      .foo {
10781        transition: opacity 2s ease-in-out .5s, color 4s ease-in;
10782      }
10783    "#},
10784    );
10785    test(
10786      r#"
10787      .foo {
10788        transition-property: opacity, color;
10789        transition-duration: 2s;
10790        transition-timing-function: ease-in-out;
10791        transition-delay: 500ms;
10792      }
10793    "#,
10794      indoc! {r#"
10795      .foo {
10796        transition: opacity 2s ease-in-out .5s, color 2s ease-in-out .5s;
10797      }
10798    "#},
10799    );
10800    test(
10801      r#"
10802      .foo {
10803        transition-property: opacity, color, width, height;
10804        transition-duration: 2s, 4s;
10805        transition-timing-function: ease;
10806        transition-delay: 0s;
10807      }
10808    "#,
10809      indoc! {r#"
10810      .foo {
10811        transition: opacity 2s, color 4s, width 2s, height 4s;
10812      }
10813    "#},
10814    );
10815
10816    test(
10817      r#"
10818      .foo {
10819        -webkit-transition-property: opacity, color;
10820        -webkit-transition-duration: 2s, 4s;
10821        -webkit-transition-timing-function: ease-in-out, ease-in;
10822        -webkit-transition-delay: 500ms, 0s;
10823      }
10824    "#,
10825      indoc! {r#"
10826      .foo {
10827        -webkit-transition: opacity 2s ease-in-out .5s, color 4s ease-in;
10828      }
10829    "#},
10830    );
10831
10832    test(
10833      r#"
10834      .foo {
10835        -webkit-transition-property: opacity, color;
10836        -webkit-transition-duration: 2s, 4s;
10837        -webkit-transition-timing-function: ease-in-out, ease-in;
10838        -webkit-transition-delay: 500ms, 0s;
10839        -moz-transition-property: opacity, color;
10840        -moz-transition-duration: 2s, 4s;
10841        -moz-transition-timing-function: ease-in-out, ease-in;
10842        -moz-transition-delay: 500ms, 0s;
10843        transition-property: opacity, color;
10844        transition-duration: 2s, 4s;
10845        transition-timing-function: ease-in-out, ease-in;
10846        transition-delay: 500ms, 0s;
10847      }
10848    "#,
10849      indoc! {r#"
10850      .foo {
10851        -webkit-transition: opacity 2s ease-in-out .5s, color 4s ease-in;
10852        -moz-transition: opacity 2s ease-in-out .5s, color 4s ease-in;
10853        transition: opacity 2s ease-in-out .5s, color 4s ease-in;
10854      }
10855    "#},
10856    );
10857
10858    test(
10859      r#"
10860      .foo {
10861        -webkit-transition-property: opacity, color;
10862        -moz-transition-property: opacity, color;
10863        transition-property: opacity, color;
10864        -webkit-transition-duration: 2s, 4s;
10865        -moz-transition-duration: 2s, 4s;
10866        transition-duration: 2s, 4s;
10867        -webkit-transition-timing-function: ease-in-out, ease-in;
10868        transition-timing-function: ease-in-out, ease-in;
10869        -moz-transition-timing-function: ease-in-out, ease-in;
10870        -webkit-transition-delay: 500ms, 0s;
10871        -moz-transition-delay: 500ms, 0s;
10872        transition-delay: 500ms, 0s;
10873      }
10874    "#,
10875      indoc! {r#"
10876      .foo {
10877        -webkit-transition: opacity 2s ease-in-out .5s, color 4s ease-in;
10878        -moz-transition: opacity 2s ease-in-out .5s, color 4s ease-in;
10879        transition: opacity 2s ease-in-out .5s, color 4s ease-in;
10880      }
10881    "#},
10882    );
10883
10884    test(
10885      r#"
10886      .foo {
10887        -webkit-transition-property: opacity;
10888        -moz-transition-property: color;
10889        transition-property: opacity, color;
10890        -webkit-transition-duration: 2s;
10891        -moz-transition-duration: 4s;
10892        transition-duration: 2s, 4s;
10893        -webkit-transition-timing-function: ease-in-out;
10894        -moz-transition-timing-function: ease-in-out;
10895        transition-timing-function: ease-in-out, ease-in;
10896        -webkit-transition-delay: 500ms;
10897        -moz-transition-delay: 0s;
10898        transition-delay: 500ms, 0s;
10899      }
10900    "#,
10901      indoc! {r#"
10902      .foo {
10903        -webkit-transition-property: opacity;
10904        -moz-transition-property: color;
10905        transition-property: opacity, color;
10906        -webkit-transition-duration: 2s;
10907        -moz-transition-duration: 4s;
10908        transition-duration: 2s, 4s;
10909        -webkit-transition-timing-function: ease-in-out;
10910        -moz-transition-timing-function: ease-in-out;
10911        -webkit-transition-delay: .5s;
10912        transition-timing-function: ease-in-out, ease-in;
10913        -moz-transition-delay: 0s;
10914        transition-delay: .5s, 0s;
10915      }
10916    "#},
10917    );
10918
10919    test(
10920      r#"
10921      .foo {
10922        -webkit-transition-property: opacity;
10923        transition-property: opacity, color;
10924        -moz-transition-property: color;
10925        -webkit-transition-duration: 2s;
10926        transition-duration: 2s, 4s;
10927        -moz-transition-duration: 4s;
10928        -webkit-transition-timing-function: ease-in-out;
10929        transition-timing-function: ease-in-out, ease-in;
10930        -moz-transition-timing-function: ease-in-out;
10931        -webkit-transition-delay: 500ms;
10932        transition-delay: 500ms, 0s;
10933        -moz-transition-delay: 0s;
10934      }
10935    "#,
10936      indoc! {r#"
10937      .foo {
10938        -webkit-transition-property: opacity;
10939        transition-property: opacity, color;
10940        -moz-transition-property: color;
10941        -webkit-transition-duration: 2s;
10942        transition-duration: 2s, 4s;
10943        -moz-transition-duration: 4s;
10944        -webkit-transition-timing-function: ease-in-out;
10945        transition-timing-function: ease-in-out, ease-in;
10946        -webkit-transition-delay: .5s;
10947        -moz-transition-timing-function: ease-in-out;
10948        transition-delay: .5s, 0s;
10949        -moz-transition-delay: 0s;
10950      }
10951    "#},
10952    );
10953
10954    test(
10955      r#"
10956      .foo {
10957        transition: opacity 2s;
10958        -webkit-transition-duration: 2s;
10959      }
10960    "#,
10961      indoc! {r#"
10962      .foo {
10963        transition: opacity 2s;
10964        -webkit-transition-duration: 2s;
10965      }
10966    "#},
10967    );
10968
10969    prefix_test(
10970      r#"
10971      .foo {
10972        transition-property: margin-inline-start;
10973      }
10974    "#,
10975      indoc! {r#"
10976      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
10977        transition-property: margin-left;
10978      }
10979
10980      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
10981        transition-property: margin-left;
10982      }
10983
10984      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
10985        transition-property: margin-right;
10986      }
10987
10988      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
10989        transition-property: margin-right;
10990      }
10991    "#
10992      },
10993      Browsers {
10994        safari: Some(8 << 16),
10995        ..Browsers::default()
10996      },
10997    );
10998
10999    prefix_test(
11000      r#"
11001      .foo {
11002        transition-property: margin-inline-start, padding-inline-start;
11003      }
11004    "#,
11005      indoc! {r#"
11006      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
11007        transition-property: margin-left, padding-left;
11008      }
11009
11010      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
11011        transition-property: margin-left, padding-left;
11012      }
11013
11014      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
11015        transition-property: margin-right, padding-right;
11016      }
11017
11018      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
11019        transition-property: margin-right, padding-right;
11020      }
11021    "#
11022      },
11023      Browsers {
11024        safari: Some(8 << 16),
11025        ..Browsers::default()
11026      },
11027    );
11028
11029    prefix_test(
11030      r#"
11031      .foo {
11032        transition-property: margin-inline-start, opacity, padding-inline-start, color;
11033      }
11034    "#,
11035      indoc! {r#"
11036      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
11037        transition-property: margin-left, opacity, padding-left, color;
11038      }
11039
11040      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
11041        transition-property: margin-left, opacity, padding-left, color;
11042      }
11043
11044      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
11045        transition-property: margin-right, opacity, padding-right, color;
11046      }
11047
11048      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
11049        transition-property: margin-right, opacity, padding-right, color;
11050      }
11051    "#
11052      },
11053      Browsers {
11054        safari: Some(8 << 16),
11055        ..Browsers::default()
11056      },
11057    );
11058
11059    prefix_test(
11060      r#"
11061      .foo {
11062        transition-property: margin-block;
11063      }
11064    "#,
11065      indoc! {r#"
11066      .foo {
11067        transition-property: margin-top, margin-bottom;
11068      }
11069    "#
11070      },
11071      Browsers {
11072        safari: Some(8 << 16),
11073        ..Browsers::default()
11074      },
11075    );
11076
11077    prefix_test(
11078      r#"
11079      .foo {
11080        transition: margin-inline-start 2s;
11081      }
11082    "#,
11083      indoc! {r#"
11084      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
11085        transition: margin-left 2s;
11086      }
11087
11088      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
11089        transition: margin-left 2s;
11090      }
11091
11092      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
11093        transition: margin-right 2s;
11094      }
11095
11096      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
11097        transition: margin-right 2s;
11098      }
11099    "#
11100      },
11101      Browsers {
11102        safari: Some(8 << 16),
11103        ..Browsers::default()
11104      },
11105    );
11106
11107    prefix_test(
11108      r#"
11109      .foo {
11110        transition: margin-inline-start 2s, padding-inline-start 2s;
11111      }
11112    "#,
11113      indoc! {r#"
11114      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
11115        transition: margin-left 2s, padding-left 2s;
11116      }
11117
11118      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
11119        transition: margin-left 2s, padding-left 2s;
11120      }
11121
11122      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
11123        transition: margin-right 2s, padding-right 2s;
11124      }
11125
11126      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
11127        transition: margin-right 2s, padding-right 2s;
11128      }
11129    "#
11130      },
11131      Browsers {
11132        safari: Some(8 << 16),
11133        ..Browsers::default()
11134      },
11135    );
11136
11137    prefix_test(
11138      r#"
11139      .foo {
11140        transition: margin-block-start 2s;
11141      }
11142    "#,
11143      indoc! {r#"
11144      .foo {
11145        transition: margin-top 2s;
11146      }
11147    "#
11148      },
11149      Browsers {
11150        safari: Some(8 << 16),
11151        ..Browsers::default()
11152      },
11153    );
11154
11155    prefix_test(
11156      r#"
11157      .foo {
11158        transition: transform;
11159      }
11160    "#,
11161      indoc! {r#"
11162      .foo {
11163        -webkit-transition: -webkit-transform, transform;
11164        transition: -webkit-transform, transform;
11165      }
11166    "#
11167      },
11168      Browsers {
11169        safari: Some(6 << 16),
11170        ..Browsers::default()
11171      },
11172    );
11173
11174    prefix_test(
11175      r#"
11176      .foo {
11177        transition: border-start-start-radius;
11178      }
11179    "#,
11180      indoc! {r#"
11181      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
11182        -webkit-transition: -webkit-border-top-left-radius, border-top-left-radius;
11183        transition: -webkit-border-top-left-radius, border-top-left-radius;
11184      }
11185
11186      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
11187        -webkit-transition: -webkit-border-top-right-radius, border-top-right-radius;
11188        transition: -webkit-border-top-right-radius, border-top-right-radius;
11189      }
11190    "#
11191      },
11192      Browsers {
11193        safari: Some(4 << 16),
11194        ..Browsers::default()
11195      },
11196    );
11197
11198    prefix_test(
11199      r#"
11200      .foo {
11201        transition: border-start-start-radius;
11202      }
11203    "#,
11204      indoc! {r#"
11205      .foo:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
11206        transition: border-top-left-radius;
11207      }
11208
11209      .foo:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
11210        transition: border-top-right-radius;
11211      }
11212    "#
11213      },
11214      Browsers {
11215        safari: Some(12 << 16),
11216        ..Browsers::default()
11217      },
11218    );
11219
11220    test(
11221      r#"
11222      .foo {
11223        -webkit-transition: background 200ms;
11224        -moz-transition: background 200ms;
11225        transition: background 230ms;
11226      }
11227    "#,
11228      indoc! {r#"
11229      .foo {
11230        -webkit-transition: background .2s;
11231        -moz-transition: background .2s;
11232        transition: background .23s;
11233      }
11234    "#},
11235    );
11236
11237    prefix_test(
11238      r#"
11239      .foo {
11240        -webkit-transition: background 200ms;
11241        -moz-transition: background 200ms;
11242        transition: background 230ms;
11243      }
11244    "#,
11245      indoc! {r#"
11246      .foo {
11247        -webkit-transition: background .2s;
11248        -moz-transition: background .2s;
11249        transition: background .23s;
11250      }
11251    "#},
11252      Browsers {
11253        chrome: Some(95 << 16),
11254        ..Browsers::default()
11255      },
11256    );
11257  }
11258
11259  #[test]
11260  fn test_animation() {
11261    minify_test(".foo { animation-name: test }", ".foo{animation-name:test}");
11262    minify_test(".foo { animation-name: \"test\" }", ".foo{animation-name:test}");
11263    minify_test(".foo { animation-name: foo, bar }", ".foo{animation-name:foo,bar}");
11264    minify_test(".foo { animation-name: \"none\" }", ".foo{animation-name:\"none\"}");
11265    minify_test(
11266      ".foo { animation-name: \"none\", foo }",
11267      ".foo{animation-name:\"none\",foo}",
11268    );
11269    let name = crate::properties::animation::AnimationName::parse_string("default");
11270    assert!(matches!(name, Err(..)));
11271
11272    minify_test(".foo { animation-name: none }", ".foo{animation-name:none}");
11273    minify_test(".foo { animation-name: none, none }", ".foo{animation-name:none,none}");
11274
11275    // Test CSS-wide keywords
11276    minify_test(".foo { animation-name: unset }", ".foo{animation-name:unset}");
11277    minify_test(".foo { animation-name: \"unset\" }", ".foo{animation-name:\"unset\"}");
11278    minify_test(".foo { animation-name: \"revert\" }", ".foo{animation-name:\"revert\"}");
11279    minify_test(
11280      ".foo { animation-name: \"unset\", \"revert\"}",
11281      ".foo{animation-name:\"unset\",\"revert\"}",
11282    );
11283    minify_test(
11284      ".foo { animation-name: foo, \"revert\"}",
11285      ".foo{animation-name:foo,\"revert\"}",
11286    );
11287    minify_test(
11288      ".foo { animation-name: \"string\", \"revert\"}",
11289      ".foo{animation-name:string,\"revert\"}",
11290    );
11291    minify_test(
11292      ".foo { animation-name: \"string\", foo, \"revert\"}",
11293      ".foo{animation-name:string,foo,\"revert\"}",
11294    );
11295    minify_test(
11296      ".foo { animation-name: \"default\" }",
11297      ".foo{animation-name:\"default\"}",
11298    );
11299    minify_test(".foo { animation-duration: 100ms }", ".foo{animation-duration:.1s}");
11300    minify_test(
11301      ".foo { animation-duration: 100ms, 2000ms }",
11302      ".foo{animation-duration:.1s,2s}",
11303    );
11304    minify_test(
11305      ".foo { animation-timing-function: ease }",
11306      ".foo{animation-timing-function:ease}",
11307    );
11308    minify_test(
11309      ".foo { animation-timing-function: cubic-bezier(0.42, 0, 1, 1) }",
11310      ".foo{animation-timing-function:ease-in}",
11311    );
11312    minify_test(
11313      ".foo { animation-timing-function: ease, cubic-bezier(0.42, 0, 1, 1) }",
11314      ".foo{animation-timing-function:ease,ease-in}",
11315    );
11316    minify_test(
11317      ".foo { animation-iteration-count: 5 }",
11318      ".foo{animation-iteration-count:5}",
11319    );
11320    minify_test(
11321      ".foo { animation-iteration-count: 2.5 }",
11322      ".foo{animation-iteration-count:2.5}",
11323    );
11324    minify_test(
11325      ".foo { animation-iteration-count: 2.0 }",
11326      ".foo{animation-iteration-count:2}",
11327    );
11328    minify_test(
11329      ".foo { animation-iteration-count: infinite }",
11330      ".foo{animation-iteration-count:infinite}",
11331    );
11332    minify_test(
11333      ".foo { animation-iteration-count: 1, infinite }",
11334      ".foo{animation-iteration-count:1,infinite}",
11335    );
11336    minify_test(
11337      ".foo { animation-direction: reverse }",
11338      ".foo{animation-direction:reverse}",
11339    );
11340    minify_test(
11341      ".foo { animation-direction: alternate, reverse }",
11342      ".foo{animation-direction:alternate,reverse}",
11343    );
11344    minify_test(
11345      ".foo { animation-play-state: paused }",
11346      ".foo{animation-play-state:paused}",
11347    );
11348    minify_test(
11349      ".foo { animation-play-state: running, paused }",
11350      ".foo{animation-play-state:running,paused}",
11351    );
11352    minify_test(".foo { animation-delay: 100ms }", ".foo{animation-delay:.1s}");
11353    minify_test(
11354      ".foo { animation-delay: 100ms, 2000ms }",
11355      ".foo{animation-delay:.1s,2s}",
11356    );
11357    minify_test(
11358      ".foo { animation-fill-mode: forwards }",
11359      ".foo{animation-fill-mode:forwards}",
11360    );
11361    minify_test(
11362      ".foo { animation-fill-mode: Backwards,forwards }",
11363      ".foo{animation-fill-mode:backwards,forwards}",
11364    );
11365    minify_test(".foo { animation: none }", ".foo{animation:none}");
11366    minify_test(".foo { animation: \"none\" }", ".foo{animation:\"none\"}");
11367    minify_test(".foo { animation: \"None\" }", ".foo{animation:\"None\"}");
11368    minify_test(".foo { animation: \"none\", none }", ".foo{animation:\"none\",none}");
11369    minify_test(".foo { animation: none, none }", ".foo{animation:none,none}");
11370    minify_test(".foo { animation: \"none\" none }", ".foo{animation:\"none\"}");
11371    minify_test(".foo { animation: none none }", ".foo{animation:none}");
11372
11373    // Test animation-name + animation-fill-mode
11374    minify_test(
11375      ".foo { animation: 2s both \"none\"}",
11376      ".foo{animation:2s both \"none\"}",
11377    );
11378    minify_test(
11379      ".foo { animation: both \"none\" 2s}",
11380      ".foo{animation:2s both \"none\"}",
11381    );
11382    minify_test(".foo { animation: \"none\" 2s none}", ".foo{animation:2s \"none\"}");
11383    minify_test(".foo { animation: none \"none\" 2s}", ".foo{animation:2s \"none\"}");
11384    minify_test(
11385      ".foo { animation: none, \"none\" 2s forwards}",
11386      ".foo{animation:none,2s forwards \"none\"}",
11387    );
11388
11389    minify_test(".foo { animation: \"unset\" }", ".foo{animation:\"unset\"}");
11390    minify_test(".foo { animation: \"string\" .5s }", ".foo{animation:.5s string}");
11391    minify_test(".foo { animation: \"unset\" .5s }", ".foo{animation:.5s \"unset\"}");
11392    minify_test(
11393      ".foo { animation: none, \"unset\" .5s}",
11394      ".foo{animation:none,.5s \"unset\"}",
11395    );
11396    minify_test(
11397      ".foo { animation: \"unset\" 0s 3s infinite, none }",
11398      ".foo{animation:0s 3s infinite \"unset\",none}",
11399    );
11400
11401    minify_test(".foo { animation: \"infinite\" 2s 1 }", ".foo{animation:2s 1 infinite}");
11402    minify_test(".foo { animation: \"paused\" 2s }", ".foo{animation:2s running paused}");
11403    minify_test(
11404      ".foo { animation: \"forwards\" 2s }",
11405      ".foo{animation:2s none forwards}",
11406    );
11407    minify_test(
11408      ".foo { animation: \"reverse\" 2s }",
11409      ".foo{animation:2s normal reverse}",
11410    );
11411    minify_test(
11412      ".foo { animation: \"reverse\" 2s alternate }",
11413      ".foo{animation:2s alternate reverse}",
11414    );
11415
11416    minify_test(
11417      ".foo { animation: 3s ease-in 1s infinite reverse both running slidein }",
11418      ".foo{animation:3s ease-in 1s infinite reverse both slidein}",
11419    );
11420    minify_test(
11421      ".foo { animation: 3s slidein paused ease 1s 1 reverse both }",
11422      ".foo{animation:3s 1s reverse both paused slidein}",
11423    );
11424    minify_test(".foo { animation: 3s ease ease }", ".foo{animation:3s ease ease}");
11425    minify_test(
11426      ".foo { animation: 3s cubic-bezier(0.25, 0.1, 0.25, 1) foo }",
11427      ".foo{animation:3s foo}",
11428    );
11429    minify_test(
11430      ".foo { animation: foo 0s 3s infinite }",
11431      ".foo{animation:0s 3s infinite foo}",
11432    );
11433    minify_test(".foo { animation: foo 3s --test }", ".foo{animation:3s foo --test}");
11434    minify_test(".foo { animation: foo 3s scroll() }", ".foo{animation:3s foo scroll()}");
11435    minify_test(
11436      ".foo { animation: foo 3s scroll(block) }",
11437      ".foo{animation:3s foo scroll()}",
11438    );
11439    minify_test(
11440      ".foo { animation: foo 3s scroll(root inline) }",
11441      ".foo{animation:3s foo scroll(root inline)}",
11442    );
11443    minify_test(
11444      ".foo { animation: foo 3s scroll(inline root) }",
11445      ".foo{animation:3s foo scroll(root inline)}",
11446    );
11447    minify_test(
11448      ".foo { animation: foo 3s scroll(inline nearest) }",
11449      ".foo{animation:3s foo scroll(inline)}",
11450    );
11451    minify_test(
11452      ".foo { animation: foo 3s view(block) }",
11453      ".foo{animation:3s foo view()}",
11454    );
11455    minify_test(
11456      ".foo { animation: foo 3s view(inline) }",
11457      ".foo{animation:3s foo view(inline)}",
11458    );
11459    minify_test(
11460      ".foo { animation: foo 3s view(inline 10px 10px) }",
11461      ".foo{animation:3s foo view(inline 10px)}",
11462    );
11463    minify_test(
11464      ".foo { animation: foo 3s view(inline 10px 12px) }",
11465      ".foo{animation:3s foo view(inline 10px 12px)}",
11466    );
11467    minify_test(
11468      ".foo { animation: foo 3s view(inline auto auto) }",
11469      ".foo{animation:3s foo view(inline)}",
11470    );
11471    minify_test(".foo { animation: foo 3s auto }", ".foo{animation:3s foo}");
11472    minify_test(".foo { animation-composition: add }", ".foo{animation-composition:add}");
11473    test(
11474      r#"
11475      .foo {
11476        animation-name: foo;
11477        animation-duration: 0.09s;
11478        animation-timing-function: ease-in-out;
11479        animation-iteration-count: 2;
11480        animation-direction: alternate;
11481        animation-play-state: running;
11482        animation-delay: 100ms;
11483        animation-fill-mode: forwards;
11484        animation-timeline: auto;
11485      }
11486    "#,
11487      indoc! {r#"
11488      .foo {
11489        animation: 90ms ease-in-out .1s 2 alternate forwards foo;
11490      }
11491    "#},
11492    );
11493    test(
11494      r#"
11495      .foo {
11496        animation-name: foo, bar;
11497        animation-duration: 0.09s, 200ms;
11498        animation-timing-function: ease-in-out, ease;
11499        animation-iteration-count: 2, 1;
11500        animation-direction: alternate, normal;
11501        animation-play-state: running, paused;
11502        animation-delay: 100ms, 0s;
11503        animation-fill-mode: forwards, none;
11504        animation-timeline: auto, auto;
11505      }
11506    "#,
11507      indoc! {r#"
11508      .foo {
11509        animation: 90ms ease-in-out .1s 2 alternate forwards foo, .2s paused bar;
11510      }
11511    "#},
11512    );
11513    test(
11514      r#"
11515      .foo {
11516        animation: bar 200ms;
11517        animation-timing-function: ease-in-out;
11518      }
11519    "#,
11520      indoc! {r#"
11521      .foo {
11522        animation: .2s ease-in-out bar;
11523      }
11524    "#},
11525    );
11526    test(
11527      r#"
11528      .foo {
11529        animation: bar 200ms;
11530        animation-timing-function: var(--ease);
11531      }
11532    "#,
11533      indoc! {r#"
11534      .foo {
11535        animation: .2s bar;
11536        animation-timing-function: var(--ease);
11537      }
11538    "#},
11539    );
11540    test(
11541      r#"
11542      .foo {
11543        animation-name: foo, bar;
11544        animation-duration: 0.09s;
11545        animation-timing-function: ease-in-out;
11546        animation-iteration-count: 2;
11547        animation-direction: alternate;
11548        animation-play-state: running;
11549        animation-delay: 100ms;
11550        animation-fill-mode: forwards;
11551        animation-timeline: auto;
11552      }
11553    "#,
11554      indoc! {r#"
11555      .foo {
11556        animation-name: foo, bar;
11557        animation-duration: 90ms;
11558        animation-timing-function: ease-in-out;
11559        animation-iteration-count: 2;
11560        animation-direction: alternate;
11561        animation-play-state: running;
11562        animation-delay: .1s;
11563        animation-fill-mode: forwards;
11564        animation-timeline: auto;
11565      }
11566    "#},
11567    );
11568    test(
11569      r#"
11570      .foo {
11571        animation-name: foo;
11572        animation-duration: 0.09s;
11573        animation-timing-function: ease-in-out;
11574        animation-iteration-count: 2;
11575        animation-direction: alternate;
11576        animation-play-state: running;
11577        animation-delay: 100ms;
11578        animation-fill-mode: forwards;
11579        animation-timeline: scroll();
11580      }
11581    "#,
11582      indoc! {r#"
11583      .foo {
11584        animation: 90ms ease-in-out .1s 2 alternate forwards foo scroll();
11585      }
11586    "#},
11587    );
11588    test(
11589      r#"
11590      .foo {
11591        animation-name: foo;
11592        animation-duration: 0.09s;
11593        animation-timing-function: ease-in-out;
11594        animation-iteration-count: 2;
11595        animation-direction: alternate;
11596        animation-play-state: running;
11597        animation-delay: 100ms;
11598        animation-fill-mode: forwards;
11599        animation-timeline: scroll(), view();
11600      }
11601    "#,
11602      indoc! {r#"
11603      .foo {
11604        animation-name: foo;
11605        animation-duration: 90ms;
11606        animation-timing-function: ease-in-out;
11607        animation-iteration-count: 2;
11608        animation-direction: alternate;
11609        animation-play-state: running;
11610        animation-delay: .1s;
11611        animation-fill-mode: forwards;
11612        animation-timeline: scroll(), view();
11613      }
11614    "#},
11615    );
11616    test(
11617      r#"
11618      .foo {
11619        -webkit-animation-name: foo;
11620        -webkit-animation-duration: 0.09s;
11621        -webkit-animation-timing-function: ease-in-out;
11622        -webkit-animation-iteration-count: 2;
11623        -webkit-animation-direction: alternate;
11624        -webkit-animation-play-state: running;
11625        -webkit-animation-delay: 100ms;
11626        -webkit-animation-fill-mode: forwards;
11627      }
11628    "#,
11629      indoc! {r#"
11630      .foo {
11631        -webkit-animation: 90ms ease-in-out .1s 2 alternate forwards foo;
11632      }
11633    "#},
11634    );
11635    test(
11636      r#"
11637      .foo {
11638        -moz-animation: bar 200ms;
11639        -moz-animation-timing-function: ease-in-out;
11640      }
11641    "#,
11642      indoc! {r#"
11643      .foo {
11644        -moz-animation: .2s ease-in-out bar;
11645      }
11646    "#},
11647    );
11648    test(
11649      r#"
11650      .foo {
11651        -webkit-animation: bar 200ms;
11652        -webkit-animation-timing-function: ease-in-out;
11653        -moz-animation: bar 200ms;
11654        -moz-animation-timing-function: ease-in-out;
11655      }
11656    "#,
11657      indoc! {r#"
11658      .foo {
11659        -webkit-animation: .2s ease-in-out bar;
11660        -moz-animation: .2s ease-in-out bar;
11661      }
11662    "#},
11663    );
11664
11665    prefix_test(
11666      r#"
11667      .foo {
11668        animation: .2s ease-in-out bar;
11669      }
11670    "#,
11671      indoc! {r#"
11672      .foo {
11673        -webkit-animation: .2s ease-in-out bar;
11674        -moz-animation: .2s ease-in-out bar;
11675        animation: .2s ease-in-out bar;
11676      }
11677    "#},
11678      Browsers {
11679        firefox: Some(6 << 16),
11680        safari: Some(6 << 16),
11681        ..Browsers::default()
11682      },
11683    );
11684
11685    prefix_test(
11686      r#"
11687      .foo {
11688        -webkit-animation: .2s ease-in-out bar;
11689        -moz-animation: .2s ease-in-out bar;
11690        animation: .2s ease-in-out bar;
11691      }
11692    "#,
11693      indoc! {r#"
11694      .foo {
11695        animation: .2s ease-in-out bar;
11696      }
11697    "#},
11698      Browsers {
11699        firefox: Some(20 << 16),
11700        safari: Some(14 << 16),
11701        ..Browsers::default()
11702      },
11703    );
11704    prefix_test(
11705      r#"
11706      .foo {
11707        animation: 200ms var(--ease) bar;
11708      }
11709    "#,
11710      indoc! {r#"
11711      .foo {
11712        -webkit-animation: .2s var(--ease) bar;
11713        -moz-animation: .2s var(--ease) bar;
11714        animation: .2s var(--ease) bar;
11715      }
11716    "#},
11717      Browsers {
11718        firefox: Some(6 << 16),
11719        safari: Some(6 << 16),
11720        ..Browsers::default()
11721      },
11722    );
11723
11724    prefix_test(
11725      r#"
11726      .foo {
11727        animation: .2s ease-in-out bar scroll();
11728      }
11729    "#,
11730      indoc! {r#"
11731      .foo {
11732        animation: .2s ease-in-out bar;
11733        animation-timeline: scroll();
11734      }
11735    "#},
11736      Browsers {
11737        safari: Some(16 << 16),
11738        ..Browsers::default()
11739      },
11740    );
11741    prefix_test(
11742      r#"
11743      .foo {
11744        animation: .2s ease-in-out bar scroll();
11745      }
11746    "#,
11747      indoc! {r#"
11748      .foo {
11749        animation: .2s ease-in-out bar scroll();
11750      }
11751    "#},
11752      Browsers {
11753        chrome: Some(120 << 16),
11754        ..Browsers::default()
11755      },
11756    );
11757    prefix_test(
11758      r#"
11759      .foo {
11760        animation: .2s ease-in-out bar scroll();
11761      }
11762    "#,
11763      indoc! {r#"
11764      .foo {
11765        -webkit-animation: .2s ease-in-out bar;
11766        animation: .2s ease-in-out bar;
11767        animation-timeline: scroll();
11768      }
11769    "#},
11770      Browsers {
11771        safari: Some(6 << 16),
11772        ..Browsers::default()
11773      },
11774    );
11775
11776    minify_test(
11777      ".foo { animation-range-start: entry 10% }",
11778      ".foo{animation-range-start:entry 10%}",
11779    );
11780    minify_test(
11781      ".foo { animation-range-start: entry 0% }",
11782      ".foo{animation-range-start:entry}",
11783    );
11784    minify_test(
11785      ".foo { animation-range-start: entry }",
11786      ".foo{animation-range-start:entry}",
11787    );
11788    minify_test(".foo { animation-range-start: 50% }", ".foo{animation-range-start:50%}");
11789    minify_test(
11790      ".foo { animation-range-end: exit 10% }",
11791      ".foo{animation-range-end:exit 10%}",
11792    );
11793    minify_test(
11794      ".foo { animation-range-end: exit 100% }",
11795      ".foo{animation-range-end:exit}",
11796    );
11797    minify_test(".foo { animation-range-end: exit }", ".foo{animation-range-end:exit}");
11798    minify_test(".foo { animation-range-end: 50% }", ".foo{animation-range-end:50%}");
11799    minify_test(
11800      ".foo { animation-range: entry 10% exit 90% }",
11801      ".foo{animation-range:entry 10% exit 90%}",
11802    );
11803    minify_test(
11804      ".foo { animation-range: entry 0% exit 100% }",
11805      ".foo{animation-range:entry exit}",
11806    );
11807    minify_test(".foo { animation-range: entry }", ".foo{animation-range:entry}");
11808    minify_test(
11809      ".foo { animation-range: entry 0% entry 100% }",
11810      ".foo{animation-range:entry}",
11811    );
11812    minify_test(".foo { animation-range: 50% normal }", ".foo{animation-range:50%}");
11813    minify_test(
11814      ".foo { animation-range: normal normal }",
11815      ".foo{animation-range:normal}",
11816    );
11817    test(
11818      r#"
11819      .foo {
11820        animation-range-start: entry 10%;
11821        animation-range-end: exit 90%;
11822      }
11823      "#,
11824      indoc! {r#"
11825      .foo {
11826        animation-range: entry 10% exit 90%;
11827      }
11828      "#},
11829    );
11830    test(
11831      r#"
11832      .foo {
11833        animation-range-start: entry 0%;
11834        animation-range-end: entry 100%;
11835      }
11836      "#,
11837      indoc! {r#"
11838      .foo {
11839        animation-range: entry;
11840      }
11841      "#},
11842    );
11843    test(
11844      r#"
11845      .foo {
11846        animation-range-start: entry 0%;
11847        animation-range-end: exit 100%;
11848      }
11849      "#,
11850      indoc! {r#"
11851      .foo {
11852        animation-range: entry exit;
11853      }
11854      "#},
11855    );
11856    test(
11857      r#"
11858      .foo {
11859        animation-range-start: 10%;
11860        animation-range-end: normal;
11861      }
11862      "#,
11863      indoc! {r#"
11864      .foo {
11865        animation-range: 10%;
11866      }
11867      "#},
11868    );
11869    test(
11870      r#"
11871      .foo {
11872        animation-range-start: 10%;
11873        animation-range-end: 90%;
11874      }
11875      "#,
11876      indoc! {r#"
11877      .foo {
11878        animation-range: 10% 90%;
11879      }
11880      "#},
11881    );
11882    test(
11883      r#"
11884      .foo {
11885        animation-range-start: entry 10%;
11886        animation-range-end: exit 100%;
11887      }
11888      "#,
11889      indoc! {r#"
11890      .foo {
11891        animation-range: entry 10% exit;
11892      }
11893      "#},
11894    );
11895    test(
11896      r#"
11897      .foo {
11898        animation-range-start: 10%;
11899        animation-range-end: exit 90%;
11900      }
11901      "#,
11902      indoc! {r#"
11903      .foo {
11904        animation-range: 10% exit 90%;
11905      }
11906      "#},
11907    );
11908    test(
11909      r#"
11910      .foo {
11911        animation-range-start: entry 10%;
11912        animation-range-end: 90%;
11913      }
11914      "#,
11915      indoc! {r#"
11916      .foo {
11917        animation-range: entry 10% 90%;
11918      }
11919      "#},
11920    );
11921    test(
11922      r#"
11923      .foo {
11924        animation-range: entry;
11925        animation-range-end: 90%;
11926      }
11927      "#,
11928      indoc! {r#"
11929      .foo {
11930        animation-range: entry 90%;
11931      }
11932      "#},
11933    );
11934    test(
11935      r#"
11936      .foo {
11937        animation-range: entry;
11938        animation-range-end: var(--end);
11939      }
11940      "#,
11941      indoc! {r#"
11942      .foo {
11943        animation-range: entry;
11944        animation-range-end: var(--end);
11945      }
11946      "#},
11947    );
11948    test(
11949      r#"
11950      .foo {
11951        animation-range-start: entry 10%, entry 50%;
11952        animation-range-end: exit 90%;
11953      }
11954      "#,
11955      indoc! {r#"
11956      .foo {
11957        animation-range-start: entry 10%, entry 50%;
11958        animation-range-end: exit 90%;
11959      }
11960      "#},
11961    );
11962    test(
11963      r#"
11964      .foo {
11965        animation-range-start: entry 10%, entry 50%;
11966        animation-range-end: exit 90%, exit 100%;
11967      }
11968      "#,
11969      indoc! {r#"
11970      .foo {
11971        animation-range: entry 10% exit 90%, entry 50% exit;
11972      }
11973      "#},
11974    );
11975    test(
11976      r#"
11977      .foo {
11978        animation-range: entry;
11979        animation-range-end: 90%;
11980        animation: spin 100ms;
11981      }
11982      "#,
11983      indoc! {r#"
11984      .foo {
11985        animation: .1s spin;
11986      }
11987      "#},
11988    );
11989    test(
11990      r#"
11991      .foo {
11992        animation: spin 100ms;
11993        animation-range: entry;
11994        animation-range-end: 90%;
11995      }
11996      "#,
11997      indoc! {r#"
11998      .foo {
11999        animation: .1s spin;
12000        animation-range: entry 90%;
12001      }
12002      "#},
12003    );
12004    test(
12005      r#"
12006      .foo {
12007        animation-range: entry;
12008        animation-range-end: 90%;
12009        animation: var(--animation) 100ms;
12010      }
12011      "#,
12012      indoc! {r#"
12013      .foo {
12014        animation: var(--animation) .1s;
12015      }
12016      "#},
12017    );
12018  }
12019
12020  #[test]
12021  fn test_transform() {
12022    minify_test(
12023      ".foo { transform: translate(2px, 3px)",
12024      ".foo{transform:translate(2px,3px)}",
12025    );
12026    minify_test(
12027      ".foo { transform: translate(2px, 0px)",
12028      ".foo{transform:translate(2px)}",
12029    );
12030    minify_test(
12031      ".foo { transform: translate(0px, 2px)",
12032      ".foo{transform:translateY(2px)}",
12033    );
12034    minify_test(".foo { transform: translateX(2px)", ".foo{transform:translate(2px)}");
12035    minify_test(".foo { transform: translateY(2px)", ".foo{transform:translateY(2px)}");
12036    minify_test(".foo { transform: translateZ(2px)", ".foo{transform:translateZ(2px)}");
12037    minify_test(
12038      ".foo { transform: translate3d(2px, 3px, 4px)",
12039      ".foo{transform:translate3d(2px,3px,4px)}",
12040    );
12041    minify_test(
12042      ".foo { transform: translate3d(10%, 20%, 4px)",
12043      ".foo{transform:translate3d(10%,20%,4px)}",
12044    );
12045    minify_test(
12046      ".foo { transform: translate3d(2px, 0px, 0px)",
12047      ".foo{transform:translate(2px)}",
12048    );
12049    minify_test(
12050      ".foo { transform: translate3d(0px, 2px, 0px)",
12051      ".foo{transform:translateY(2px)}",
12052    );
12053    minify_test(
12054      ".foo { transform: translate3d(0px, 0px, 2px)",
12055      ".foo{transform:translateZ(2px)}",
12056    );
12057    minify_test(
12058      ".foo { transform: translate3d(2px, 3px, 0px)",
12059      ".foo{transform:translate(2px,3px)}",
12060    );
12061    minify_test(".foo { transform: scale(2, 3)", ".foo{transform:scale(2,3)}");
12062    minify_test(".foo { transform: scale(10%, 20%)", ".foo{transform:scale(.1,.2)}");
12063    minify_test(".foo { transform: scale(2, 2)", ".foo{transform:scale(2)}");
12064    minify_test(".foo { transform: scale(2, 1)", ".foo{transform:scaleX(2)}");
12065    minify_test(".foo { transform: scale(1, 2)", ".foo{transform:scaleY(2)}");
12066    minify_test(".foo { transform: scaleX(2)", ".foo{transform:scaleX(2)}");
12067    minify_test(".foo { transform: scaleY(2)", ".foo{transform:scaleY(2)}");
12068    minify_test(".foo { transform: scaleZ(2)", ".foo{transform:scaleZ(2)}");
12069    minify_test(".foo { transform: scale3d(2, 3, 4)", ".foo{transform:scale3d(2,3,4)}");
12070    minify_test(".foo { transform: scale3d(2, 1, 1)", ".foo{transform:scaleX(2)}");
12071    minify_test(".foo { transform: scale3d(1, 2, 1)", ".foo{transform:scaleY(2)}");
12072    minify_test(".foo { transform: scale3d(1, 1, 2)", ".foo{transform:scaleZ(2)}");
12073    minify_test(".foo { transform: scale3d(2, 2, 1)", ".foo{transform:scale(2)}");
12074    minify_test(".foo { transform: rotate(20deg)", ".foo{transform:rotate(20deg)}");
12075    minify_test(".foo { transform: rotateX(20deg)", ".foo{transform:rotateX(20deg)}");
12076    minify_test(".foo { transform: rotateY(20deg)", ".foo{transform:rotateY(20deg)}");
12077    minify_test(".foo { transform: rotateZ(20deg)", ".foo{transform:rotate(20deg)}");
12078    minify_test(".foo { transform: rotate(360deg)", ".foo{transform:rotate(360deg)}");
12079    minify_test(
12080      ".foo { transform: rotate3d(2, 3, 4, 20deg)",
12081      ".foo{transform:rotate3d(2,3,4,20deg)}",
12082    );
12083    minify_test(
12084      ".foo { transform: rotate3d(1, 0, 0, 20deg)",
12085      ".foo{transform:rotateX(20deg)}",
12086    );
12087    minify_test(
12088      ".foo { transform: rotate3d(0, 1, 0, 20deg)",
12089      ".foo{transform:rotateY(20deg)}",
12090    );
12091    minify_test(
12092      ".foo { transform: rotate3d(0, 0, 1, 20deg)",
12093      ".foo{transform:rotate(20deg)}",
12094    );
12095    minify_test(".foo { transform: rotate(405deg)}", ".foo{transform:rotate(405deg)}");
12096    minify_test(".foo { transform: rotateX(405deg)}", ".foo{transform:rotateX(405deg)}");
12097    minify_test(".foo { transform: rotateY(405deg)}", ".foo{transform:rotateY(405deg)}");
12098    minify_test(".foo { transform: rotate(-200deg)}", ".foo{transform:rotate(-200deg)}");
12099    minify_test(".foo { transform: rotate(0)", ".foo{transform:rotate(0)}");
12100    minify_test(".foo { transform: rotate(0deg)", ".foo{transform:rotate(0)}");
12101    minify_test(
12102      ".foo { transform: rotateX(-200deg)}",
12103      ".foo{transform:rotateX(-200deg)}",
12104    );
12105    minify_test(
12106      ".foo { transform: rotateY(-200deg)}",
12107      ".foo{transform:rotateY(-200deg)}",
12108    );
12109    minify_test(
12110      ".foo { transform: rotate3d(1, 1, 0, -200deg)",
12111      ".foo{transform:rotate3d(1,1,0,-200deg)}",
12112    );
12113    minify_test(".foo { transform: skew(20deg)", ".foo{transform:skew(20deg)}");
12114    minify_test(".foo { transform: skew(20deg, 0deg)", ".foo{transform:skew(20deg)}");
12115    minify_test(".foo { transform: skew(0deg, 20deg)", ".foo{transform:skewY(20deg)}");
12116    minify_test(".foo { transform: skewX(20deg)", ".foo{transform:skew(20deg)}");
12117    minify_test(".foo { transform: skewY(20deg)", ".foo{transform:skewY(20deg)}");
12118    minify_test(
12119      ".foo { transform: perspective(10px)",
12120      ".foo{transform:perspective(10px)}",
12121    );
12122    minify_test(
12123      ".foo { transform: matrix(1, 2, -1, 1, 80, 80)",
12124      ".foo{transform:matrix(1,2,-1,1,80,80)}",
12125    );
12126    minify_test(
12127      ".foo { transform: matrix3d(1, 0, 0, 0, 0, 1, 6, 0, 0, 0, 1, 0, 50, 100, 0, 1.1)",
12128      ".foo{transform:matrix3d(1,0,0,0,0,1,6,0,0,0,1,0,50,100,0,1.1)}",
12129    );
12130    // TODO: Re-enable with a better solution
12131    //       See: https://github.com/parcel-bundler/lightningcss/issues/288
12132    // minify_test(
12133    //   ".foo{transform:translate(100px,200px) rotate(45deg) skew(10deg) scale(2)}",
12134    //   ".foo{transform:matrix(1.41421,1.41421,-1.16485,1.66358,100,200)}",
12135    // );
12136    // minify_test(
12137    //   ".foo{transform:translate(200px,300px) translate(100px,200px) scale(2)}",
12138    //   ".foo{transform:matrix(2,0,0,2,300,500)}",
12139    // );
12140    minify_test(
12141      ".foo{transform:translate(100px,200px) rotate(45deg)}",
12142      ".foo{transform:translate(100px,200px)rotate(45deg)}",
12143    );
12144    minify_test(
12145      ".foo{transform:rotate3d(1, 1, 1, 45deg) translate3d(100px, 100px, 10px)}",
12146      ".foo{transform:rotate3d(1,1,1,45deg)translate3d(100px,100px,10px)}",
12147    );
12148    // TODO: Re-enable with a better solution
12149    //       See: https://github.com/parcel-bundler/lightningcss/issues/288
12150    // minify_test(
12151    //   ".foo{transform:translate3d(100px, 100px, 10px) skew(10deg) scale3d(2, 3, 4)}",
12152    //   ".foo{transform:matrix3d(2,0,0,0,.528981,3,0,0,0,0,4,0,100,100,10,1)}",
12153    // );
12154    // minify_test(
12155    //   ".foo{transform:matrix3d(0.804737854124365, 0.5058793634016805, -0.31061721752604554, 0, -0.31061721752604554, 0.804737854124365, 0.5058793634016805, 0, 0.5058793634016805, -0.31061721752604554, 0.804737854124365, 0, 100, 100, 10, 1)}",
12156    //   ".foo{transform:translate3d(100px,100px,10px)rotate3d(1,1,1,45deg)}"
12157    // );
12158    // minify_test(
12159    //   ".foo{transform:matrix3d(1, 0, 0, 0, 0, 0.7071067811865476, 0.7071067811865475, 0, 0, -0.7071067811865475, 0.7071067811865476, 0, 100, 100, 10, 1)}",
12160    //   ".foo{transform:translate3d(100px,100px,10px)rotateX(45deg)}"
12161    // );
12162    // minify_test(
12163    //   ".foo{transform:translate3d(100px, 200px, 10px) translate(100px, 100px)}",
12164    //   ".foo{transform:translate3d(200px,300px,10px)}",
12165    // );
12166    // minify_test(
12167    //   ".foo{transform:rotate(45deg) rotate(45deg)}",
12168    //   ".foo{transform:rotate(90deg)}",
12169    // );
12170    // minify_test(
12171    //   ".foo{transform:matrix(0.7071067811865476, 0.7071067811865475, -0.7071067811865475, 0.7071067811865476, 100, 100)}",
12172    //   ".foo{transform:translate(100px,100px)rotate(45deg)}"
12173    // );
12174    // minify_test(
12175    //   ".foo{transform:translateX(2in) translateX(50px)}",
12176    //   ".foo{transform:translate(242px)}",
12177    // );
12178    minify_test(
12179      ".foo{transform:translateX(calc(2in + 50px))}",
12180      ".foo{transform:translate(242px)}",
12181    );
12182    minify_test(".foo{transform:translateX(50%)}", ".foo{transform:translate(50%)}");
12183    minify_test(
12184      ".foo{transform:translateX(calc(50% - 100px + 20px))}",
12185      ".foo{transform:translate(calc(50% - 80px))}",
12186    );
12187    minify_test(
12188      ".foo{transform:rotate(calc(10deg + 20deg))}",
12189      ".foo{transform:rotate(30deg)}",
12190    );
12191    minify_test(
12192      ".foo{transform:rotate(calc(10deg + 0.349066rad))}",
12193      ".foo{transform:rotate(30deg)}",
12194    );
12195    minify_test(
12196      ".foo{transform:rotate(calc(10deg + 1.5turn))}",
12197      ".foo{transform:rotate(550deg)}",
12198    );
12199    minify_test(
12200      ".foo{transform:rotate(calc(10deg * 2))}",
12201      ".foo{transform:rotate(20deg)}",
12202    );
12203    minify_test(
12204      ".foo{transform:rotate(calc(-10deg * 2))}",
12205      ".foo{transform:rotate(-20deg)}",
12206    );
12207    minify_test(
12208      ".foo{transform:rotate(calc(10deg + var(--test)))}",
12209      ".foo{transform:rotate(calc(10deg + var(--test)))}",
12210    );
12211    minify_test(".foo { transform: scale(calc(10% + 20%))", ".foo{transform:scale(.3)}");
12212    minify_test(".foo { transform: scale(calc(.1 + .2))", ".foo{transform:scale(.3)}");
12213
12214    minify_test(
12215      ".foo { -webkit-transform: scale(calc(10% + 20%))",
12216      ".foo{-webkit-transform:scale(.3)}",
12217    );
12218
12219    minify_test(".foo { translate: 1px 2px 3px }", ".foo{translate:1px 2px 3px}");
12220    minify_test(".foo { translate: 1px 0px 0px }", ".foo{translate:1px}");
12221    minify_test(".foo { translate: 1px 2px 0px }", ".foo{translate:1px 2px}");
12222    minify_test(".foo { translate: 1px 0px 2px }", ".foo{translate:1px 0 2px}");
12223    minify_test(".foo { translate: none }", ".foo{translate:none}");
12224    minify_test(".foo { rotate: 10deg }", ".foo{rotate:10deg}");
12225    minify_test(".foo { rotate: z 10deg }", ".foo{rotate:10deg}");
12226    minify_test(".foo { rotate: 0 0 1 10deg }", ".foo{rotate:10deg}");
12227    minify_test(".foo { rotate: x 10deg }", ".foo{rotate:x 10deg}");
12228    minify_test(".foo { rotate: 1 0 0 10deg }", ".foo{rotate:x 10deg}");
12229    minify_test(".foo { rotate: y 10deg }", ".foo{rotate:y 10deg}");
12230    minify_test(".foo { rotate: 0 1 0 10deg }", ".foo{rotate:y 10deg}");
12231    minify_test(".foo { rotate: 1 1 1 10deg }", ".foo{rotate:1 1 1 10deg}");
12232    minify_test(".foo { rotate: 0 0 1 0deg }", ".foo{rotate:none}");
12233    minify_test(".foo { rotate: none }", ".foo{rotate:none}");
12234    minify_test(".foo { scale: 1 }", ".foo{scale:1}");
12235    minify_test(".foo { scale: 1 1 }", ".foo{scale:1}");
12236    minify_test(".foo { scale: 1 1 1 }", ".foo{scale:1}");
12237    minify_test(".foo { scale: none }", ".foo{scale:none}");
12238    minify_test(".foo { scale: 1 0 }", ".foo{scale:1 0}");
12239    minify_test(".foo { scale: 1 0 1 }", ".foo{scale:1 0}");
12240    minify_test(".foo { scale: 1 0 0 }", ".foo{scale:1 0 0}");
12241
12242    // TODO: Re-enable with a better solution
12243    //       See: https://github.com/parcel-bundler/lightningcss/issues/288
12244    // minify_test(".foo { transform: scale(3); scale: 0.5 }", ".foo{transform:scale(1.5)}");
12245    minify_test(".foo { scale: 0.5; transform: scale(3); }", ".foo{transform:scale(3)}");
12246
12247    prefix_test(
12248      r#"
12249      .foo {
12250        transform: scale(0.5);
12251      }
12252    "#,
12253      indoc! {r#"
12254      .foo {
12255        -webkit-transform: scale(.5);
12256        -moz-transform: scale(.5);
12257        transform: scale(.5);
12258      }
12259    "#},
12260      Browsers {
12261        firefox: Some(6 << 16),
12262        safari: Some(6 << 16),
12263        ..Browsers::default()
12264      },
12265    );
12266
12267    prefix_test(
12268      r#"
12269      .foo {
12270        transform: var(--transform);
12271      }
12272    "#,
12273      indoc! {r#"
12274      .foo {
12275        -webkit-transform: var(--transform);
12276        -moz-transform: var(--transform);
12277        transform: var(--transform);
12278      }
12279    "#},
12280      Browsers {
12281        firefox: Some(6 << 16),
12282        safari: Some(6 << 16),
12283        ..Browsers::default()
12284      },
12285    );
12286
12287    test(
12288      r#"
12289      .foo {
12290        transform: translateX(-50%);
12291        transform: translateX(20px);
12292      }
12293      "#,
12294      indoc! {r#"
12295      .foo {
12296        transform: translateX(20px);
12297      }
12298      "#},
12299    );
12300  }
12301
12302  #[test]
12303  pub fn test_gradients() {
12304    minify_test(
12305      ".foo { background: linear-gradient(yellow, blue) }",
12306      ".foo{background:linear-gradient(#ff0,#00f)}",
12307    );
12308    minify_test(
12309      ".foo { background: linear-gradient(to bottom, yellow, blue); }",
12310      ".foo{background:linear-gradient(#ff0,#00f)}",
12311    );
12312    minify_test(
12313      ".foo { background: linear-gradient(180deg, yellow, blue); }",
12314      ".foo{background:linear-gradient(#ff0,#00f)}",
12315    );
12316    minify_test(
12317      ".foo { background: linear-gradient(0.5turn, yellow, blue); }",
12318      ".foo{background:linear-gradient(#ff0,#00f)}",
12319    );
12320    minify_test(
12321      ".foo { background: linear-gradient(yellow 10%, blue 20%) }",
12322      ".foo{background:linear-gradient(#ff0 10%,#00f 20%)}",
12323    );
12324    minify_test(
12325      ".foo { background: linear-gradient(to top, blue, yellow); }",
12326      ".foo{background:linear-gradient(#ff0,#00f)}",
12327    );
12328    minify_test(
12329      ".foo { background: linear-gradient(to top, blue 10%, yellow 20%); }",
12330      ".foo{background:linear-gradient(#ff0 80%,#00f 90%)}",
12331    );
12332    minify_test(
12333      ".foo { background: linear-gradient(to top, blue 10px, yellow 20px); }",
12334      ".foo{background:linear-gradient(0deg,#00f 10px,#ff0 20px)}",
12335    );
12336    minify_test(
12337      ".foo { background: linear-gradient(135deg, yellow, blue); }",
12338      ".foo{background:linear-gradient(135deg,#ff0,#00f)}",
12339    );
12340    minify_test(
12341      ".foo { background: linear-gradient(yellow, blue 20%, #0f0); }",
12342      ".foo{background:linear-gradient(#ff0,#00f 20%,#0f0)}",
12343    );
12344    minify_test(
12345      ".foo { background: linear-gradient(to top right, red, white, blue) }",
12346      ".foo{background:linear-gradient(to top right,red,#fff,#00f)}",
12347    );
12348    minify_test(
12349      ".foo { background: linear-gradient(yellow, blue calc(10% * 2), #0f0); }",
12350      ".foo{background:linear-gradient(#ff0,#00f 20%,#0f0)}",
12351    );
12352    minify_test(
12353      ".foo { background: linear-gradient(yellow, 20%, blue); }",
12354      ".foo{background:linear-gradient(#ff0,20%,#00f)}",
12355    );
12356    minify_test(
12357      ".foo { background: linear-gradient(yellow, 50%, blue); }",
12358      ".foo{background:linear-gradient(#ff0,#00f)}",
12359    );
12360    minify_test(
12361      ".foo { background: linear-gradient(yellow, 20px, blue); }",
12362      ".foo{background:linear-gradient(#ff0,20px,#00f)}",
12363    );
12364    minify_test(
12365      ".foo { background: linear-gradient(yellow, 50px, blue); }",
12366      ".foo{background:linear-gradient(#ff0,50px,#00f)}",
12367    );
12368    minify_test(
12369      ".foo { background: linear-gradient(yellow, 50px, blue); }",
12370      ".foo{background:linear-gradient(#ff0,50px,#00f)}",
12371    );
12372    minify_test(
12373      ".foo { background: linear-gradient(yellow, red 30% 40%, blue); }",
12374      ".foo{background:linear-gradient(#ff0,red 30% 40%,#00f)}",
12375    );
12376    minify_test(
12377      ".foo { background: linear-gradient(yellow, red 30%, red 40%, blue); }",
12378      ".foo{background:linear-gradient(#ff0,red 30% 40%,#00f)}",
12379    );
12380    minify_test(
12381      ".foo { background: linear-gradient(0, yellow, blue); }",
12382      ".foo{background:linear-gradient(#00f,#ff0)}",
12383    );
12384    minify_test(
12385      ".foo { background: -webkit-linear-gradient(yellow, blue) }",
12386      ".foo{background:-webkit-linear-gradient(#ff0,#00f)}",
12387    );
12388    minify_test(
12389      ".foo { background: -webkit-linear-gradient(bottom, yellow, blue); }",
12390      ".foo{background:-webkit-linear-gradient(#ff0,#00f)}",
12391    );
12392    minify_test(
12393      ".foo { background: -webkit-linear-gradient(top right, red, white, blue) }",
12394      ".foo{background:-webkit-linear-gradient(top right,red,#fff,#00f)}",
12395    );
12396    minify_test(
12397      ".foo { background: -moz-linear-gradient(yellow, blue) }",
12398      ".foo{background:-moz-linear-gradient(#ff0,#00f)}",
12399    );
12400    minify_test(
12401      ".foo { background: -moz-linear-gradient(bottom, yellow, blue); }",
12402      ".foo{background:-moz-linear-gradient(#ff0,#00f)}",
12403    );
12404    minify_test(
12405      ".foo { background: -moz-linear-gradient(top right, red, white, blue) }",
12406      ".foo{background:-moz-linear-gradient(top right,red,#fff,#00f)}",
12407    );
12408    minify_test(
12409      ".foo { background: -o-linear-gradient(yellow, blue) }",
12410      ".foo{background:-o-linear-gradient(#ff0,#00f)}",
12411    );
12412    minify_test(
12413      ".foo { background: -o-linear-gradient(bottom, yellow, blue); }",
12414      ".foo{background:-o-linear-gradient(#ff0,#00f)}",
12415    );
12416    minify_test(
12417      ".foo { background: -o-linear-gradient(top right, red, white, blue) }",
12418      ".foo{background:-o-linear-gradient(top right,red,#fff,#00f)}",
12419    );
12420    minify_test(
12421      ".foo { background: -webkit-gradient(linear, left top, left bottom, from(blue), to(yellow)) }",
12422      ".foo{background:-webkit-gradient(linear,0 0,0 100%,from(#00f),to(#ff0))}",
12423    );
12424    minify_test(
12425      ".foo { background: -webkit-gradient(linear, left top, left bottom, from(blue), color-stop(50%, red), to(yellow)) }",
12426      ".foo{background:-webkit-gradient(linear,0 0,0 100%,from(#00f),color-stop(.5,red),to(#ff0))}"
12427    );
12428    minify_test(
12429      ".foo { background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, blue), color-stop(50%, red), color-stop(100%, yellow)) }",
12430      ".foo{background:-webkit-gradient(linear,0 0,0 100%,from(#00f),color-stop(.5,red),to(#ff0))}"
12431    );
12432    minify_test(
12433      ".foo { background: repeating-linear-gradient(yellow 10px, blue 50px) }",
12434      ".foo{background:repeating-linear-gradient(#ff0 10px,#00f 50px)}",
12435    );
12436    minify_test(
12437      ".foo { background: -webkit-repeating-linear-gradient(yellow 10px, blue 50px) }",
12438      ".foo{background:-webkit-repeating-linear-gradient(#ff0 10px,#00f 50px)}",
12439    );
12440    minify_test(
12441      ".foo { background: -moz-repeating-linear-gradient(yellow 10px, blue 50px) }",
12442      ".foo{background:-moz-repeating-linear-gradient(#ff0 10px,#00f 50px)}",
12443    );
12444    minify_test(
12445      ".foo { background: -o-repeating-linear-gradient(yellow 10px, blue 50px) }",
12446      ".foo{background:-o-repeating-linear-gradient(#ff0 10px,#00f 50px)}",
12447    );
12448    minify_test(
12449      ".foo { background: radial-gradient(yellow, blue) }",
12450      ".foo{background:radial-gradient(#ff0,#00f)}",
12451    );
12452    minify_test(
12453      ".foo { background: radial-gradient(at top left, yellow, blue) }",
12454      ".foo{background:radial-gradient(at 0 0,#ff0,#00f)}",
12455    );
12456    minify_test(
12457      ".foo { background: radial-gradient(5em circle at top left, yellow, blue) }",
12458      ".foo{background:radial-gradient(5em at 0 0,#ff0,#00f)}",
12459    );
12460    minify_test(
12461      ".foo { background: radial-gradient(circle at 100%, #333, #333 50%, #eee 75%, #333 75%) }",
12462      ".foo{background:radial-gradient(circle at 100%,#333,#333 50%,#eee 75%,#333 75%)}",
12463    );
12464    minify_test(
12465      ".foo { background: radial-gradient(farthest-corner circle at 100% 50%, #333, #333 50%, #eee 75%, #333 75%) }",
12466      ".foo{background:radial-gradient(circle at 100%,#333,#333 50%,#eee 75%,#333 75%)}"
12467    );
12468    minify_test(
12469      ".foo { background: radial-gradient(farthest-corner circle at 50% 50%, #333, #333 50%, #eee 75%, #333 75%) }",
12470      ".foo{background:radial-gradient(circle,#333,#333 50%,#eee 75%,#333 75%)}"
12471    );
12472    minify_test(
12473      ".foo { background: radial-gradient(ellipse at top, #e66465, transparent) }",
12474      ".foo{background:radial-gradient(at top,#e66465,#0000)}",
12475    );
12476    minify_test(
12477      ".foo { background: radial-gradient(20px, yellow, blue) }",
12478      ".foo{background:radial-gradient(20px,#ff0,#00f)}",
12479    );
12480    minify_test(
12481      ".foo { background: radial-gradient(circle 20px, yellow, blue) }",
12482      ".foo{background:radial-gradient(20px,#ff0,#00f)}",
12483    );
12484    minify_test(
12485      ".foo { background: radial-gradient(20px 40px, yellow, blue) }",
12486      ".foo{background:radial-gradient(20px 40px,#ff0,#00f)}",
12487    );
12488    minify_test(
12489      ".foo { background: radial-gradient(ellipse 20px 40px, yellow, blue) }",
12490      ".foo{background:radial-gradient(20px 40px,#ff0,#00f)}",
12491    );
12492    minify_test(
12493      ".foo { background: radial-gradient(ellipse calc(20px + 10px) 40px, yellow, blue) }",
12494      ".foo{background:radial-gradient(30px 40px,#ff0,#00f)}",
12495    );
12496    minify_test(
12497      ".foo { background: radial-gradient(circle farthest-side, yellow, blue) }",
12498      ".foo{background:radial-gradient(circle farthest-side,#ff0,#00f)}",
12499    );
12500    minify_test(
12501      ".foo { background: radial-gradient(farthest-side circle, yellow, blue) }",
12502      ".foo{background:radial-gradient(circle farthest-side,#ff0,#00f)}",
12503    );
12504    minify_test(
12505      ".foo { background: radial-gradient(ellipse farthest-side, yellow, blue) }",
12506      ".foo{background:radial-gradient(farthest-side,#ff0,#00f)}",
12507    );
12508    minify_test(
12509      ".foo { background: radial-gradient(farthest-side ellipse, yellow, blue) }",
12510      ".foo{background:radial-gradient(farthest-side,#ff0,#00f)}",
12511    );
12512    minify_test(
12513      ".foo { background: -webkit-radial-gradient(yellow, blue) }",
12514      ".foo{background:-webkit-radial-gradient(#ff0,#00f)}",
12515    );
12516    minify_test(
12517      ".foo { background: -moz-radial-gradient(yellow, blue) }",
12518      ".foo{background:-moz-radial-gradient(#ff0,#00f)}",
12519    );
12520    minify_test(
12521      ".foo { background: -o-radial-gradient(yellow, blue) }",
12522      ".foo{background:-o-radial-gradient(#ff0,#00f)}",
12523    );
12524    minify_test(
12525      ".foo { background: repeating-radial-gradient(circle 20px, yellow, blue) }",
12526      ".foo{background:repeating-radial-gradient(20px,#ff0,#00f)}",
12527    );
12528    minify_test(
12529      ".foo { background: -webkit-repeating-radial-gradient(circle 20px, yellow, blue) }",
12530      ".foo{background:-webkit-repeating-radial-gradient(20px,#ff0,#00f)}",
12531    );
12532    minify_test(
12533      ".foo { background: -moz-repeating-radial-gradient(circle 20px, yellow, blue) }",
12534      ".foo{background:-moz-repeating-radial-gradient(20px,#ff0,#00f)}",
12535    );
12536    minify_test(
12537      ".foo { background: -o-repeating-radial-gradient(circle 20px, yellow, blue) }",
12538      ".foo{background:-o-repeating-radial-gradient(20px,#ff0,#00f)}",
12539    );
12540    minify_test(
12541      ".foo { background: -webkit-gradient(radial, center center, 0, center center, 100, from(blue), to(yellow)) }",
12542      ".foo{background:-webkit-gradient(radial,50% 50%,0,50% 50%,100,from(#00f),to(#ff0))}"
12543    );
12544    minify_test(
12545      ".foo { background: conic-gradient(#f06, gold) }",
12546      ".foo{background:conic-gradient(#f06,gold)}",
12547    );
12548    minify_test(
12549      ".foo { background: conic-gradient(at 50% 50%, #f06, gold) }",
12550      ".foo{background:conic-gradient(#f06,gold)}",
12551    );
12552    minify_test(
12553      ".foo { background: conic-gradient(from 0deg, #f06, gold) }",
12554      ".foo{background:conic-gradient(#f06,gold)}",
12555    );
12556    minify_test(
12557      ".foo { background: conic-gradient(from 0, #f06, gold) }",
12558      ".foo{background:conic-gradient(#f06,gold)}",
12559    );
12560    minify_test(
12561      ".foo { background: conic-gradient(from 0deg at center, #f06, gold) }",
12562      ".foo{background:conic-gradient(#f06,gold)}",
12563    );
12564    minify_test(
12565      ".foo { background: conic-gradient(white -50%, black 150%) }",
12566      ".foo{background:conic-gradient(#fff -50%,#000 150%)}",
12567    );
12568    minify_test(
12569      ".foo { background: conic-gradient(white -180deg, black 540deg) }",
12570      ".foo{background:conic-gradient(#fff -180deg,#000 540deg)}",
12571    );
12572    minify_test(
12573      ".foo { background: conic-gradient(from 45deg, white, black, white) }",
12574      ".foo{background:conic-gradient(from 45deg,#fff,#000,#fff)}",
12575    );
12576    minify_test(
12577      ".foo { background: repeating-conic-gradient(from 45deg, white, black, white) }",
12578      ".foo{background:repeating-conic-gradient(from 45deg,#fff,#000,#fff)}",
12579    );
12580    minify_test(
12581      ".foo { background: repeating-conic-gradient(black 0deg 25%, white 0deg 50%) }",
12582      ".foo{background:repeating-conic-gradient(#000 0deg 25%,#fff 0deg 50%)}",
12583    );
12584
12585    test(
12586      r#"
12587        .foo {
12588          background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue));
12589          background: -webkit-linear-gradient(red, blue);
12590          background: -moz-linear-gradient(red, blue);
12591          background: -o-linear-gradient(red, blue);
12592          background: linear-gradient(red, blue);
12593        }
12594      "#,
12595      indoc! {r#"
12596        .foo {
12597          background: -webkit-gradient(linear, left top, left bottom, from(red), to(#00f));
12598          background: -webkit-linear-gradient(red, #00f);
12599          background: -moz-linear-gradient(red, #00f);
12600          background: -o-linear-gradient(red, #00f);
12601          background: linear-gradient(red, #00f);
12602        }
12603      "#},
12604    );
12605
12606    prefix_test(
12607      r#"
12608      .foo {
12609        background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue));
12610        background: -webkit-linear-gradient(red, blue);
12611        background: -moz-linear-gradient(red, blue);
12612        background: -o-linear-gradient(red, blue);
12613        background: linear-gradient(red, blue);
12614      }
12615      "#,
12616      indoc! {r#"
12617      .foo {
12618        background: linear-gradient(red, #00f);
12619      }
12620      "#},
12621      Browsers {
12622        chrome: Some(95 << 16),
12623        ..Browsers::default()
12624      },
12625    );
12626    prefix_test(
12627      r#"
12628      .foo {
12629        background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue));
12630        background: -webkit-linear-gradient(red, blue);
12631        background: -moz-linear-gradient(red, blue);
12632        background: -o-linear-gradient(red, blue);
12633      }
12634      "#,
12635      indoc! {r#"
12636      .foo {
12637        background: -webkit-gradient(linear, left top, left bottom, from(red), to(#00f));
12638        background: -webkit-linear-gradient(red, #00f);
12639        background: -moz-linear-gradient(red, #00f);
12640        background: -o-linear-gradient(red, #00f);
12641      }
12642      "#},
12643      Browsers {
12644        chrome: Some(95 << 16),
12645        ..Browsers::default()
12646      },
12647    );
12648    prefix_test(
12649      r#"
12650      .foo {
12651        background-image: linear-gradient(red, blue);
12652      }
12653      "#,
12654      indoc! {r#"
12655      .foo {
12656        background-image: -webkit-gradient(linear, 0 0, 0 100%, from(red), to(#00f));
12657        background-image: -webkit-linear-gradient(red, #00f);
12658        background-image: linear-gradient(red, #00f);
12659      }
12660      "#},
12661      Browsers {
12662        chrome: Some(8 << 16),
12663        ..Browsers::default()
12664      },
12665    );
12666    prefix_test(
12667      r#"
12668      .foo {
12669        background-image: linear-gradient(to right, red, blue);
12670      }
12671      "#,
12672      indoc! {r#"
12673      .foo {
12674        background-image: -webkit-gradient(linear, 0 0, 100% 0, from(red), to(#00f));
12675        background-image: -webkit-linear-gradient(right, red, #00f);
12676        background-image: linear-gradient(to right, red, #00f);
12677      }
12678      "#},
12679      Browsers {
12680        chrome: Some(8 << 16),
12681        ..Browsers::default()
12682      },
12683    );
12684    prefix_test(
12685      r#"
12686      .foo {
12687        background-image: linear-gradient(to top, red, blue);
12688      }
12689      "#,
12690      indoc! {r#"
12691      .foo {
12692        background-image: -webkit-gradient(linear, 0 100%, 0 0, from(red), to(#00f));
12693        background-image: -webkit-linear-gradient(top, red, #00f);
12694        background-image: linear-gradient(to top, red, #00f);
12695      }
12696      "#},
12697      Browsers {
12698        chrome: Some(8 << 16),
12699        ..Browsers::default()
12700      },
12701    );
12702    prefix_test(
12703      r#"
12704      .foo {
12705        background-image: linear-gradient(to left, red, blue);
12706      }
12707      "#,
12708      indoc! {r#"
12709      .foo {
12710        background-image: -webkit-gradient(linear, 100% 0, 0 0, from(red), to(#00f));
12711        background-image: -webkit-linear-gradient(left, red, #00f);
12712        background-image: linear-gradient(to left, red, #00f);
12713      }
12714      "#},
12715      Browsers {
12716        chrome: Some(8 << 16),
12717        ..Browsers::default()
12718      },
12719    );
12720    prefix_test(
12721      r#"
12722      .foo {
12723        background-image: linear-gradient(to left bottom, red, blue);
12724      }
12725      "#,
12726      indoc! {r#"
12727      .foo {
12728        background-image: -webkit-gradient(linear, 100% 0, 0 100%, from(red), to(#00f));
12729        background-image: -webkit-linear-gradient(bottom left, red, #00f);
12730        background-image: linear-gradient(to bottom left, red, #00f);
12731      }
12732      "#},
12733      Browsers {
12734        chrome: Some(8 << 16),
12735        ..Browsers::default()
12736      },
12737    );
12738    prefix_test(
12739      r#"
12740      .foo {
12741        background-image: linear-gradient(to top right, red, blue);
12742      }
12743      "#,
12744      indoc! {r#"
12745      .foo {
12746        background-image: -webkit-gradient(linear, 0 100%, 100% 0, from(red), to(#00f));
12747        background-image: -webkit-linear-gradient(top right, red, #00f);
12748        background-image: linear-gradient(to top right, red, #00f);
12749      }
12750      "#},
12751      Browsers {
12752        chrome: Some(8 << 16),
12753        ..Browsers::default()
12754      },
12755    );
12756    prefix_test(
12757      r#"
12758      .foo {
12759        background-image: linear-gradient(90deg, red, blue);
12760      }
12761      "#,
12762      indoc! {r#"
12763      .foo {
12764        background-image: -webkit-gradient(linear, 0 0, 100% 0, from(red), to(#00f));
12765        background-image: -webkit-linear-gradient(90deg, red, #00f);
12766        background-image: linear-gradient(90deg, red, #00f);
12767      }
12768      "#},
12769      Browsers {
12770        chrome: Some(8 << 16),
12771        ..Browsers::default()
12772      },
12773    );
12774    prefix_test(
12775      r#"
12776      .foo {
12777        background-image: linear-gradient(45deg, red, blue);
12778      }
12779      "#,
12780      indoc! {r#"
12781      .foo {
12782        background-image: -webkit-linear-gradient(45deg, red, #00f);
12783        background-image: linear-gradient(45deg, red, #00f);
12784      }
12785      "#},
12786      Browsers {
12787        chrome: Some(8 << 16),
12788        ..Browsers::default()
12789      },
12790    );
12791    prefix_test(
12792      r#"
12793      .foo {
12794        background-image: linear-gradient(red, blue);
12795      }
12796      "#,
12797      indoc! {r#"
12798      .foo {
12799        background-image: -webkit-linear-gradient(red, #00f);
12800        background-image: linear-gradient(red, #00f);
12801      }
12802      "#},
12803      Browsers {
12804        chrome: Some(10 << 16),
12805        ..Browsers::default()
12806      },
12807    );
12808    prefix_test(
12809      r#"
12810      .foo {
12811        background-image: radial-gradient(20px, red, blue);
12812      }
12813      "#,
12814      indoc! {r#"
12815      .foo {
12816        background-image: -webkit-gradient(radial, center center, 0, center center, 20, from(red), to(#00f));
12817        background-image: -webkit-radial-gradient(20px, red, #00f);
12818        background-image: radial-gradient(20px, red, #00f);
12819      }
12820      "#},
12821      Browsers {
12822        chrome: Some(8 << 16),
12823        ..Browsers::default()
12824      },
12825    );
12826    prefix_test(
12827      r#"
12828      .foo {
12829        background-image: radial-gradient(20px at top left, red, blue);
12830      }
12831      "#,
12832      indoc! {r#"
12833      .foo {
12834        background-image: -webkit-gradient(radial, left top, 0, left top, 20, from(red), to(#00f));
12835        background-image: -webkit-radial-gradient(20px at 0 0, red, #00f);
12836        background-image: radial-gradient(20px at 0 0, red, #00f);
12837      }
12838      "#},
12839      Browsers {
12840        chrome: Some(8 << 16),
12841        ..Browsers::default()
12842      },
12843    );
12844    prefix_test(
12845      r#"
12846      .foo {
12847        background-image: radial-gradient(red, blue);
12848      }
12849      "#,
12850      indoc! {r#"
12851      .foo {
12852        background-image: -webkit-radial-gradient(red, #00f);
12853        background-image: radial-gradient(red, #00f);
12854      }
12855      "#},
12856      Browsers {
12857        chrome: Some(8 << 16),
12858        ..Browsers::default()
12859      },
12860    );
12861    prefix_test(
12862      r#"
12863      .foo {
12864        background-image: -webkit-gradient(radial, left top, 0, left top, 20, from(red), to(#00f));
12865        background-image: -webkit-radial-gradient(20px at 0% 0%, red, #00f);
12866        background-image: radial-gradient(20px at 0% 0%, red, #00f);
12867      }
12868      "#,
12869      indoc! {r#"
12870      .foo {
12871        background-image: radial-gradient(20px at 0 0, red, #00f);
12872      }
12873      "#},
12874      Browsers {
12875        chrome: Some(30 << 16),
12876        ..Browsers::default()
12877      },
12878    );
12879    prefix_test(
12880      r#"
12881      .foo {
12882        background: -webkit-gradient(radial, left top, 0, left top, 20, from(red), to(#00f));
12883        background: -webkit-radial-gradient(20px at 0% 0%, red, #00f);
12884        background: radial-gradient(20px at 0% 0%, red, #00f);
12885      }
12886      "#,
12887      indoc! {r#"
12888      .foo {
12889        background: radial-gradient(20px at 0 0, red, #00f);
12890      }
12891      "#},
12892      Browsers {
12893        chrome: Some(30 << 16),
12894        ..Browsers::default()
12895      },
12896    );
12897    prefix_test(
12898      r#"
12899      .foo {
12900        background: radial-gradient(red, blue);
12901      }
12902      "#,
12903      indoc! {r#"
12904      .foo {
12905        background: -webkit-radial-gradient(red, #00f);
12906        background: radial-gradient(red, #00f);
12907      }
12908      "#},
12909      Browsers {
12910        chrome: Some(8 << 16),
12911        ..Browsers::default()
12912      },
12913    );
12914    prefix_test(
12915      r#"
12916      .foo {
12917        background: radial-gradient(red, blue), linear-gradient(yellow, red), url(bg.jpg);
12918      }
12919      "#,
12920      indoc! {r#"
12921      .foo {
12922        background: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0), to(red)), url("bg.jpg");
12923        background: -webkit-radial-gradient(red, #00f), -webkit-linear-gradient(#ff0, red), url("bg.jpg");
12924        background: -moz-radial-gradient(red, #00f), -moz-linear-gradient(#ff0, red), url("bg.jpg");
12925        background: -o-radial-gradient(red, #00f), -o-linear-gradient(#ff0, red), url("bg.jpg");
12926        background: radial-gradient(red, #00f), linear-gradient(#ff0, red), url("bg.jpg");
12927      }
12928      "#},
12929      Browsers {
12930        chrome: Some(8 << 16),
12931        firefox: Some(4 << 16),
12932        opera: Some(11 << 16 | 5 << 8),
12933        ..Browsers::default()
12934      },
12935    );
12936
12937    prefix_test(
12938      r#"
12939      .foo {
12940        background: linear-gradient(yellow, red 30% 40%, blue);
12941      }
12942      "#,
12943      indoc! {r#"
12944      .foo {
12945        background: linear-gradient(#ff0, red 30%, red 40%, #00f);
12946      }
12947      "#},
12948      Browsers {
12949        chrome: Some(70 << 16),
12950        ..Browsers::default()
12951      },
12952    );
12953
12954    prefix_test(
12955      r#"
12956      .foo {
12957        background: linear-gradient(yellow, red 30% 40%, blue);
12958      }
12959      "#,
12960      indoc! {r#"
12961      .foo {
12962        background: linear-gradient(#ff0, red 30% 40%, #00f);
12963      }
12964      "#},
12965      Browsers {
12966        chrome: Some(71 << 16),
12967        ..Browsers::default()
12968      },
12969    );
12970
12971    prefix_test(
12972      ".foo { background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
12973      indoc! { r#"
12974        .foo {
12975          background: linear-gradient(#ff0f0e, #7773ff);
12976          background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
12977        }
12978      "#},
12979      Browsers {
12980        chrome: Some(90 << 16),
12981        ..Browsers::default()
12982      },
12983    );
12984
12985    prefix_test(
12986      ".foo { background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
12987      indoc! { r#"
12988        .foo {
12989          background: linear-gradient(#ff0f0e, #7773ff);
12990          background: linear-gradient(color(display-p3 1 .0000153435 -.00000303562), color(display-p3 .440289 .28452 1.23485));
12991          background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
12992        }
12993      "#},
12994      Browsers {
12995        chrome: Some(90 << 16),
12996        safari: Some(14 << 16),
12997        ..Browsers::default()
12998      },
12999    );
13000
13001    prefix_test(
13002      ".foo { background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13003      indoc! { r#"
13004        .foo {
13005          background: -webkit-linear-gradient(#ff0f0e, #7773ff);
13006          background: linear-gradient(#ff0f0e, #7773ff);
13007          background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13008        }
13009      "#},
13010      Browsers {
13011        chrome: Some(20 << 16),
13012        ..Browsers::default()
13013      },
13014    );
13015
13016    prefix_test(
13017      ".foo { background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13018      indoc! { r#"
13019        .foo {
13020          background: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0f0e), to(#7773ff));
13021          background: -webkit-linear-gradient(#ff0f0e, #7773ff);
13022          background: linear-gradient(#ff0f0e, #7773ff);
13023          background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13024        }
13025      "#},
13026      Browsers {
13027        chrome: Some(8 << 16),
13028        ..Browsers::default()
13029      },
13030    );
13031
13032    prefix_test(
13033      ".foo { background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13034      indoc! { r#"
13035        .foo {
13036          background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13037        }
13038      "#},
13039      Browsers {
13040        safari: Some(15 << 16),
13041        ..Browsers::default()
13042      },
13043    );
13044
13045    prefix_test(
13046      ".foo { background-image: linear-gradient(oklab(59.686% 0.1009 0.1192), oklab(54.0% -0.10 -0.02)); }",
13047      indoc! { r#"
13048        .foo {
13049          background-image: linear-gradient(lab(52.2319% 40.1449 59.9171), lab(47.7776% -34.2947 -7.65904));
13050        }
13051      "#},
13052      Browsers {
13053        safari: Some(15 << 16),
13054        ..Browsers::default()
13055      },
13056    );
13057
13058    prefix_test(
13059      ".foo { background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13060      indoc! { r#"
13061        .foo {
13062          background-image: linear-gradient(#ff0f0e, #7773ff);
13063          background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13064        }
13065      "#},
13066      Browsers {
13067        chrome: Some(90 << 16),
13068        ..Browsers::default()
13069      },
13070    );
13071
13072    prefix_test(
13073      ".foo { background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13074      indoc! { r#"
13075        .foo {
13076          background-image: linear-gradient(#ff0f0e, #7773ff);
13077          background-image: linear-gradient(color(display-p3 1 .0000153435 -.00000303562), color(display-p3 .440289 .28452 1.23485));
13078          background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13079        }
13080      "#},
13081      Browsers {
13082        chrome: Some(90 << 16),
13083        safari: Some(14 << 16),
13084        ..Browsers::default()
13085      },
13086    );
13087
13088    prefix_test(
13089      ".foo { background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13090      indoc! { r#"
13091        .foo {
13092          background-image: -webkit-linear-gradient(#ff0f0e, #7773ff);
13093          background-image: linear-gradient(#ff0f0e, #7773ff);
13094          background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13095        }
13096      "#},
13097      Browsers {
13098        chrome: Some(20 << 16),
13099        ..Browsers::default()
13100      },
13101    );
13102
13103    prefix_test(
13104      ".foo { background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13105      indoc! { r#"
13106        .foo {
13107          background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0f0e), to(#7773ff));
13108          background-image: -webkit-linear-gradient(#ff0f0e, #7773ff);
13109          background-image: linear-gradient(#ff0f0e, #7773ff);
13110          background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13111        }
13112      "#},
13113      Browsers {
13114        chrome: Some(8 << 16),
13115        ..Browsers::default()
13116      },
13117    );
13118
13119    prefix_test(
13120      ".foo { background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13121      indoc! { r#"
13122        .foo {
13123          background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13124        }
13125      "#},
13126      Browsers {
13127        safari: Some(15 << 16),
13128        ..Browsers::default()
13129      },
13130    );
13131
13132    prefix_test(
13133      ".foo { background-image: linear-gradient(oklab(59.686% 0.1009 0.1192), oklab(54.0% -0.10 -0.02)); }",
13134      indoc! { r#"
13135        .foo {
13136          background-image: linear-gradient(lab(52.2319% 40.1449 59.9171), lab(47.7776% -34.2947 -7.65904));
13137        }
13138      "#},
13139      Browsers {
13140        safari: Some(15 << 16),
13141        ..Browsers::default()
13142      },
13143    );
13144  }
13145
13146  #[test]
13147  fn test_font_face() {
13148    minify_test(
13149      r#"@font-face {
13150      src: url("test.woff");
13151      font-family: "Helvetica";
13152      font-weight: bold;
13153      font-style: italic;
13154    }"#,
13155      "@font-face{src:url(test.woff);font-family:Helvetica;font-weight:700;font-style:italic}",
13156    );
13157    minify_test("@font-face {src: url(test.woff);}", "@font-face{src:url(test.woff)}");
13158    minify_test("@font-face {src: local(\"Test\");}", "@font-face{src:local(Test)}");
13159    minify_test(
13160      "@font-face {src: local(\"Foo Bar\");}",
13161      "@font-face{src:local(Foo Bar)}",
13162    );
13163    minify_test("@font-face {src: local(Test);}", "@font-face{src:local(Test)}");
13164    minify_test("@font-face {src: local(Foo Bar);}", "@font-face{src:local(Foo Bar)}");
13165
13166    minify_test(
13167      "@font-face {src: url(\"test.woff\") format(woff);}",
13168      "@font-face{src:url(test.woff)format(\"woff\")}",
13169    );
13170    minify_test(
13171      "@font-face {src: url(\"test.ttc\") format(collection), url(test.ttf) format(truetype);}",
13172      "@font-face{src:url(test.ttc)format(\"collection\"),url(test.ttf)format(\"truetype\")}",
13173    );
13174    minify_test(
13175      "@font-face {src: url(\"test.otf\") format(opentype) tech(features-aat);}",
13176      "@font-face{src:url(test.otf)format(\"opentype\")tech(features-aat)}",
13177    );
13178    minify_test(
13179      "@font-face {src: url(\"test.woff\") format(woff) tech(color-colrv1);}",
13180      "@font-face{src:url(test.woff)format(\"woff\")tech(color-colrv1)}",
13181    );
13182    minify_test(
13183      "@font-face {src: url(\"test.woff2\") format(woff2) tech(variations);}",
13184      "@font-face{src:url(test.woff2)format(\"woff2\")tech(variations)}",
13185    );
13186    minify_test(
13187      "@font-face {src: url(\"test.woff\") format(woff) tech(palettes);}",
13188      "@font-face{src:url(test.woff)format(\"woff\")tech(palettes)}",
13189    );
13190    // multiple tech
13191    minify_test(
13192      "@font-face {src: url(\"test.woff\") format(woff) tech(features-opentype, color-sbix);}",
13193      "@font-face{src:url(test.woff)format(\"woff\")tech(features-opentype,color-sbix)}",
13194    );
13195    minify_test(
13196      "@font-face {src: url(\"test.woff\")   format(woff)    tech(incremental, color-svg, features-graphite, features-aat);}",
13197      "@font-face{src:url(test.woff)format(\"woff\")tech(incremental,color-svg,features-graphite,features-aat)}",
13198    );
13199    // format() function must precede tech() if both are present
13200    minify_test(
13201      "@font-face {src: url(\"foo.ttf\") format(opentype) tech(color-colrv1);}",
13202      "@font-face{src:url(foo.ttf)format(\"opentype\")tech(color-colrv1)}",
13203    );
13204    // only have tech is valid
13205    minify_test(
13206      "@font-face {src: url(\"foo.ttf\") tech(color-SVG);}",
13207      "@font-face{src:url(foo.ttf)tech(color-svg)}",
13208    );
13209    // CGQAQ: if tech and format both presence, order is matter, tech before format is invalid
13210    // but now just return raw token, we don't have strict mode yet.
13211    // ref: https://github.com/parcel-bundler/lightningcss/pull/255#issuecomment-1219049998
13212    minify_test(
13213      "@font-face {src: url(\"foo.ttf\") tech(palettes  color-colrv0  variations) format(opentype);}",
13214      "@font-face{src:url(foo.ttf) tech(palettes color-colrv0 variations)format(opentype)}",
13215    );
13216    // TODO(CGQAQ): make this test pass when we have strict mode
13217    // ref: https://github.com/web-platform-tests/wpt/blob/9f8a6ccc41aa725e8f51f4f096f686313bb88d8d/css/css-fonts/parsing/font-face-src-tech.html#L45
13218    // error_test(
13219    //   "@font-face {src: url(\"foo.ttf\") tech(features-opentype) format(opentype);}",
13220    //   ParserError::AtRuleBodyInvalid,
13221    // );
13222    // error_test(
13223    //   "@font-face {src: url(\"foo.ttf\") tech();}",
13224    //   ParserError::AtRuleBodyInvalid,
13225    // );
13226    // error_test(
13227    //   "@font-face {src: url(\"foo.ttf\") tech(\"features-opentype\");}",
13228    //   ParserError::AtRuleBodyInvalid,
13229    // );
13230    // error_test(
13231    //   "@font-face {src: url(\"foo.ttf\") tech(\"color-colrv0\");}",
13232    //   ParserError::AtRuleBodyInvalid,
13233    // );
13234    minify_test(
13235      "@font-face {src: local(\"\") url(\"test.woff\");}",
13236      "@font-face{src:local(\"\")url(test.woff)}",
13237    );
13238    minify_test("@font-face {font-weight: 200 400}", "@font-face{font-weight:200 400}");
13239    minify_test("@font-face {font-weight: 400 400}", "@font-face{font-weight:400}");
13240    minify_test(
13241      "@font-face {font-stretch: 50% 200%}",
13242      "@font-face{font-stretch:50% 200%}",
13243    );
13244    minify_test("@font-face {font-stretch: 50% 50%}", "@font-face{font-stretch:50%}");
13245    minify_test("@font-face {unicode-range: U+26;}", "@font-face{unicode-range:U+26}");
13246    minify_test("@font-face {unicode-range: u+26;}", "@font-face{unicode-range:U+26}");
13247    minify_test(
13248      "@font-face {unicode-range: U+0-7F;}",
13249      "@font-face{unicode-range:U+0-7F}",
13250    );
13251    minify_test(
13252      "@font-face {unicode-range: U+0025-00FF;}",
13253      "@font-face{unicode-range:U+25-FF}",
13254    );
13255    minify_test("@font-face {unicode-range: U+4??;}", "@font-face{unicode-range:U+4??}");
13256    minify_test(
13257      "@font-face {unicode-range: U+400-4FF;}",
13258      "@font-face{unicode-range:U+4??}",
13259    );
13260    minify_test(
13261      "@font-face {unicode-range: U+0025-00FF, U+4??;}",
13262      "@font-face{unicode-range:U+25-FF,U+4??}",
13263    );
13264    minify_test(
13265      "@font-face {unicode-range: U+A5, U+4E00-9FFF, U+30??, U+FF00-FF9F;}",
13266      "@font-face{unicode-range:U+A5,U+4E00-9FFF,U+30??,U+FF00-FF9F}",
13267    );
13268    minify_test(
13269      "@font-face {unicode-range: U+????;}",
13270      "@font-face{unicode-range:U+????}",
13271    );
13272    minify_test(
13273      "@font-face {unicode-range: U+0000-FFFF;}",
13274      "@font-face{unicode-range:U+????}",
13275    );
13276    minify_test(
13277      "@font-face {unicode-range: U+10????;}",
13278      "@font-face{unicode-range:U+10????}",
13279    );
13280    minify_test(
13281      "@font-face {unicode-range: U+100000-10FFFF;}",
13282      "@font-face{unicode-range:U+10????}",
13283    );
13284    minify_test(
13285      "@font-face {unicode-range: U+1e1e?;}",
13286      "@font-face{unicode-range:U+1E1E?}",
13287    );
13288    minify_test(
13289      "@font-face {unicode-range: u+????, U+1????, U+10????;}",
13290      "@font-face{unicode-range:U+????,U+1????,U+10????}",
13291    );
13292    minify_test(r#"
13293      @font-face {
13294        font-family: Inter;
13295        font-style: oblique 0deg 10deg;
13296        font-weight: 100 900;
13297        src: url("../fonts/Inter.var.woff2?v=3.19") format("woff2");
13298        font-display: swap;
13299      }
13300    "#, "@font-face{font-family:Inter;font-style:oblique 0deg 10deg;font-weight:100 900;src:url(../fonts/Inter.var.woff2?v=3.19)format(\"woff2\");font-display:swap}");
13301    minify_test(r#"
13302    @font-face {
13303      font-family: Inter;
13304      font-style: oblique 14deg 14deg;
13305      font-weight: 100 900;
13306      src: url("../fonts/Inter.var.woff2?v=3.19") format("woff2");
13307      font-display: swap;
13308    }
13309  "#, "@font-face{font-family:Inter;font-style:oblique;font-weight:100 900;src:url(../fonts/Inter.var.woff2?v=3.19)format(\"woff2\");font-display:swap}");
13310  }
13311
13312  #[test]
13313  fn test_font_palette_values() {
13314    minify_test(
13315      r#"@font-palette-values --Cooler {
13316      font-family: Bixa;
13317      base-palette: 1;
13318      override-colors: 1 #7EB7E4;
13319    }"#,
13320      "@font-palette-values --Cooler{font-family:Bixa;base-palette:1;override-colors:1 #7eb7e4}",
13321    );
13322    minify_test(
13323      r#"@font-palette-values --Cooler {
13324      font-family: Handover Sans;
13325      base-palette: 3;
13326      override-colors: 1 rgb(43, 12, 9), 3 lime;
13327    }"#,
13328      "@font-palette-values --Cooler{font-family:Handover Sans;base-palette:3;override-colors:1 #2b0c09,3 #0f0}",
13329    );
13330    minify_test(r#"@font-palette-values --Cooler {
13331      font-family: Handover Sans;
13332      base-palette: 3;
13333      override-colors: 1 rgb(43, 12, 9), 3 var(--highlight);
13334    }"#, "@font-palette-values --Cooler{font-family:Handover Sans;base-palette:3;override-colors:1 #2b0c09,3 var(--highlight)}");
13335    prefix_test(
13336      r#"@font-palette-values --Cooler {
13337      font-family: Handover Sans;
13338      base-palette: 3;
13339      override-colors: 1 rgb(43, 12, 9), 3 lch(50.998% 135.363 338);
13340    }"#,
13341      indoc! {r#"@font-palette-values --Cooler {
13342      font-family: Handover Sans;
13343      base-palette: 3;
13344      override-colors: 1 #2b0c09, 3 #ee00be;
13345      override-colors: 1 #2b0c09, 3 lch(50.998% 135.363 338);
13346    }
13347    "#},
13348      Browsers {
13349        chrome: Some(90 << 16),
13350        ..Browsers::default()
13351      },
13352    );
13353    prefix_test(
13354      r#"@font-palette-values --Cooler {
13355      font-family: Handover Sans;
13356      base-palette: 3;
13357      override-colors: 1 var(--foo), 3 lch(50.998% 135.363 338);
13358    }"#,
13359      indoc! {r#"@font-palette-values --Cooler {
13360      font-family: Handover Sans;
13361      base-palette: 3;
13362      override-colors: 1 var(--foo), 3 #ee00be;
13363    }
13364
13365    @supports (color: lab(0% 0 0)) {
13366      @font-palette-values --Cooler {
13367        font-family: Handover Sans;
13368        base-palette: 3;
13369        override-colors: 1 var(--foo), 3 lab(50.998% 125.506 -50.7078);
13370      }
13371    }
13372    "#},
13373      Browsers {
13374        chrome: Some(90 << 16),
13375        ..Browsers::default()
13376      },
13377    );
13378    minify_test(".foo { font-palette: --Custom; }", ".foo{font-palette:--Custom}");
13379  }
13380
13381  #[test]
13382  fn test_page_rule() {
13383    minify_test("@page {margin: 0.5cm}", "@page{margin:.5cm}");
13384    minify_test("@page :left {margin: 0.5cm}", "@page:left{margin:.5cm}");
13385    minify_test("@page :right {margin: 0.5cm}", "@page:right{margin:.5cm}");
13386    minify_test(
13387      "@page LandscapeTable {margin: 0.5cm}",
13388      "@page LandscapeTable{margin:.5cm}",
13389    );
13390    minify_test(
13391      "@page CompanyLetterHead:first {margin: 0.5cm}",
13392      "@page CompanyLetterHead:first{margin:.5cm}",
13393    );
13394    minify_test("@page:first {margin: 0.5cm}", "@page:first{margin:.5cm}");
13395    minify_test("@page :blank:first {margin: 0.5cm}", "@page:blank:first{margin:.5cm}");
13396    minify_test("@page toc, index {margin: 0.5cm}", "@page toc,index{margin:.5cm}");
13397    minify_test(
13398      r#"
13399    @page :right {
13400      @bottom-left {
13401        margin: 10pt;
13402      }
13403    }
13404    "#,
13405      "@page:right{@bottom-left{margin:10pt}}",
13406    );
13407    minify_test(
13408      r#"
13409    @page :right {
13410      margin: 1in;
13411
13412      @bottom-left {
13413        margin: 10pt;
13414      }
13415    }
13416    "#,
13417      "@page:right{margin:1in;@bottom-left{margin:10pt}}",
13418    );
13419
13420    test(
13421      r#"
13422    @page :right {
13423      @bottom-left {
13424        margin: 10pt;
13425      }
13426    }
13427    "#,
13428      indoc! {r#"
13429      @page :right {
13430        @bottom-left {
13431          margin: 10pt;
13432        }
13433      }
13434      "#},
13435    );
13436
13437    test(
13438      r#"
13439    @page :right {
13440      margin: 1in;
13441
13442      @bottom-left-corner { content: "Foo"; }
13443      @bottom-right-corner { content: "Bar"; }
13444    }
13445    "#,
13446      indoc! {r#"
13447      @page :right {
13448        margin: 1in;
13449
13450        @bottom-left-corner {
13451          content: "Foo";
13452        }
13453
13454        @bottom-right-corner {
13455          content: "Bar";
13456        }
13457      }
13458      "#},
13459    );
13460
13461    error_test(
13462      r#"
13463      @page {
13464        @foo {
13465          margin: 1in;
13466        }
13467      }
13468      "#,
13469      ParserError::AtRuleInvalid("foo".into()),
13470    );
13471
13472    error_test(
13473      r#"
13474      @page {
13475        @top-left-corner {
13476          @bottom-left {
13477            margin: 1in;
13478          }
13479        }
13480      }
13481      "#,
13482      ParserError::AtRuleInvalid("bottom-left".into()),
13483    );
13484  }
13485
13486  #[test]
13487  fn test_supports_rule() {
13488    test(
13489      r#"
13490      @supports (foo: bar) {
13491        .test {
13492          foo: bar;
13493        }
13494      }
13495    "#,
13496      indoc! { r#"
13497      @supports (foo: bar) {
13498        .test {
13499          foo: bar;
13500        }
13501      }
13502    "#},
13503    );
13504    test(
13505      r#"
13506      @supports not (foo: bar) {
13507        .test {
13508          foo: bar;
13509        }
13510      }
13511    "#,
13512      indoc! { r#"
13513      @supports not (foo: bar) {
13514        .test {
13515          foo: bar;
13516        }
13517      }
13518    "#},
13519    );
13520    test(
13521      r#"
13522      @supports (foo: bar) or (bar: baz) {
13523        .test {
13524          foo: bar;
13525        }
13526      }
13527    "#,
13528      indoc! { r#"
13529      @supports (foo: bar) or (bar: baz) {
13530        .test {
13531          foo: bar;
13532        }
13533      }
13534    "#},
13535    );
13536    test(
13537      r#"
13538      @supports (((foo: bar) or (bar: baz))) {
13539        .test {
13540          foo: bar;
13541        }
13542      }
13543    "#,
13544      indoc! { r#"
13545      @supports (foo: bar) or (bar: baz) {
13546        .test {
13547          foo: bar;
13548        }
13549      }
13550    "#},
13551    );
13552    test(
13553      r#"
13554      @supports (foo: bar) and (bar: baz) {
13555        .test {
13556          foo: bar;
13557        }
13558      }
13559    "#,
13560      indoc! { r#"
13561      @supports (foo: bar) and (bar: baz) {
13562        .test {
13563          foo: bar;
13564        }
13565      }
13566    "#},
13567    );
13568    test(
13569      r#"
13570      @supports (((foo: bar) and (bar: baz))) {
13571        .test {
13572          foo: bar;
13573        }
13574      }
13575    "#,
13576      indoc! { r#"
13577      @supports (foo: bar) and (bar: baz) {
13578        .test {
13579          foo: bar;
13580        }
13581      }
13582    "#},
13583    );
13584    test(
13585      r#"
13586      @supports (foo: bar) and (((bar: baz) or (test: foo))) {
13587        .test {
13588          foo: bar;
13589        }
13590      }
13591    "#,
13592      indoc! { r#"
13593      @supports (foo: bar) and ((bar: baz) or (test: foo)) {
13594        .test {
13595          foo: bar;
13596        }
13597      }
13598    "#},
13599    );
13600    test(
13601      r#"
13602      @supports not (((foo: bar) and (bar: baz))) {
13603        .test {
13604          foo: bar;
13605        }
13606      }
13607    "#,
13608      indoc! { r#"
13609      @supports not ((foo: bar) and (bar: baz)) {
13610        .test {
13611          foo: bar;
13612        }
13613      }
13614    "#},
13615    );
13616    test(
13617      r#"
13618      @supports selector(a > b) {
13619        .test {
13620          foo: bar;
13621        }
13622      }
13623    "#,
13624      indoc! { r#"
13625      @supports selector(a > b) {
13626        .test {
13627          foo: bar;
13628        }
13629      }
13630    "#},
13631    );
13632    test(
13633      r#"
13634      @supports unknown(test) {
13635        .test {
13636          foo: bar;
13637        }
13638      }
13639    "#,
13640      indoc! { r#"
13641      @supports unknown(test) {
13642        .test {
13643          foo: bar;
13644        }
13645      }
13646    "#},
13647    );
13648    test(
13649      r#"
13650      @supports (unknown) {
13651        .test {
13652          foo: bar;
13653        }
13654      }
13655    "#,
13656      indoc! { r#"
13657      @supports (unknown) {
13658        .test {
13659          foo: bar;
13660        }
13661      }
13662    "#},
13663    );
13664    test(
13665      r#"
13666      @supports (display: grid) and (not (display: inline-grid)) {
13667        .test {
13668          foo: bar;
13669        }
13670      }
13671    "#,
13672      indoc! { r#"
13673      @supports (display: grid) and (not (display: inline-grid)) {
13674        .test {
13675          foo: bar;
13676        }
13677      }
13678    "#},
13679    );
13680    prefix_test(
13681      r#"
13682      @supports (backdrop-filter: blur(10px)) {
13683        div {
13684          backdrop-filter: blur(10px);
13685        }
13686      }
13687    "#,
13688      indoc! { r#"
13689      @supports ((-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px))) {
13690        div {
13691          -webkit-backdrop-filter: blur(10px);
13692          backdrop-filter: blur(10px);
13693        }
13694      }
13695    "#},
13696      Browsers {
13697        safari: Some(14 << 16),
13698        ..Default::default()
13699      },
13700    );
13701    prefix_test(
13702      r#"
13703      @supports ((-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px))) {
13704        div {
13705          backdrop-filter: blur(10px);
13706        }
13707      }
13708    "#,
13709      indoc! { r#"
13710      @supports ((-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px))) {
13711        div {
13712          -webkit-backdrop-filter: blur(10px);
13713          backdrop-filter: blur(10px);
13714        }
13715      }
13716    "#},
13717      Browsers {
13718        safari: Some(14 << 16),
13719        ..Default::default()
13720      },
13721    );
13722    prefix_test(
13723      r#"
13724      @supports ((-webkit-backdrop-filter: blur(20px)) or (backdrop-filter: blur(10px))) {
13725        div {
13726          backdrop-filter: blur(10px);
13727        }
13728      }
13729    "#,
13730      indoc! { r#"
13731      @supports ((-webkit-backdrop-filter: blur(20px))) or ((-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px))) {
13732        div {
13733          -webkit-backdrop-filter: blur(10px);
13734          backdrop-filter: blur(10px);
13735        }
13736      }
13737    "#},
13738      Browsers {
13739        safari: Some(14 << 16),
13740        ..Default::default()
13741      },
13742    );
13743    prefix_test(
13744      r#"
13745      @supports ((-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px))) {
13746        div {
13747          backdrop-filter: blur(10px);
13748        }
13749      }
13750    "#,
13751      indoc! { r#"
13752      @supports (backdrop-filter: blur(10px)) {
13753        div {
13754          backdrop-filter: blur(10px);
13755        }
13756      }
13757    "#},
13758      Browsers {
13759        chrome: Some(80 << 16),
13760        ..Default::default()
13761      },
13762    );
13763    minify_test(
13764      r#"
13765      @supports (width: calc(10px * 2)) {
13766        .test {
13767          width: calc(10px * 2);
13768        }
13769      }
13770    "#,
13771      "@supports (width:calc(10px * 2)){.test{width:20px}}",
13772    );
13773    minify_test(
13774      r#"
13775      @supports (color: hsl(0deg, 0%, 0%)) {
13776        .test {
13777          color: hsl(0deg, 0%, 0%);
13778        }
13779      }
13780    "#,
13781      "@supports (color:hsl(0deg, 0%, 0%)){.test{color:#000}}",
13782    );
13783  }
13784
13785  #[test]
13786  fn test_counter_style() {
13787    test(
13788      r#"
13789      @counter-style circled-alpha {
13790        system: fixed;
13791        symbols: Ⓐ Ⓑ Ⓒ;
13792        suffix: " ";
13793      }
13794    "#,
13795      indoc! { r#"
13796      @counter-style circled-alpha {
13797        system: fixed;
13798        symbols: Ⓐ Ⓑ Ⓒ;
13799        suffix: " ";
13800      }
13801    "#},
13802    );
13803  }
13804
13805  #[test]
13806  fn test_namespace() {
13807    minify_test(
13808      "@namespace url(http://toto.example.org);",
13809      "@namespace \"http://toto.example.org\";",
13810    );
13811    minify_test(
13812      "@namespace \"http://toto.example.org\";",
13813      "@namespace \"http://toto.example.org\";",
13814    );
13815    minify_test(
13816      "@namespace toto \"http://toto.example.org\";",
13817      "@namespace toto \"http://toto.example.org\";",
13818    );
13819    minify_test(
13820      "@namespace toto url(http://toto.example.org);",
13821      "@namespace toto \"http://toto.example.org\";",
13822    );
13823
13824    test(
13825      r#"
13826      @namespace "http://example.com/foo";
13827
13828      x {
13829        color: red;
13830      }
13831    "#,
13832      indoc! {r#"
13833      @namespace "http://example.com/foo";
13834
13835      x {
13836        color: red;
13837      }
13838    "#},
13839    );
13840
13841    test(
13842      r#"
13843      @namespace toto "http://toto.example.org";
13844
13845      toto|x {
13846        color: red;
13847      }
13848
13849      [toto|att=val] {
13850        color: blue
13851      }
13852    "#,
13853      indoc! {r#"
13854      @namespace toto "http://toto.example.org";
13855
13856      toto|x {
13857        color: red;
13858      }
13859
13860      [toto|att="val"] {
13861        color: #00f;
13862      }
13863    "#},
13864    );
13865
13866    test(
13867      r#"
13868      @namespace "http://example.com/foo";
13869
13870      |x {
13871        color: red;
13872      }
13873
13874      [|att=val] {
13875        color: blue
13876      }
13877    "#,
13878      indoc! {r#"
13879      @namespace "http://example.com/foo";
13880
13881      |x {
13882        color: red;
13883      }
13884
13885      [att="val"] {
13886        color: #00f;
13887      }
13888    "#},
13889    );
13890
13891    test(
13892      r#"
13893      @namespace "http://example.com/foo";
13894
13895      *|x {
13896        color: red;
13897      }
13898
13899      [*|att=val] {
13900        color: blue
13901      }
13902    "#,
13903      indoc! {r#"
13904      @namespace "http://example.com/foo";
13905
13906      *|x {
13907        color: red;
13908      }
13909
13910      [*|att="val"] {
13911        color: #00f;
13912      }
13913    "#},
13914    );
13915
13916    error_test(
13917      ".foo { color: red } @namespace \"http://example.com/foo\";",
13918      ParserError::UnexpectedNamespaceRule,
13919    );
13920  }
13921
13922  #[test]
13923  fn test_import() {
13924    minify_test("@import url(foo.css);", "@import \"foo.css\";");
13925    minify_test("@import \"foo.css\";", "@import \"foo.css\";");
13926    minify_test("@import url(foo.css) print;", "@import \"foo.css\" print;");
13927    minify_test("@import \"foo.css\" print;", "@import \"foo.css\" print;");
13928    minify_test(
13929      "@import \"foo.css\" screen and (orientation: landscape);",
13930      "@import \"foo.css\" screen and (orientation:landscape);",
13931    );
13932    minify_test(
13933      "@import url(foo.css) supports(display: flex);",
13934      "@import \"foo.css\" supports(display:flex);",
13935    );
13936    minify_test(
13937      "@import url(foo.css) supports(display: flex) print;",
13938      "@import \"foo.css\" supports(display:flex) print;",
13939    );
13940    minify_test(
13941      "@import url(foo.css) supports(not (display: flex));",
13942      "@import \"foo.css\" supports(not (display:flex));",
13943    );
13944    minify_test(
13945      "@import url(foo.css) supports((display: flex));",
13946      "@import \"foo.css\" supports(display:flex);",
13947    );
13948    minify_test("@charset \"UTF-8\"; @import url(foo.css);", "@import \"foo.css\";");
13949    minify_test("@layer foo; @import url(foo.css);", "@layer foo;@import \"foo.css\";");
13950    error_test(
13951      ".foo { color: red } @import url(bar.css);",
13952      ParserError::UnexpectedImportRule,
13953    );
13954    error_test(
13955      "@namespace \"http://example.com/foo\"; @import url(bar.css);",
13956      ParserError::UnexpectedImportRule,
13957    );
13958    error_test(
13959      "@media print { .foo { color: red }} @import url(bar.css);",
13960      ParserError::UnexpectedImportRule,
13961    );
13962    error_test(
13963      "@layer foo; @import url(foo.css); @layer bar; @import url(bar.css)",
13964      ParserError::UnexpectedImportRule,
13965    );
13966  }
13967
13968  #[test]
13969  fn test_prefixes() {
13970    prefix_test(
13971      r#"
13972      .foo {
13973        -webkit-transition: opacity 200ms;
13974        -moz-transition: opacity 200ms;
13975        transition: opacity 200ms;
13976      }
13977      "#,
13978      indoc! {r#"
13979      .foo {
13980        transition: opacity .2s;
13981      }
13982      "#},
13983      Browsers {
13984        chrome: Some(95 << 16),
13985        ..Browsers::default()
13986      },
13987    );
13988
13989    prefix_test(
13990      ".foo{transition:opacity 200ms}",
13991      indoc! {r#"
13992      .foo {
13993        -webkit-transition: opacity .2s;
13994        -moz-transition: opacity .2s;
13995        transition: opacity .2s;
13996      }
13997      "#},
13998      Browsers {
13999        safari: Some(5 << 16),
14000        firefox: Some(14 << 16),
14001        ..Browsers::default()
14002      },
14003    );
14004  }
14005
14006  #[test]
14007  fn test_display() {
14008    minify_test(".foo { display: block }", ".foo{display:block}");
14009    minify_test(".foo { display: block flow }", ".foo{display:block}");
14010    minify_test(".foo { display: flow-root }", ".foo{display:flow-root}");
14011    minify_test(".foo { display: block flow-root }", ".foo{display:flow-root}");
14012    minify_test(".foo { display: inline }", ".foo{display:inline}");
14013    minify_test(".foo { display: inline flow }", ".foo{display:inline}");
14014    minify_test(".foo { display: inline-block }", ".foo{display:inline-block}");
14015    minify_test(".foo { display: inline flow-root }", ".foo{display:inline-block}");
14016    minify_test(".foo { display: run-in }", ".foo{display:run-in}");
14017    minify_test(".foo { display: run-in flow }", ".foo{display:run-in}");
14018    minify_test(".foo { display: list-item }", ".foo{display:list-item}");
14019    minify_test(".foo { display: block flow list-item }", ".foo{display:list-item}");
14020    minify_test(".foo { display: inline list-item }", ".foo{display:inline list-item}");
14021    minify_test(
14022      ".foo { display: inline flow list-item }",
14023      ".foo{display:inline list-item}",
14024    );
14025    minify_test(".foo { display: flex }", ".foo{display:flex}");
14026    minify_test(".foo { display: block flex }", ".foo{display:flex}");
14027    minify_test(".foo { display: inline-flex }", ".foo{display:inline-flex}");
14028    minify_test(".foo { display: inline flex }", ".foo{display:inline-flex}");
14029    minify_test(".foo { display: grid }", ".foo{display:grid}");
14030    minify_test(".foo { display: block grid }", ".foo{display:grid}");
14031    minify_test(".foo { display: inline-grid }", ".foo{display:inline-grid}");
14032    minify_test(".foo { display: inline grid }", ".foo{display:inline-grid}");
14033    minify_test(".foo { display: ruby }", ".foo{display:ruby}");
14034    minify_test(".foo { display: inline ruby }", ".foo{display:ruby}");
14035    minify_test(".foo { display: block ruby }", ".foo{display:block ruby}");
14036    minify_test(".foo { display: table }", ".foo{display:table}");
14037    minify_test(".foo { display: block table }", ".foo{display:table}");
14038    minify_test(".foo { display: inline-table }", ".foo{display:inline-table}");
14039    minify_test(".foo { display: inline table }", ".foo{display:inline-table}");
14040    minify_test(".foo { display: table-row-group }", ".foo{display:table-row-group}");
14041    minify_test(".foo { display: contents }", ".foo{display:contents}");
14042    minify_test(".foo { display: none }", ".foo{display:none}");
14043    minify_test(".foo { display: -webkit-flex }", ".foo{display:-webkit-flex}");
14044    minify_test(".foo { display: -ms-flexbox }", ".foo{display:-ms-flexbox}");
14045    minify_test(".foo { display: -webkit-box }", ".foo{display:-webkit-box}");
14046    minify_test(".foo { display: -moz-box }", ".foo{display:-moz-box}");
14047    minify_test(
14048      ".foo { display: -webkit-flex; display: -moz-box; display: flex }",
14049      ".foo{display:-webkit-flex;display:-moz-box;display:flex}",
14050    );
14051    minify_test(
14052      ".foo { display: -webkit-flex; display: flex; display: -moz-box }",
14053      ".foo{display:-webkit-flex;display:flex;display:-moz-box}",
14054    );
14055    minify_test(".foo { display: flex; display: grid }", ".foo{display:grid}");
14056    minify_test(
14057      ".foo { display: -webkit-inline-flex; display: -moz-inline-box; display: inline-flex }",
14058      ".foo{display:-webkit-inline-flex;display:-moz-inline-box;display:inline-flex}",
14059    );
14060    minify_test(
14061      ".foo { display: flex; display: var(--grid); }",
14062      ".foo{display:flex;display:var(--grid)}",
14063    );
14064    prefix_test(
14065      ".foo{ display: flex }",
14066      indoc! {r#"
14067      .foo {
14068        display: -webkit-box;
14069        display: -moz-box;
14070        display: -webkit-flex;
14071        display: -ms-flexbox;
14072        display: flex;
14073      }
14074      "#},
14075      Browsers {
14076        safari: Some(4 << 16),
14077        firefox: Some(14 << 16),
14078        ie: Some(10 << 16),
14079        ..Browsers::default()
14080      },
14081    );
14082    prefix_test(
14083      ".foo{ display: flex; display: -webkit-box; }",
14084      indoc! {r#"
14085      .foo {
14086        display: -webkit-box;
14087      }
14088      "#},
14089      Browsers {
14090        safari: Some(4 << 16),
14091        firefox: Some(14 << 16),
14092        ie: Some(10 << 16),
14093        ..Browsers::default()
14094      },
14095    );
14096    prefix_test(
14097      ".foo{ display: -webkit-box; display: flex; }",
14098      indoc! {r#"
14099      .foo {
14100        display: -webkit-box;
14101        display: -moz-box;
14102        display: -webkit-flex;
14103        display: -ms-flexbox;
14104        display: flex;
14105      }
14106      "#},
14107      Browsers {
14108        safari: Some(4 << 16),
14109        firefox: Some(14 << 16),
14110        ie: Some(10 << 16),
14111        ..Browsers::default()
14112      },
14113    );
14114    prefix_test(
14115      r#"
14116      .foo {
14117        display: -webkit-box;
14118        display: -moz-box;
14119        display: -webkit-flex;
14120        display: -ms-flexbox;
14121        display: flex;
14122      }
14123      "#,
14124      indoc! {r#"
14125      .foo {
14126        display: flex;
14127      }
14128      "#},
14129      Browsers {
14130        safari: Some(14 << 16),
14131        ..Browsers::default()
14132      },
14133    );
14134    prefix_test(
14135      r#"
14136      .foo {
14137        display: -webkit-box;
14138        display: flex;
14139        display: -moz-box;
14140        display: -webkit-flex;
14141        display: -ms-flexbox;
14142      }
14143      "#,
14144      indoc! {r#"
14145      .foo {
14146        display: -moz-box;
14147        display: -webkit-flex;
14148        display: -ms-flexbox;
14149      }
14150      "#},
14151      Browsers {
14152        safari: Some(14 << 16),
14153        ..Browsers::default()
14154      },
14155    );
14156    prefix_test(
14157      ".foo{ display: inline-flex }",
14158      indoc! {r#"
14159      .foo {
14160        display: -webkit-inline-box;
14161        display: -moz-inline-box;
14162        display: -webkit-inline-flex;
14163        display: -ms-inline-flexbox;
14164        display: inline-flex;
14165      }
14166      "#},
14167      Browsers {
14168        safari: Some(4 << 16),
14169        firefox: Some(14 << 16),
14170        ie: Some(10 << 16),
14171        ..Browsers::default()
14172      },
14173    );
14174    prefix_test(
14175      r#"
14176      .foo {
14177        display: -webkit-inline-box;
14178        display: -moz-inline-box;
14179        display: -webkit-inline-flex;
14180        display: -ms-inline-flexbox;
14181        display: inline-flex;
14182      }
14183      "#,
14184      indoc! {r#"
14185      .foo {
14186        display: inline-flex;
14187      }
14188      "#},
14189      Browsers {
14190        safari: Some(14 << 16),
14191        ..Browsers::default()
14192      },
14193    );
14194  }
14195
14196  #[test]
14197  fn test_visibility() {
14198    minify_test(".foo { visibility: visible }", ".foo{visibility:visible}");
14199    minify_test(".foo { visibility: hidden }", ".foo{visibility:hidden}");
14200    minify_test(".foo { visibility: collapse }", ".foo{visibility:collapse}");
14201    minify_test(".foo { visibility: Visible }", ".foo{visibility:visible}");
14202  }
14203
14204  #[test]
14205  fn test_text_transform() {
14206    minify_test(".foo { text-transform: uppercase }", ".foo{text-transform:uppercase}");
14207    minify_test(".foo { text-transform: lowercase }", ".foo{text-transform:lowercase}");
14208    minify_test(".foo { text-transform: capitalize }", ".foo{text-transform:capitalize}");
14209    minify_test(".foo { text-transform: none }", ".foo{text-transform:none}");
14210    minify_test(".foo { text-transform: full-width }", ".foo{text-transform:full-width}");
14211    minify_test(
14212      ".foo { text-transform: full-size-kana }",
14213      ".foo{text-transform:full-size-kana}",
14214    );
14215    minify_test(
14216      ".foo { text-transform: uppercase full-width }",
14217      ".foo{text-transform:uppercase full-width}",
14218    );
14219    minify_test(
14220      ".foo { text-transform: full-width uppercase }",
14221      ".foo{text-transform:uppercase full-width}",
14222    );
14223    minify_test(
14224      ".foo { text-transform: uppercase full-width full-size-kana }",
14225      ".foo{text-transform:uppercase full-width full-size-kana}",
14226    );
14227    minify_test(
14228      ".foo { text-transform: full-width uppercase full-size-kana }",
14229      ".foo{text-transform:uppercase full-width full-size-kana}",
14230    );
14231  }
14232
14233  #[test]
14234  fn test_whitespace() {
14235    minify_test(".foo { white-space: normal }", ".foo{white-space:normal}");
14236    minify_test(".foo { white-space: pre }", ".foo{white-space:pre}");
14237    minify_test(".foo { white-space: nowrap }", ".foo{white-space:nowrap}");
14238    minify_test(".foo { white-space: pre-wrap }", ".foo{white-space:pre-wrap}");
14239    minify_test(".foo { white-space: break-spaces }", ".foo{white-space:break-spaces}");
14240    minify_test(".foo { white-space: pre-line }", ".foo{white-space:pre-line}");
14241    minify_test(".foo { white-space: NoWrAp }", ".foo{white-space:nowrap}");
14242  }
14243
14244  #[test]
14245  fn test_tab_size() {
14246    minify_test(".foo { tab-size: 8 }", ".foo{tab-size:8}");
14247    minify_test(".foo { tab-size: 4px }", ".foo{tab-size:4px}");
14248    minify_test(".foo { -moz-tab-size: 4px }", ".foo{-moz-tab-size:4px}");
14249    minify_test(".foo { -o-tab-size: 4px }", ".foo{-o-tab-size:4px}");
14250    prefix_test(
14251      ".foo{ tab-size: 4 }",
14252      indoc! {r#"
14253      .foo {
14254        -moz-tab-size: 4;
14255        -o-tab-size: 4;
14256        tab-size: 4;
14257      }
14258      "#},
14259      Browsers {
14260        safari: Some(8 << 16),
14261        firefox: Some(50 << 16),
14262        opera: Some(12 << 16),
14263        ..Browsers::default()
14264      },
14265    );
14266    prefix_test(
14267      r#"
14268      .foo {
14269        -moz-tab-size: 4;
14270        -o-tab-size: 4;
14271        tab-size: 4;
14272      }
14273      "#,
14274      indoc! {r#"
14275      .foo {
14276        tab-size: 4;
14277      }
14278      "#},
14279      Browsers {
14280        safari: Some(8 << 16),
14281        firefox: Some(94 << 16),
14282        opera: Some(30 << 16),
14283        ..Browsers::default()
14284      },
14285    );
14286  }
14287
14288  #[test]
14289  fn test_word_break() {
14290    minify_test(".foo { word-break: normal }", ".foo{word-break:normal}");
14291    minify_test(".foo { word-break: keep-all }", ".foo{word-break:keep-all}");
14292    minify_test(".foo { word-break: break-all }", ".foo{word-break:break-all}");
14293    minify_test(".foo { word-break: break-word }", ".foo{word-break:break-word}");
14294  }
14295
14296  #[test]
14297  fn test_line_break() {
14298    minify_test(".foo { line-break: auto }", ".foo{line-break:auto}");
14299    minify_test(".foo { line-break: Loose }", ".foo{line-break:loose}");
14300    minify_test(".foo { line-break: anywhere }", ".foo{line-break:anywhere}");
14301  }
14302
14303  #[test]
14304  fn test_wrap() {
14305    minify_test(".foo { overflow-wrap: nOrmal }", ".foo{overflow-wrap:normal}");
14306    minify_test(".foo { overflow-wrap: break-Word }", ".foo{overflow-wrap:break-word}");
14307    minify_test(".foo { overflow-wrap: Anywhere }", ".foo{overflow-wrap:anywhere}");
14308    minify_test(".foo { word-wrap: Normal }", ".foo{word-wrap:normal}");
14309    minify_test(".foo { word-wrap: Break-wOrd }", ".foo{word-wrap:break-word}");
14310    minify_test(".foo { word-wrap: Anywhere }", ".foo{word-wrap:anywhere}");
14311  }
14312
14313  #[test]
14314  fn test_hyphens() {
14315    minify_test(".foo { hyphens: manual }", ".foo{hyphens:manual}");
14316    minify_test(".foo { hyphens: auto }", ".foo{hyphens:auto}");
14317    minify_test(".foo { hyphens: none }", ".foo{hyphens:none}");
14318    minify_test(".foo { -webkit-hyphens: manual }", ".foo{-webkit-hyphens:manual}");
14319    minify_test(".foo { -moz-hyphens: manual }", ".foo{-moz-hyphens:manual}");
14320    minify_test(".foo { -ms-hyphens: manual }", ".foo{-ms-hyphens:manual}");
14321    prefix_test(
14322      ".foo{ hyphens: manual }",
14323      indoc! {r#"
14324      .foo {
14325        -webkit-hyphens: manual;
14326        -moz-hyphens: manual;
14327        -ms-hyphens: manual;
14328        hyphens: manual;
14329      }
14330      "#},
14331      Browsers {
14332        safari: Some(14 << 16),
14333        firefox: Some(40 << 16),
14334        ie: Some(10 << 16),
14335        ..Browsers::default()
14336      },
14337    );
14338    prefix_test(
14339      r#"
14340      .foo {
14341        -webkit-hyphens: manual;
14342        -moz-hyphens: manual;
14343        -ms-hyphens: manual;
14344        hyphens: manual;
14345      }
14346      "#,
14347      indoc! {r#"
14348      .foo {
14349        -webkit-hyphens: manual;
14350        hyphens: manual;
14351      }
14352      "#},
14353      Browsers {
14354        safari: Some(14 << 16),
14355        chrome: Some(88 << 16),
14356        firefox: Some(88 << 16),
14357        edge: Some(79 << 16),
14358        ..Browsers::default()
14359      },
14360    );
14361    prefix_test(
14362      r#"
14363      .foo {
14364        -webkit-hyphens: manual;
14365        -moz-hyphens: manual;
14366        -ms-hyphens: manual;
14367        hyphens: manual;
14368      }
14369      "#,
14370      indoc! {r#"
14371      .foo {
14372        hyphens: manual;
14373      }
14374      "#},
14375      Browsers {
14376        chrome: Some(88 << 16),
14377        firefox: Some(88 << 16),
14378        edge: Some(79 << 16),
14379        ..Browsers::default()
14380      },
14381    );
14382  }
14383
14384  #[test]
14385  fn test_text_align() {
14386    minify_test(".foo { text-align: left }", ".foo{text-align:left}");
14387    minify_test(".foo { text-align: Left }", ".foo{text-align:left}");
14388    minify_test(".foo { text-align: END }", ".foo{text-align:end}");
14389    minify_test(".foo { text-align: left }", ".foo{text-align:left}");
14390
14391    prefix_test(
14392      r#"
14393      .foo {
14394        text-align: start;
14395      }
14396    "#,
14397      indoc! {r#"
14398      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
14399        text-align: left;
14400      }
14401
14402      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
14403        text-align: right;
14404      }
14405    "#
14406      },
14407      Browsers {
14408        safari: Some(2 << 16),
14409        ..Browsers::default()
14410      },
14411    );
14412
14413    prefix_test(
14414      r#"
14415      .foo {
14416        text-align: end;
14417      }
14418    "#,
14419      indoc! {r#"
14420      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
14421        text-align: right;
14422      }
14423
14424      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
14425        text-align: left;
14426      }
14427    "#
14428      },
14429      Browsers {
14430        safari: Some(2 << 16),
14431        ..Browsers::default()
14432      },
14433    );
14434
14435    prefix_test(
14436      r#"
14437      .foo {
14438        text-align: start;
14439      }
14440    "#,
14441      indoc! {r#"
14442      .foo {
14443        text-align: start;
14444      }
14445    "#
14446      },
14447      Browsers {
14448        safari: Some(14 << 16),
14449        ..Browsers::default()
14450      },
14451    );
14452
14453    prefix_test(
14454      r#"
14455      .foo > .bar {
14456        text-align: start;
14457      }
14458    "#,
14459      indoc! {r#"
14460      .foo > .bar:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
14461        text-align: left;
14462      }
14463
14464      .foo > .bar:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
14465        text-align: right;
14466      }
14467    "#
14468      },
14469      Browsers {
14470        safari: Some(2 << 16),
14471        ..Browsers::default()
14472      },
14473    );
14474
14475    prefix_test(
14476      r#"
14477      .foo:after {
14478        text-align: start;
14479      }
14480    "#,
14481      indoc! {r#"
14482      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))):after {
14483        text-align: left;
14484      }
14485
14486      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)):after {
14487        text-align: right;
14488      }
14489    "#
14490      },
14491      Browsers {
14492        safari: Some(2 << 16),
14493        ..Browsers::default()
14494      },
14495    );
14496
14497    prefix_test(
14498      r#"
14499      .foo:hover {
14500        text-align: start;
14501      }
14502    "#,
14503      indoc! {r#"
14504      .foo:hover:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
14505        text-align: left;
14506      }
14507
14508      .foo:hover:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
14509        text-align: right;
14510      }
14511    "#
14512      },
14513      Browsers {
14514        safari: Some(2 << 16),
14515        ..Browsers::default()
14516      },
14517    );
14518  }
14519
14520  #[test]
14521  fn test_text_align_last() {
14522    minify_test(".foo { text-align-last: left }", ".foo{text-align-last:left}");
14523    minify_test(".foo { text-align-last: justify }", ".foo{text-align-last:justify}");
14524    prefix_test(
14525      ".foo{ text-align-last: left }",
14526      indoc! {r#"
14527      .foo {
14528        -moz-text-align-last: left;
14529        text-align-last: left;
14530      }
14531      "#},
14532      Browsers {
14533        firefox: Some(40 << 16),
14534        ..Browsers::default()
14535      },
14536    );
14537    prefix_test(
14538      r#"
14539      .foo {
14540        -moz-text-align-last: left;
14541        text-align-last: left;
14542      }
14543      "#,
14544      indoc! {r#"
14545      .foo {
14546        text-align-last: left;
14547      }
14548      "#},
14549      Browsers {
14550        firefox: Some(88 << 16),
14551        ..Browsers::default()
14552      },
14553    );
14554  }
14555
14556  #[test]
14557  fn test_text_justify() {
14558    minify_test(".foo { text-justify: auto }", ".foo{text-justify:auto}");
14559    minify_test(".foo { text-justify: inter-word }", ".foo{text-justify:inter-word}");
14560  }
14561
14562  #[test]
14563  fn test_word_spacing() {
14564    minify_test(".foo { word-spacing: normal }", ".foo{word-spacing:normal}");
14565    minify_test(".foo { word-spacing: 3px }", ".foo{word-spacing:3px}");
14566  }
14567
14568  #[test]
14569  fn test_letter_spacing() {
14570    minify_test(".foo { letter-spacing: normal }", ".foo{letter-spacing:normal}");
14571    minify_test(".foo { letter-spacing: 3px }", ".foo{letter-spacing:3px}");
14572  }
14573
14574  #[test]
14575  fn test_text_indent() {
14576    minify_test(".foo { text-indent: 20px }", ".foo{text-indent:20px}");
14577    minify_test(".foo { text-indent: 10% }", ".foo{text-indent:10%}");
14578    minify_test(".foo { text-indent: 3em hanging }", ".foo{text-indent:3em hanging}");
14579    minify_test(".foo { text-indent: 3em each-line }", ".foo{text-indent:3em each-line}");
14580    minify_test(
14581      ".foo { text-indent: 3em hanging each-line }",
14582      ".foo{text-indent:3em hanging each-line}",
14583    );
14584    minify_test(
14585      ".foo { text-indent: 3em each-line hanging }",
14586      ".foo{text-indent:3em hanging each-line}",
14587    );
14588    minify_test(
14589      ".foo { text-indent: each-line 3em hanging }",
14590      ".foo{text-indent:3em hanging each-line}",
14591    );
14592    minify_test(
14593      ".foo { text-indent: each-line hanging 3em }",
14594      ".foo{text-indent:3em hanging each-line}",
14595    );
14596  }
14597
14598  #[test]
14599  fn test_text_size_adjust() {
14600    minify_test(".foo { text-size-adjust: none }", ".foo{text-size-adjust:none}");
14601    minify_test(".foo { text-size-adjust: auto }", ".foo{text-size-adjust:auto}");
14602    minify_test(".foo { text-size-adjust: 80% }", ".foo{text-size-adjust:80%}");
14603    prefix_test(
14604      r#"
14605      .foo {
14606        text-size-adjust: none;
14607      }
14608    "#,
14609      indoc! {r#"
14610      .foo {
14611        -webkit-text-size-adjust: none;
14612        -moz-text-size-adjust: none;
14613        -ms-text-size-adjust: none;
14614        text-size-adjust: none;
14615      }
14616    "#},
14617      Browsers {
14618        ios_saf: Some(16 << 16),
14619        edge: Some(15 << 16),
14620        firefox: Some(20 << 16),
14621        ..Browsers::default()
14622      },
14623    );
14624    prefix_test(
14625      r#"
14626      .foo {
14627        -webkit-text-size-adjust: none;
14628        -moz-text-size-adjust: none;
14629        -ms-text-size-adjust: none;
14630        text-size-adjust: none;
14631      }
14632    "#,
14633      indoc! {r#"
14634      .foo {
14635        text-size-adjust: none;
14636      }
14637    "#},
14638      Browsers {
14639        chrome: Some(110 << 16),
14640        ..Browsers::default()
14641      },
14642    );
14643  }
14644
14645  #[test]
14646  fn test_text_decoration() {
14647    minify_test(".foo { text-decoration-line: none }", ".foo{text-decoration-line:none}");
14648    minify_test(
14649      ".foo { text-decoration-line: underline }",
14650      ".foo{text-decoration-line:underline}",
14651    );
14652    minify_test(
14653      ".foo { text-decoration-line: overline }",
14654      ".foo{text-decoration-line:overline}",
14655    );
14656    minify_test(
14657      ".foo { text-decoration-line: line-through }",
14658      ".foo{text-decoration-line:line-through}",
14659    );
14660    minify_test(
14661      ".foo { text-decoration-line: blink }",
14662      ".foo{text-decoration-line:blink}",
14663    );
14664    minify_test(
14665      ".foo { text-decoration-line: underline overline }",
14666      ".foo{text-decoration-line:underline overline}",
14667    );
14668    minify_test(
14669      ".foo { text-decoration-line: overline underline }",
14670      ".foo{text-decoration-line:underline overline}",
14671    );
14672    minify_test(
14673      ".foo { text-decoration-line: overline line-through underline }",
14674      ".foo{text-decoration-line:underline overline line-through}",
14675    );
14676    minify_test(
14677      ".foo { text-decoration-line: spelling-error }",
14678      ".foo{text-decoration-line:spelling-error}",
14679    );
14680    minify_test(
14681      ".foo { text-decoration-line: grammar-error }",
14682      ".foo{text-decoration-line:grammar-error}",
14683    );
14684    minify_test(
14685      ".foo { -webkit-text-decoration-line: overline underline }",
14686      ".foo{-webkit-text-decoration-line:underline overline}",
14687    );
14688    minify_test(
14689      ".foo { -moz-text-decoration-line: overline underline }",
14690      ".foo{-moz-text-decoration-line:underline overline}",
14691    );
14692
14693    minify_test(
14694      ".foo { text-decoration-style: solid }",
14695      ".foo{text-decoration-style:solid}",
14696    );
14697    minify_test(
14698      ".foo { text-decoration-style: dotted }",
14699      ".foo{text-decoration-style:dotted}",
14700    );
14701    minify_test(
14702      ".foo { -webkit-text-decoration-style: solid }",
14703      ".foo{-webkit-text-decoration-style:solid}",
14704    );
14705
14706    minify_test(
14707      ".foo { text-decoration-color: yellow }",
14708      ".foo{text-decoration-color:#ff0}",
14709    );
14710    minify_test(
14711      ".foo { -webkit-text-decoration-color: yellow }",
14712      ".foo{-webkit-text-decoration-color:#ff0}",
14713    );
14714
14715    minify_test(".foo { text-decoration: none }", ".foo{text-decoration:none}");
14716    minify_test(
14717      ".foo { text-decoration: underline dotted }",
14718      ".foo{text-decoration:underline dotted}",
14719    );
14720    minify_test(
14721      ".foo { text-decoration: underline dotted yellow }",
14722      ".foo{text-decoration:underline dotted #ff0}",
14723    );
14724    minify_test(
14725      ".foo { text-decoration: yellow dotted underline }",
14726      ".foo{text-decoration:underline dotted #ff0}",
14727    );
14728    minify_test(
14729      ".foo { text-decoration: underline overline dotted yellow }",
14730      ".foo{text-decoration:underline overline dotted #ff0}",
14731    );
14732    minify_test(
14733      ".foo { -webkit-text-decoration: yellow dotted underline }",
14734      ".foo{-webkit-text-decoration:underline dotted #ff0}",
14735    );
14736    minify_test(
14737      ".foo { -moz-text-decoration: yellow dotted underline }",
14738      ".foo{-moz-text-decoration:underline dotted #ff0}",
14739    );
14740
14741    test(
14742      r#"
14743      .foo {
14744        text-decoration-line: underline;
14745        text-decoration-style: dotted;
14746        text-decoration-color: yellow;
14747        text-decoration-thickness: 2px;
14748      }
14749    "#,
14750      indoc! {r#"
14751      .foo {
14752        text-decoration: underline 2px dotted #ff0;
14753      }
14754    "#},
14755    );
14756
14757    test(
14758      r#"
14759      .foo {
14760        text-decoration: underline;
14761        text-decoration-style: dotted;
14762      }
14763    "#,
14764      indoc! {r#"
14765      .foo {
14766        text-decoration: underline dotted;
14767      }
14768    "#},
14769    );
14770
14771    test(
14772      r#"
14773      .foo {
14774        text-decoration: underline;
14775        text-decoration-style: var(--style);
14776      }
14777    "#,
14778      indoc! {r#"
14779      .foo {
14780        text-decoration: underline;
14781        text-decoration-style: var(--style);
14782      }
14783    "#},
14784    );
14785
14786    test(
14787      r#"
14788      .foo {
14789        -webkit-text-decoration: underline;
14790        -webkit-text-decoration-style: dotted;
14791      }
14792    "#,
14793      indoc! {r#"
14794      .foo {
14795        -webkit-text-decoration: underline dotted;
14796      }
14797    "#},
14798    );
14799
14800    prefix_test(
14801      r#"
14802      .foo {
14803        text-decoration: underline dotted;
14804      }
14805    "#,
14806      indoc! {r#"
14807      .foo {
14808        -webkit-text-decoration: underline dotted;
14809        text-decoration: underline dotted;
14810      }
14811    "#},
14812      Browsers {
14813        safari: Some(8 << 16),
14814        firefox: Some(30 << 16),
14815        ..Browsers::default()
14816      },
14817    );
14818
14819    prefix_test(
14820      r#"
14821      .foo {
14822        text-decoration-line: underline;
14823      }
14824    "#,
14825      indoc! {r#"
14826      .foo {
14827        -webkit-text-decoration-line: underline;
14828        -moz-text-decoration-line: underline;
14829        text-decoration-line: underline;
14830      }
14831    "#},
14832      Browsers {
14833        safari: Some(8 << 16),
14834        firefox: Some(30 << 16),
14835        ..Browsers::default()
14836      },
14837    );
14838
14839    prefix_test(
14840      r#"
14841      .foo {
14842        text-decoration-style: dotted;
14843      }
14844    "#,
14845      indoc! {r#"
14846      .foo {
14847        -webkit-text-decoration-style: dotted;
14848        -moz-text-decoration-style: dotted;
14849        text-decoration-style: dotted;
14850      }
14851    "#},
14852      Browsers {
14853        safari: Some(8 << 16),
14854        firefox: Some(30 << 16),
14855        ..Browsers::default()
14856      },
14857    );
14858
14859    prefix_test(
14860      r#"
14861      .foo {
14862        text-decoration-color: yellow;
14863      }
14864    "#,
14865      indoc! {r#"
14866      .foo {
14867        -webkit-text-decoration-color: #ff0;
14868        -moz-text-decoration-color: #ff0;
14869        text-decoration-color: #ff0;
14870      }
14871    "#},
14872      Browsers {
14873        safari: Some(8 << 16),
14874        firefox: Some(30 << 16),
14875        ..Browsers::default()
14876      },
14877    );
14878
14879    prefix_test(
14880      r#"
14881      .foo {
14882        text-decoration: underline;
14883      }
14884    "#,
14885      indoc! {r#"
14886      .foo {
14887        text-decoration: underline;
14888      }
14889    "#},
14890      Browsers {
14891        safari: Some(8 << 16),
14892        firefox: Some(30 << 16),
14893        ..Browsers::default()
14894      },
14895    );
14896
14897    prefix_test(
14898      r#"
14899      .foo {
14900        -webkit-text-decoration: underline dotted;
14901        text-decoration: underline dotted;
14902      }
14903    "#,
14904      indoc! {r#"
14905      .foo {
14906        -webkit-text-decoration: underline dotted;
14907        text-decoration: underline dotted;
14908      }
14909    "#},
14910      Browsers {
14911        safari: Some(14 << 16),
14912        firefox: Some(45 << 16),
14913        ..Browsers::default()
14914      },
14915    );
14916
14917    prefix_test(
14918      r#"
14919      .foo {
14920        text-decoration: double underline;
14921      }
14922    "#,
14923      indoc! {r#"
14924      .foo {
14925        -webkit-text-decoration: underline double;
14926        text-decoration: underline double;
14927      }
14928    "#},
14929      Browsers {
14930        safari: Some(16 << 16),
14931        ..Browsers::default()
14932      },
14933    );
14934
14935    prefix_test(
14936      r#"
14937      .foo {
14938        text-decoration: underline;
14939        text-decoration-style: double;
14940      }
14941    "#,
14942      indoc! {r#"
14943      .foo {
14944        -webkit-text-decoration: underline double;
14945        text-decoration: underline double;
14946      }
14947    "#},
14948      Browsers {
14949        safari: Some(16 << 16),
14950        ..Browsers::default()
14951      },
14952    );
14953
14954    prefix_test(
14955      r#"
14956      .foo {
14957        text-decoration: underline;
14958        text-decoration-color: red;
14959      }
14960    "#,
14961      indoc! {r#"
14962      .foo {
14963        -webkit-text-decoration: underline red;
14964        text-decoration: underline red;
14965      }
14966    "#},
14967      Browsers {
14968        safari: Some(16 << 16),
14969        ..Browsers::default()
14970      },
14971    );
14972
14973    prefix_test(
14974      r#"
14975      .foo {
14976        text-decoration: var(--test);
14977      }
14978    "#,
14979      indoc! {r#"
14980      .foo {
14981        -webkit-text-decoration: var(--test);
14982        text-decoration: var(--test);
14983      }
14984    "#},
14985      Browsers {
14986        safari: Some(8 << 16),
14987        firefox: Some(30 << 16),
14988        ..Browsers::default()
14989      },
14990    );
14991
14992    minify_test(
14993      ".foo { text-decoration-skip-ink: all }",
14994      ".foo{text-decoration-skip-ink:all}",
14995    );
14996    minify_test(
14997      ".foo { -webkit-text-decoration-skip-ink: all }",
14998      ".foo{-webkit-text-decoration-skip-ink:all}",
14999    );
15000
15001    prefix_test(
15002      r#"
15003      .foo {
15004        text-decoration: lch(50.998% 135.363 338) underline;
15005      }
15006    "#,
15007      indoc! {r#"
15008      .foo {
15009        -webkit-text-decoration: underline #ee00be;
15010        text-decoration: underline #ee00be;
15011        -webkit-text-decoration: underline lch(50.998% 135.363 338);
15012        text-decoration: underline lch(50.998% 135.363 338);
15013      }
15014    "#},
15015      Browsers {
15016        safari: Some(8 << 16),
15017        firefox: Some(30 << 16),
15018        ..Browsers::default()
15019      },
15020    );
15021
15022    prefix_test(
15023      r#"
15024      .foo {
15025        text-decoration-color: lch(50.998% 135.363 338);
15026      }
15027    "#,
15028      indoc! {r#"
15029      .foo {
15030        -webkit-text-decoration-color: #ee00be;
15031        -moz-text-decoration-color: #ee00be;
15032        text-decoration-color: #ee00be;
15033        -webkit-text-decoration-color: lch(50.998% 135.363 338);
15034        -moz-text-decoration-color: lch(50.998% 135.363 338);
15035        text-decoration-color: lch(50.998% 135.363 338);
15036      }
15037    "#},
15038      Browsers {
15039        safari: Some(8 << 16),
15040        firefox: Some(30 << 16),
15041        ..Browsers::default()
15042      },
15043    );
15044
15045    prefix_test(
15046      r#"
15047      .foo {
15048        text-decoration: lch(50.998% 135.363 338) var(--style);
15049      }
15050    "#,
15051      indoc! {r#"
15052      .foo {
15053        text-decoration: #ee00be var(--style);
15054      }
15055
15056      @supports (color: lab(0% 0 0)) {
15057        .foo {
15058          text-decoration: lab(50.998% 125.506 -50.7078) var(--style);
15059        }
15060      }
15061    "#},
15062      Browsers {
15063        chrome: Some(90 << 16),
15064        ..Browsers::default()
15065      },
15066    );
15067
15068    prefix_test(
15069      r#"
15070      .foo {
15071        text-decoration: underline 10px;
15072      }
15073    "#,
15074      indoc! {r#"
15075      .foo {
15076        text-decoration: underline;
15077        text-decoration-thickness: 10px;
15078      }
15079    "#},
15080      Browsers {
15081        safari: Some(15 << 16),
15082        ..Browsers::default()
15083      },
15084    );
15085
15086    prefix_test(
15087      r#"
15088      .foo {
15089        text-decoration: underline 10px;
15090      }
15091    "#,
15092      indoc! {r#"
15093      .foo {
15094        text-decoration: underline 10px;
15095      }
15096    "#},
15097      Browsers {
15098        chrome: Some(90 << 16),
15099        ..Browsers::default()
15100      },
15101    );
15102
15103    prefix_test(
15104      r#"
15105      .foo {
15106        text-decoration: underline 10%;
15107      }
15108    "#,
15109      indoc! {r#"
15110      .foo {
15111        text-decoration: underline;
15112        text-decoration-thickness: calc(1em / 10);
15113      }
15114    "#},
15115      Browsers {
15116        safari: Some(12 << 16),
15117        ..Browsers::default()
15118      },
15119    );
15120
15121    prefix_test(
15122      r#"
15123      .foo {
15124        text-decoration: underline 10%;
15125      }
15126    "#,
15127      indoc! {r#"
15128      .foo {
15129        text-decoration: underline 10%;
15130      }
15131    "#},
15132      Browsers {
15133        firefox: Some(89 << 16),
15134        ..Browsers::default()
15135      },
15136    );
15137
15138    prefix_test(
15139      r#"
15140      .foo {
15141        text-decoration-thickness: 10%;
15142      }
15143    "#,
15144      indoc! {r#"
15145      .foo {
15146        text-decoration-thickness: calc(1em / 10);
15147      }
15148    "#},
15149      Browsers {
15150        safari: Some(12 << 16),
15151        ..Browsers::default()
15152      },
15153    );
15154
15155    prefix_test(
15156      r#"
15157      .foo {
15158        text-decoration-thickness: 10%;
15159      }
15160    "#,
15161      indoc! {r#"
15162      .foo {
15163        text-decoration-thickness: 10%;
15164      }
15165    "#},
15166      Browsers {
15167        firefox: Some(89 << 16),
15168        ..Browsers::default()
15169      },
15170    );
15171  }
15172
15173  #[test]
15174  fn test_text_emphasis() {
15175    minify_test(".foo { text-emphasis-style: none }", ".foo{text-emphasis-style:none}");
15176    minify_test(
15177      ".foo { text-emphasis-style: filled }",
15178      ".foo{text-emphasis-style:filled}",
15179    );
15180    minify_test(".foo { text-emphasis-style: open }", ".foo{text-emphasis-style:open}");
15181    minify_test(".foo { text-emphasis-style: dot }", ".foo{text-emphasis-style:dot}");
15182    minify_test(
15183      ".foo { text-emphasis-style: filled dot }",
15184      ".foo{text-emphasis-style:dot}",
15185    );
15186    minify_test(
15187      ".foo { text-emphasis-style: dot filled }",
15188      ".foo{text-emphasis-style:dot}",
15189    );
15190    minify_test(
15191      ".foo { text-emphasis-style: open dot }",
15192      ".foo{text-emphasis-style:open dot}",
15193    );
15194    minify_test(
15195      ".foo { text-emphasis-style: dot open }",
15196      ".foo{text-emphasis-style:open dot}",
15197    );
15198    minify_test(".foo { text-emphasis-style: \"x\" }", ".foo{text-emphasis-style:\"x\"}");
15199
15200    minify_test(".foo { text-emphasis-color: yellow }", ".foo{text-emphasis-color:#ff0}");
15201
15202    minify_test(".foo { text-emphasis: none }", ".foo{text-emphasis:none}");
15203    minify_test(".foo { text-emphasis: filled }", ".foo{text-emphasis:filled}");
15204    minify_test(
15205      ".foo { text-emphasis: filled yellow }",
15206      ".foo{text-emphasis:filled #ff0}",
15207    );
15208    minify_test(
15209      ".foo { text-emphasis: dot filled yellow }",
15210      ".foo{text-emphasis:dot #ff0}",
15211    );
15212
15213    test(
15214      r#"
15215      .foo {
15216        text-emphasis-style: filled;
15217        text-emphasis-color: yellow;
15218      }
15219    "#,
15220      indoc! {r#"
15221      .foo {
15222        text-emphasis: filled #ff0;
15223      }
15224    "#},
15225    );
15226
15227    test(
15228      r#"
15229      .foo {
15230        text-emphasis: filled red;
15231        text-emphasis-color: yellow;
15232      }
15233    "#,
15234      indoc! {r#"
15235      .foo {
15236        text-emphasis: filled #ff0;
15237      }
15238    "#},
15239    );
15240
15241    test(
15242      r#"
15243      .foo {
15244        text-emphasis: filled yellow;
15245        text-emphasis-color: var(--color);
15246      }
15247    "#,
15248      indoc! {r#"
15249      .foo {
15250        text-emphasis: filled #ff0;
15251        text-emphasis-color: var(--color);
15252      }
15253    "#},
15254    );
15255
15256    prefix_test(
15257      r#"
15258      .foo {
15259        text-emphasis-style: filled;
15260      }
15261    "#,
15262      indoc! {r#"
15263      .foo {
15264        -webkit-text-emphasis-style: filled;
15265        text-emphasis-style: filled;
15266      }
15267    "#},
15268      Browsers {
15269        safari: Some(10 << 16),
15270        chrome: Some(30 << 16),
15271        firefox: Some(45 << 16),
15272        ..Browsers::default()
15273      },
15274    );
15275
15276    prefix_test(
15277      r#"
15278      .foo {
15279        -webkit-text-emphasis-style: filled;
15280        text-emphasis-style: filled;
15281      }
15282    "#,
15283      indoc! {r#"
15284      .foo {
15285        text-emphasis-style: filled;
15286      }
15287    "#},
15288      Browsers {
15289        safari: Some(10 << 16),
15290        firefox: Some(45 << 16),
15291        ..Browsers::default()
15292      },
15293    );
15294
15295    minify_test(
15296      ".foo { text-emphasis-position: over }",
15297      ".foo{text-emphasis-position:over}",
15298    );
15299    minify_test(
15300      ".foo { text-emphasis-position: under }",
15301      ".foo{text-emphasis-position:under}",
15302    );
15303    minify_test(
15304      ".foo { text-emphasis-position: over right }",
15305      ".foo{text-emphasis-position:over}",
15306    );
15307    minify_test(
15308      ".foo { text-emphasis-position: over left }",
15309      ".foo{text-emphasis-position:over left}",
15310    );
15311
15312    prefix_test(
15313      r#"
15314      .foo {
15315        text-emphasis-position: over;
15316      }
15317    "#,
15318      indoc! {r#"
15319      .foo {
15320        -webkit-text-emphasis-position: over;
15321        text-emphasis-position: over;
15322      }
15323    "#},
15324      Browsers {
15325        safari: Some(10 << 16),
15326        chrome: Some(30 << 16),
15327        firefox: Some(45 << 16),
15328        ..Browsers::default()
15329      },
15330    );
15331
15332    prefix_test(
15333      r#"
15334      .foo {
15335        text-emphasis-position: over left;
15336      }
15337    "#,
15338      indoc! {r#"
15339      .foo {
15340        text-emphasis-position: over left;
15341      }
15342    "#},
15343      Browsers {
15344        safari: Some(10 << 16),
15345        chrome: Some(30 << 16),
15346        firefox: Some(45 << 16),
15347        ..Browsers::default()
15348      },
15349    );
15350
15351    prefix_test(
15352      r#"
15353      .foo {
15354        text-emphasis-position: var(--test);
15355      }
15356    "#,
15357      indoc! {r#"
15358      .foo {
15359        -webkit-text-emphasis-position: var(--test);
15360        text-emphasis-position: var(--test);
15361      }
15362    "#},
15363      Browsers {
15364        safari: Some(10 << 16),
15365        chrome: Some(30 << 16),
15366        firefox: Some(45 << 16),
15367        ..Browsers::default()
15368      },
15369    );
15370
15371    prefix_test(
15372      r#"
15373      .foo {
15374        text-emphasis: filled lch(50.998% 135.363 338);
15375      }
15376    "#,
15377      indoc! {r#"
15378      .foo {
15379        -webkit-text-emphasis: filled #ee00be;
15380        text-emphasis: filled #ee00be;
15381        -webkit-text-emphasis: filled lch(50.998% 135.363 338);
15382        text-emphasis: filled lch(50.998% 135.363 338);
15383      }
15384    "#},
15385      Browsers {
15386        chrome: Some(25 << 16),
15387        firefox: Some(48 << 16),
15388        ..Browsers::default()
15389      },
15390    );
15391
15392    prefix_test(
15393      r#"
15394      .foo {
15395        text-emphasis-color: lch(50.998% 135.363 338);
15396      }
15397    "#,
15398      indoc! {r#"
15399      .foo {
15400        -webkit-text-emphasis-color: #ee00be;
15401        text-emphasis-color: #ee00be;
15402        -webkit-text-emphasis-color: lch(50.998% 135.363 338);
15403        text-emphasis-color: lch(50.998% 135.363 338);
15404      }
15405    "#},
15406      Browsers {
15407        chrome: Some(25 << 16),
15408        firefox: Some(48 << 16),
15409        ..Browsers::default()
15410      },
15411    );
15412
15413    prefix_test(
15414      r#"
15415      .foo {
15416        text-emphasis: lch(50.998% 135.363 338) var(--style);
15417      }
15418    "#,
15419      indoc! {r#"
15420      .foo {
15421        text-emphasis: #ee00be var(--style);
15422      }
15423
15424      @supports (color: lab(0% 0 0)) {
15425        .foo {
15426          text-emphasis: lab(50.998% 125.506 -50.7078) var(--style);
15427        }
15428      }
15429    "#},
15430      Browsers {
15431        safari: Some(8 << 16),
15432        ..Browsers::default()
15433      },
15434    );
15435  }
15436
15437  #[test]
15438  fn test_text_shadow() {
15439    minify_test(
15440      ".foo { text-shadow: 1px 1px 2px yellow; }",
15441      ".foo{text-shadow:1px 1px 2px #ff0}",
15442    );
15443    minify_test(
15444      ".foo { text-shadow: 1px 1px 2px 3px yellow; }",
15445      ".foo{text-shadow:1px 1px 2px 3px #ff0}",
15446    );
15447    minify_test(
15448      ".foo { text-shadow: 1px 1px 0 yellow; }",
15449      ".foo{text-shadow:1px 1px #ff0}",
15450    );
15451    minify_test(
15452      ".foo { text-shadow: 1px 1px yellow; }",
15453      ".foo{text-shadow:1px 1px #ff0}",
15454    );
15455    minify_test(
15456      ".foo { text-shadow: 1px 1px yellow, 2px 3px red; }",
15457      ".foo{text-shadow:1px 1px #ff0,2px 3px red}",
15458    );
15459
15460    prefix_test(
15461      ".foo { text-shadow: 12px 12px lab(40% 56.6 39) }",
15462      indoc! { r#"
15463        .foo {
15464          text-shadow: 12px 12px #b32323;
15465          text-shadow: 12px 12px lab(40% 56.6 39);
15466        }
15467      "#},
15468      Browsers {
15469        chrome: Some(4 << 16),
15470        ..Browsers::default()
15471      },
15472    );
15473
15474    prefix_test(
15475      ".foo { text-shadow: 12px 12px lab(40% 56.6 39) }",
15476      indoc! { r#"
15477        .foo {
15478          text-shadow: 12px 12px #b32323;
15479          text-shadow: 12px 12px color(display-p3 .643308 .192455 .167712);
15480          text-shadow: 12px 12px lab(40% 56.6 39);
15481        }
15482      "#},
15483      Browsers {
15484        chrome: Some(90 << 16),
15485        safari: Some(14 << 16),
15486        ..Browsers::default()
15487      },
15488    );
15489
15490    prefix_test(
15491      ".foo { text-shadow: 12px 12px lab(40% 56.6 39), 12px 12px yellow }",
15492      indoc! { r#"
15493        .foo {
15494          text-shadow: 12px 12px #b32323, 12px 12px #ff0;
15495          text-shadow: 12px 12px lab(40% 56.6 39), 12px 12px #ff0;
15496        }
15497      "#},
15498      Browsers {
15499        chrome: Some(4 << 16),
15500        ..Browsers::default()
15501      },
15502    );
15503
15504    prefix_test(
15505      ".foo { text-shadow: var(--foo) 12px lab(40% 56.6 39) }",
15506      indoc! { r#"
15507        .foo {
15508          text-shadow: var(--foo) 12px #b32323;
15509        }
15510
15511        @supports (color: lab(0% 0 0)) {
15512          .foo {
15513            text-shadow: var(--foo) 12px lab(40% 56.6 39);
15514          }
15515        }
15516      "#},
15517      Browsers {
15518        chrome: Some(4 << 16),
15519        ..Browsers::default()
15520      },
15521    );
15522  }
15523
15524  #[test]
15525  fn test_break() {
15526    prefix_test(
15527      r#"
15528      .foo {
15529        box-decoration-break: clone;
15530      }
15531    "#,
15532      indoc! {r#"
15533      .foo {
15534        -webkit-box-decoration-break: clone;
15535        box-decoration-break: clone;
15536      }
15537    "#},
15538      Browsers {
15539        safari: Some(15 << 16),
15540        ..Browsers::default()
15541      },
15542    );
15543
15544    prefix_test(
15545      r#"
15546      .foo {
15547        box-decoration-break: clone;
15548      }
15549    "#,
15550      indoc! {r#"
15551      .foo {
15552        box-decoration-break: clone;
15553      }
15554    "#},
15555      Browsers {
15556        firefox: Some(95 << 16),
15557        ..Browsers::default()
15558      },
15559    );
15560  }
15561
15562  #[test]
15563  fn test_position() {
15564    test(
15565      r#"
15566      .foo {
15567        position: relative;
15568        position: absolute;
15569      }
15570    "#,
15571      indoc! {r#"
15572      .foo {
15573        position: absolute;
15574      }
15575    "#},
15576    );
15577
15578    test(
15579      r#"
15580      .foo {
15581        position: -webkit-sticky;
15582        position: sticky;
15583      }
15584    "#,
15585      indoc! {r#"
15586      .foo {
15587        position: -webkit-sticky;
15588        position: sticky;
15589      }
15590    "#},
15591    );
15592
15593    prefix_test(
15594      r#"
15595      .foo {
15596        position: sticky;
15597      }
15598    "#,
15599      indoc! {r#"
15600      .foo {
15601        position: -webkit-sticky;
15602        position: sticky;
15603      }
15604    "#},
15605      Browsers {
15606        safari: Some(8 << 16),
15607        ..Browsers::default()
15608      },
15609    );
15610
15611    prefix_test(
15612      r#"
15613      .foo {
15614        position: -webkit-sticky;
15615        position: sticky;
15616      }
15617    "#,
15618      indoc! {r#"
15619      .foo {
15620        position: sticky;
15621      }
15622    "#},
15623      Browsers {
15624        safari: Some(13 << 16),
15625        ..Browsers::default()
15626      },
15627    );
15628
15629    test(
15630      r#"
15631      .foo {
15632        top: 0;
15633        left: 0;
15634        bottom: 0;
15635        right: 0;
15636      }
15637    "#,
15638      indoc! {r#"
15639      .foo {
15640        inset: 0;
15641      }
15642    "#},
15643    );
15644
15645    test(
15646      r#"
15647      .foo {
15648        top: 2px;
15649        left: 4px;
15650        bottom: 2px;
15651        right: 4px;
15652      }
15653    "#,
15654      indoc! {r#"
15655      .foo {
15656        inset: 2px 4px;
15657      }
15658    "#},
15659    );
15660
15661    test(
15662      r#"
15663      .foo {
15664        top: 1px;
15665        left: 2px;
15666        bottom: 3px;
15667        right: 4px;
15668      }
15669    "#,
15670      indoc! {r#"
15671      .foo {
15672        inset: 1px 4px 3px 2px;
15673      }
15674    "#},
15675    );
15676
15677    test(
15678      r#"
15679      .foo {
15680        inset-block-start: 2px;
15681        inset-block-end: 2px;
15682        inset-inline-start: 4px;
15683        inset-inline-end: 4px;
15684      }
15685    "#,
15686      indoc! {r#"
15687      .foo {
15688        inset-block: 2px;
15689        inset-inline: 4px;
15690      }
15691    "#},
15692    );
15693
15694    test(
15695      r#"
15696      .foo {
15697        inset-block-start: 2px;
15698        inset-block-end: 3px;
15699        inset-inline-start: 4px;
15700        inset-inline-end: 5px;
15701      }
15702    "#,
15703      indoc! {r#"
15704      .foo {
15705        inset-block: 2px 3px;
15706        inset-inline: 4px 5px;
15707      }
15708    "#},
15709    );
15710
15711    test(
15712      r#"
15713      .foo {
15714        inset-block-start: 2px;
15715        inset-block-end: 3px;
15716        inset: 4px;
15717        inset-inline-start: 4px;
15718        inset-inline-end: 5px;
15719      }
15720    "#,
15721      indoc! {r#"
15722      .foo {
15723        inset: 4px;
15724        inset-inline: 4px 5px;
15725      }
15726    "#},
15727    );
15728
15729    prefix_test(
15730      r#"
15731      .foo {
15732        inset-inline-start: 2px;
15733      }
15734    "#,
15735      indoc! {r#"
15736      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
15737        left: 2px;
15738      }
15739
15740      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
15741        left: 2px;
15742      }
15743
15744      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
15745        right: 2px;
15746      }
15747
15748      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
15749        right: 2px;
15750      }
15751    "#
15752      },
15753      Browsers {
15754        safari: Some(8 << 16),
15755        ..Browsers::default()
15756      },
15757    );
15758
15759    prefix_test(
15760      r#"
15761      .foo {
15762        inset-inline-start: 2px;
15763        inset-inline-end: 4px;
15764      }
15765    "#,
15766      indoc! {r#"
15767      .foo:not(:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
15768        left: 2px;
15769        right: 4px;
15770      }
15771
15772      .foo:not(:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi))) {
15773        left: 2px;
15774        right: 4px;
15775      }
15776
15777      .foo:-webkit-any(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
15778        left: 4px;
15779        right: 2px;
15780      }
15781
15782      .foo:is(:lang(ae), :lang(ar), :lang(arc), :lang(bcc), :lang(bqi), :lang(ckb), :lang(dv), :lang(fa), :lang(glk), :lang(he), :lang(ku), :lang(mzn), :lang(nqo), :lang(pnb), :lang(ps), :lang(sd), :lang(ug), :lang(ur), :lang(yi)) {
15783        left: 4px;
15784        right: 2px;
15785      }
15786    "#
15787      },
15788      Browsers {
15789        safari: Some(8 << 16),
15790        ..Browsers::default()
15791      },
15792    );
15793
15794    prefix_test(
15795      r#"
15796      .foo {
15797        inset-inline: 2px;
15798      }
15799    "#,
15800      indoc! {r#"
15801      .foo {
15802        left: 2px;
15803        right: 2px;
15804      }
15805    "#
15806      },
15807      Browsers {
15808        safari: Some(8 << 16),
15809        ..Browsers::default()
15810      },
15811    );
15812
15813    prefix_test(
15814      r#"
15815      .foo {
15816        inset-block-start: 2px;
15817      }
15818    "#,
15819      indoc! {r#"
15820      .foo {
15821        top: 2px;
15822      }
15823    "#
15824      },
15825      Browsers {
15826        safari: Some(8 << 16),
15827        ..Browsers::default()
15828      },
15829    );
15830
15831    prefix_test(
15832      r#"
15833      .foo {
15834        inset-block-end: 2px;
15835      }
15836    "#,
15837      indoc! {r#"
15838      .foo {
15839        bottom: 2px;
15840      }
15841    "#
15842      },
15843      Browsers {
15844        safari: Some(8 << 16),
15845        ..Browsers::default()
15846      },
15847    );
15848
15849    prefix_test(
15850      r#"
15851      .foo {
15852        top: 1px;
15853        left: 2px;
15854        bottom: 3px;
15855        right: 4px;
15856      }
15857    "#,
15858      indoc! {r#"
15859      .foo {
15860        top: 1px;
15861        bottom: 3px;
15862        left: 2px;
15863        right: 4px;
15864      }
15865    "#},
15866      Browsers {
15867        safari: Some(8 << 16),
15868        ..Browsers::default()
15869      },
15870    );
15871  }
15872
15873  #[test]
15874  fn test_overflow() {
15875    minify_test(".foo { overflow: hidden }", ".foo{overflow:hidden}");
15876    minify_test(".foo { overflow: hidden hidden }", ".foo{overflow:hidden}");
15877    minify_test(".foo { overflow: hidden auto }", ".foo{overflow:hidden auto}");
15878
15879    test(
15880      r#"
15881      .foo {
15882        overflow-x: hidden;
15883        overflow-y: auto;
15884      }
15885    "#,
15886      indoc! {r#"
15887      .foo {
15888        overflow: hidden auto;
15889      }
15890    "#},
15891    );
15892
15893    test(
15894      r#"
15895      .foo {
15896        overflow: hidden;
15897        overflow-y: auto;
15898      }
15899    "#,
15900      indoc! {r#"
15901      .foo {
15902        overflow: hidden auto;
15903      }
15904    "#},
15905    );
15906    test(
15907      r#"
15908      .foo {
15909        overflow: hidden;
15910        overflow-y: var(--y);
15911      }
15912    "#,
15913      indoc! {r#"
15914      .foo {
15915        overflow: hidden;
15916        overflow-y: var(--y);
15917      }
15918    "#},
15919    );
15920    prefix_test(
15921      r#"
15922      .foo {
15923        overflow: hidden auto;
15924      }
15925    "#,
15926      indoc! {r#"
15927      .foo {
15928        overflow-x: hidden;
15929        overflow-y: auto;
15930      }
15931    "#},
15932      Browsers {
15933        chrome: Some(67 << 16),
15934        ..Browsers::default()
15935      },
15936    );
15937    prefix_test(
15938      r#"
15939      .foo {
15940        overflow: hidden hidden;
15941      }
15942    "#,
15943      indoc! {r#"
15944      .foo {
15945        overflow: hidden;
15946      }
15947    "#},
15948      Browsers {
15949        chrome: Some(67 << 16),
15950        ..Browsers::default()
15951      },
15952    );
15953    prefix_test(
15954      r#"
15955      .foo {
15956        overflow: hidden auto;
15957      }
15958    "#,
15959      indoc! {r#"
15960      .foo {
15961        overflow: hidden auto;
15962      }
15963    "#},
15964      Browsers {
15965        chrome: Some(68 << 16),
15966        ..Browsers::default()
15967      },
15968    );
15969
15970    minify_test(".foo { text-overflow: ellipsis }", ".foo{text-overflow:ellipsis}");
15971    prefix_test(
15972      r#"
15973      .foo {
15974        text-overflow: ellipsis;
15975      }
15976    "#,
15977      indoc! {r#"
15978      .foo {
15979        -o-text-overflow: ellipsis;
15980        text-overflow: ellipsis;
15981      }
15982    "#},
15983      Browsers {
15984        safari: Some(4 << 16),
15985        opera: Some(10 << 16),
15986        ..Browsers::default()
15987      },
15988    );
15989
15990    prefix_test(
15991      r#"
15992      .foo {
15993        -o-text-overflow: ellipsis;
15994        text-overflow: ellipsis;
15995      }
15996    "#,
15997      indoc! {r#"
15998      .foo {
15999        text-overflow: ellipsis;
16000      }
16001    "#},
16002      Browsers {
16003        safari: Some(4 << 16),
16004        opera: Some(14 << 16),
16005        ..Browsers::default()
16006      },
16007    );
16008  }
16009
16010  #[test]
16011  fn test_ui() {
16012    minify_test(".foo { resize: both }", ".foo{resize:both}");
16013    minify_test(".foo { resize: Horizontal }", ".foo{resize:horizontal}");
16014    minify_test(".foo { cursor: ew-resize }", ".foo{cursor:ew-resize}");
16015    minify_test(
16016      ".foo { cursor: url(\"test.cur\"), ew-resize }",
16017      ".foo{cursor:url(test.cur),ew-resize}",
16018    );
16019    minify_test(
16020      ".foo { cursor: url(\"test.cur\"), url(\"foo.cur\"), ew-resize }",
16021      ".foo{cursor:url(test.cur),url(foo.cur),ew-resize}",
16022    );
16023    minify_test(".foo { caret-color: auto }", ".foo{caret-color:auto}");
16024    minify_test(".foo { caret-color: yellow }", ".foo{caret-color:#ff0}");
16025    minify_test(".foo { caret-shape: block }", ".foo{caret-shape:block}");
16026    minify_test(".foo { caret: yellow block }", ".foo{caret:#ff0 block}");
16027    minify_test(".foo { caret: block yellow }", ".foo{caret:#ff0 block}");
16028    minify_test(".foo { caret: block }", ".foo{caret:block}");
16029    minify_test(".foo { caret: yellow }", ".foo{caret:#ff0}");
16030    minify_test(".foo { caret: auto auto }", ".foo{caret:auto}");
16031    minify_test(".foo { caret: auto }", ".foo{caret:auto}");
16032    minify_test(".foo { caret: yellow auto }", ".foo{caret:#ff0}");
16033    minify_test(".foo { caret: auto block }", ".foo{caret:block}");
16034    minify_test(".foo { user-select: none }", ".foo{user-select:none}");
16035    minify_test(".foo { -webkit-user-select: none }", ".foo{-webkit-user-select:none}");
16036    minify_test(".foo { accent-color: auto }", ".foo{accent-color:auto}");
16037    minify_test(".foo { accent-color: yellow }", ".foo{accent-color:#ff0}");
16038    minify_test(".foo { appearance: None }", ".foo{appearance:none}");
16039    minify_test(
16040      ".foo { -webkit-appearance: textfield }",
16041      ".foo{-webkit-appearance:textfield}",
16042    );
16043
16044    prefix_test(
16045      r#"
16046      .foo {
16047        user-select: none;
16048      }
16049    "#,
16050      indoc! {r#"
16051      .foo {
16052        -webkit-user-select: none;
16053        -moz-user-select: none;
16054        -ms-user-select: none;
16055        user-select: none;
16056      }
16057    "#},
16058      Browsers {
16059        safari: Some(8 << 16),
16060        opera: Some(5 << 16),
16061        firefox: Some(10 << 16),
16062        ie: Some(10 << 16),
16063        ..Browsers::default()
16064      },
16065    );
16066
16067    prefix_test(
16068      r#"
16069      .foo {
16070        -webkit-user-select: none;
16071        -moz-user-select: none;
16072        -ms-user-select: none;
16073        user-select: none;
16074      }
16075    "#,
16076      indoc! {r#"
16077      .foo {
16078        -webkit-user-select: none;
16079        user-select: none;
16080      }
16081    "#},
16082      Browsers {
16083        safari: Some(8 << 16),
16084        opera: Some(80 << 16),
16085        firefox: Some(80 << 16),
16086        edge: Some(80 << 16),
16087        ..Browsers::default()
16088      },
16089    );
16090
16091    prefix_test(
16092      r#"
16093      .foo {
16094        -webkit-user-select: none;
16095        -moz-user-select: none;
16096        -ms-user-select: none;
16097        user-select: none;
16098      }
16099    "#,
16100      indoc! {r#"
16101      .foo {
16102        user-select: none;
16103      }
16104    "#},
16105      Browsers {
16106        opera: Some(80 << 16),
16107        firefox: Some(80 << 16),
16108        edge: Some(80 << 16),
16109        ..Browsers::default()
16110      },
16111    );
16112
16113    prefix_test(
16114      r#"
16115      .foo {
16116        appearance: none;
16117      }
16118    "#,
16119      indoc! {r#"
16120      .foo {
16121        -webkit-appearance: none;
16122        -moz-appearance: none;
16123        -ms-appearance: none;
16124        appearance: none;
16125      }
16126    "#},
16127      Browsers {
16128        safari: Some(8 << 16),
16129        chrome: Some(80 << 16),
16130        firefox: Some(10 << 16),
16131        ie: Some(11 << 16),
16132        ..Browsers::default()
16133      },
16134    );
16135
16136    prefix_test(
16137      r#"
16138      .foo {
16139        -webkit-appearance: none;
16140        -moz-appearance: none;
16141        -ms-appearance: none;
16142        appearance: none;
16143      }
16144    "#,
16145      indoc! {r#"
16146      .foo {
16147        -webkit-appearance: none;
16148        appearance: none;
16149      }
16150    "#},
16151      Browsers {
16152        safari: Some(15 << 16),
16153        chrome: Some(85 << 16),
16154        firefox: Some(80 << 16),
16155        edge: Some(85 << 16),
16156        ..Browsers::default()
16157      },
16158    );
16159
16160    prefix_test(
16161      r#"
16162      .foo {
16163        -webkit-appearance: none;
16164        -moz-appearance: none;
16165        -ms-appearance: none;
16166        appearance: none;
16167      }
16168    "#,
16169      indoc! {r#"
16170      .foo {
16171        appearance: none;
16172      }
16173    "#},
16174      Browsers {
16175        chrome: Some(85 << 16),
16176        firefox: Some(80 << 16),
16177        edge: Some(85 << 16),
16178        ..Browsers::default()
16179      },
16180    );
16181
16182    prefix_test(
16183      ".foo { caret-color: lch(50.998% 135.363 338) }",
16184      indoc! { r#"
16185        .foo {
16186          caret-color: #ee00be;
16187          caret-color: color(display-p3 .972962 -.362078 .804206);
16188          caret-color: lch(50.998% 135.363 338);
16189        }
16190      "#},
16191      Browsers {
16192        chrome: Some(90 << 16),
16193        safari: Some(14 << 16),
16194        ..Browsers::default()
16195      },
16196    );
16197
16198    prefix_test(
16199      ".foo { caret: lch(50.998% 135.363 338) block }",
16200      indoc! { r#"
16201        .foo {
16202          caret: #ee00be block;
16203          caret: color(display-p3 .972962 -.362078 .804206) block;
16204          caret: lch(50.998% 135.363 338) block;
16205        }
16206      "#},
16207      Browsers {
16208        chrome: Some(90 << 16),
16209        safari: Some(14 << 16),
16210        ..Browsers::default()
16211      },
16212    );
16213
16214    prefix_test(
16215      ".foo { caret: lch(50.998% 135.363 338) var(--foo) }",
16216      indoc! { r#"
16217        .foo {
16218          caret: #ee00be var(--foo);
16219        }
16220
16221        @supports (color: lab(0% 0 0)) {
16222          .foo {
16223            caret: lab(50.998% 125.506 -50.7078) var(--foo);
16224          }
16225        }
16226      "#},
16227      Browsers {
16228        chrome: Some(90 << 16),
16229        ..Browsers::default()
16230      },
16231    );
16232  }
16233
16234  #[test]
16235  fn test_list() {
16236    minify_test(".foo { list-style-type: disc; }", ".foo{list-style-type:disc}");
16237    minify_test(".foo { list-style-type: \"★\"; }", ".foo{list-style-type:\"★\"}");
16238    minify_test(
16239      ".foo { list-style-type: symbols(cyclic '○' '●'); }",
16240      ".foo{list-style-type:symbols(cyclic \"○\" \"●\")}",
16241    );
16242    minify_test(
16243      ".foo { list-style-type: symbols('○' '●'); }",
16244      ".foo{list-style-type:symbols(\"○\" \"●\")}",
16245    );
16246    minify_test(
16247      ".foo { list-style-type: symbols(symbolic '○' '●'); }",
16248      ".foo{list-style-type:symbols(\"○\" \"●\")}",
16249    );
16250    minify_test(
16251      ".foo { list-style-type: symbols(symbolic url('ellipse.png')); }",
16252      ".foo{list-style-type:symbols(url(ellipse.png))}",
16253    );
16254    minify_test(
16255      ".foo { list-style-image: url('ellipse.png'); }",
16256      ".foo{list-style-image:url(ellipse.png)}",
16257    );
16258    minify_test(
16259      ".foo { list-style-position: outside; }",
16260      ".foo{list-style-position:outside}",
16261    );
16262    minify_test(
16263      ".foo { list-style: \"★\" url(ellipse.png) outside; }",
16264      ".foo{list-style:\"★\" url(ellipse.png)}",
16265    );
16266
16267    test(
16268      r#"
16269      .foo {
16270        list-style-type: disc;
16271        list-style-image: url(ellipse.png);
16272        list-style-position: outside;
16273      }
16274    "#,
16275      indoc! {r#"
16276      .foo {
16277        list-style: url("ellipse.png");
16278      }
16279    "#},
16280    );
16281
16282    test(
16283      r#"
16284      .foo {
16285        list-style: \"★\" url(ellipse.png) outside;
16286        list-style-image: none;
16287      }
16288    "#,
16289      indoc! {r#"
16290      .foo {
16291        list-style: \"★\";
16292      }
16293    "#},
16294    );
16295
16296    test(
16297      r#"
16298      .foo {
16299        list-style: \"★\" url(ellipse.png) outside;
16300        list-style-image: var(--img);
16301      }
16302    "#,
16303      indoc! {r#"
16304      .foo {
16305        list-style: \"★\" url("ellipse.png");
16306        list-style-image: var(--img);
16307      }
16308    "#},
16309    );
16310
16311    prefix_test(
16312      ".foo { list-style-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
16313      indoc! { r#"
16314        .foo {
16315          list-style-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0f0e), to(#7773ff));
16316          list-style-image: -webkit-linear-gradient(#ff0f0e, #7773ff);
16317          list-style-image: linear-gradient(#ff0f0e, #7773ff);
16318          list-style-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
16319        }
16320      "#},
16321      Browsers {
16322        chrome: Some(8 << 16),
16323        ..Browsers::default()
16324      },
16325    );
16326
16327    prefix_test(
16328      ".foo { list-style: \"★\" linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
16329      indoc! { r#"
16330        .foo {
16331          list-style: "★" linear-gradient(#ff0f0e, #7773ff);
16332          list-style: "★" linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
16333        }
16334      "#},
16335      Browsers {
16336        chrome: Some(90 << 16),
16337        ..Browsers::default()
16338      },
16339    );
16340
16341    prefix_test(
16342      ".foo { list-style: var(--foo) linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
16343      indoc! { r#"
16344        .foo {
16345          list-style: var(--foo) linear-gradient(#ff0f0e, #7773ff);
16346        }
16347
16348        @supports (color: lab(0% 0 0)) {
16349          .foo {
16350            list-style: var(--foo) linear-gradient(lab(56.208% 94.4644 98.8928), lab(51% 70.4544 -115.586));
16351          }
16352        }
16353      "#},
16354      Browsers {
16355        chrome: Some(90 << 16),
16356        ..Browsers::default()
16357      },
16358    );
16359  }
16360
16361  #[test]
16362  fn test_image_set() {
16363    // Spec: https://drafts.csswg.org/css-images-4/#image-set-notation
16364    // WPT: https://github.com/web-platform-tests/wpt/blob/master/css/css-images/image-set/image-set-parsing.html
16365    // test image-set(<string>)
16366    minify_test(
16367      ".foo { background: image-set(\"foo.png\" 2x, url(bar.png) 1x) }",
16368      ".foo{background:image-set(\"foo.png\" 2x,\"bar.png\" 1x)}",
16369    );
16370
16371    // test image-set(type(<string>))
16372    minify_test(
16373      ".foo { background: image-set('foo.webp' type('webp'), url(foo.jpg)) }",
16374      ".foo{background:image-set(\"foo.webp\" 1x type(\"webp\"),\"foo.jpg\" 1x)}",
16375    );
16376    minify_test(
16377      ".foo { background: image-set('foo.avif' 2x type('image/avif'), url(foo.png)) }",
16378      ".foo{background:image-set(\"foo.avif\" 2x type(\"image/avif\"),\"foo.png\" 1x)}",
16379    );
16380    minify_test(
16381      ".foo { background: image-set(url('example.png') 3x type('image/png')) }",
16382      ".foo{background:image-set(\"example.png\" 3x type(\"image/png\"))}",
16383    );
16384
16385    minify_test(
16386      ".foo { background: image-set(url(example.png) type('image/png') 1x) }",
16387      ".foo{background:image-set(\"example.png\" 1x type(\"image/png\"))}",
16388    );
16389
16390    minify_test(
16391      ".foo { background: -webkit-image-set(url(\"foo.png\") 2x, url(bar.png) 1x) }",
16392      ".foo{background:-webkit-image-set(url(foo.png) 2x,url(bar.png) 1x)}",
16393    );
16394
16395    test(
16396      r#"
16397      .foo {
16398        background: -webkit-image-set(url("foo.png") 2x, url(bar.png) 1x);
16399        background: image-set(url("foo.png") 2x, url(bar.png) 1x);
16400      }
16401    "#,
16402      indoc! {r#"
16403      .foo {
16404        background: -webkit-image-set(url("foo.png") 2x, url("bar.png") 1x);
16405        background: image-set("foo.png" 2x, "bar.png" 1x);
16406      }
16407    "#},
16408    );
16409
16410    // test image-set(<gradient>)
16411    test(
16412      r#"
16413      .foo {
16414        background: image-set(linear-gradient(cornflowerblue, white) 1x, url("detailed-gradient.png") 3x);
16415      }
16416    "#,
16417      indoc! {r#"
16418      .foo {
16419        background: image-set(linear-gradient(#6495ed, #fff) 1x, "detailed-gradient.png" 3x);
16420      }
16421    "#},
16422    );
16423
16424    prefix_test(
16425      r#"
16426      .foo {
16427        background: image-set(url("foo.png") 2x, url(bar.png) 1x);
16428      }
16429    "#,
16430      indoc! {r#"
16431      .foo {
16432        background: -webkit-image-set(url("foo.png") 2x, url("bar.png") 1x);
16433        background: image-set("foo.png" 2x, "bar.png" 1x);
16434      }
16435    "#},
16436      Browsers {
16437        chrome: Some(85 << 16),
16438        firefox: Some(80 << 16),
16439        ..Browsers::default()
16440      },
16441    );
16442
16443    prefix_test(
16444      r#"
16445      .foo {
16446        background: -webkit-image-set(url("foo.png") 2x, url(bar.png) 1x);
16447        background: image-set(url("foo.png") 2x, url(bar.png) 1x);
16448      }
16449    "#,
16450      indoc! {r#"
16451      .foo {
16452        background: -webkit-image-set(url("foo.png") 2x, url("bar.png") 1x);
16453        background: image-set("foo.png" 2x, "bar.png" 1x);
16454      }
16455    "#},
16456      Browsers {
16457        firefox: Some(80 << 16),
16458        ..Browsers::default()
16459      },
16460    );
16461
16462    prefix_test(
16463      r#"
16464      .foo {
16465        background: -webkit-image-set(url("foo.png") 2x, url(bar.png) 1x);
16466      }
16467    "#,
16468      indoc! {r#"
16469      .foo {
16470        background: -webkit-image-set(url("foo.png") 2x, url("bar.png") 1x);
16471      }
16472    "#},
16473      Browsers {
16474        chrome: Some(95 << 16),
16475        ..Browsers::default()
16476      },
16477    );
16478
16479    for property in &[
16480      "background",
16481      "background-image",
16482      "border-image-source",
16483      "border-image",
16484      "border-image-source",
16485      "-webkit-mask-image",
16486      "-webkit-mask",
16487      "list-style-image",
16488      "list-style",
16489    ] {
16490      prefix_test(
16491        &format!(
16492          r#"
16493        .foo {{
16494          {}: url(foo.png);
16495          {}: image-set(url("foo.png") 2x, url(bar.png) 1x);
16496        }}
16497      "#,
16498          property, property
16499        ),
16500        &format!(
16501          indoc! {r#"
16502        .foo {{
16503          {}: url("foo.png");
16504          {}: image-set("foo.png" 2x, "bar.png" 1x);
16505        }}
16506      "#},
16507          property, property
16508        ),
16509        Browsers {
16510          ie: Some(11 << 16),
16511          chrome: Some(95 << 16),
16512          ..Browsers::default()
16513        },
16514      );
16515
16516      prefix_test(
16517        &format!(
16518          r#"
16519        .foo {{
16520          {}: url(foo.png);
16521          {}: image-set(url("foo.png") 2x, url(bar.png) 1x);
16522        }}
16523      "#,
16524          property, property
16525        ),
16526        &format!(
16527          indoc! {r#"
16528        .foo {{
16529          {}: -webkit-image-set(url("foo.png") 2x, url("bar.png") 1x);
16530          {}: image-set("foo.png" 2x, "bar.png" 1x);
16531        }}
16532      "#},
16533          property, property
16534        ),
16535        Browsers {
16536          chrome: Some(95 << 16),
16537          ..Browsers::default()
16538        },
16539      );
16540    }
16541  }
16542
16543  #[test]
16544  fn test_color() {
16545    minify_test(".foo { color: yellow }", ".foo{color:#ff0}");
16546    minify_test(".foo { color: rgb(255, 255, 0) }", ".foo{color:#ff0}");
16547    minify_test(".foo { color: rgba(255, 255, 0, 1) }", ".foo{color:#ff0}");
16548    minify_test(".foo { color: rgba(255, 255, 0, 0.8) }", ".foo{color:#ff0c}");
16549    minify_test(".foo { color: rgb(128, 128, 128) }", ".foo{color:gray}");
16550    minify_test(".foo { color: rgb(123, 255, 255) }", ".foo{color:#7bffff}");
16551    minify_test(".foo { color: rgba(123, 255, 255, 0.5) }", ".foo{color:#7bffff80}");
16552    minify_test(".foo { color: rgb(123 255 255) }", ".foo{color:#7bffff}");
16553    minify_test(".foo { color: rgb(123 255 255 / .5) }", ".foo{color:#7bffff80}");
16554    minify_test(".foo { color: rgb(123 255 255 / 50%) }", ".foo{color:#7bffff80}");
16555    minify_test(".foo { color: rgb(48% 100% 100% / 50%) }", ".foo{color:#7affff80}");
16556    minify_test(".foo { color: hsl(100deg, 100%, 50%) }", ".foo{color:#5f0}");
16557    minify_test(".foo { color: hsl(100, 100%, 50%) }", ".foo{color:#5f0}");
16558    minify_test(".foo { color: hsl(100 100% 50%) }", ".foo{color:#5f0}");
16559    minify_test(".foo { color: hsl(100, 100%, 50%, .8) }", ".foo{color:#5f0c}");
16560    minify_test(".foo { color: hsl(100 100% 50% / .8) }", ".foo{color:#5f0c}");
16561    minify_test(".foo { color: hsla(100, 100%, 50%, .8) }", ".foo{color:#5f0c}");
16562    minify_test(".foo { color: hsla(100 100% 50% / .8) }", ".foo{color:#5f0c}");
16563    minify_test(".foo { color: transparent }", ".foo{color:#0000}");
16564    minify_test(".foo { color: currentColor }", ".foo{color:currentColor}");
16565    minify_test(".foo { color: ButtonBorder }", ".foo{color:buttonborder}");
16566    minify_test(".foo { color: hwb(194 0% 0%) }", ".foo{color:#00c4ff}");
16567    minify_test(".foo { color: hwb(194 0% 0% / 50%) }", ".foo{color:#00c4ff80}");
16568    minify_test(".foo { color: hwb(194 0% 50%) }", ".foo{color:#006280}");
16569    minify_test(".foo { color: hwb(194 50% 0%) }", ".foo{color:#80e1ff}");
16570    minify_test(".foo { color: hwb(194 50% 50%) }", ".foo{color:gray}");
16571    // minify_test(".foo { color: ActiveText }", ".foo{color:ActiveTet}");
16572    minify_test(
16573      ".foo { color: lab(29.2345% 39.3825 20.0664); }",
16574      ".foo{color:lab(29.2345% 39.3825 20.0664)}",
16575    );
16576    minify_test(
16577      ".foo { color: lab(29.2345% 39.3825 20.0664 / 100%); }",
16578      ".foo{color:lab(29.2345% 39.3825 20.0664)}",
16579    );
16580    minify_test(
16581      ".foo { color: lab(29.2345% 39.3825 20.0664 / 50%); }",
16582      ".foo{color:lab(29.2345% 39.3825 20.0664/.5)}",
16583    );
16584    minify_test(
16585      ".foo { color: lch(29.2345% 44.2 27); }",
16586      ".foo{color:lch(29.2345% 44.2 27)}",
16587    );
16588    minify_test(
16589      ".foo { color: lch(29.2345% 44.2 45deg); }",
16590      ".foo{color:lch(29.2345% 44.2 45)}",
16591    );
16592    minify_test(
16593      ".foo { color: lch(29.2345% 44.2 .5turn); }",
16594      ".foo{color:lch(29.2345% 44.2 180)}",
16595    );
16596    minify_test(
16597      ".foo { color: lch(29.2345% 44.2 27 / 100%); }",
16598      ".foo{color:lch(29.2345% 44.2 27)}",
16599    );
16600    minify_test(
16601      ".foo { color: lch(29.2345% 44.2 27 / 50%); }",
16602      ".foo{color:lch(29.2345% 44.2 27/.5)}",
16603    );
16604    minify_test(
16605      ".foo { color: oklab(40.101% 0.1147 0.0453); }",
16606      ".foo{color:oklab(40.101% .1147 .0453)}",
16607    );
16608    minify_test(
16609      ".foo { color: oklch(40.101% 0.12332 21.555); }",
16610      ".foo{color:oklch(40.101% .12332 21.555)}",
16611    );
16612    minify_test(
16613      ".foo { color: oklch(40.101% 0.12332 .5turn); }",
16614      ".foo{color:oklch(40.101% .12332 180)}",
16615    );
16616    minify_test(
16617      ".foo { color: color(display-p3 1 0.5 0); }",
16618      ".foo{color:color(display-p3 1 .5 0)}",
16619    );
16620    minify_test(
16621      ".foo { color: color(display-p3 100% 50% 0%); }",
16622      ".foo{color:color(display-p3 1 .5 0)}",
16623    );
16624    minify_test(
16625      ".foo { color: color(xyz-d50 0.2005 0.14089 0.4472); }",
16626      ".foo{color:color(xyz-d50 .2005 .14089 .4472)}",
16627    );
16628    minify_test(
16629      ".foo { color: color(xyz-d50 20.05% 14.089% 44.72%); }",
16630      ".foo{color:color(xyz-d50 .2005 .14089 .4472)}",
16631    );
16632    minify_test(
16633      ".foo { color: color(xyz-d65 0.2005 0.14089 0.4472); }",
16634      ".foo{color:color(xyz .2005 .14089 .4472)}",
16635    );
16636    minify_test(
16637      ".foo { color: color(xyz-d65 20.05% 14.089% 44.72%); }",
16638      ".foo{color:color(xyz .2005 .14089 .4472)}",
16639    );
16640    minify_test(
16641      ".foo { color: color(xyz 0.2005 0.14089 0.4472); }",
16642      ".foo{color:color(xyz .2005 .14089 .4472)}",
16643    );
16644    minify_test(
16645      ".foo { color: color(xyz 20.05% 14.089% 44.72%); }",
16646      ".foo{color:color(xyz .2005 .14089 .4472)}",
16647    );
16648    minify_test(
16649      ".foo { color: color(xyz 0.2005 0 0); }",
16650      ".foo{color:color(xyz .2005 0 0)}",
16651    );
16652    minify_test(".foo { color: color(xyz 0 0 0); }", ".foo{color:color(xyz 0 0 0)}");
16653    minify_test(".foo { color: color(xyz 0 1 0); }", ".foo{color:color(xyz 0 1 0)}");
16654    minify_test(
16655      ".foo { color: color(xyz 0 1 0 / 20%); }",
16656      ".foo{color:color(xyz 0 1 0/.2)}",
16657    );
16658    minify_test(
16659      ".foo { color: color(xyz 0 0 0 / 20%); }",
16660      ".foo{color:color(xyz 0 0 0/.2)}",
16661    );
16662    minify_test(
16663      ".foo { color: color(display-p3 100% 50% 0 / 20%); }",
16664      ".foo{color:color(display-p3 1 .5 0/.2)}",
16665    );
16666    minify_test(
16667      ".foo { color: color(display-p3 100% 0 0 / 20%); }",
16668      ".foo{color:color(display-p3 1 0 0/.2)}",
16669    );
16670    minify_test(".foo { color: hsl(none none none) }", ".foo{color:#000}");
16671    minify_test(".foo { color: hwb(none none none) }", ".foo{color:red}");
16672    minify_test(".foo { color: rgb(none none none) }", ".foo{color:#000}");
16673
16674    // If the browser doesn't support `#rrggbbaa` color syntax, it is converted to `transparent`.
16675    attr_test(
16676      "color: rgba(0, 0, 0, 0)",
16677      "color:transparent",
16678      true,
16679      Some(Browsers {
16680        chrome: Some(61 << 16), // Chrome >= 62 supports `#rrggbbaa` color.
16681        ..Browsers::default()
16682      }),
16683    );
16684
16685    attr_test(
16686      "color: #0000",
16687      "color:transparent",
16688      true,
16689      Some(Browsers {
16690        chrome: Some(61 << 16), // Chrome >= 62 supports `#rrggbbaa` color.
16691        ..Browsers::default()
16692      }),
16693    );
16694
16695    attr_test(
16696      "color: transparent",
16697      "color:transparent",
16698      true,
16699      Some(Browsers {
16700        chrome: Some(61 << 16),
16701        ..Browsers::default()
16702      }),
16703    );
16704
16705    attr_test(
16706      "color: rgba(0, 0, 0, 0)",
16707      "color: rgba(0, 0, 0, 0)",
16708      false,
16709      Some(Browsers {
16710        chrome: Some(61 << 16),
16711        ..Browsers::default()
16712      }),
16713    );
16714
16715    attr_test(
16716      "color: rgba(255, 0, 0, 0)",
16717      "color:rgba(255,0,0,0)",
16718      true,
16719      Some(Browsers {
16720        chrome: Some(61 << 16),
16721        ..Browsers::default()
16722      }),
16723    );
16724
16725    attr_test(
16726      "color: rgba(255, 0, 0, 0)",
16727      "color:#f000",
16728      true,
16729      Some(Browsers {
16730        chrome: Some(62 << 16),
16731        ..Browsers::default()
16732      }),
16733    );
16734
16735    prefix_test(
16736      ".foo { color: rgba(123, 456, 789, 0.5) }",
16737      indoc! { r#"
16738        .foo {
16739          color: #7bffff80;
16740        }
16741      "#},
16742      Browsers {
16743        chrome: Some(95 << 16),
16744        ..Browsers::default()
16745      },
16746    );
16747
16748    prefix_test(
16749      ".foo { color: rgba(123, 255, 255, 0.5) }",
16750      indoc! { r#"
16751        .foo {
16752          color: rgba(123, 255, 255, .5);
16753        }
16754      "#},
16755      Browsers {
16756        ie: Some(11 << 16),
16757        ..Browsers::default()
16758      },
16759    );
16760
16761    prefix_test(
16762      ".foo { color: #7bffff80 }",
16763      indoc! { r#"
16764        .foo {
16765          color: rgba(123, 255, 255, .5);
16766        }
16767      "#},
16768      Browsers {
16769        ie: Some(11 << 16),
16770        ..Browsers::default()
16771      },
16772    );
16773
16774    prefix_test(
16775      ".foo { color: rgba(123, 456, 789, 0.5) }",
16776      indoc! { r#"
16777        .foo {
16778          color: rgba(123, 255, 255, .5);
16779        }
16780      "#},
16781      Browsers {
16782        firefox: Some(48 << 16),
16783        safari: Some(10 << 16),
16784        ios_saf: Some(9 << 16),
16785        ..Browsers::default()
16786      },
16787    );
16788
16789    prefix_test(
16790      ".foo { color: rgba(123, 456, 789, 0.5) }",
16791      indoc! { r#"
16792        .foo {
16793          color: #7bffff80;
16794        }
16795      "#},
16796      Browsers {
16797        firefox: Some(49 << 16),
16798        safari: Some(10 << 16),
16799        ios_saf: Some(10 << 16),
16800        ..Browsers::default()
16801      },
16802    );
16803
16804    prefix_test(
16805      ".foo { background-color: lab(40% 56.6 39) }",
16806      indoc! { r#"
16807        .foo {
16808          background-color: #b32323;
16809          background-color: lab(40% 56.6 39);
16810        }
16811      "#},
16812      Browsers {
16813        chrome: Some(90 << 16),
16814        ..Browsers::default()
16815      },
16816    );
16817
16818    prefix_test(
16819      ".foo { background-color: lch(40% 68.735435 34.568626) }",
16820      indoc! { r#"
16821        .foo {
16822          background-color: #b32323;
16823          background-color: lch(40% 68.7354 34.5686);
16824        }
16825      "#},
16826      Browsers {
16827        chrome: Some(90 << 16),
16828        ..Browsers::default()
16829      },
16830    );
16831
16832    prefix_test(
16833      ".foo { background-color: oklab(59.686% 0.1009 0.1192); }",
16834      indoc! { r#"
16835        .foo {
16836          background-color: #c65d07;
16837          background-color: lab(52.2319% 40.1449 59.9171);
16838        }
16839      "#},
16840      Browsers {
16841        chrome: Some(90 << 16),
16842        ..Browsers::default()
16843      },
16844    );
16845
16846    prefix_test(
16847      ".foo { background-color: oklch(40% 0.1268735435 34.568626) }",
16848      indoc! { r#"
16849        .foo {
16850          background-color: #7e250f;
16851          background-color: lab(29.2661% 38.2437 35.3889);
16852        }
16853      "#},
16854      Browsers {
16855        chrome: Some(90 << 16),
16856        ..Browsers::default()
16857      },
16858    );
16859
16860    prefix_test(
16861      ".foo { background-color: lab(40% 56.6 39) }",
16862      indoc! { r#"
16863        .foo {
16864          background-color: lab(40% 56.6 39);
16865        }
16866      "#},
16867      Browsers {
16868        safari: Some(15 << 16),
16869        ..Browsers::default()
16870      },
16871    );
16872
16873    prefix_test(
16874      ".foo { background-color: oklab(59.686% 0.1009 0.1192); }",
16875      indoc! { r#"
16876        .foo {
16877          background-color: #c65d07;
16878          background-color: lab(52.2319% 40.1449 59.9171);
16879        }
16880      "#},
16881      Browsers {
16882        chrome: Some(90 << 16),
16883        safari: Some(15 << 16),
16884        ..Browsers::default()
16885      },
16886    );
16887
16888    prefix_test(
16889      ".foo { background-color: oklab(59.686% 0.1009 0.1192); }",
16890      indoc! { r#"
16891        .foo {
16892          background-color: #c65d07;
16893          background-color: color(display-p3 .724144 .386777 .148795);
16894          background-color: lab(52.2319% 40.1449 59.9171);
16895        }
16896      "#},
16897      Browsers {
16898        chrome: Some(90 << 16),
16899        safari: Some(14 << 16),
16900        ..Browsers::default()
16901      },
16902    );
16903
16904    prefix_test(
16905      ".foo { background-color: lab(40% 56.6 39) }",
16906      indoc! { r#"
16907        .foo {
16908          background-color: #b32323;
16909          background-color: color(display-p3 .643308 .192455 .167712);
16910          background-color: lab(40% 56.6 39);
16911        }
16912      "#},
16913      Browsers {
16914        chrome: Some(90 << 16),
16915        safari: Some(14 << 16),
16916        ..Browsers::default()
16917      },
16918    );
16919
16920    prefix_test(
16921      ".foo { background-color: oklch(59.686% 0.15619 49.7694); }",
16922      indoc! { r#"
16923        .foo {
16924          background-color: #c65d06;
16925          background-color: lab(52.2321% 40.1417 59.9527);
16926        }
16927      "#},
16928      Browsers {
16929        chrome: Some(90 << 16),
16930        safari: Some(15 << 16),
16931        ..Browsers::default()
16932      },
16933    );
16934
16935    prefix_test(
16936      ".foo { background-color: color(sRGB 0.41587 0.503670 0.36664); }",
16937      indoc! { r#"
16938        .foo {
16939          background-color: #6a805d;
16940          background-color: color(srgb .41587 .50367 .36664);
16941        }
16942      "#},
16943      Browsers {
16944        chrome: Some(90 << 16),
16945        ..Browsers::default()
16946      },
16947    );
16948
16949    prefix_test(
16950      ".foo { background-color: color(display-p3 0.43313 0.50108 0.37950); }",
16951      indoc! { r#"
16952        .foo {
16953          background-color: #6a805d;
16954          background-color: color(display-p3 .43313 .50108 .3795);
16955        }
16956      "#},
16957      Browsers {
16958        chrome: Some(90 << 16),
16959        ..Browsers::default()
16960      },
16961    );
16962
16963    prefix_test(
16964      ".foo { background-color: color(display-p3 0.43313 0.50108 0.37950); }",
16965      indoc! { r#"
16966        .foo {
16967          background-color: #6a805d;
16968          background-color: color(display-p3 .43313 .50108 .3795);
16969        }
16970      "#},
16971      Browsers {
16972        chrome: Some(90 << 16),
16973        safari: Some(14 << 16),
16974        ..Browsers::default()
16975      },
16976    );
16977
16978    prefix_test(
16979      ".foo { background-color: color(display-p3 0.43313 0.50108 0.37950); }",
16980      indoc! { r#"
16981        .foo {
16982          background-color: color(display-p3 .43313 .50108 .3795);
16983        }
16984      "#},
16985      Browsers {
16986        safari: Some(14 << 16),
16987        ..Browsers::default()
16988      },
16989    );
16990
16991    prefix_test(
16992      ".foo { background-color: color(display-p3 0.43313 0.50108 0.37950); }",
16993      indoc! { r#"
16994        .foo {
16995          background-color: #6a805d;
16996          background-color: color(display-p3 .43313 .50108 .3795);
16997        }
16998      "#},
16999      Browsers {
17000        chrome: Some(90 << 16),
17001        safari: Some(15 << 16),
17002        ..Browsers::default()
17003      },
17004    );
17005
17006    prefix_test(
17007      ".foo { background-color: color(display-p3 0.43313 0.50108 0.37950); }",
17008      indoc! { r#"
17009        .foo {
17010          background-color: #6a805d;
17011          background-color: color(display-p3 .43313 .50108 .3795);
17012        }
17013      "#},
17014      Browsers {
17015        chrome: Some(90 << 16),
17016        ..Browsers::default()
17017      },
17018    );
17019
17020    prefix_test(
17021      ".foo { background-color: color(a98-rgb 0.44091 0.49971 0.37408); }",
17022      indoc! { r#"
17023        .foo {
17024          background-color: #6a805d;
17025          background-color: color(a98-rgb .44091 .49971 .37408);
17026        }
17027      "#},
17028      Browsers {
17029        chrome: Some(90 << 16),
17030        ..Browsers::default()
17031      },
17032    );
17033
17034    prefix_test(
17035      ".foo { background-color: color(a98-rgb 0.44091 0.49971 0.37408); }",
17036      indoc! { r#"
17037        .foo {
17038          background-color: color(a98-rgb .44091 .49971 .37408);
17039        }
17040      "#},
17041      Browsers {
17042        safari: Some(15 << 16),
17043        ..Browsers::default()
17044      },
17045    );
17046
17047    prefix_test(
17048      ".foo { background-color: color(prophoto-rgb 0.36589 0.41717 0.31333); }",
17049      indoc! { r#"
17050        .foo {
17051          background-color: #6a805d;
17052          background-color: color(prophoto-rgb .36589 .41717 .31333);
17053        }
17054      "#},
17055      Browsers {
17056        chrome: Some(90 << 16),
17057        ..Browsers::default()
17058      },
17059    );
17060
17061    prefix_test(
17062      ".foo { background-color: color(rec2020 0.42210 0.47580 0.35605); }",
17063      indoc! { r#"
17064        .foo {
17065          background-color: #728765;
17066          background-color: color(rec2020 .4221 .4758 .35605);
17067        }
17068      "#},
17069      Browsers {
17070        chrome: Some(90 << 16),
17071        ..Browsers::default()
17072      },
17073    );
17074
17075    prefix_test(
17076      ".foo { background-color: color(xyz-d50 0.2005 0.14089 0.4472); }",
17077      indoc! { r#"
17078        .foo {
17079          background-color: #7654cd;
17080          background-color: color(xyz-d50 .2005 .14089 .4472);
17081        }
17082      "#},
17083      Browsers {
17084        chrome: Some(90 << 16),
17085        ..Browsers::default()
17086      },
17087    );
17088
17089    prefix_test(
17090      ".foo { background-color: color(xyz-d65 0.21661 0.14602 0.59452); }",
17091      indoc! { r#"
17092        .foo {
17093          background-color: #7654cd;
17094          background-color: color(xyz .21661 .14602 .59452);
17095        }
17096      "#},
17097      Browsers {
17098        chrome: Some(90 << 16),
17099        ..Browsers::default()
17100      },
17101    );
17102
17103    prefix_test(
17104      ".foo { background-color: lch(50.998% 135.363 338) }",
17105      indoc! { r#"
17106        .foo {
17107          background-color: #ee00be;
17108          background-color: color(display-p3 .972962 -.362078 .804206);
17109          background-color: lch(50.998% 135.363 338);
17110        }
17111      "#},
17112      Browsers {
17113        chrome: Some(90 << 16),
17114        safari: Some(14 << 16),
17115        ..Browsers::default()
17116      },
17117    );
17118
17119    prefix_test(
17120      ".foo { color: lch(50.998% 135.363 338) }",
17121      indoc! { r#"
17122        .foo {
17123          color: #ee00be;
17124          color: color(display-p3 .972962 -.362078 .804206);
17125          color: lch(50.998% 135.363 338);
17126        }
17127      "#},
17128      Browsers {
17129        chrome: Some(90 << 16),
17130        safari: Some(14 << 16),
17131        ..Browsers::default()
17132      },
17133    );
17134
17135    prefix_test(
17136      ".foo { background: var(--image) lch(40% 68.735435 34.568626) }",
17137      indoc! { r#"
17138        .foo {
17139          background: var(--image) #b32323;
17140        }
17141
17142        @supports (color: lab(0% 0 0)) {
17143          .foo {
17144            background: var(--image) lab(40% 56.6 39);
17145          }
17146        }
17147      "#},
17148      Browsers {
17149        chrome: Some(90 << 16),
17150        ..Browsers::default()
17151      },
17152    );
17153
17154    prefix_test(
17155      r#"
17156      .foo {
17157        color: red;
17158        color: lab(40% 56.6 39);
17159      }
17160    "#,
17161      indoc! {r#"
17162      .foo {
17163        color: red;
17164        color: lab(40% 56.6 39);
17165      }
17166    "#
17167      },
17168      Browsers {
17169        safari: Some(14 << 16),
17170        ..Browsers::default()
17171      },
17172    );
17173    prefix_test(
17174      r#"
17175      .foo {
17176        color: red;
17177        color: lab(40% 56.6 39);
17178      }
17179    "#,
17180      indoc! {r#"
17181      .foo {
17182        color: lab(40% 56.6 39);
17183      }
17184    "#
17185      },
17186      Browsers {
17187        safari: Some(16 << 16),
17188        ..Browsers::default()
17189      },
17190    );
17191
17192    prefix_test(
17193      r#"
17194      .foo {
17195        color: var(--fallback);
17196        color: lab(40% 56.6 39);
17197      }
17198    "#,
17199      indoc! {r#"
17200      .foo {
17201        color: var(--fallback);
17202        color: lab(40% 56.6 39);
17203      }
17204    "#
17205      },
17206      Browsers {
17207        safari: Some(14 << 16),
17208        ..Browsers::default()
17209      },
17210    );
17211
17212    prefix_test(
17213      r#"
17214      .foo {
17215        color: var(--fallback);
17216        color: lab(40% 56.6 39);
17217      }
17218    "#,
17219      indoc! {r#"
17220      .foo {
17221        color: lab(40% 56.6 39);
17222      }
17223    "#
17224      },
17225      Browsers {
17226        safari: Some(16 << 16),
17227        ..Browsers::default()
17228      },
17229    );
17230
17231    prefix_test(
17232      r#"
17233      .foo {
17234        color: red;
17235        color: var(--foo, lab(40% 56.6 39));
17236      }
17237    "#,
17238      indoc! {r#"
17239      .foo {
17240        color: var(--foo, color(display-p3 .643308 .192455 .167712));
17241      }
17242
17243      @supports (color: lab(0% 0 0)) {
17244        .foo {
17245          color: var(--foo, lab(40% 56.6 39));
17246        }
17247      }
17248    "#
17249      },
17250      Browsers {
17251        safari: Some(14 << 16),
17252        ..Browsers::default()
17253      },
17254    );
17255
17256    prefix_test(
17257      r#"
17258      .foo {
17259        --a: rgb(0 0 0 / var(--alpha));
17260        --b: rgb(50% 50% 50% / var(--alpha));
17261        --c: rgb(var(--x) 0 0);
17262        --d: rgb(0 var(--x) 0);
17263        --e: rgb(0 0 var(--x));
17264        --f: rgb(var(--x) 0 0 / var(--alpha));
17265        --g: rgb(0 var(--x) 0 / var(--alpha));
17266        --h: rgb(0 0 var(--x) / var(--alpha));
17267        --i: rgb(none 0 0 / var(--alpha));
17268        --j: rgb(from yellow r g b / var(--alpha));
17269      }
17270      "#,
17271      indoc! { r#"
17272        .foo {
17273          --a: rgba(0, 0, 0, var(--alpha));
17274          --b: rgba(128, 128, 128, var(--alpha));
17275          --c: rgb(var(--x) 0 0);
17276          --d: rgb(0 var(--x) 0);
17277          --e: rgb(0 0 var(--x));
17278          --f: rgb(var(--x) 0 0 / var(--alpha));
17279          --g: rgb(0 var(--x) 0 / var(--alpha));
17280          --h: rgb(0 0 var(--x) / var(--alpha));
17281          --i: rgb(none 0 0 / var(--alpha));
17282          --j: rgba(255, 255, 0, var(--alpha));
17283        }
17284      "#},
17285      Browsers {
17286        safari: Some(11 << 16),
17287        ..Browsers::default()
17288      },
17289    );
17290
17291    prefix_test(
17292      r#"
17293      .foo {
17294        --a: rgb(0 0 0 / var(--alpha));
17295        --b: rgb(50% 50% 50% / var(--alpha));
17296        --c: rgb(var(--x) 0 0);
17297        --d: rgb(0 var(--x) 0);
17298        --e: rgb(0 0 var(--x));
17299        --f: rgb(var(--x) 0 0 / var(--alpha));
17300        --g: rgb(0 var(--x) 0 / var(--alpha));
17301        --h: rgb(0 0 var(--x) / var(--alpha));
17302        --i: rgb(none 0 0 / var(--alpha));
17303        --j: rgb(from yellow r g b / var(--alpha));
17304      }
17305      "#,
17306      indoc! { r#"
17307        .foo {
17308          --a: rgb(0 0 0 / var(--alpha));
17309          --b: rgb(128 128 128 / var(--alpha));
17310          --c: rgb(var(--x) 0 0);
17311          --d: rgb(0 var(--x) 0);
17312          --e: rgb(0 0 var(--x));
17313          --f: rgb(var(--x) 0 0 / var(--alpha));
17314          --g: rgb(0 var(--x) 0 / var(--alpha));
17315          --h: rgb(0 0 var(--x) / var(--alpha));
17316          --i: rgb(none 0 0 / var(--alpha));
17317          --j: rgb(255 255 0 / var(--alpha));
17318        }
17319      "#},
17320      Browsers {
17321        safari: Some(13 << 16),
17322        ..Browsers::default()
17323      },
17324    );
17325
17326    prefix_test(
17327      r#"
17328      .foo {
17329        --a: hsl(270 100% 50% / var(--alpha));
17330        --b: hsl(var(--x) 0 0);
17331        --c: hsl(0 var(--x) 0);
17332        --d: hsl(0 0 var(--x));
17333        --e: hsl(var(--x) 0 0 / var(--alpha));
17334        --f: hsl(0 var(--x) 0 / var(--alpha));
17335        --g: hsl(0 0 var(--x) / var(--alpha));
17336        --h: hsl(270 100% 50% / calc(var(--alpha) / 2));
17337        --i: hsl(none 100% 50% / var(--alpha));
17338        --j: hsl(from yellow h s l / var(--alpha));
17339      }
17340      "#,
17341      indoc! { r#"
17342        .foo {
17343          --a: hsla(270, 100%, 50%, var(--alpha));
17344          --b: hsl(var(--x) 0 0);
17345          --c: hsl(0 var(--x) 0);
17346          --d: hsl(0 0 var(--x));
17347          --e: hsl(var(--x) 0 0 / var(--alpha));
17348          --f: hsl(0 var(--x) 0 / var(--alpha));
17349          --g: hsl(0 0 var(--x) / var(--alpha));
17350          --h: hsla(270, 100%, 50%, calc(var(--alpha) / 2));
17351          --i: hsl(none 100% 50% / var(--alpha));
17352          --j: hsla(60, 100%, 50%, var(--alpha));
17353        }
17354      "#},
17355      Browsers {
17356        safari: Some(11 << 16),
17357        ..Browsers::default()
17358      },
17359    );
17360
17361    prefix_test(
17362      r#"
17363      .foo {
17364        --a: hsl(270 100% 50% / var(--alpha));
17365        --b: hsl(var(--x) 0 0);
17366        --c: hsl(0 var(--x) 0);
17367        --d: hsl(0 0 var(--x));
17368        --e: hsl(var(--x) 0 0 / var(--alpha));
17369        --f: hsl(0 var(--x) 0 / var(--alpha));
17370        --g: hsl(0 0 var(--x) / var(--alpha));
17371        --h: hsl(270 100% 50% / calc(var(--alpha) / 2));
17372        --i: hsl(none 100% 50% / var(--alpha));
17373      }
17374      "#,
17375      indoc! { r#"
17376        .foo {
17377          --a: hsl(270 100% 50% / var(--alpha));
17378          --b: hsl(var(--x) 0 0);
17379          --c: hsl(0 var(--x) 0);
17380          --d: hsl(0 0 var(--x));
17381          --e: hsl(var(--x) 0 0 / var(--alpha));
17382          --f: hsl(0 var(--x) 0 / var(--alpha));
17383          --g: hsl(0 0 var(--x) / var(--alpha));
17384          --h: hsl(270 100% 50% / calc(var(--alpha) / 2));
17385          --i: hsl(none 100% 50% / var(--alpha));
17386        }
17387      "#},
17388      Browsers {
17389        safari: Some(13 << 16),
17390        ..Browsers::default()
17391      },
17392    );
17393
17394    test(
17395      r#"
17396      .foo {
17397        --a: rgb(50% 50% 50% / calc(100% / 2));
17398        --b: hsl(calc(360deg / 2) 50% 50%);
17399        --c: oklab(40.101% calc(0.1 + 0.2) 0.0453);
17400        --d: color(display-p3 0.43313 0.50108 calc(0.1 + 0.2));
17401        --e: rgb(calc(255 / 2), calc(255 / 2), calc(255 / 2));
17402      }
17403      "#,
17404      indoc! { r#"
17405        .foo {
17406          --a: #80808080;
17407          --b: #40bfbf;
17408          --c: oklab(40.101% .3 .0453);
17409          --d: color(display-p3 .43313 .50108 .3);
17410          --e: gray;
17411        }
17412      "#},
17413    );
17414  }
17415
17416  #[test]
17417  fn test_relative_color() {
17418    fn test(input: &str, output: &str) {
17419      let output = CssColor::parse_string(output)
17420        .unwrap()
17421        .to_css_string(PrinterOptions {
17422          minify: true,
17423          ..PrinterOptions::default()
17424        })
17425        .unwrap();
17426      minify_test(
17427        &format!(".foo {{ color: {} }}", input),
17428        &format!(".foo{{color:{}}}", output),
17429      );
17430    }
17431
17432    test("lab(from indianred calc(l * .8) a b)", "lab(43.1402% 45.7516 23.1557)");
17433    test("lch(from indianred calc(l + 10%) c h)", "lch(63.9252% 51.2776 26.8448)");
17434    test("lch(from indianred l calc(c - 50) h)", "lch(53.9252% 1.27763 26.8448)");
17435    test(
17436      "lch(from indianred l c calc(h + 180deg))",
17437      "lch(53.9252% 51.2776 206.845)",
17438    );
17439    test("lch(from orchid l 30 h)", "lch(62.7526% 30 326.969)");
17440    test("lch(from orchid l 30 h)", "lch(62.7526% 30 326.969)");
17441    test("lch(from peru calc(l * 0.8) c h)", "lch(49.8022% 54.0117 63.6804)");
17442    test("rgb(from indianred 255 g b)", "rgb(255, 92, 92)");
17443    test("rgb(from indianred r g b / .5)", "rgba(205, 92, 92, .5)");
17444    test(
17445      "rgb(from rgba(205, 92, 92, .5) r g b / calc(alpha + .2))",
17446      "rgba(205, 92, 92, .7)",
17447    );
17448    test(
17449      "rgb(from rgba(205, 92, 92, .5) r g b / calc(alpha + 20%))",
17450      "rgba(205, 92, 92, .7)",
17451    );
17452    test("lch(from indianred l sin(c) h)", "lch(53.9252% .84797 26.8448)");
17453    test("lch(from indianred l sqrt(c) h)", "lch(53.9252% 7.16084 26.8448)");
17454    test("lch(from indianred l c sin(h))", "lch(53.9252% 51.2776 .990043)");
17455    minify_test(
17456      ".foo{color:lch(from currentColor l c sin(h))}",
17457      ".foo{color:lch(from currentColor l c sin(h))}",
17458    );
17459
17460    // The following tests were converted from WPT: https://github.com/web-platform-tests/wpt/blob/master/css/css-color/parsing/relative-color-valid.html
17461    // Find: test_valid_value\(`color`, `(.*?)`,\s*`(.*?)`\)
17462    // Replace: test("$1", "$2")
17463
17464    // Testing no modifications.
17465    test("rgb(from rebeccapurple r g b)", "#639");
17466    test("rgb(from rebeccapurple r g b / alpha)", "#639");
17467    test("rgb(from rgb(20%, 40%, 60%, 80%) r g b / alpha)", "#369c");
17468    test("rgb(from hsl(120deg 20% 50% / .5) r g b / alpha)", "#66996680");
17469
17470    // Test nesting relative colors.
17471    test("rgb(from rgb(from rebeccapurple r g b) r g b)", "#639");
17472
17473    // Testing non-sRGB origin colors to see gamut mapping.
17474    test("rgb(from color(display-p3 0 1 0) r g b / alpha)", "#00f942"); // Naive clip based mapping would give rgb(0, 255, 0).
17475    test("rgb(from lab(100% 104.3 -50.9) r g b)", "#fff"); // Naive clip based mapping would give rgb(255, 150, 255).
17476    test("rgb(from lab(0% 104.3 -50.9) r g b)", "#2a0022"); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black.
17477    test("rgb(from lch(100% 116 334) r g b)", "#fff"); // Naive clip based mapping would give rgb(255, 150, 255).
17478    test("rgb(from lch(0% 116 334) r g b)", "#2a0022"); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black.
17479    test("rgb(from oklab(100% 0.365 -0.16) r g b)", "#fff"); // Naive clip based mapping would give rgb(255, 92, 255).
17480    test("rgb(from oklab(0% 0.365 -0.16) r g b)", "#000"); // Naive clip based mapping would give rgb(19, 0, 24).
17481    test("rgb(from oklch(100% 0.399 336.3) r g b)", "#fff"); // Naive clip based mapping would give rgb(255, 91, 255).
17482    test("rgb(from oklch(0% 0.399 336.3) r g b)", "#000"); // Naive clip based mapping would give rgb(20, 0, 24).
17483
17484    // Testing replacement with 0.
17485    test("rgb(from rebeccapurple 0 0 0)", "rgb(0, 0, 0)");
17486    test("rgb(from rebeccapurple 0 0 0 / 0)", "rgba(0, 0, 0, 0)");
17487    test("rgb(from rebeccapurple 0 g b / alpha)", "rgb(0, 51, 153)");
17488    test("rgb(from rebeccapurple r 0 b / alpha)", "rgb(102, 0, 153)");
17489    test("rgb(from rebeccapurple r g 0 / alpha)", "rgb(102, 51, 0)");
17490    test("rgb(from rebeccapurple r g b / 0)", "rgba(102, 51, 153, 0)");
17491    test(
17492      "rgb(from rgb(20%, 40%, 60%, 80%) 0 g b / alpha)",
17493      "rgba(0, 102, 153, 0.8)",
17494    );
17495    test(
17496      "rgb(from rgb(20%, 40%, 60%, 80%) r 0 b / alpha)",
17497      "rgba(51, 0, 153, 0.8)",
17498    );
17499    test(
17500      "rgb(from rgb(20%, 40%, 60%, 80%) r g 0 / alpha)",
17501      "rgba(51, 102, 0, 0.8)",
17502    );
17503    test("rgb(from rgb(20%, 40%, 60%, 80%) r g b / 0)", "rgba(51, 102, 153, 0)");
17504
17505    // Testing replacement with a number.
17506    test("rgb(from rebeccapurple 25 g b / alpha)", "rgb(25, 51, 153)");
17507    test("rgb(from rebeccapurple r 25 b / alpha)", "rgb(102, 25, 153)");
17508    test("rgb(from rebeccapurple r g 25 / alpha)", "rgb(102, 51, 25)");
17509    test("rgb(from rebeccapurple r g b / .25)", "rgba(102, 51, 153, 0.25)");
17510    test(
17511      "rgb(from rgb(20%, 40%, 60%, 80%) 25 g b / alpha)",
17512      "rgba(25, 102, 153, 0.8)",
17513    );
17514    test(
17515      "rgb(from rgb(20%, 40%, 60%, 80%) r 25 b / alpha)",
17516      "rgba(51, 25, 153, 0.8)",
17517    );
17518    test(
17519      "rgb(from rgb(20%, 40%, 60%, 80%) r g 25 / alpha)",
17520      "rgba(51, 102, 25, 0.8)",
17521    );
17522    test(
17523      "rgb(from rgb(20%, 40%, 60%, 80%) r g b / .20)",
17524      "rgba(51, 102, 153, 0.2)",
17525    );
17526
17527    // Testing replacement with a percentage.
17528    test("rgb(from rebeccapurple 20% g b / alpha)", "rgb(51, 51, 153)");
17529    test("rgb(from rebeccapurple r 20% b / alpha)", "rgb(102, 51, 153)");
17530    test("rgb(from rebeccapurple r g 20% / alpha)", "rgb(102, 51, 51)");
17531    test("rgb(from rebeccapurple r g b / 20%)", "rgba(102, 51, 153, 0.2)");
17532    test(
17533      "rgb(from rgb(20%, 40%, 60%, 80%) 20% g b / alpha)",
17534      "rgba(51, 102, 153, 0.8)",
17535    );
17536    test(
17537      "rgb(from rgb(20%, 40%, 60%, 80%) r 20% b / alpha)",
17538      "rgba(51, 51, 153, 0.8)",
17539    );
17540    test(
17541      "rgb(from rgb(20%, 40%, 60%, 80%) r g 20% / alpha)",
17542      "rgba(51, 102, 51, 0.8)",
17543    );
17544    test(
17545      "rgb(from rgb(20%, 40%, 60%, 80%) r g b / 20%)",
17546      "rgba(51, 102, 153, 0.2)",
17547    );
17548
17549    // Testing replacement with a number for r, g, b but percent for alpha.
17550    test("rgb(from rebeccapurple 25 g b / 25%)", "rgba(25, 51, 153, 0.25)");
17551    test("rgb(from rebeccapurple r 25 b / 25%)", "rgba(102, 25, 153, 0.25)");
17552    test("rgb(from rebeccapurple r g 25 / 25%)", "rgba(102, 51, 25, 0.25)");
17553    test(
17554      "rgb(from rgb(20%, 40%, 60%, 80%) 25 g b / 25%)",
17555      "rgba(25, 102, 153, 0.25)",
17556    );
17557    test(
17558      "rgb(from rgb(20%, 40%, 60%, 80%) r 25 b / 25%)",
17559      "rgba(51, 25, 153, 0.25)",
17560    );
17561    test(
17562      "rgb(from rgb(20%, 40%, 60%, 80%) r g 25 / 25%)",
17563      "rgba(51, 102, 25, 0.25)",
17564    );
17565
17566    // Testing permutation.
17567    test("rgb(from rebeccapurple g b r)", "rgb(51, 153, 102)");
17568    test("rgb(from rebeccapurple b alpha r / g)", "rgba(153, 255, 102, 0.2)");
17569    test("rgb(from rebeccapurple r r r / r)", "rgba(102, 102, 102, 0.4)");
17570    test(
17571      "rgb(from rebeccapurple alpha alpha alpha / alpha)",
17572      "rgb(255, 255, 255)",
17573    );
17574    test("rgb(from rgb(20%, 40%, 60%, 80%) g b r)", "rgb(102, 153, 51)");
17575    test(
17576      "rgb(from rgb(20%, 40%, 60%, 80%) b alpha r / g)",
17577      "rgba(153, 204, 51, 0.4)",
17578    );
17579    test("rgb(from rgb(20%, 40%, 60%, 80%) r r r / r)", "rgba(51, 51, 51, 0.2)");
17580    test(
17581      "rgb(from rgb(20%, 40%, 60%, 80%) alpha alpha alpha / alpha)",
17582      "rgba(204, 204, 204, 0.8)",
17583    );
17584
17585    // Testing mixes of number and percentage. (These would not be allowed in the non-relative syntax).
17586    test("rgb(from rebeccapurple r 20% 10)", "rgb(102, 51, 10)");
17587    test("rgb(from rebeccapurple r 10 20%)", "rgb(102, 10, 51)");
17588    test("rgb(from rebeccapurple 0% 10 10)", "rgb(0, 10, 10)");
17589    test("rgb(from rgb(20%, 40%, 60%, 80%) r 20% 10)", "rgb(51, 51, 10)");
17590    test("rgb(from rgb(20%, 40%, 60%, 80%) r 10 20%)", "rgb(51, 10, 51)");
17591    test("rgb(from rgb(20%, 40%, 60%, 80%) 0% 10 10)", "rgb(0, 10, 10)");
17592
17593    // Testing with calc().
17594    test("rgb(from rebeccapurple calc(r) calc(g) calc(b))", "rgb(102, 51, 153)");
17595    test("rgb(from rebeccapurple r calc(g * 2) 10)", "rgb(102, 102, 10)");
17596    test("rgb(from rebeccapurple b calc(r * .5) 10)", "rgb(153, 51, 10)");
17597    test("rgb(from rebeccapurple r calc(g * .5 + g * .5) 10)", "rgb(102, 51, 10)");
17598    test("rgb(from rebeccapurple r calc(b * .5 - g * .5) 10)", "rgb(102, 51, 10)");
17599    test(
17600      "rgb(from rgb(20%, 40%, 60%, 80%) calc(r) calc(g) calc(b) / calc(alpha))",
17601      "rgba(51, 102, 153, 0.8)",
17602    );
17603
17604    // Testing with 'none'.
17605    test("rgb(from rebeccapurple none none none)", "rgb(0, 0, 0)");
17606    test("rgb(from rebeccapurple none none none / none)", "rgba(0, 0, 0, 0)");
17607    test("rgb(from rebeccapurple r g none)", "rgb(102, 51, 0)");
17608    test("rgb(from rebeccapurple r g none / alpha)", "rgb(102, 51, 0)");
17609    test("rgb(from rebeccapurple r g b / none)", "rgba(102, 51, 153, 0)");
17610    test(
17611      "rgb(from rgb(20% 40% 60% / 80%) r g none / alpha)",
17612      "rgba(51, 102, 0, 0.8)",
17613    );
17614    test("rgb(from rgb(20% 40% 60% / 80%) r g b / none)", "rgba(51, 102, 153, 0)");
17615    // FIXME: Clarify with spec editors if 'none' should pass through to the constants.
17616    test("rgb(from rgb(none none none) r g b)", "rgb(0, 0, 0)");
17617    test("rgb(from rgb(none none none / none) r g b / alpha)", "rgba(0, 0, 0, 0)");
17618    test("rgb(from rgb(20% none 60%) r g b)", "rgb(51, 0, 153)");
17619    test(
17620      "rgb(from rgb(20% 40% 60% / none) r g b / alpha)",
17621      "rgba(51, 102, 153, 0)",
17622    );
17623
17624    // hsl(from ...)
17625
17626    // Testing no modifications.
17627    test("hsl(from rebeccapurple h s l)", "rgb(102, 51, 153)");
17628    test("hsl(from rebeccapurple h s l / alpha)", "rgb(102, 51, 153)");
17629    test(
17630      "hsl(from rgb(20%, 40%, 60%, 80%) h s l / alpha)",
17631      "rgba(51, 102, 153, 0.8)",
17632    );
17633    test(
17634      "hsl(from hsl(120deg 20% 50% / .5) h s l / alpha)",
17635      "rgba(102, 153, 102, 0.5)",
17636    );
17637
17638    // Test nesting relative colors.
17639    test("hsl(from hsl(from rebeccapurple h s l) h s l)", "rgb(102, 51, 153)");
17640
17641    // Testing non-sRGB origin colors to see gamut mapping.
17642    test("hsl(from color(display-p3 0 1 0) h s l / alpha)", "rgb(0, 249, 66)"); // Naive clip based mapping would give rgb(0, 255, 0).
17643    test("hsl(from lab(100% 104.3 -50.9) h s l)", "rgb(255, 255, 255)"); // Naive clip based mapping would give rgb(255, 150, 255).
17644    test("hsl(from lab(0% 104.3 -50.9) h s l)", "rgb(42, 0, 34)"); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black,
17645    test("hsl(from lch(100% 116 334) h s l)", "rgb(255, 255, 255)"); // Naive clip based mapping would give rgb(255, 150, 255).
17646    test("hsl(from lch(0% 116 334) h s l)", "rgb(42, 0, 34)"); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black,
17647    test("hsl(from oklab(100% 0.365 -0.16) h s l)", "rgb(255, 255, 255)"); // Naive clip based mapping would give rgb(255, 92, 255).
17648    test("hsl(from oklab(0% 0.365 -0.16) h s l)", "rgb(0, 0, 0)"); // Naive clip based mapping would give rgb(19, 0, 24).
17649    test("hsl(from oklch(100% 0.399 336.3) h s l)", "rgb(255, 255, 255)"); // Naive clip based mapping would give rgb(255, 91, 255).
17650    test("hsl(from oklch(0% 0.399 336.3) h s l)", "rgb(0, 0, 0)"); // Naive clip based mapping would give rgb(20, 0, 24).
17651
17652    // Testing replacement with 0.
17653    test("hsl(from rebeccapurple 0 0% 0%)", "rgb(0, 0, 0)");
17654    test("hsl(from rebeccapurple 0deg 0% 0%)", "rgb(0, 0, 0)");
17655    test("hsl(from rebeccapurple 0 0% 0% / 0)", "rgba(0, 0, 0, 0)");
17656    test("hsl(from rebeccapurple 0deg 0% 0% / 0)", "rgba(0, 0, 0, 0)");
17657    test("hsl(from rebeccapurple 0 s l / alpha)", "rgb(153, 51, 51)");
17658    test("hsl(from rebeccapurple 0deg s l / alpha)", "rgb(153, 51, 51)");
17659    test("hsl(from rebeccapurple h 0% l / alpha)", "rgb(102, 102, 102)");
17660    test("hsl(from rebeccapurple h s 0% / alpha)", "rgb(0, 0, 0)");
17661    test("hsl(from rebeccapurple h s l / 0)", "rgba(102, 51, 153, 0)");
17662    test(
17663      "hsl(from rgb(20%, 40%, 60%, 80%) 0 s l / alpha)",
17664      "rgba(153, 51, 51, 0.8)",
17665    );
17666    test(
17667      "hsl(from rgb(20%, 40%, 60%, 80%) 0deg s l / alpha)",
17668      "rgba(153, 51, 51, 0.8)",
17669    );
17670    test(
17671      "hsl(from rgb(20%, 40%, 60%, 80%) h 0% l / alpha)",
17672      "rgba(102, 102, 102, 0.8)",
17673    );
17674    test("hsl(from rgb(20%, 40%, 60%, 80%) h s 0% / alpha)", "rgba(0, 0, 0, 0.8)");
17675    test("hsl(from rgb(20%, 40%, 60%, 80%) h s l / 0)", "rgba(51, 102, 153, 0)");
17676
17677    // Testing replacement with a constant.
17678    test("hsl(from rebeccapurple 25 s l / alpha)", "rgb(153, 94, 51)");
17679    test("hsl(from rebeccapurple 25deg s l / alpha)", "rgb(153, 94, 51)");
17680    test("hsl(from rebeccapurple h 20% l / alpha)", "rgb(102, 82, 122)");
17681    test("hsl(from rebeccapurple h s 20% / alpha)", "rgb(51, 25, 77)");
17682    test("hsl(from rebeccapurple h s l / .25)", "rgba(102, 51, 153, 0.25)");
17683    test(
17684      "hsl(from rgb(20%, 40%, 60%, 80%) 25 s l / alpha)",
17685      "rgba(153, 94, 51, 0.8)",
17686    );
17687    test(
17688      "hsl(from rgb(20%, 40%, 60%, 80%) 25deg s l / alpha)",
17689      "rgba(153, 94, 51, 0.8)",
17690    );
17691    test(
17692      "hsl(from rgb(20%, 40%, 60%, 80%) h 20% l / alpha)",
17693      "rgba(82, 102, 122, 0.8)",
17694    );
17695    test(
17696      "hsl(from rgb(20%, 40%, 60%, 80%) h s 20% / alpha)",
17697      "rgba(25, 51, 77, 0.8)",
17698    );
17699    test(
17700      "hsl(from rgb(20%, 40%, 60%, 80%) h s l / .2)",
17701      "rgba(51, 102, 153, 0.2)",
17702    );
17703
17704    // Testing valid permutation (types match).
17705    test("hsl(from rebeccapurple h l s)", "rgb(128, 77, 179)");
17706    test("hsl(from rebeccapurple h alpha l / s)", "rgba(102, 0, 204, 0.5)");
17707    test("hsl(from rebeccapurple h l l / l)", "rgba(102, 61, 143, 0.4)");
17708    test("hsl(from rebeccapurple h alpha alpha / alpha)", "rgb(255, 255, 255)");
17709    test("hsl(from rgb(20%, 40%, 60%, 80%) h l s)", "rgb(77, 128, 179)");
17710    test(
17711      "hsl(from rgb(20%, 40%, 60%, 80%) h alpha l / s)",
17712      "rgba(20, 102, 184, 0.5)",
17713    );
17714    test("hsl(from rgb(20%, 40%, 60%, 80%) h l l / l)", "rgba(61, 102, 143, 0.4)");
17715    test(
17716      "hsl(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)",
17717      "rgba(163, 204, 245, 0.8)",
17718    );
17719
17720    // Testing with calc().
17721    test("hsl(from rebeccapurple calc(h) calc(s) calc(l))", "rgb(102, 51, 153)");
17722    test(
17723      "hsl(from rgb(20%, 40%, 60%, 80%) calc(h) calc(s) calc(l) / calc(alpha))",
17724      "rgba(51, 102, 153, 0.8)",
17725    );
17726
17727    // Testing with 'none'.
17728    test("hsl(from rebeccapurple none none none)", "rgb(0, 0, 0)");
17729    test("hsl(from rebeccapurple none none none / none)", "rgba(0, 0, 0, 0)");
17730    test("hsl(from rebeccapurple h s none)", "rgb(0, 0, 0)");
17731    test("hsl(from rebeccapurple h s none / alpha)", "rgb(0, 0, 0)");
17732    test("hsl(from rebeccapurple h s l / none)", "rgba(102, 51, 153, 0)");
17733    test("hsl(from rebeccapurple none s l / alpha)", "rgb(153, 51, 51)");
17734    test(
17735      "hsl(from hsl(120deg 20% 50% / .5) h s none / alpha)",
17736      "rgba(0, 0, 0, 0.5)",
17737    );
17738    test(
17739      "hsl(from hsl(120deg 20% 50% / .5) h s l / none)",
17740      "rgba(102, 153, 102, 0)",
17741    );
17742    test(
17743      "hsl(from hsl(120deg 20% 50% / .5) none s l / alpha)",
17744      "rgba(153, 102, 102, 0.5)",
17745    );
17746    // FIXME: Clarify with spec editors if 'none' should pass through to the constants.
17747    test("hsl(from hsl(none none none) h s l)", "rgb(0, 0, 0)");
17748    test("hsl(from hsl(none none none / none) h s l / alpha)", "rgba(0, 0, 0, 0)");
17749    test("hsl(from hsl(120deg none 50% / .5) h s l)", "rgb(128, 128, 128)");
17750    test(
17751      "hsl(from hsl(120deg 20% 50% / none) h s l / alpha)",
17752      "rgba(102, 153, 102, 0)",
17753    );
17754    test(
17755      "hsl(from hsl(none 20% 50% / .5) h s l / alpha)",
17756      "rgba(153, 102, 102, 0.5)",
17757    );
17758
17759    // hwb(from ...)
17760
17761    // Testing no modifications.
17762    test("hwb(from rebeccapurple h w b)", "rgb(102, 51, 153)");
17763    test("hwb(from rebeccapurple h w b / alpha)", "rgb(102, 51, 153)");
17764    test(
17765      "hwb(from rgb(20%, 40%, 60%, 80%) h w b / alpha)",
17766      "rgba(51, 102, 153, 0.8)",
17767    );
17768    test(
17769      "hwb(from hsl(120deg 20% 50% / .5) h w b / alpha)",
17770      "rgba(102, 153, 102, 0.5)",
17771    );
17772
17773    // Test nesting relative colors.
17774    test("hwb(from hwb(from rebeccapurple h w b) h w b)", "rgb(102, 51, 153)");
17775
17776    // Testing non-sRGB origin colors to see gamut mapping.
17777    test("hwb(from color(display-p3 0 1 0) h w b / alpha)", "rgb(0, 249, 66)"); // Naive clip based mapping would give rgb(0, 255, 0).
17778    test("hwb(from lab(100% 104.3 -50.9) h w b)", "rgb(255, 255, 255)"); // Naive clip based mapping would give rgb(255, 150, 255).
17779    test("hwb(from lab(0% 104.3 -50.9) h w b)", "rgb(42, 0, 34)"); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black,
17780    test("hwb(from lch(100% 116 334) h w b)", "rgb(255, 255, 255)"); // Naive clip based mapping would give rgb(255, 150, 255).
17781    test("hwb(from lch(0% 116 334) h w b)", "rgb(42, 0, 34)"); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black,
17782    test("hwb(from oklab(100% 0.365 -0.16) h w b)", "rgb(255, 255, 255)"); // Naive clip based mapping would give rgb(255, 92, 255).
17783    test("hwb(from oklab(0% 0.365 -0.16) h w b)", "rgb(0, 0, 0)"); // Naive clip based mapping would give rgb(19, 0, 24).
17784    test("hwb(from oklch(100% 0.399 336.3) h w b)", "rgb(255, 255, 255)"); // Naive clip based mapping would give rgb(255, 91, 255).
17785    test("hwb(from oklch(0% 0.399 336.3) h w b)", "rgb(0, 0, 0)"); // Naive clip based mapping would give rgb(20, 0, 24).
17786
17787    // Testing replacement with 0.
17788    test("hwb(from rebeccapurple 0 0% 0%)", "rgb(255, 0, 0)");
17789    test("hwb(from rebeccapurple 0deg 0% 0%)", "rgb(255, 0, 0)");
17790    test("hwb(from rebeccapurple 0 0% 0% / 0)", "rgba(255, 0, 0, 0)");
17791    test("hwb(from rebeccapurple 0deg 0% 0% / 0)", "rgba(255, 0, 0, 0)");
17792    test("hwb(from rebeccapurple 0 w b / alpha)", "rgb(153, 51, 51)");
17793    test("hwb(from rebeccapurple 0deg w b / alpha)", "rgb(153, 51, 51)");
17794    test("hwb(from rebeccapurple h 0% b / alpha)", "rgb(77, 0, 153)");
17795    test("hwb(from rebeccapurple h w 0% / alpha)", "rgb(153, 51, 255)");
17796    test("hwb(from rebeccapurple h w b / 0)", "rgba(102, 51, 153, 0)");
17797    test(
17798      "hwb(from rgb(20%, 40%, 60%, 80%) 0 w b / alpha)",
17799      "rgba(153, 51, 51, 0.8)",
17800    );
17801    test(
17802      "hwb(from rgb(20%, 40%, 60%, 80%) 0deg w b / alpha)",
17803      "rgba(153, 51, 51, 0.8)",
17804    );
17805    test(
17806      "hwb(from rgb(20%, 40%, 60%, 80%) h 0% b / alpha)",
17807      "rgba(0, 77, 153, 0.8)",
17808    );
17809    test(
17810      "hwb(from rgb(20%, 40%, 60%, 80%) h w 0% / alpha)",
17811      "rgba(51, 153, 255, 0.8)",
17812    );
17813    test("hwb(from rgb(20%, 40%, 60%, 80%) h w b / 0)", "rgba(51, 102, 153, 0)");
17814
17815    // Testing replacement with a constant.
17816    test("hwb(from rebeccapurple 25 w b / alpha)", "rgb(153, 94, 51)");
17817    test("hwb(from rebeccapurple 25deg w b / alpha)", "rgb(153, 94, 51)");
17818    test("hwb(from rebeccapurple h 20% b / alpha)", "rgb(102, 51, 153)");
17819    test("hwb(from rebeccapurple h w 20% / alpha)", "rgb(128, 51, 204)");
17820    test("hwb(from rebeccapurple h w b / .2)", "rgba(102, 51, 153, 0.2)");
17821    test(
17822      "hwb(from rgb(20%, 40%, 60%, 80%) 25 w b / alpha)",
17823      "rgba(153, 94, 51, 0.8)",
17824    );
17825    test(
17826      "hwb(from rgb(20%, 40%, 60%, 80%) 25deg w b / alpha)",
17827      "rgba(153, 94, 51, 0.8)",
17828    );
17829    test(
17830      "hwb(from rgb(20%, 40%, 60%, 80%) h 20% b / alpha)",
17831      "rgba(51, 102, 153, 0.8)",
17832    );
17833    test(
17834      "hwb(from rgb(20%, 40%, 60%, 80%) h w 20% / alpha)",
17835      "rgba(51, 128, 204, 0.8)",
17836    );
17837    test(
17838      "hwb(from rgb(20%, 40%, 60%, 80%) h w b / .2)",
17839      "rgba(51, 102, 153, 0.2)",
17840    );
17841
17842    // Testing valid permutation (types match).
17843    test("hwb(from rebeccapurple h b w)", "rgb(153, 102, 204)");
17844    test("hwb(from rebeccapurple h alpha w / b)", "rgba(213, 213, 213, 0.4)");
17845    test("hwb(from rebeccapurple h w w / w)", "rgba(128, 51, 204, 0.2)");
17846    test("hwb(from rebeccapurple h alpha alpha / alpha)", "rgb(128, 128, 128)");
17847    test("hwb(from rgb(20%, 40%, 60%, 80%) h b w)", "rgb(102, 153, 204)");
17848    test(
17849      "hwb(from rgb(20%, 40%, 60%, 80%) h alpha w / b)",
17850      "rgba(204, 204, 204, 0.4)",
17851    );
17852    test("hwb(from rgb(20%, 40%, 60%, 80%) h w w / w)", "rgba(51, 128, 204, 0.2)");
17853    test(
17854      "hwb(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)",
17855      "rgba(128, 128, 128, 0.8)",
17856    );
17857
17858    // Testing with calc().
17859    test("hwb(from rebeccapurple calc(h) calc(w) calc(b))", "rgb(102, 51, 153)");
17860    test(
17861      "hwb(from rgb(20%, 40%, 60%, 80%) calc(h) calc(w) calc(b) / calc(alpha))",
17862      "rgba(51, 102, 153, 0.8)",
17863    );
17864
17865    // Testing with 'none'.
17866    test("hwb(from rebeccapurple none none none)", "rgb(255, 0, 0)");
17867    test("hwb(from rebeccapurple none none none / none)", "rgba(255, 0, 0, 0)");
17868    test("hwb(from rebeccapurple h w none)", "rgb(153, 51, 255)");
17869    test("hwb(from rebeccapurple h w none / alpha)", "rgb(153, 51, 255)");
17870    test("hwb(from rebeccapurple h w b / none)", "rgba(102, 51, 153, 0)");
17871    test("hwb(from rebeccapurple none w b / alpha)", "rgb(153, 51, 51)");
17872    test(
17873      "hwb(from hwb(120deg 20% 50% / .5) h w none / alpha)",
17874      "rgba(51, 255, 51, 0.5)",
17875    );
17876    test(
17877      "hwb(from hwb(120deg 20% 50% / .5) h w b / none)",
17878      "rgba(51, 128, 51, 0)",
17879    );
17880    test(
17881      "hwb(from hwb(120deg 20% 50% / .5) none w b / alpha)",
17882      "rgba(128, 51, 51, 0.5)",
17883    );
17884    // FIXME: Clarify with spec editors if 'none' should pass through to the constants.
17885    test("hwb(from hwb(none none none) h w b)", "rgb(255, 0, 0)");
17886    test(
17887      "hwb(from hwb(none none none / none) h w b / alpha)",
17888      "rgba(255, 0, 0, 0)",
17889    );
17890    test("hwb(from hwb(120deg none 50% / .5) h w b)", "rgb(0, 128, 0)");
17891    test(
17892      "hwb(from hwb(120deg 20% 50% / none) h w b / alpha)",
17893      "rgba(51, 128, 51, 0)",
17894    );
17895    test(
17896      "hwb(from hwb(none 20% 50% / .5) h w b / alpha)",
17897      "rgba(128, 51, 51, 0.5)",
17898    );
17899
17900    for color_space in &["lab", "oklab"] {
17901      // Testing no modifications.
17902      test(
17903        &format!("{}(from {}(25% 20 50) l a b)", color_space, color_space),
17904        &format!("{}(25% 20 50)", color_space),
17905      );
17906      test(
17907        &format!("{}(from {}(25% 20 50) l a b / alpha)", color_space, color_space),
17908        &format!("{}(25% 20 50)", color_space),
17909      );
17910      test(
17911        &format!("{}(from {}(25% 20 50 / 40%) l a b / alpha)", color_space, color_space),
17912        &format!("{}(25% 20 50 / 0.4)", color_space),
17913      );
17914      test(
17915        &format!(
17916          "{}(from {}(200% 300 400 / 500%) l a b / alpha)",
17917          color_space, color_space
17918        ),
17919        &format!("{}(200% 300 400)", color_space),
17920      );
17921      test(
17922        &format!(
17923          "{}(from {}(-200% -300 -400 / -500%) l a b / alpha)",
17924          color_space, color_space
17925        ),
17926        &format!("{}(0% -300 -400 / 0)", color_space),
17927      );
17928
17929      // Test nesting relative colors.
17930      test(
17931        &format!(
17932          "{}(from {}(from {}(25% 20 50) l a b) l a b)",
17933          color_space, color_space, color_space
17934        ),
17935        &format!("{}(25% 20 50)", color_space),
17936      );
17937
17938      // Testing non-${colorSpace} origin to see conversion.
17939      test(
17940        &format!("{}(from color(display-p3 0 0 0) l a b / alpha)", color_space),
17941        &format!("{}(0% 0 0)", color_space),
17942      );
17943
17944      // Testing replacement with 0.
17945      test(
17946        &format!("{}(from {}(25% 20 50) 0% 0 0)", color_space, color_space),
17947        &format!("{}(0% 0 0)", color_space),
17948      );
17949      test(
17950        &format!("{}(from {}(25% 20 50) 0% 0 0 / 0)", color_space, color_space),
17951        &format!("{}(0% 0 0 / 0)", color_space),
17952      );
17953      test(
17954        &format!("{}(from {}(25% 20 50) 0% a b / alpha)", color_space, color_space),
17955        &format!("{}(0% 20 50)", color_space),
17956      );
17957      test(
17958        &format!("{}(from {}(25% 20 50) l 0 b / alpha)", color_space, color_space),
17959        &format!("{}(25% 0 50)", color_space),
17960      );
17961      test(
17962        &format!("{}(from {}(25% 20 50) l a 0 / alpha)", color_space, color_space),
17963        &format!("{}(25% 20 0)", color_space),
17964      );
17965      test(
17966        &format!("{}(from {}(25% 20 50) l a b / 0)", color_space, color_space),
17967        &format!("{}(25% 20 50 / 0)", color_space),
17968      );
17969      test(
17970        &format!("{}(from {}(25% 20 50 / 40%) 0% a b / alpha)", color_space, color_space),
17971        &format!("{}(0% 20 50 / 0.4)", color_space),
17972      );
17973      test(
17974        &format!("{}(from {}(25% 20 50 / 40%) l 0 b / alpha)", color_space, color_space),
17975        &format!("{}(25% 0 50 / 0.4)", color_space),
17976      );
17977      test(
17978        &format!("{}(from {}(25% 20 50 / 40%) l a 0 / alpha)", color_space, color_space),
17979        &format!("{}(25% 20 0 / 0.4)", color_space),
17980      );
17981      test(
17982        &format!("{}(from {}(25% 20 50 / 40%) l a b / 0)", color_space, color_space),
17983        &format!("{}(25% 20 50 / 0)", color_space),
17984      );
17985
17986      // Testing replacement with a constant.
17987      test(
17988        &format!("{}(from {}(25% 20 50) 35% a b / alpha)", color_space, color_space),
17989        &format!("{}(35% 20 50)", color_space),
17990      );
17991      test(
17992        &format!("{}(from {}(25% 20 50) l 35 b / alpha)", color_space, color_space),
17993        &format!("{}(25% 35 50)", color_space),
17994      );
17995      test(
17996        &format!("{}(from {}(25% 20 50) l a 35 / alpha)", color_space, color_space),
17997        &format!("{}(25% 20 35)", color_space),
17998      );
17999      test(
18000        &format!("{}(from {}(25% 20 50) l a b / .35)", color_space, color_space),
18001        &format!("{}(25% 20 50 / 0.35)", color_space),
18002      );
18003      test(
18004        &format!("{}(from {}(25% 20 50 / 40%) 35% a b / alpha)", color_space, color_space),
18005        &format!("{}(35% 20 50 / 0.4)", color_space),
18006      );
18007      test(
18008        &format!("{}(from {}(25% 20 50 / 40%) l 35 b / alpha)", color_space, color_space),
18009        &format!("{}(25% 35 50 / 0.4)", color_space),
18010      );
18011      test(
18012        &format!("{}(from {}(25% 20 50 / 40%) l a 35 / alpha)", color_space, color_space),
18013        &format!("{}(25% 20 35 / 0.4)", color_space),
18014      );
18015      test(
18016        &format!("{}(from {}(25% 20 50 / 40%) l a b / .35)", color_space, color_space),
18017        &format!("{}(25% 20 50 / 0.35)", color_space),
18018      );
18019      test(
18020        &format!(
18021          "{}(from {}(70% 45 30 / 40%) 200% 300 400 / 500)",
18022          color_space, color_space
18023        ),
18024        &format!("{}(200% 300 400)", color_space),
18025      );
18026      test(
18027        &format!(
18028          "{}(from {}(70% 45 30 / 40%) -200% -300 -400 / -500)",
18029          color_space, color_space
18030        ),
18031        &format!("{}(0% -300 -400 / 0)", color_space),
18032      );
18033
18034      // Testing valid permutation (types match).
18035      test(
18036        &format!("{}(from {}(25% 20 50) l b a)", color_space, color_space),
18037        &format!("{}(25% 50 20)", color_space),
18038      );
18039      test(
18040        &format!("{}(from {}(25% 20 50) l a a / a)", color_space, color_space),
18041        &format!("{}(25% 20 20)", color_space),
18042      );
18043      test(
18044        &format!("{}(from {}(25% 20 50 / 40%) l b a)", color_space, color_space),
18045        &format!("{}(25% 50 20)", color_space),
18046      );
18047      test(
18048        &format!("{}(from {}(25% 20 50 / 40%) l a a / a)", color_space, color_space),
18049        &format!("{}(25% 20 20)", color_space),
18050      );
18051
18052      // Testing with calc().
18053      test(
18054        &format!(
18055          "{}(from {}(25% 20 50) calc(l) calc(a) calc(b))",
18056          color_space, color_space
18057        ),
18058        &format!("{}(25% 20 50)", color_space),
18059      );
18060      test(
18061        &format!(
18062          "{}(from {}(25% 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))",
18063          color_space, color_space
18064        ),
18065        &format!("{}(25% 20 50 / 0.4)", color_space),
18066      );
18067
18068      // Testing with 'none'.
18069      test(
18070        &format!("{}(from {}(25% 20 50) none none none)", color_space, color_space),
18071        &format!("{}(none none none)", color_space),
18072      );
18073      test(
18074        &format!("{}(from {}(25% 20 50) none none none / none)", color_space, color_space),
18075        &format!("{}(none none none / none)", color_space),
18076      );
18077      test(
18078        &format!("{}(from {}(25% 20 50) l a none)", color_space, color_space),
18079        &format!("{}(25% 20 none)", color_space),
18080      );
18081      test(
18082        &format!("{}(from {}(25% 20 50) l a none / alpha)", color_space, color_space),
18083        &format!("{}(25% 20 none)", color_space),
18084      );
18085      test(
18086        &format!("{}(from {}(25% 20 50) l a b / none)", color_space, color_space),
18087        &format!("{}(25% 20 50 / none)", color_space),
18088      );
18089      test(
18090        &format!(
18091          "{}(from {}(25% 20 50 / 40%) l a none / alpha)",
18092          color_space, color_space
18093        ),
18094        &format!("{}(25% 20 none / 0.4)", color_space),
18095      );
18096      test(
18097        &format!("{}(from {}(25% 20 50 / 40%) l a b / none)", color_space, color_space),
18098        &format!("{}(25% 20 50 / none)", color_space),
18099      );
18100      // FIXME: Clarify with spec editors if 'none' should pass through to the constants.
18101      test(
18102        &format!("{}(from {}(none none none) l a b)", color_space, color_space),
18103        &format!("{}(0% 0 0)", color_space),
18104      );
18105      test(
18106        &format!(
18107          "{}(from {}(none none none / none) l a b / alpha)",
18108          color_space, color_space
18109        ),
18110        &format!("{}(0% 0 0 / 0)", color_space),
18111      );
18112      test(
18113        &format!("{}(from {}(25% none 50) l a b)", color_space, color_space),
18114        &format!("{}(25% 0 50)", color_space),
18115      );
18116      test(
18117        &format!("{}(from {}(25% 20 50 / none) l a b / alpha)", color_space, color_space),
18118        &format!("{}(25% 20 50 / 0)", color_space),
18119      );
18120    }
18121
18122    // test_valid_value\(`color`, `\$\{colorSpace\}\(from \$\{colorSpace\}\((.*?)`,\s*`\$\{colorSpace\}(.*?)`\)
18123    // test(&format!("{}(from {}($1", color_space, color_space), &format!("{}$2", color_space))
18124
18125    for color_space in &["lch", "oklch"] {
18126      // Testing no modifications.
18127      test(
18128        &format!("{}(from {}(70% 45 30) l c h)", color_space, color_space),
18129        &format!("{}(70% 45 30)", color_space),
18130      );
18131      test(
18132        &format!("{}(from {}(70% 45 30) l c h / alpha)", color_space, color_space),
18133        &format!("{}(70% 45 30)", color_space),
18134      );
18135      test(
18136        &format!("{}(from {}(70% 45 30 / 40%) l c h / alpha)", color_space, color_space),
18137        &format!("{}(70% 45 30 / 0.4)", color_space),
18138      );
18139      test(
18140        &format!(
18141          "{}(from {}(200% 300 400 / 500%) l c h / alpha)",
18142          color_space, color_space
18143        ),
18144        &format!("{}(200% 300 40)", color_space),
18145      );
18146      test(
18147        &format!(
18148          "{}(from {}(-200% -300 -400 / -500%) l c h / alpha)",
18149          color_space, color_space
18150        ),
18151        &format!("{}(0% 0 320 / 0)", color_space),
18152      );
18153
18154      // Test nesting relative colors.
18155      test(
18156        &format!(
18157          "{}(from {}(from {}(70% 45 30) l c h) l c h)",
18158          color_space, color_space, color_space
18159        ),
18160        &format!("{}(70% 45 30)", color_space),
18161      );
18162
18163      // Testing non-sRGB origin colors (no gamut mapping will happen since the destination is not a bounded RGB color space).
18164      test(
18165        &format!("{}(from color(display-p3 0 0 0) l c h / alpha)", color_space),
18166        &format!("{}(0% 0 0)", color_space),
18167      );
18168
18169      // Testing replacement with 0.
18170      test(
18171        &format!("{}(from {}(70% 45 30) 0% 0 0)", color_space, color_space),
18172        &format!("{}(0% 0 0)", color_space),
18173      );
18174      test(
18175        &format!("{}(from {}(70% 45 30) 0% 0 0deg)", color_space, color_space),
18176        &format!("{}(0% 0 0)", color_space),
18177      );
18178      test(
18179        &format!("{}(from {}(70% 45 30) 0% 0 0 / 0)", color_space, color_space),
18180        &format!("{}(0% 0 0 / 0)", color_space),
18181      );
18182      test(
18183        &format!("{}(from {}(70% 45 30) 0% 0 0deg / 0)", color_space, color_space),
18184        &format!("{}(0% 0 0 / 0)", color_space),
18185      );
18186      test(
18187        &format!("{}(from {}(70% 45 30) 0% c h / alpha)", color_space, color_space),
18188        &format!("{}(0% 45 30)", color_space),
18189      );
18190      test(
18191        &format!("{}(from {}(70% 45 30) l 0 h / alpha)", color_space, color_space),
18192        &format!("{}(70% 0 30)", color_space),
18193      );
18194      test(
18195        &format!("{}(from {}(70% 45 30) l c 0 / alpha)", color_space, color_space),
18196        &format!("{}(70% 45 0)", color_space),
18197      );
18198      test(
18199        &format!("{}(from {}(70% 45 30) l c 0deg / alpha)", color_space, color_space),
18200        &format!("{}(70% 45 0)", color_space),
18201      );
18202      test(
18203        &format!("{}(from {}(70% 45 30) l c h / 0)", color_space, color_space),
18204        &format!("{}(70% 45 30 / 0)", color_space),
18205      );
18206      test(
18207        &format!("{}(from {}(70% 45 30 / 40%) 0% c h / alpha)", color_space, color_space),
18208        &format!("{}(0% 45 30 / 0.4)", color_space),
18209      );
18210      test(
18211        &format!("{}(from {}(70% 45 30 / 40%) l 0 h / alpha)", color_space, color_space),
18212        &format!("{}(70% 0 30 / 0.4)", color_space),
18213      );
18214      test(
18215        &format!("{}(from {}(70% 45 30 / 40%) l c 0 / alpha)", color_space, color_space),
18216        &format!("{}(70% 45 0 / 0.4)", color_space),
18217      );
18218      test(
18219        &format!(
18220          "{}(from {}(70% 45 30 / 40%) l c 0deg / alpha)",
18221          color_space, color_space
18222        ),
18223        &format!("{}(70% 45 0 / 0.4)", color_space),
18224      );
18225      test(
18226        &format!("{}(from {}(70% 45 30 / 40%) l c h / 0)", color_space, color_space),
18227        &format!("{}(70% 45 30 / 0)", color_space),
18228      );
18229
18230      // Testing replacement with a constant.
18231      test(
18232        &format!("{}(from {}(70% 45 30) 25% c h / alpha)", color_space, color_space),
18233        &format!("{}(25% 45 30)", color_space),
18234      );
18235      test(
18236        &format!("{}(from {}(70% 45 30) l 25 h / alpha)", color_space, color_space),
18237        &format!("{}(70% 25 30)", color_space),
18238      );
18239      test(
18240        &format!("{}(from {}(70% 45 30) l c 25 / alpha)", color_space, color_space),
18241        &format!("{}(70% 45 25)", color_space),
18242      );
18243      test(
18244        &format!("{}(from {}(70% 45 30) l c 25deg / alpha)", color_space, color_space),
18245        &format!("{}(70% 45 25)", color_space),
18246      );
18247      test(
18248        &format!("{}(from {}(70% 45 30) l c h / .25)", color_space, color_space),
18249        &format!("{}(70% 45 30 / 0.25)", color_space),
18250      );
18251      test(
18252        &format!("{}(from {}(70% 45 30 / 40%) 25% c h / alpha)", color_space, color_space),
18253        &format!("{}(25% 45 30 / 0.4)", color_space),
18254      );
18255      test(
18256        &format!("{}(from {}(70% 45 30 / 40%) l 25 h / alpha)", color_space, color_space),
18257        &format!("{}(70% 25 30 / 0.4)", color_space),
18258      );
18259      test(
18260        &format!("{}(from {}(70% 45 30 / 40%) l c 25 / alpha)", color_space, color_space),
18261        &format!("{}(70% 45 25 / 0.4)", color_space),
18262      );
18263      test(
18264        &format!(
18265          "{}(from {}(70% 45 30 / 40%) l c 25deg / alpha)",
18266          color_space, color_space
18267        ),
18268        &format!("{}(70% 45 25 / 0.4)", color_space),
18269      );
18270      test(
18271        &format!("{}(from {}(70% 45 30 / 40%) l c h / .25)", color_space, color_space),
18272        &format!("{}(70% 45 30 / 0.25)", color_space),
18273      );
18274      test(
18275        &format!(
18276          "{}(from {}(70% 45 30 / 40%) 200% 300 400 / 500)",
18277          color_space, color_space
18278        ),
18279        &format!("{}(200% 300 400)", color_space),
18280      );
18281      test(
18282        &format!(
18283          "{}(from {}(70% 45 30 / 40%) -200% -300 -400 / -500)",
18284          color_space, color_space
18285        ),
18286        &format!("{}(0% 0 -400 / 0)", color_space),
18287      );
18288      test(
18289        &format!(
18290          "{}(from {}(70% 45 30 / 40%) 50% 120 400deg / 500)",
18291          color_space, color_space
18292        ),
18293        &format!("{}(50% 120 400)", color_space),
18294      );
18295      test(
18296        &format!(
18297          "{}(from {}(70% 45 30 / 40%) 50% 120 -400deg / -500)",
18298          color_space, color_space
18299        ),
18300        &format!("{}(50% 120 -400 / 0)", color_space),
18301      );
18302
18303      // Testing valid permutation (types match).
18304      // NOTE: 'c' is a valid hue, as hue is <angle>|<number>.
18305      test(
18306        &format!("{}(from {}(70% 45 30) alpha c h / l)", color_space, color_space),
18307        &format!("{}(100% 45 30 / 0.7)", color_space),
18308      );
18309      test(
18310        &format!("{}(from {}(70% 45 30) l c c / alpha)", color_space, color_space),
18311        &format!("{}(70% 45 45)", color_space),
18312      );
18313      test(
18314        &format!("{}(from {}(70% 45 30) alpha c h / alpha)", color_space, color_space),
18315        &format!("{}(100% 45 30)", color_space),
18316      );
18317      test(
18318        &format!("{}(from {}(70% 45 30) alpha c c / alpha)", color_space, color_space),
18319        &format!("{}(100% 45 45)", color_space),
18320      );
18321      test(
18322        &format!("{}(from {}(70% 45 30 / 40%) alpha c h / l)", color_space, color_space),
18323        &format!("{}(40% 45 30 / 0.7)", color_space),
18324      );
18325      test(
18326        &format!("{}(from {}(70% 45 30 / 40%) l c c / alpha)", color_space, color_space),
18327        &format!("{}(70% 45 45 / 0.4)", color_space),
18328      );
18329      test(
18330        &format!(
18331          "{}(from {}(70% 45 30 / 40%) alpha c h / alpha)",
18332          color_space, color_space
18333        ),
18334        &format!("{}(40% 45 30 / 0.4)", color_space),
18335      );
18336      test(
18337        &format!(
18338          "{}(from {}(70% 45 30 / 40%) alpha c c / alpha)",
18339          color_space, color_space
18340        ),
18341        &format!("{}(40% 45 45 / 0.4)", color_space),
18342      );
18343
18344      // Testing with calc().
18345      test(
18346        &format!(
18347          "{}(from {}(70% 45 30) calc(l) calc(c) calc(h))",
18348          color_space, color_space
18349        ),
18350        &format!("{}(70% 45 30)", color_space),
18351      );
18352      test(
18353        &format!(
18354          "{}(from {}(70% 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))",
18355          color_space, color_space
18356        ),
18357        &format!("{}(70% 45 30 / 0.4)", color_space),
18358      );
18359
18360      // Testing with 'none'.
18361      test(
18362        &format!("{}(from {}(70% 45 30) none none none)", color_space, color_space),
18363        &format!("{}(none none none)", color_space),
18364      );
18365      test(
18366        &format!("{}(from {}(70% 45 30) none none none / none)", color_space, color_space),
18367        &format!("{}(none none none / none)", color_space),
18368      );
18369      test(
18370        &format!("{}(from {}(70% 45 30) l c none)", color_space, color_space),
18371        &format!("{}(70% 45 none)", color_space),
18372      );
18373      test(
18374        &format!("{}(from {}(70% 45 30) l c none / alpha)", color_space, color_space),
18375        &format!("{}(70% 45 none)", color_space),
18376      );
18377      test(
18378        &format!("{}(from {}(70% 45 30) l c h / none)", color_space, color_space),
18379        &format!("{}(70% 45 30 / none)", color_space),
18380      );
18381      test(
18382        &format!(
18383          "{}(from {}(70% 45 30 / 40%) l c none / alpha)",
18384          color_space, color_space
18385        ),
18386        &format!("{}(70% 45 none / 0.4)", color_space),
18387      );
18388      test(
18389        &format!("{}(from {}(70% 45 30 / 40%) l c h / none)", color_space, color_space),
18390        &format!("{}(70% 45 30 / none)", color_space),
18391      );
18392      // FIXME: Clarify with spec editors if 'none' should pass through to the constants.
18393      test(
18394        &format!("{}(from {}(none none none) l c h)", color_space, color_space),
18395        &format!("{}(0% 0 0)", color_space),
18396      );
18397      test(
18398        &format!(
18399          "{}(from {}(none none none / none) l c h / alpha)",
18400          color_space, color_space
18401        ),
18402        &format!("{}(0% 0 0 / 0)", color_space),
18403      );
18404      test(
18405        &format!("{}(from {}(70% none 30) l c h)", color_space, color_space),
18406        &format!("{}(70% 0 30)", color_space),
18407      );
18408      test(
18409        &format!("{}(from {}(70% 45 30 / none) l c h / alpha)", color_space, color_space),
18410        &format!("{}(70% 45 30 / 0)", color_space),
18411      );
18412    }
18413
18414    // test_valid_value\(`color`, `color\(from color\(\$\{colorSpace\}(.*?) \$\{colorSpace\}(.*?)`,\s*`color\(\$\{colorSpace\}(.*?)`\)
18415    // test(&format!("color(from color({}$1 {}$2", color_space, color_space), &format!("color({}$3", color_space))
18416
18417    for color_space in &["srgb", "srgb-linear", "a98-rgb", "rec2020", "prophoto-rgb"] {
18418      // Testing no modifications.
18419      test(
18420        &format!("color(from color({} 0.7 0.5 0.3) {} r g b)", color_space, color_space),
18421        &format!("color({} 0.7 0.5 0.3)", color_space),
18422      );
18423      test(
18424        &format!(
18425          "color(from color({} 0.7 0.5 0.3) {} r g b / alpha)",
18426          color_space, color_space
18427        ),
18428        &format!("color({} 0.7 0.5 0.3)", color_space),
18429      );
18430      test(
18431        &format!(
18432          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g b)",
18433          color_space, color_space
18434        ),
18435        &format!("color({} 0.7 0.5 0.3)", color_space),
18436      );
18437      test(
18438        &format!(
18439          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g b / alpha)",
18440          color_space, color_space
18441        ),
18442        &format!("color({} 0.7 0.5 0.3 / 0.4)", color_space),
18443      );
18444
18445      // Test nesting relative colors.
18446      test(
18447        &format!(
18448          "color(from color(from color({} 0.7 0.5 0.3) {} r g b) {} r g b)",
18449          color_space, color_space, color_space
18450        ),
18451        &format!("color({} 0.7 0.5 0.3)", color_space),
18452      );
18453
18454      // Testing replacement with 0.
18455      test(
18456        &format!("color(from color({} 0.7 0.5 0.3) {} 0 0 0)", color_space, color_space),
18457        &format!("color({} 0 0 0)", color_space),
18458      );
18459      test(
18460        &format!(
18461          "color(from color({} 0.7 0.5 0.3) {} 0 0 0 / 0)",
18462          color_space, color_space
18463        ),
18464        &format!("color({} 0 0 0 / 0)", color_space),
18465      );
18466      test(
18467        &format!(
18468          "color(from color({} 0.7 0.5 0.3) {} 0 g b / alpha)",
18469          color_space, color_space
18470        ),
18471        &format!("color({} 0 0.5 0.3)", color_space),
18472      );
18473      test(
18474        &format!(
18475          "color(from color({} 0.7 0.5 0.3) {} r 0 b / alpha)",
18476          color_space, color_space
18477        ),
18478        &format!("color({} 0.7 0 0.3)", color_space),
18479      );
18480      test(
18481        &format!(
18482          "color(from color({} 0.7 0.5 0.3) {} r g 0 / alpha)",
18483          color_space, color_space
18484        ),
18485        &format!("color({} 0.7 0.5 0)", color_space),
18486      );
18487      test(
18488        &format!(
18489          "color(from color({} 0.7 0.5 0.3) {} r g b / 0)",
18490          color_space, color_space
18491        ),
18492        &format!("color({} 0.7 0.5 0.3 / 0)", color_space),
18493      );
18494      test(
18495        &format!(
18496          "color(from color({} 0.7 0.5 0.3 / 40%) {} 0 g b / alpha)",
18497          color_space, color_space
18498        ),
18499        &format!("color({} 0 0.5 0.3 / 0.4)", color_space),
18500      );
18501      test(
18502        &format!(
18503          "color(from color({} 0.7 0.5 0.3 / 40%) {} r 0 b / alpha)",
18504          color_space, color_space
18505        ),
18506        &format!("color({} 0.7 0 0.3 / 0.4)", color_space),
18507      );
18508      test(
18509        &format!(
18510          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g 0 / alpha)",
18511          color_space, color_space
18512        ),
18513        &format!("color({} 0.7 0.5 0 / 0.4)", color_space),
18514      );
18515      test(
18516        &format!(
18517          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g b / 0)",
18518          color_space, color_space
18519        ),
18520        &format!("color({} 0.7 0.5 0.3 / 0)", color_space),
18521      );
18522
18523      // Testing replacement with a constant.
18524      test(
18525        &format!(
18526          "color(from color({} 0.7 0.5 0.3) {} 0.2 g b / alpha)",
18527          color_space, color_space
18528        ),
18529        &format!("color({} 0.2 0.5 0.3)", color_space),
18530      );
18531      test(
18532        &format!(
18533          "color(from color({} 0.7 0.5 0.3) {} 20% g b / alpha)",
18534          color_space, color_space
18535        ),
18536        &format!("color({} 0.2 0.5 0.3)", color_space),
18537      );
18538      test(
18539        &format!(
18540          "color(from color({} 0.7 0.5 0.3) {} r 0.2 b / alpha)",
18541          color_space, color_space
18542        ),
18543        &format!("color({} 0.7 0.2 0.3)", color_space),
18544      );
18545      test(
18546        &format!(
18547          "color(from color({} 0.7 0.5 0.3) {} r 20% b / alpha)",
18548          color_space, color_space
18549        ),
18550        &format!("color({} 0.7 0.2 0.3)", color_space),
18551      );
18552      test(
18553        &format!(
18554          "color(from color({} 0.7 0.5 0.3) {} r g 0.2 / alpha)",
18555          color_space, color_space
18556        ),
18557        &format!("color({} 0.7 0.5 0.2)", color_space),
18558      );
18559      test(
18560        &format!(
18561          "color(from color({} 0.7 0.5 0.3) {} r g 20% / alpha)",
18562          color_space, color_space
18563        ),
18564        &format!("color({} 0.7 0.5 0.2)", color_space),
18565      );
18566      test(
18567        &format!(
18568          "color(from color({} 0.7 0.5 0.3) {} r g b / 0.2)",
18569          color_space, color_space
18570        ),
18571        &format!("color({} 0.7 0.5 0.3 / 0.2)", color_space),
18572      );
18573      test(
18574        &format!(
18575          "color(from color({} 0.7 0.5 0.3) {} r g b / 20%)",
18576          color_space, color_space
18577        ),
18578        &format!("color({} 0.7 0.5 0.3 / 0.2)", color_space),
18579      );
18580      test(
18581        &format!(
18582          "color(from color({} 0.7 0.5 0.3 / 40%) {} 0.2 g b / alpha)",
18583          color_space, color_space
18584        ),
18585        &format!("color({} 0.2 0.5 0.3 / 0.4)", color_space),
18586      );
18587      test(
18588        &format!(
18589          "color(from color({} 0.7 0.5 0.3 / 40%) {} 20% g b / alpha)",
18590          color_space, color_space
18591        ),
18592        &format!("color({} 0.2 0.5 0.3 / 0.4)", color_space),
18593      );
18594      test(
18595        &format!(
18596          "color(from color({} 0.7 0.5 0.3 / 40%) {} r 0.2 b / alpha)",
18597          color_space, color_space
18598        ),
18599        &format!("color({} 0.7 0.2 0.3 / 0.4)", color_space),
18600      );
18601      test(
18602        &format!(
18603          "color(from color({} 0.7 0.5 0.3 / 40%) {} r 20% b / alpha)",
18604          color_space, color_space
18605        ),
18606        &format!("color({} 0.7 0.2 0.3 / 0.4)", color_space),
18607      );
18608      test(
18609        &format!(
18610          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g 0.2 / alpha)",
18611          color_space, color_space
18612        ),
18613        &format!("color({} 0.7 0.5 0.2 / 0.4)", color_space),
18614      );
18615      test(
18616        &format!(
18617          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g 20% / alpha)",
18618          color_space, color_space
18619        ),
18620        &format!("color({} 0.7 0.5 0.2 / 0.4)", color_space),
18621      );
18622      test(
18623        &format!(
18624          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g b / 0.2)",
18625          color_space, color_space
18626        ),
18627        &format!("color({} 0.7 0.5 0.3 / 0.2)", color_space),
18628      );
18629      test(
18630        &format!(
18631          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g b / 20%)",
18632          color_space, color_space
18633        ),
18634        &format!("color({} 0.7 0.5 0.3 / 0.2)", color_space),
18635      );
18636      test(
18637        &format!("color(from color({} 0.7 0.5 0.3) {} 2 3 4)", color_space, color_space),
18638        &format!("color({} 2 3 4)", color_space),
18639      );
18640      test(
18641        &format!(
18642          "color(from color({} 0.7 0.5 0.3) {} 2 3 4 / 5)",
18643          color_space, color_space
18644        ),
18645        &format!("color({} 2 3 4)", color_space),
18646      );
18647      test(
18648        &format!(
18649          "color(from color({} 0.7 0.5 0.3) {} -2 -3 -4)",
18650          color_space, color_space
18651        ),
18652        &format!("color({} -2 -3 -4)", color_space),
18653      );
18654      test(
18655        &format!(
18656          "color(from color({} 0.7 0.5 0.3) {} -2 -3 -4 / -5)",
18657          color_space, color_space
18658        ),
18659        &format!("color({} -2 -3 -4 / 0)", color_space),
18660      );
18661      test(
18662        &format!(
18663          "color(from color({} 0.7 0.5 0.3) {} 200% 300% 400%)",
18664          color_space, color_space
18665        ),
18666        &format!("color({} 2 3 4)", color_space),
18667      );
18668      test(
18669        &format!(
18670          "color(from color({} 0.7 0.5 0.3) {} 200% 300% 400% / 500%)",
18671          color_space, color_space
18672        ),
18673        &format!("color({} 2 3 4)", color_space),
18674      );
18675      test(
18676        &format!(
18677          "color(from color({} 0.7 0.5 0.3) {} -200% -300% -400%)",
18678          color_space, color_space
18679        ),
18680        &format!("color({} -2 -3 -4)", color_space),
18681      );
18682      test(
18683        &format!(
18684          "color(from color({} 0.7 0.5 0.3) {} -200% -300% -400% / -500%)",
18685          color_space, color_space
18686        ),
18687        &format!("color({} -2 -3 -4 / 0)", color_space),
18688      );
18689
18690      // Testing valid permutation (types match).
18691      test(
18692        &format!("color(from color({} 0.7 0.5 0.3) {} g b r)", color_space, color_space),
18693        &format!("color({} 0.5 0.3 0.7)", color_space),
18694      );
18695      test(
18696        &format!(
18697          "color(from color({} 0.7 0.5 0.3) {} b alpha r / g)",
18698          color_space, color_space
18699        ),
18700        &format!("color({} 0.3 1 0.7 / 0.5)", color_space),
18701      );
18702      test(
18703        &format!(
18704          "color(from color({} 0.7 0.5 0.3) {} r r r / r)",
18705          color_space, color_space
18706        ),
18707        &format!("color({} 0.7 0.7 0.7 / 0.7)", color_space),
18708      );
18709      test(
18710        &format!(
18711          "color(from color({} 0.7 0.5 0.3) {} alpha alpha alpha / alpha)",
18712          color_space, color_space
18713        ),
18714        &format!("color({} 1 1 1)", color_space),
18715      );
18716      test(
18717        &format!(
18718          "color(from color({} 0.7 0.5 0.3 / 40%) {} g b r)",
18719          color_space, color_space
18720        ),
18721        &format!("color({} 0.5 0.3 0.7)", color_space),
18722      );
18723      test(
18724        &format!(
18725          "color(from color({} 0.7 0.5 0.3 / 40%) {} b alpha r / g)",
18726          color_space, color_space
18727        ),
18728        &format!("color({} 0.3 0.4 0.7 / 0.5)", color_space),
18729      );
18730      test(
18731        &format!(
18732          "color(from color({} 0.7 0.5 0.3 / 40%) {} r r r / r)",
18733          color_space, color_space
18734        ),
18735        &format!("color({} 0.7 0.7 0.7 / 0.7)", color_space),
18736      );
18737      test(
18738        &format!(
18739          "color(from color({} 0.7 0.5 0.3 / 40%) {} alpha alpha alpha / alpha)",
18740          color_space, color_space
18741        ),
18742        &format!("color({} 0.4 0.4 0.4 / 0.4)", color_space),
18743      );
18744
18745      // Testing out of gamut components.
18746      test(
18747        &format!("color(from color({} 1.7 1.5 1.3) {} r g b)", color_space, color_space),
18748        &format!("color({} 1.7 1.5 1.3)", color_space),
18749      );
18750      test(
18751        &format!(
18752          "color(from color({} 1.7 1.5 1.3) {} r g b / alpha)",
18753          color_space, color_space
18754        ),
18755        &format!("color({} 1.7 1.5 1.3)", color_space),
18756      );
18757      test(
18758        &format!(
18759          "color(from color({} 1.7 1.5 1.3 / 140%) {} r g b)",
18760          color_space, color_space
18761        ),
18762        &format!("color({} 1.7 1.5 1.3)", color_space),
18763      );
18764      test(
18765        &format!(
18766          "color(from color({} 1.7 1.5 1.3 / 140%) {} r g b / alpha)",
18767          color_space, color_space
18768        ),
18769        &format!("color({} 1.7 1.5 1.3)", color_space),
18770      );
18771      test(
18772        &format!(
18773          "color(from color({} -0.7 -0.5 -0.3) {} r g b)",
18774          color_space, color_space
18775        ),
18776        &format!("color({} -0.7 -0.5 -0.3)", color_space),
18777      );
18778      test(
18779        &format!(
18780          "color(from color({} -0.7 -0.5 -0.3) {} r g b / alpha)",
18781          color_space, color_space
18782        ),
18783        &format!("color({} -0.7 -0.5 -0.3)", color_space),
18784      );
18785      test(
18786        &format!(
18787          "color(from color({} -0.7 -0.5 -0.3 / -40%) {} r g b)",
18788          color_space, color_space
18789        ),
18790        &format!("color({} -0.7 -0.5 -0.3)", color_space),
18791      );
18792      test(
18793        &format!(
18794          "color(from color({} -0.7 -0.5 -0.3 / -40%) {} r g b / alpha)",
18795          color_space, color_space
18796        ),
18797        &format!("color({} -0.7 -0.5 -0.3 / 0)", color_space),
18798      );
18799
18800      // Testing with calc().
18801      test(
18802        &format!(
18803          "color(from color({} 0.7 0.5 0.3) {} calc(r) calc(g) calc(b))",
18804          color_space, color_space
18805        ),
18806        &format!("color({} 0.7 0.5 0.3)", color_space),
18807      );
18808      test(
18809        &format!(
18810          "color(from color({} 0.7 0.5 0.3 / 40%) {} calc(r) calc(g) calc(b) / calc(alpha))",
18811          color_space, color_space
18812        ),
18813        &format!("color({} 0.7 0.5 0.3 / 0.4)", color_space),
18814      );
18815
18816      // Testing with 'none'.
18817      test(
18818        &format!(
18819          "color(from color({} 0.7 0.5 0.3) {} none none none)",
18820          color_space, color_space
18821        ),
18822        &format!("color({} none none none)", color_space),
18823      );
18824      test(
18825        &format!(
18826          "color(from color({} 0.7 0.5 0.3) {} none none none / none)",
18827          color_space, color_space
18828        ),
18829        &format!("color({} none none none / none)", color_space),
18830      );
18831      test(
18832        &format!(
18833          "color(from color({} 0.7 0.5 0.3) {} r g none)",
18834          color_space, color_space
18835        ),
18836        &format!("color({} 0.7 0.5 none)", color_space),
18837      );
18838      test(
18839        &format!(
18840          "color(from color({} 0.7 0.5 0.3) {} r g none / alpha)",
18841          color_space, color_space
18842        ),
18843        &format!("color({} 0.7 0.5 none)", color_space),
18844      );
18845      test(
18846        &format!(
18847          "color(from color({} 0.7 0.5 0.3) {} r g b / none)",
18848          color_space, color_space
18849        ),
18850        &format!("color({} 0.7 0.5 0.3 / none)", color_space),
18851      );
18852      test(
18853        &format!(
18854          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g none / alpha)",
18855          color_space, color_space
18856        ),
18857        &format!("color({} 0.7 0.5 none / 0.4)", color_space),
18858      );
18859      test(
18860        &format!(
18861          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g b / none)",
18862          color_space, color_space
18863        ),
18864        &format!("color({} 0.7 0.5 0.3 / none)", color_space),
18865      );
18866      // FIXME: Clarify with spec editors if 'none' should pass through to the constants.
18867      test(
18868        &format!(
18869          "color(from color({} none none none) {} r g b)",
18870          color_space, color_space
18871        ),
18872        &format!("color({} 0 0 0)", color_space),
18873      );
18874      test(
18875        &format!(
18876          "color(from color({} none none none / none) {} r g b / alpha)",
18877          color_space, color_space
18878        ),
18879        &format!("color({} 0 0 0 / 0)", color_space),
18880      );
18881      test(
18882        &format!("color(from color({} 0.7 none 0.3) {} r g b)", color_space, color_space),
18883        &format!("color({} 0.7 0 0.3)", color_space),
18884      );
18885      test(
18886        &format!(
18887          "color(from color({} 0.7 0.5 0.3 / none) {} r g b / alpha)",
18888          color_space, color_space
18889        ),
18890        &format!("color({} 0.7 0.5 0.3 / 0)", color_space),
18891      );
18892    }
18893
18894    // test_valid_value\(`color`, `color\(from color\(\$\{colorSpace\}(.*?) \$\{colorSpace\}(.*?)`,\s*`color\(\$\{resultColorSpace\}(.*?)`\)
18895    // test(&format!("color(from color({}$1 {}$2", color_space, color_space), &format!("color({}$3", result_color_space))
18896
18897    for color_space in &["xyz", "xyz-d50", "xyz-d65"] {
18898      let result_color_space = if *color_space == "xyz" { "xyz-d65" } else { color_space };
18899
18900      // Testing no modifications.
18901      test(
18902        &format!("color(from color({} 7 -20.5 100) {} x y z)", color_space, color_space),
18903        &format!("color({} 7 -20.5 100)", result_color_space),
18904      );
18905      test(
18906        &format!(
18907          "color(from color({} 7 -20.5 100) {} x y z / alpha)",
18908          color_space, color_space
18909        ),
18910        &format!("color({} 7 -20.5 100)", result_color_space),
18911      );
18912      test(
18913        &format!(
18914          "color(from color({} 7 -20.5 100 / 40%) {} x y z)",
18915          color_space, color_space
18916        ),
18917        &format!("color({} 7 -20.5 100)", result_color_space),
18918      );
18919      test(
18920        &format!(
18921          "color(from color({} 7 -20.5 100 / 40%) {} x y z / alpha)",
18922          color_space, color_space
18923        ),
18924        &format!("color({} 7 -20.5 100 / 0.4)", result_color_space),
18925      );
18926
18927      // Test nesting relative colors.
18928      test(
18929        &format!(
18930          "color(from color(from color({} 7 -20.5 100) {} x y z) {} x y z)",
18931          color_space, color_space, color_space
18932        ),
18933        &format!("color({} 7 -20.5 100)", result_color_space),
18934      );
18935
18936      // Testing replacement with 0.
18937      test(
18938        &format!("color(from color({} 7 -20.5 100) {} 0 0 0)", color_space, color_space),
18939        &format!("color({} 0 0 0)", result_color_space),
18940      );
18941      test(
18942        &format!(
18943          "color(from color({} 7 -20.5 100) {} 0 0 0 / 0)",
18944          color_space, color_space
18945        ),
18946        &format!("color({} 0 0 0 / 0)", result_color_space),
18947      );
18948      test(
18949        &format!(
18950          "color(from color({} 7 -20.5 100) {} 0 y z / alpha)",
18951          color_space, color_space
18952        ),
18953        &format!("color({} 0 -20.5 100)", result_color_space),
18954      );
18955      test(
18956        &format!(
18957          "color(from color({} 7 -20.5 100) {} x 0 z / alpha)",
18958          color_space, color_space
18959        ),
18960        &format!("color({} 7 0 100)", result_color_space),
18961      );
18962      test(
18963        &format!(
18964          "color(from color({} 7 -20.5 100) {} x y 0 / alpha)",
18965          color_space, color_space
18966        ),
18967        &format!("color({} 7 -20.5 0)", result_color_space),
18968      );
18969      test(
18970        &format!(
18971          "color(from color({} 7 -20.5 100) {} x y z / 0)",
18972          color_space, color_space
18973        ),
18974        &format!("color({} 7 -20.5 100 / 0)", result_color_space),
18975      );
18976      test(
18977        &format!(
18978          "color(from color({} 7 -20.5 100 / 40%) {} 0 y z / alpha)",
18979          color_space, color_space
18980        ),
18981        &format!("color({} 0 -20.5 100 / 0.4)", result_color_space),
18982      );
18983      test(
18984        &format!(
18985          "color(from color({} 7 -20.5 100 / 40%) {} x 0 z / alpha)",
18986          color_space, color_space
18987        ),
18988        &format!("color({} 7 0 100 / 0.4)", result_color_space),
18989      );
18990      test(
18991        &format!(
18992          "color(from color({} 7 -20.5 100 / 40%) {} x y 0 / alpha)",
18993          color_space, color_space
18994        ),
18995        &format!("color({} 7 -20.5 0 / 0.4)", result_color_space),
18996      );
18997      test(
18998        &format!(
18999          "color(from color({} 7 -20.5 100 / 40%) {} x y z / 0)",
19000          color_space, color_space
19001        ),
19002        &format!("color({} 7 -20.5 100 / 0)", result_color_space),
19003      );
19004
19005      // Testing replacement with a constant.
19006      test(
19007        &format!(
19008          "color(from color({} 7 -20.5 100) {} 0.2 y z / alpha)",
19009          color_space, color_space
19010        ),
19011        &format!("color({} 0.2 -20.5 100)", result_color_space),
19012      );
19013      test(
19014        &format!(
19015          "color(from color({} 7 -20.5 100) {} x 0.2 z / alpha)",
19016          color_space, color_space
19017        ),
19018        &format!("color({} 7 0.2 100)", result_color_space),
19019      );
19020      test(
19021        &format!(
19022          "color(from color({} 7 -20.5 100) {} x y 0.2 / alpha)",
19023          color_space, color_space
19024        ),
19025        &format!("color({} 7 -20.5 0.2)", result_color_space),
19026      );
19027      test(
19028        &format!(
19029          "color(from color({} 7 -20.5 100) {} x y z / 0.2)",
19030          color_space, color_space
19031        ),
19032        &format!("color({} 7 -20.5 100 / 0.2)", result_color_space),
19033      );
19034      test(
19035        &format!(
19036          "color(from color({} 7 -20.5 100) {} x y z / 20%)",
19037          color_space, color_space
19038        ),
19039        &format!("color({} 7 -20.5 100 / 0.2)", result_color_space),
19040      );
19041      test(
19042        &format!(
19043          "color(from color({} 7 -20.5 100 / 40%) {} 0.2 y z / alpha)",
19044          color_space, color_space
19045        ),
19046        &format!("color({} 0.2 -20.5 100 / 0.4)", result_color_space),
19047      );
19048      test(
19049        &format!(
19050          "color(from color({} 7 -20.5 100 / 40%) {} x 0.2 z / alpha)",
19051          color_space, color_space
19052        ),
19053        &format!("color({} 7 0.2 100 / 0.4)", result_color_space),
19054      );
19055      test(
19056        &format!(
19057          "color(from color({} 7 -20.5 100 / 40%) {} x y 0.2 / alpha)",
19058          color_space, color_space
19059        ),
19060        &format!("color({} 7 -20.5 0.2 / 0.4)", result_color_space),
19061      );
19062      test(
19063        &format!(
19064          "color(from color({} 7 -20.5 100 / 40%) {} x y z / 0.2)",
19065          color_space, color_space
19066        ),
19067        &format!("color({} 7 -20.5 100 / 0.2)", result_color_space),
19068      );
19069
19070      // Testing valid permutation (types match).
19071      test(
19072        &format!("color(from color({} 7 -20.5 100) {} y z x)", color_space, color_space),
19073        &format!("color({} -20.5 100 7)", result_color_space),
19074      );
19075      test(
19076        &format!(
19077          "color(from color({} 7 -20.5 100) {} x x x / x)",
19078          color_space, color_space
19079        ),
19080        &format!("color({} 7 7 7)", result_color_space),
19081      );
19082      test(
19083        &format!(
19084          "color(from color({} 7 -20.5 100 / 40%) {} y z x)",
19085          color_space, color_space
19086        ),
19087        &format!("color({} -20.5 100 7)", result_color_space),
19088      );
19089      test(
19090        &format!(
19091          "color(from color({} 7 -20.5 100 / 40%) {} x x x / x)",
19092          color_space, color_space
19093        ),
19094        &format!("color({} 7 7 7)", result_color_space),
19095      );
19096
19097      // Testing with calc().
19098      test(
19099        &format!(
19100          "color(from color({} 7 -20.5 100) {} calc(x) calc(y) calc(z))",
19101          color_space, color_space
19102        ),
19103        &format!("color({} 7 -20.5 100)", result_color_space),
19104      );
19105      test(
19106        &format!(
19107          "color(from color({} 7 -20.5 100 / 40%) {} calc(x) calc(y) calc(z) / calc(alpha))",
19108          color_space, color_space
19109        ),
19110        &format!("color({} 7 -20.5 100 / 0.4)", result_color_space),
19111      );
19112
19113      // Testing with 'none'.
19114      test(
19115        &format!(
19116          "color(from color({} 7 -20.5 100) {} none none none)",
19117          color_space, color_space
19118        ),
19119        &format!("color({} none none none)", result_color_space),
19120      );
19121      test(
19122        &format!(
19123          "color(from color({} 7 -20.5 100) {} none none none / none)",
19124          color_space, color_space
19125        ),
19126        &format!("color({} none none none / none)", result_color_space),
19127      );
19128      test(
19129        &format!(
19130          "color(from color({} 7 -20.5 100) {} x y none)",
19131          color_space, color_space
19132        ),
19133        &format!("color({} 7 -20.5 none)", result_color_space),
19134      );
19135      test(
19136        &format!(
19137          "color(from color({} 7 -20.5 100) {} x y none / alpha)",
19138          color_space, color_space
19139        ),
19140        &format!("color({} 7 -20.5 none)", result_color_space),
19141      );
19142      test(
19143        &format!(
19144          "color(from color({} 7 -20.5 100) {} x y z / none)",
19145          color_space, color_space
19146        ),
19147        &format!("color({} 7 -20.5 100 / none)", result_color_space),
19148      );
19149      test(
19150        &format!(
19151          "color(from color({} 7 -20.5 100 / 40%) {} x y none / alpha)",
19152          color_space, color_space
19153        ),
19154        &format!("color({} 7 -20.5 none / 0.4)", result_color_space),
19155      );
19156      test(
19157        &format!(
19158          "color(from color({} 7 -20.5 100 / 40%) {} x y z / none)",
19159          color_space, color_space
19160        ),
19161        &format!("color({} 7 -20.5 100 / none)", result_color_space),
19162      );
19163      // FIXME: Clarify with spec editors if 'none' should pass through to the constants.
19164      test(
19165        &format!(
19166          "color(from color({} none none none) {} x y z)",
19167          color_space, color_space
19168        ),
19169        &format!("color({} 0 0 0)", result_color_space),
19170      );
19171      test(
19172        &format!(
19173          "color(from color({} none none none / none) {} x y z / alpha)",
19174          color_space, color_space
19175        ),
19176        &format!("color({} 0 0 0 / 0)", result_color_space),
19177      );
19178      test(
19179        &format!("color(from color({} 7 none 100) {} x y z)", color_space, color_space),
19180        &format!("color({} 7 0 100)", result_color_space),
19181      );
19182      test(
19183        &format!(
19184          "color(from color({} 7 -20.5 100 / none) {} x y z / alpha)",
19185          color_space, color_space
19186        ),
19187        &format!("color({} 7 -20.5 100 / 0)", result_color_space),
19188      );
19189
19190      // https://github.com/web-platform-tests/wpt/blob/master/css/css-color/parsing/relative-color-invalid.html
19191      minify_test(
19192        ".foo{color:rgb(from rebeccapurple r 10deg 10)}",
19193        ".foo{color:rgb(from rebeccapurple r 10deg 10)}",
19194      );
19195      minify_test(
19196        ".foo{color:rgb(from rebeccapurple l g b)}",
19197        ".foo{color:rgb(from rebeccapurple l g b)}",
19198      );
19199      minify_test(
19200        ".foo{color:hsl(from rebeccapurple s h l)}",
19201        ".foo{color:hsl(from rebeccapurple s h l)}",
19202      );
19203      minify_test(
19204        ".foo{color:hsl(from rebeccapurple s s s / s)}",
19205        ".foo{color:hsl(from rebeccapurple s s s/s)}",
19206      );
19207      minify_test(
19208        ".foo{color:hsl(from rebeccapurple alpha alpha alpha / alpha)}",
19209        ".foo{color:hsl(from rebeccapurple alpha alpha alpha/alpha)}",
19210      );
19211    }
19212  }
19213
19214  #[test]
19215  fn test_color_mix() {
19216    minify_test(
19217      ".foo { color: color-mix(in lab, purple 50%, plum 50%); }",
19218      ".foo{color:lab(51.5117% 43.3777 -29.0443)}",
19219    );
19220    minify_test(
19221      ".foo { color: color-mix(in lch, peru 40%, palegoldenrod); }",
19222      ".foo{color:lch(79.7255% 40.4542 84.7634)}",
19223    );
19224    minify_test(
19225      ".foo { color: color-mix(in lch, teal 65%, olive); }",
19226      ".foo{color:lch(49.4431% 40.4806 162.546)}",
19227    );
19228    minify_test(
19229      ".foo { color: color-mix(in lch, white, black); }",
19230      ".foo{color:lch(50% 0 none)}",
19231    );
19232    minify_test(
19233      ".foo { color: color-mix(in xyz, rgb(82.02% 30.21% 35.02%) 75.23%, rgb(5.64% 55.94% 85.31%)); }",
19234      ".foo{color:color(xyz .287458 .208776 .260566)}",
19235    );
19236    minify_test(
19237      ".foo { color: color-mix(in lch, white, blue); }",
19238      ".foo{color:lch(64.7842% 65.6007 301.364)}",
19239    );
19240    minify_test(
19241      ".foo { color: color-mix(in oklch, white, blue); }",
19242      ".foo{color:oklch(72.6007% .156607 264.052)}",
19243    );
19244    minify_test(
19245      ".foo { color: color-mix(in srgb, white, blue); }",
19246      ".foo{color:#8080ff}",
19247    );
19248    minify_test(
19249      ".foo { color: color-mix(in lch, blue, white); }",
19250      ".foo{color:lch(64.7842% 65.6007 301.364)}",
19251    );
19252    minify_test(
19253      ".foo { color: color-mix(in oklch, blue, white); }",
19254      ".foo{color:oklch(72.6007% .156607 264.052)}",
19255    );
19256    minify_test(
19257      ".foo { color: color-mix(in srgb, blue, white); }",
19258      ".foo{color:#8080ff}",
19259    );
19260    // minify_test(".foo { color: color-mix(in hsl, color(display-p3 0 1 0) 80%, yellow); }", ".foo{color:hsl(108 100% 49.9184%) }");
19261    minify_test(
19262      ".foo { color: color-mix(in hsl, hsl(120 100% 49.898%) 80%, yellow); }",
19263      ".foo{color:#33fe00}",
19264    );
19265    minify_test(
19266      ".foo { color: color-mix(in srgb, rgb(100% 0% 0% / 0.7) 25%, rgb(0% 100% 0% / 0.2)); }",
19267      ".foo{color:#89760053}",
19268    );
19269    minify_test(
19270      ".foo { color: color-mix(in srgb, rgb(100% 0% 0% / 0.7) 20%, rgb(0% 100% 0% / 0.2) 60%); }",
19271      ".foo{color:#89760042}",
19272    );
19273    minify_test(
19274      ".foo { color: color-mix(in lch, color(display-p3 0 1 none), color(display-p3 0 0 1)); }",
19275      ".foo{color:lch(58.8143% 141.732 218.684)}",
19276    );
19277    minify_test(
19278      ".foo { color: color-mix(in srgb, rgb(128 128 none), rgb(none none 128)); }",
19279      ".foo{color:gray}",
19280    );
19281    minify_test(
19282      ".foo { color: color-mix(in srgb, rgb(50% 50% none), rgb(none none 50%)); }",
19283      ".foo{color:gray}",
19284    );
19285    minify_test(
19286      ".foo { color: color-mix(in srgb, rgb(none 50% none), rgb(50% none 50%)); }",
19287      ".foo{color:gray}",
19288    );
19289    minify_test(
19290      ".foo { --color: color-mix(in lch, teal 65%, olive); }",
19291      ".foo{--color:lch(49.4431% 40.4806 162.546)}",
19292    );
19293    minify_test(
19294      ".foo { color: color-mix(in xyz, transparent, green 65%); }",
19295      ".foo{color:color(xyz .0771883 .154377 .0257295/.65)}",
19296    );
19297    prefix_test(
19298      ".foo { color: color-mix(in xyz, transparent, green 65%); }",
19299      indoc! { r#"
19300      .foo {
19301        color: #008000a6;
19302        color: color(xyz .0771883 .154377 .0257295 / .65);
19303      }
19304      "# },
19305      Browsers {
19306        chrome: Some(95 << 16),
19307        ..Default::default()
19308      },
19309    );
19310    minify_test(
19311      ".foo { color: color-mix(in srgb, currentColor, blue); }",
19312      ".foo{color:color-mix(in srgb,currentColor,blue)}",
19313    );
19314    minify_test(
19315      ".foo { color: color-mix(in srgb, blue, currentColor); }",
19316      ".foo{color:color-mix(in srgb,blue,currentColor)}",
19317    );
19318
19319    // regex for converting web platform tests:
19320    // test_computed_value\(.*?, `(.*?)`, `(.*?)`\);
19321    // minify_test(".foo { color: $1 }", ".foo{color:$2}");
19322
19323    // https://github.com/web-platform-tests/wpt/blob/f8c76b11cff66a7adc87264a18e39353cb5a60c9/css/css-color/parsing/color-mix-computed.html
19324    minify_test(
19325      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%)) }",
19326      ".foo{color:#545c3d}",
19327    );
19328    minify_test(
19329      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40%)) }",
19330      ".foo{color:#706a43}",
19331    );
19332    minify_test(
19333      ".foo { color: color-mix(in hsl, 25% hsl(120deg 10% 20%), hsl(30deg 30% 40%)) }",
19334      ".foo{color:#706a43}",
19335    );
19336    minify_test(
19337      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%), 25% hsl(30deg 30% 40%)) }",
19338      ".foo{color:#3d4936}",
19339    );
19340    minify_test(
19341      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%) 25%) }",
19342      ".foo{color:#3d4936}",
19343    );
19344    minify_test(
19345      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40%) 75%) }",
19346      ".foo{color:#706a43}",
19347    );
19348    minify_test(
19349      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%) 30%, hsl(30deg 30% 40%) 90%) }",
19350      ".foo{color:#706a43}",
19351    ); // Scale down > 100% sum.
19352    minify_test(
19353      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%) 12.5%, hsl(30deg 30% 40%) 37.5%) }",
19354      ".foo{color:#706a4380}",
19355    ); // Scale up < 100% sum, causes alpha multiplication.
19356    minify_test(
19357      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%) 0%, hsl(30deg 30% 40%)) }",
19358      ".foo{color:#856647}",
19359    );
19360
19361    minify_test(
19362      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20% / .4), hsl(30deg 30% 40% / .8)) }",
19363      ".foo{color:#5f694199}",
19364    );
19365    minify_test(
19366      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40% / .8)) }",
19367      ".foo{color:#6c6742d9}",
19368    );
19369    minify_test(
19370      ".foo { color: color-mix(in hsl, 25% hsl(120deg 10% 20% / .4), hsl(30deg 30% 40% / .8)) }",
19371      ".foo{color:#797245b3}",
19372    );
19373    minify_test(
19374      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20% / .4), 25% hsl(30deg 30% 40% / .8)) }",
19375      ".foo{color:#44543b80}",
19376    );
19377    minify_test(
19378      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20% / .4), hsl(30deg 30% 40% / .8) 25%) }",
19379      ".foo{color:#44543b80}",
19380    );
19381    minify_test(
19382      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20% / .4) 25%, hsl(30deg 30% 40% / .8) 75%) }",
19383      ".foo{color:#797245b3}",
19384    );
19385    minify_test(
19386      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20% / .4) 30%, hsl(30deg 30% 40% / .8) 90%) }",
19387      ".foo{color:#797245b3}",
19388    ); // Scale down > 100% sum.
19389    minify_test(
19390      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20% / .4) 12.5%, hsl(30deg 30% 40% / .8) 37.5%) }",
19391      ".foo{color:#79724559}",
19392    ); // Scale up < 100% sum, causes alpha multiplication.
19393    minify_test(
19394      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20% / .4) 0%, hsl(30deg 30% 40% / .8)) }",
19395      ".foo{color:#856647cc}",
19396    );
19397
19398    fn canonicalize(s: &str) -> String {
19399      use crate::traits::{Parse, ToCss};
19400      use crate::values::color::CssColor;
19401      use cssparser::{Parser, ParserInput};
19402
19403      let mut input = ParserInput::new(s);
19404      let mut parser = Parser::new(&mut input);
19405      let v = CssColor::parse(&mut parser).unwrap().to_rgb().unwrap();
19406      format!(".foo{{color:{}}}", v.to_css_string(PrinterOptions::default()).unwrap())
19407    }
19408
19409    // regex for converting web platform tests:
19410    // test_computed_value\(.*?, `(.*?)`, canonicalize\(`(.*?)`\)\);
19411    // minify_test(".foo { color: $1 }", &canonicalize("$2"));
19412
19413    minify_test(
19414      ".foo { color: color-mix(in hsl, hsl(40deg 50% 50%), hsl(60deg 50% 50%)) }",
19415      &canonicalize("hsl(50deg 50% 50%)"),
19416    );
19417    minify_test(
19418      ".foo { color: color-mix(in hsl, hsl(60deg 50% 50%), hsl(40deg 50% 50%)) }",
19419      &canonicalize("hsl(50deg 50% 50%)"),
19420    );
19421    minify_test(
19422      ".foo { color: color-mix(in hsl, hsl(50deg 50% 50%), hsl(330deg 50% 50%)) }",
19423      &canonicalize("hsl(10deg 50% 50%)"),
19424    );
19425    minify_test(
19426      ".foo { color: color-mix(in hsl, hsl(330deg 50% 50%), hsl(50deg 50% 50%)) }",
19427      &canonicalize("hsl(10deg 50% 50%)"),
19428    );
19429    minify_test(
19430      ".foo { color: color-mix(in hsl, hsl(20deg 50% 50%), hsl(320deg 50% 50%)) }",
19431      &canonicalize("hsl(350deg 50% 50%)"),
19432    );
19433    minify_test(
19434      ".foo { color: color-mix(in hsl, hsl(320deg 50% 50%), hsl(20deg 50% 50%)) }",
19435      &canonicalize("hsl(350deg 50% 50%)"),
19436    );
19437
19438    minify_test(
19439      ".foo { color: color-mix(in hsl shorter hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%)) }",
19440      &canonicalize("hsl(50deg 50% 50%)"),
19441    );
19442    minify_test(
19443      ".foo { color: color-mix(in hsl shorter hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%)) }",
19444      &canonicalize("hsl(50deg 50% 50%)"),
19445    );
19446    minify_test(
19447      ".foo { color: color-mix(in hsl shorter hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%)) }",
19448      &canonicalize("hsl(10deg 50% 50%)"),
19449    );
19450    minify_test(
19451      ".foo { color: color-mix(in hsl shorter hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%)) }",
19452      &canonicalize("hsl(10deg 50% 50%)"),
19453    );
19454    minify_test(
19455      ".foo { color: color-mix(in hsl shorter hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%)) }",
19456      &canonicalize("hsl(350deg 50% 50%)"),
19457    );
19458    minify_test(
19459      ".foo { color: color-mix(in hsl shorter hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%)) }",
19460      &canonicalize("hsl(350deg 50% 50%)"),
19461    );
19462
19463    minify_test(
19464      ".foo { color: color-mix(in hsl longer hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%)) }",
19465      &canonicalize("hsl(230deg 50% 50%)"),
19466    );
19467    minify_test(
19468      ".foo { color: color-mix(in hsl longer hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%)) }",
19469      &canonicalize("hsl(230deg 50% 50%)"),
19470    );
19471    minify_test(
19472      ".foo { color: color-mix(in hsl longer hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%)) }",
19473      &canonicalize("hsl(190deg 50% 50%)"),
19474    );
19475    minify_test(
19476      ".foo { color: color-mix(in hsl longer hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%)) }",
19477      &canonicalize("hsl(190deg 50% 50%)"),
19478    );
19479    // minify_test(".foo { color: color-mix(in hsl longer hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%)) }", &canonicalize("hsl(170deg 50% 50%)"));
19480    // minify_test(".foo { color: color-mix(in hsl longer hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%)) }", &canonicalize("hsl(170deg 50% 50%)"));
19481
19482    minify_test(
19483      ".foo { color: color-mix(in hsl increasing hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%)) }",
19484      &canonicalize("hsl(50deg 50% 50%)"),
19485    );
19486    minify_test(
19487      ".foo { color: color-mix(in hsl increasing hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%)) }",
19488      &canonicalize("hsl(230deg 50% 50%)"),
19489    );
19490    minify_test(
19491      ".foo { color: color-mix(in hsl increasing hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%)) }",
19492      &canonicalize("hsl(190deg 50% 50%)"),
19493    );
19494    minify_test(
19495      ".foo { color: color-mix(in hsl increasing hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%)) }",
19496      &canonicalize("hsl(10deg 50% 50%)"),
19497    );
19498    // minify_test(".foo { color: color-mix(in hsl increasing hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%)) }", &canonicalize("hsl(170deg 50% 50%)"));
19499    // minify_test(".foo { color: color-mix(in hsl increasing hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%)) }", &canonicalize("hsl(350deg 50% 50%)"));
19500
19501    minify_test(
19502      ".foo { color: color-mix(in hsl decreasing hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%)) }",
19503      &canonicalize("hsl(230deg 50% 50%)"),
19504    );
19505    minify_test(
19506      ".foo { color: color-mix(in hsl decreasing hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%)) }",
19507      &canonicalize("hsl(50deg 50% 50%)"),
19508    );
19509    minify_test(
19510      ".foo { color: color-mix(in hsl decreasing hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%)) }",
19511      &canonicalize("hsl(10deg 50% 50%)"),
19512    );
19513    minify_test(
19514      ".foo { color: color-mix(in hsl decreasing hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%)) }",
19515      &canonicalize("hsl(190deg 50% 50%)"),
19516    );
19517    minify_test(
19518      ".foo { color: color-mix(in hsl decreasing hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%)) }",
19519      &canonicalize("hsl(350deg 50% 50%)"),
19520    );
19521    // minify_test(".foo { color: color-mix(in hsl decreasing hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%)) }", &canonicalize("hsl(170deg 50% 50%)"));
19522
19523    minify_test(
19524      ".foo { color: color-mix(in hsl specified hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%)) }",
19525      &canonicalize("hsl(50deg 50% 50%)"),
19526    );
19527    minify_test(
19528      ".foo { color: color-mix(in hsl specified hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%)) }",
19529      &canonicalize("hsl(50deg 50% 50%)"),
19530    );
19531    minify_test(
19532      ".foo { color: color-mix(in hsl specified hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%)) }",
19533      &canonicalize("hsl(190deg 50% 50%)"),
19534    );
19535    minify_test(
19536      ".foo { color: color-mix(in hsl specified hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%)) }",
19537      &canonicalize("hsl(190deg 50% 50%)"),
19538    );
19539    // minify_test(".foo { color: color-mix(in hsl specified hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%)) }", &canonicalize("hsl(170deg 50% 50%)"));
19540    // minify_test(".foo { color: color-mix(in hsl specified hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%)) }", &canonicalize("hsl(170deg 50% 50%)"));
19541
19542    minify_test(
19543      ".foo { color: color-mix(in hsl, hsl(none none none), hsl(none none none)) }",
19544      &canonicalize("hsl(none none none)"),
19545    );
19546    minify_test(
19547      ".foo { color: color-mix(in hsl, hsl(none none none), hsl(30deg 40% 80%)) }",
19548      &canonicalize("hsl(30deg 40% 80%)"),
19549    );
19550    minify_test(
19551      ".foo { color: color-mix(in hsl, hsl(120deg 20% 40%), hsl(none none none)) }",
19552      &canonicalize("hsl(120deg 20% 40%)"),
19553    );
19554    minify_test(
19555      ".foo { color: color-mix(in hsl, hsl(120deg 20% none), hsl(30deg 40% 60%)) }",
19556      &canonicalize("hsl(75deg 30% 60%)"),
19557    );
19558    minify_test(
19559      ".foo { color: color-mix(in hsl, hsl(120deg 20% 40%), hsl(30deg 20% none)) }",
19560      &canonicalize("hsl(75deg 20% 40%)"),
19561    );
19562    minify_test(
19563      ".foo { color: color-mix(in hsl, hsl(none 20% 40%), hsl(30deg none 80%)) }",
19564      &canonicalize("hsl(30deg 20% 60%)"),
19565    );
19566
19567    minify_test(
19568      ".foo { color: color-mix(in hsl, color(display-p3 0 1 0) 100%, rgb(0, 0, 0) 0%) }",
19569      &canonicalize("rgb(0, 249, 66)"),
19570    ); // Naive clip based mapping would give rgb(0, 255, 0).
19571    minify_test(
19572      ".foo { color: color-mix(in hsl, lab(100% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%) }",
19573      &canonicalize("rgb(255, 255, 255)"),
19574    ); // Naive clip based mapping would give rgb(255, 150, 255).
19575    minify_test(
19576      ".foo { color: color-mix(in hsl, lab(0% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%) }",
19577      &canonicalize("rgb(42, 0, 34)"),
19578    ); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black,
19579    minify_test(
19580      ".foo { color: color-mix(in hsl, lch(100% 116 334) 100%, rgb(0, 0, 0) 0%) }",
19581      &canonicalize("rgb(255, 255, 255)"),
19582    ); // Naive clip based mapping would give rgb(255, 150, 255).
19583    minify_test(
19584      ".foo { color: color-mix(in hsl, lch(0% 116 334) 100%, rgb(0, 0, 0) 0%) }",
19585      &canonicalize("rgb(42, 0, 34)"),
19586    ); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black,
19587    minify_test(
19588      ".foo { color: color-mix(in hsl, oklab(100% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%) }",
19589      &canonicalize("rgb(255, 255, 255)"),
19590    ); // Naive clip based mapping would give rgb(255, 92, 255).
19591    minify_test(
19592      ".foo { color: color-mix(in hsl, oklab(0% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%) }",
19593      &canonicalize("rgb(0, 0, 0)"),
19594    ); // Naive clip based mapping would give rgb(19, 0, 24).
19595    minify_test(
19596      ".foo { color: color-mix(in hsl, oklch(100% 0.399 336.3) 100%, rgb(0, 0, 0) 0%) }",
19597      &canonicalize("rgb(255, 255, 255)"),
19598    ); // Naive clip based mapping would give rgb(255, 91, 255).
19599    minify_test(
19600      ".foo { color: color-mix(in hsl, oklch(0% 0.399 336.3) 100%, rgb(0, 0, 0) 0%) }",
19601      &canonicalize("rgb(0, 0, 0)"),
19602    ); // Naive clip based mapping would give rgb(20, 0, 24).
19603
19604    minify_test(
19605      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%)) }",
19606      &canonicalize("rgb(147, 179, 52)"),
19607    );
19608    minify_test(
19609      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%)) }",
19610      &canonicalize("rgb(166, 153, 64)"),
19611    );
19612    minify_test(
19613      ".foo { color: color-mix(in hwb, 25% hwb(120deg 10% 20%), hwb(30deg 30% 40%)) }",
19614      &canonicalize("rgb(166, 153, 64)"),
19615    );
19616    minify_test(
19617      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%), 25% hwb(30deg 30% 40%)) }",
19618      &canonicalize("rgb(96, 191, 39)"),
19619    );
19620    minify_test(
19621      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%) 25%) }",
19622      &canonicalize("rgb(96, 191, 39)"),
19623    );
19624    minify_test(
19625      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%) 75%) }",
19626      &canonicalize("rgb(166, 153, 64)"),
19627    );
19628    minify_test(
19629      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%) 30%, hwb(30deg 30% 40%) 90%) }",
19630      &canonicalize("rgb(166, 153, 64)"),
19631    ); // Scale down > 100% sum.
19632    minify_test(
19633      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%) 12.5%, hwb(30deg 30% 40%) 37.5%) }",
19634      &canonicalize("rgba(166, 153, 64, 0.5)"),
19635    ); // Scale up < 100% sum, causes alpha multiplication.
19636    minify_test(
19637      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%) 0%, hwb(30deg 30% 40%)) }",
19638      &canonicalize("rgb(153, 115, 77)"),
19639    );
19640
19641    minify_test(
19642      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20% / .4), hwb(30deg 30% 40% / .8)) }",
19643      &canonicalize("rgba(143, 170, 60, 0.6)"),
19644    );
19645    minify_test(
19646      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20% / .4) 25%, hwb(30deg 30% 40% / .8)) }",
19647      &canonicalize("rgba(160, 149, 70, 0.7)"),
19648    );
19649    minify_test(
19650      ".foo { color: color-mix(in hwb, 25% hwb(120deg 10% 20% / .4), hwb(30deg 30% 40% / .8)) }",
19651      &canonicalize("rgba(160, 149, 70, 0.7)"),
19652    );
19653    minify_test(
19654      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%), 25% hwb(30deg 30% 40% / .8)) }",
19655      &canonicalize("rgba(95, 193, 37, 0.95)"),
19656    );
19657    minify_test(
19658      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20% / .4), hwb(30deg 30% 40% / .8) 25%) }",
19659      &canonicalize("rgba(98, 184, 46, 0.5)"),
19660    );
19661    minify_test(
19662      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20% / .4) 25%, hwb(30deg 30% 40% / .8) 75%) }",
19663      &canonicalize("rgba(160, 149, 70, 0.7)"),
19664    );
19665    minify_test(
19666      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20% / .4) 30%, hwb(30deg 30% 40% / .8) 90%) }",
19667      &canonicalize("rgba(160, 149, 70, 0.7)"),
19668    ); // Scale down > 100% sum.
19669    minify_test(
19670      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20% / .4) 12.5%, hwb(30deg 30% 40% / .8) 37.5%) }",
19671      &canonicalize("rgba(160, 149, 70, 0.35)"),
19672    ); // Scale up < 100% sum, causes alpha multiplication.
19673    minify_test(
19674      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20% / .4) 0%, hwb(30deg 30% 40% / .8)) }",
19675      &canonicalize("rgba(153, 115, 77, 0.8)"),
19676    );
19677
19678    //  minify_test(".foo { color: color-mix(in hwb, hwb(40deg 30% 40%), hwb(60deg 30% 40%)) }", &canonicalize("hwb(50deg 30% 40%)"));
19679    //  minify_test(".foo { color: color-mix(in hwb, hwb(60deg 30% 40%), hwb(40deg 30% 40%)) }", &canonicalize("hwb(50deg 30% 40%)"));
19680    minify_test(
19681      ".foo { color: color-mix(in hwb, hwb(50deg 30% 40%), hwb(330deg 30% 40%)) }",
19682      &canonicalize("hwb(10deg 30% 40%)"),
19683    );
19684    minify_test(
19685      ".foo { color: color-mix(in hwb, hwb(330deg 30% 40%), hwb(50deg 30% 40%)) }",
19686      &canonicalize("hwb(10deg 30% 40%)"),
19687    );
19688    minify_test(
19689      ".foo { color: color-mix(in hwb, hwb(20deg 30% 40%), hwb(320deg 30% 40%)) }",
19690      &canonicalize("hwb(350deg 30% 40%)"),
19691    );
19692    minify_test(
19693      ".foo { color: color-mix(in hwb, hwb(320deg 30% 40%), hwb(20deg 30% 40%)) }",
19694      &canonicalize("hwb(350deg 30% 40%)"),
19695    );
19696
19697    //  minify_test(".foo { color: color-mix(in hwb shorter hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%)) }", &canonicalize("hwb(50deg 30% 40%)"));
19698    //  minify_test(".foo { color: color-mix(in hwb shorter hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%)) }", &canonicalize("hwb(50deg 30% 40%)"));
19699    minify_test(
19700      ".foo { color: color-mix(in hwb shorter hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%)) }",
19701      &canonicalize("hwb(10deg 30% 40%)"),
19702    );
19703    minify_test(
19704      ".foo { color: color-mix(in hwb shorter hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%)) }",
19705      &canonicalize("hwb(10deg 30% 40%)"),
19706    );
19707    minify_test(
19708      ".foo { color: color-mix(in hwb shorter hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%)) }",
19709      &canonicalize("hwb(350deg 30% 40%)"),
19710    );
19711    minify_test(
19712      ".foo { color: color-mix(in hwb shorter hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%)) }",
19713      &canonicalize("hwb(350deg 30% 40%)"),
19714    );
19715
19716    minify_test(
19717      ".foo { color: color-mix(in hwb longer hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%)) }",
19718      &canonicalize("hwb(230deg 30% 40%)"),
19719    );
19720    minify_test(
19721      ".foo { color: color-mix(in hwb longer hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%)) }",
19722      &canonicalize("hwb(230deg 30% 40%)"),
19723    );
19724    //  minify_test(".foo { color: color-mix(in hwb longer hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%)) }", &canonicalize("hwb(190deg 30% 40%)"));
19725    //  minify_test(".foo { color: color-mix(in hwb longer hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%)) }", &canonicalize("hwb(190deg 30% 40%)"));
19726    //  minify_test(".foo { color: color-mix(in hwb longer hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%)) }", &canonicalize("hwb(170deg 30% 40%)"));
19727    //  minify_test(".foo { color: color-mix(in hwb longer hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%)) }", &canonicalize("hwb(170deg 30% 40%)"));
19728
19729    // minify_test(".foo { color: color-mix(in hwb increasing hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%)) }", &canonicalize("hwb(50deg 30% 40%)"));
19730    minify_test(
19731      ".foo { color: color-mix(in hwb increasing hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%)) }",
19732      &canonicalize("hwb(230deg 30% 40%)"),
19733    );
19734    // minify_test(".foo { color: color-mix(in hwb increasing hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%)) }", &canonicalize("hwb(190deg 30% 40%)"));
19735    minify_test(
19736      ".foo { color: color-mix(in hwb increasing hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%)) }",
19737      &canonicalize("hwb(10deg 30% 40%)"),
19738    );
19739    // minify_test(".foo { color: color-mix(in hwb increasing hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%)) }", &canonicalize("hwb(170deg 30% 40%)"));
19740    minify_test(
19741      ".foo { color: color-mix(in hwb increasing hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%)) }",
19742      &canonicalize("hwb(350deg 30% 40%)"),
19743    );
19744
19745    minify_test(
19746      ".foo { color: color-mix(in hwb decreasing hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%)) }",
19747      &canonicalize("hwb(230deg 30% 40%)"),
19748    );
19749    // minify_test(".foo { color: color-mix(in hwb decreasing hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%)) }", &canonicalize("hwb(50deg 30% 40%)"));
19750    minify_test(
19751      ".foo { color: color-mix(in hwb decreasing hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%)) }",
19752      &canonicalize("hwb(10deg 30% 40%)"),
19753    );
19754    // minify_test(".foo { color: color-mix(in hwb decreasing hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%)) }", &canonicalize("hwb(190deg 30% 40%)"));
19755    minify_test(
19756      ".foo { color: color-mix(in hwb decreasing hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%)) }",
19757      &canonicalize("hwb(350deg 30% 40%)"),
19758    );
19759    // minify_test(".foo { color: color-mix(in hwb decreasing hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%)) }", &canonicalize("hwb(170deg 30% 40%)"));
19760
19761    // minify_test(".foo { color: color-mix(in hwb specified hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%)) }", &canonicalize("hwb(50deg 30% 40%)"));
19762    // minify_test(".foo { color: color-mix(in hwb specified hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%)) }", &canonicalize("hwb(50deg 30% 40%)"));
19763    // minify_test(".foo { color: color-mix(in hwb specified hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%)) }", &canonicalize("hwb(190deg 30% 40%)"));
19764    // minify_test(".foo { color: color-mix(in hwb specified hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%)) }", &canonicalize("hwb(190deg 30% 40%)"));
19765    // minify_test(".foo { color: color-mix(in hwb specified hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%)) }", &canonicalize("hwb(170deg 30% 40%)"));
19766    // minify_test(".foo { color: color-mix(in hwb specified hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%)) }", &canonicalize("hwb(170deg 30% 40%)"));
19767
19768    minify_test(
19769      ".foo { color: color-mix(in hwb, color(display-p3 0 1 0) 100%, rgb(0, 0, 0) 0%) }",
19770      &canonicalize("rgb(0, 249, 66)"),
19771    ); // Naive clip based mapping would give rgb(0, 255, 0).
19772    minify_test(
19773      ".foo { color: color-mix(in hwb, lab(100% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%) }",
19774      &canonicalize("rgb(255, 255, 255)"),
19775    ); // Naive clip based mapping would give rgb(255, 150, 255).
19776    minify_test(
19777      ".foo { color: color-mix(in hwb, lab(0% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%) }",
19778      &canonicalize("rgb(42, 0, 34)"),
19779    ); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black,
19780    minify_test(
19781      ".foo { color: color-mix(in hwb, lch(100% 116 334) 100%, rgb(0, 0, 0) 0%) }",
19782      &canonicalize("rgb(255, 255, 255)"),
19783    ); // Naive clip based mapping would give rgb(255, 150, 255).
19784    minify_test(
19785      ".foo { color: color-mix(in hwb, lch(0% 116 334) 100%, rgb(0, 0, 0) 0%) }",
19786      &canonicalize("rgb(42, 0, 34)"),
19787    ); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black,
19788    minify_test(
19789      ".foo { color: color-mix(in hwb, oklab(100% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%) }",
19790      &canonicalize("rgb(255, 255, 255)"),
19791    ); // Naive clip based mapping would give rgb(255, 92, 255).
19792    minify_test(
19793      ".foo { color: color-mix(in hwb, oklab(0% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%) }",
19794      &canonicalize("rgb(0, 0, 0)"),
19795    ); // Naive clip based mapping would give rgb(19, 0, 24).
19796    minify_test(
19797      ".foo { color: color-mix(in hwb, oklch(100% 0.399 336.3) 100%, rgb(0, 0, 0) 0%) }",
19798      &canonicalize("rgb(255, 255, 255)"),
19799    ); // Naive clip based mapping would give rgb(255, 91, 255).
19800    minify_test(
19801      ".foo { color: color-mix(in hwb, oklch(0% 0.399 336.3) 100%, rgb(0, 0, 0) 0%) }",
19802      &canonicalize("rgb(0, 0, 0)"),
19803    ); // Naive clip based mapping would give rgb(20, 0, 24).
19804
19805    for color_space in &["lch", "oklch"] {
19806      // regex for converting web platform tests:
19807      // test_computed_value\(.*?, `color-mix\(in \$\{colorSpace\}(.*?), (.*?)\$\{colorSpace\}(.*?) \$\{colorSpace\}(.*?)`, `\$\{colorSpace\}(.*?)`\);
19808      // minify_test(&format!(".foo {{ color: color-mix(in {0}$1, $2{0}$3 {0}$4 }}", color_space), &format!(".foo{{color:{}$5}}", color_space));
19809
19810      minify_test(
19811        &format!(
19812          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg), {0}(50% 60 70deg)) }}",
19813          color_space
19814        ),
19815        &format!(".foo{{color:{}(30% 40 50)}}", color_space),
19816      );
19817      minify_test(
19818        &format!(
19819          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg) 25%, {0}(50% 60 70deg)) }}",
19820          color_space
19821        ),
19822        &format!(".foo{{color:{}(40% 50 60)}}", color_space),
19823      );
19824      minify_test(
19825        &format!(
19826          ".foo {{ color: color-mix(in {0}, 25% {0}(10% 20 30deg), {0}(50% 60 70deg)) }}",
19827          color_space
19828        ),
19829        &format!(".foo{{color:{}(40% 50 60)}}", color_space),
19830      );
19831      minify_test(
19832        &format!(
19833          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg), 25% {0}(50% 60 70deg)) }}",
19834          color_space
19835        ),
19836        &format!(".foo{{color:{}(20% 30 40)}}", color_space),
19837      );
19838      minify_test(
19839        &format!(
19840          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg), {0}(50% 60 70deg) 25%) }}",
19841          color_space
19842        ),
19843        &format!(".foo{{color:{}(20% 30 40)}}", color_space),
19844      );
19845      minify_test(
19846        &format!(
19847          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg) 25%, {0}(50% 60 70deg) 75%) }}",
19848          color_space
19849        ),
19850        &format!(".foo{{color:{}(40% 50 60)}}", color_space),
19851      );
19852      minify_test(
19853        &format!(
19854          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg) 30%, {0}(50% 60 70deg) 90%) }}",
19855          color_space
19856        ),
19857        &format!(".foo{{color:{}(40% 50 60)}}", color_space),
19858      ); // Scale down > 100% sum.
19859      minify_test(
19860        &format!(
19861          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg) 12.5%, {0}(50% 60 70deg) 37.5%) }}",
19862          color_space
19863        ),
19864        &format!(".foo{{color:{}(40% 50 60/.5)}}", color_space),
19865      ); // Scale up < 100% sum, causes alpha multiplication.
19866      minify_test(
19867        &format!(
19868          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg) 0%, {0}(50% 60 70deg)) }}",
19869          color_space
19870        ),
19871        &format!(".foo{{color:{}(50% 60 70)}}", color_space),
19872      );
19873
19874      minify_test(
19875        &format!(
19876          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / .4), {0}(50% 60 70deg / .8)) }}",
19877          color_space
19878        ),
19879        &format!(".foo{{color:{}(36.6667% 46.6667 50/.6)}}", color_space),
19880      );
19881      minify_test(
19882        &format!(
19883          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / .4) 25%, {0}(50% 60 70deg / .8)) }}",
19884          color_space
19885        ),
19886        &format!(".foo{{color:{}(44.2857% 54.2857 60/.7)}}", color_space),
19887      );
19888      minify_test(
19889        &format!(
19890          ".foo {{ color: color-mix(in {0}, 25% {0}(10% 20 30deg / .4), {0}(50% 60 70deg / .8)) }}",
19891          color_space
19892        ),
19893        &format!(".foo{{color:{}(44.2857% 54.2857 60/.7)}}", color_space),
19894      );
19895      minify_test(
19896        &format!(
19897          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / .4), 25% {0}(50% 60 70deg / .8)) }}",
19898          color_space
19899        ),
19900        &format!(".foo{{color:{}(26% 36 40/.5)}}", color_space),
19901      );
19902      minify_test(
19903        &format!(
19904          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / .4), {0}(50% 60 70deg / .8) 25%) }}",
19905          color_space
19906        ),
19907        &format!(".foo{{color:{}(26% 36 40/.5)}}", color_space),
19908      );
19909      minify_test(
19910        &format!(
19911          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / .4) 25%, {0}(50% 60 70deg / .8) 75%) }}",
19912          color_space
19913        ),
19914        &format!(".foo{{color:{}(44.2857% 54.2857 60/.7)}}", color_space),
19915      );
19916      minify_test(
19917        &format!(
19918          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / .4) 30%, {0}(50% 60 70deg / .8) 90%) }}",
19919          color_space
19920        ),
19921        &format!(".foo{{color:{}(44.2857% 54.2857 60/.7)}}", color_space),
19922      ); // Scale down > 100% sum.
19923      minify_test(
19924        &format!(
19925          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / .4) 12.5%, {0}(50% 60 70deg / .8) 37.5%) }}",
19926          color_space
19927        ),
19928        &format!(".foo{{color:{}(44.2857% 54.2857 60/.35)}}", color_space),
19929      ); // Scale up < 100% sum, causes alpha multiplication.
19930      minify_test(
19931        &format!(
19932          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / .4) 0%, {0}(50% 60 70deg / .8)) }}",
19933          color_space
19934        ),
19935        &format!(".foo{{color:{}(50% 60 70/.8)}}", color_space),
19936      );
19937
19938      minify_test(
19939        &format!(
19940          ".foo {{ color: color-mix(in {0}, {0}(100% 0 40deg), {0}(100% 0 60deg)) }}",
19941          color_space
19942        ),
19943        &format!(".foo{{color:{}(100% 0 50)}}", color_space),
19944      );
19945      minify_test(
19946        &format!(
19947          ".foo {{ color: color-mix(in {0}, {0}(100% 0 60deg), {0}(100% 0 40deg)) }}",
19948          color_space
19949        ),
19950        &format!(".foo{{color:{}(100% 0 50)}}", color_space),
19951      );
19952      minify_test(
19953        &format!(
19954          ".foo {{ color: color-mix(in {0}, {0}(100% 0 50deg), {0}(100% 0 330deg)) }}",
19955          color_space
19956        ),
19957        &format!(".foo{{color:{}(100% 0 10)}}", color_space),
19958      );
19959      minify_test(
19960        &format!(
19961          ".foo {{ color: color-mix(in {0}, {0}(100% 0 330deg), {0}(100% 0 50deg)) }}",
19962          color_space
19963        ),
19964        &format!(".foo{{color:{}(100% 0 10)}}", color_space),
19965      );
19966      minify_test(
19967        &format!(
19968          ".foo {{ color: color-mix(in {0}, {0}(100% 0 20deg), {0}(100% 0 320deg)) }}",
19969          color_space
19970        ),
19971        &format!(".foo{{color:{}(100% 0 350)}}", color_space),
19972      );
19973      minify_test(
19974        &format!(
19975          ".foo {{ color: color-mix(in {0}, {0}(100% 0 320deg), {0}(100% 0 20deg)) }}",
19976          color_space
19977        ),
19978        &format!(".foo{{color:{}(100% 0 350)}}", color_space),
19979      );
19980
19981      minify_test(
19982        &format!(
19983          ".foo {{ color: color-mix(in {0} shorter hue, {0}(100% 0 40deg), {0}(100% 0 60deg)) }}",
19984          color_space
19985        ),
19986        &format!(".foo{{color:{}(100% 0 50)}}", color_space),
19987      );
19988      minify_test(
19989        &format!(
19990          ".foo {{ color: color-mix(in {0} shorter hue, {0}(100% 0 60deg), {0}(100% 0 40deg)) }}",
19991          color_space
19992        ),
19993        &format!(".foo{{color:{}(100% 0 50)}}", color_space),
19994      );
19995      minify_test(
19996        &format!(
19997          ".foo {{ color: color-mix(in {0} shorter hue, {0}(100% 0 50deg), {0}(100% 0 330deg)) }}",
19998          color_space
19999        ),
20000        &format!(".foo{{color:{}(100% 0 10)}}", color_space),
20001      );
20002      minify_test(
20003        &format!(
20004          ".foo {{ color: color-mix(in {0} shorter hue, {0}(100% 0 330deg), {0}(100% 0 50deg)) }}",
20005          color_space
20006        ),
20007        &format!(".foo{{color:{}(100% 0 10)}}", color_space),
20008      );
20009      minify_test(
20010        &format!(
20011          ".foo {{ color: color-mix(in {0} shorter hue, {0}(100% 0 20deg), {0}(100% 0 320deg)) }}",
20012          color_space
20013        ),
20014        &format!(".foo{{color:{}(100% 0 350)}}", color_space),
20015      );
20016      minify_test(
20017        &format!(
20018          ".foo {{ color: color-mix(in {0} shorter hue, {0}(100% 0 320deg), {0}(100% 0 20deg)) }}",
20019          color_space
20020        ),
20021        &format!(".foo{{color:{}(100% 0 350)}}", color_space),
20022      );
20023
20024      minify_test(
20025        &format!(
20026          ".foo {{ color: color-mix(in {0} longer hue, {0}(100% 0 40deg), {0}(100% 0 60deg)) }}",
20027          color_space
20028        ),
20029        &format!(".foo{{color:{}(100% 0 230)}}", color_space),
20030      );
20031      minify_test(
20032        &format!(
20033          ".foo {{ color: color-mix(in {0} longer hue, {0}(100% 0 60deg), {0}(100% 0 40deg)) }}",
20034          color_space
20035        ),
20036        &format!(".foo{{color:{}(100% 0 230)}}", color_space),
20037      );
20038      minify_test(
20039        &format!(
20040          ".foo {{ color: color-mix(in {0} longer hue, {0}(100% 0 50deg), {0}(100% 0 330deg)) }}",
20041          color_space
20042        ),
20043        &format!(".foo{{color:{}(100% 0 190)}}", color_space),
20044      );
20045      minify_test(
20046        &format!(
20047          ".foo {{ color: color-mix(in {0} longer hue, {0}(100% 0 330deg), {0}(100% 0 50deg)) }}",
20048          color_space
20049        ),
20050        &format!(".foo{{color:{}(100% 0 190)}}", color_space),
20051      );
20052      minify_test(
20053        &format!(
20054          ".foo {{ color: color-mix(in {0} longer hue, {0}(100% 0 20deg), {0}(100% 0 320deg)) }}",
20055          color_space
20056        ),
20057        &format!(".foo{{color:{}(100% 0 170)}}", color_space),
20058      );
20059      minify_test(
20060        &format!(
20061          ".foo {{ color: color-mix(in {0} longer hue, {0}(100% 0 320deg), {0}(100% 0 20deg)) }}",
20062          color_space
20063        ),
20064        &format!(".foo{{color:{}(100% 0 170)}}", color_space),
20065      );
20066
20067      minify_test(
20068        &format!(
20069          ".foo {{ color: color-mix(in {0} increasing hue, {0}(100% 0 40deg), {0}(100% 0 60deg)) }}",
20070          color_space
20071        ),
20072        &format!(".foo{{color:{}(100% 0 50)}}", color_space),
20073      );
20074      minify_test(
20075        &format!(
20076          ".foo {{ color: color-mix(in {0} increasing hue, {0}(100% 0 60deg), {0}(100% 0 40deg)) }}",
20077          color_space
20078        ),
20079        &format!(".foo{{color:{}(100% 0 230)}}", color_space),
20080      );
20081      minify_test(
20082        &format!(
20083          ".foo {{ color: color-mix(in {0} increasing hue, {0}(100% 0 50deg), {0}(100% 0 330deg)) }}",
20084          color_space
20085        ),
20086        &format!(".foo{{color:{}(100% 0 190)}}", color_space),
20087      );
20088      minify_test(
20089        &format!(
20090          ".foo {{ color: color-mix(in {0} increasing hue, {0}(100% 0 330deg), {0}(100% 0 50deg)) }}",
20091          color_space
20092        ),
20093        &format!(".foo{{color:{}(100% 0 10)}}", color_space),
20094      );
20095      minify_test(
20096        &format!(
20097          ".foo {{ color: color-mix(in {0} increasing hue, {0}(100% 0 20deg), {0}(100% 0 320deg)) }}",
20098          color_space
20099        ),
20100        &format!(".foo{{color:{}(100% 0 170)}}", color_space),
20101      );
20102      minify_test(
20103        &format!(
20104          ".foo {{ color: color-mix(in {0} increasing hue, {0}(100% 0 320deg), {0}(100% 0 20deg)) }}",
20105          color_space
20106        ),
20107        &format!(".foo{{color:{}(100% 0 350)}}", color_space),
20108      );
20109
20110      minify_test(
20111        &format!(
20112          ".foo {{ color: color-mix(in {0} decreasing hue, {0}(100% 0 40deg), {0}(100% 0 60deg)) }}",
20113          color_space
20114        ),
20115        &format!(".foo{{color:{}(100% 0 230)}}", color_space),
20116      );
20117      minify_test(
20118        &format!(
20119          ".foo {{ color: color-mix(in {0} decreasing hue, {0}(100% 0 60deg), {0}(100% 0 40deg)) }}",
20120          color_space
20121        ),
20122        &format!(".foo{{color:{}(100% 0 50)}}", color_space),
20123      );
20124      minify_test(
20125        &format!(
20126          ".foo {{ color: color-mix(in {0} decreasing hue, {0}(100% 0 50deg), {0}(100% 0 330deg)) }}",
20127          color_space
20128        ),
20129        &format!(".foo{{color:{}(100% 0 10)}}", color_space),
20130      );
20131      minify_test(
20132        &format!(
20133          ".foo {{ color: color-mix(in {0} decreasing hue, {0}(100% 0 330deg), {0}(100% 0 50deg)) }}",
20134          color_space
20135        ),
20136        &format!(".foo{{color:{}(100% 0 190)}}", color_space),
20137      );
20138      minify_test(
20139        &format!(
20140          ".foo {{ color: color-mix(in {0} decreasing hue, {0}(100% 0 20deg), {0}(100% 0 320deg)) }}",
20141          color_space
20142        ),
20143        &format!(".foo{{color:{}(100% 0 350)}}", color_space),
20144      );
20145      minify_test(
20146        &format!(
20147          ".foo {{ color: color-mix(in {0} decreasing hue, {0}(100% 0 320deg), {0}(100% 0 20deg)) }}",
20148          color_space
20149        ),
20150        &format!(".foo{{color:{}(100% 0 170)}}", color_space),
20151      );
20152
20153      minify_test(
20154        &format!(
20155          ".foo {{ color: color-mix(in {0} specified hue, {0}(100% 0 40deg), {0}(100% 0 60deg)) }}",
20156          color_space
20157        ),
20158        &format!(".foo{{color:{}(100% 0 50)}}", color_space),
20159      );
20160      minify_test(
20161        &format!(
20162          ".foo {{ color: color-mix(in {0} specified hue, {0}(100% 0 60deg), {0}(100% 0 40deg)) }}",
20163          color_space
20164        ),
20165        &format!(".foo{{color:{}(100% 0 50)}}", color_space),
20166      );
20167      minify_test(
20168        &format!(
20169          ".foo {{ color: color-mix(in {0} specified hue, {0}(100% 0 50deg), {0}(100% 0 330deg)) }}",
20170          color_space
20171        ),
20172        &format!(".foo{{color:{}(100% 0 190)}}", color_space),
20173      );
20174      minify_test(
20175        &format!(
20176          ".foo {{ color: color-mix(in {0} specified hue, {0}(100% 0 330deg), {0}(100% 0 50deg)) }}",
20177          color_space
20178        ),
20179        &format!(".foo{{color:{}(100% 0 190)}}", color_space),
20180      );
20181      minify_test(
20182        &format!(
20183          ".foo {{ color: color-mix(in {0} specified hue, {0}(100% 0 20deg), {0}(100% 0 320deg)) }}",
20184          color_space
20185        ),
20186        &format!(".foo{{color:{}(100% 0 170)}}", color_space),
20187      );
20188      minify_test(
20189        &format!(
20190          ".foo {{ color: color-mix(in {0} specified hue, {0}(100% 0 320deg), {0}(100% 0 20deg)) }}",
20191          color_space
20192        ),
20193        &format!(".foo{{color:{}(100% 0 170)}}", color_space),
20194      );
20195
20196      minify_test(
20197        &format!(
20198          ".foo {{ color: color-mix(in {0}, {0}(none none none), {0}(none none none)) }}",
20199          color_space
20200        ),
20201        &format!(".foo{{color:{}(none none none)}}", color_space),
20202      );
20203      minify_test(
20204        &format!(
20205          ".foo {{ color: color-mix(in {0}, {0}(none none none), {0}(50% 60 70deg)) }}",
20206          color_space
20207        ),
20208        &format!(".foo{{color:{}(50% 60 70)}}", color_space),
20209      );
20210      minify_test(
20211        &format!(
20212          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg), {0}(none none none)) }}",
20213          color_space
20214        ),
20215        &format!(".foo{{color:{}(10% 20 30)}}", color_space),
20216      );
20217      minify_test(
20218        &format!(
20219          ".foo {{ color: color-mix(in {0}, {0}(10% 20 none), {0}(50% 60 70deg)) }}",
20220          color_space
20221        ),
20222        &format!(".foo{{color:{}(30% 40 70)}}", color_space),
20223      );
20224      minify_test(
20225        &format!(
20226          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg), {0}(50% 60 none)) }}",
20227          color_space
20228        ),
20229        &format!(".foo{{color:{}(30% 40 30)}}", color_space),
20230      );
20231      minify_test(
20232        &format!(
20233          ".foo {{ color: color-mix(in {0}, {0}(none 20 30deg), {0}(50% none 70deg)) }}",
20234          color_space
20235        ),
20236        &format!(".foo{{color:{}(50% 20 50)}}", color_space),
20237      );
20238      minify_test(
20239        &format!(
20240          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / none), {0}(50% 60 70deg)) }}",
20241          color_space
20242        ),
20243        &format!(".foo{{color:{}(30% 40 50)}}", color_space),
20244      );
20245      minify_test(
20246        &format!(
20247          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / none), {0}(50% 60 70deg / 0.5)) }}",
20248          color_space
20249        ),
20250        &format!(".foo{{color:{}(30% 40 50/.5)}}", color_space),
20251      );
20252      minify_test(
20253        &format!(
20254          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / none), {0}(50% 60 70deg / none)) }}",
20255          color_space
20256        ),
20257        &format!(".foo{{color:{}(30% 40 50/none)}}", color_space),
20258      );
20259    }
20260
20261    for color_space in ["lab", "oklab"] {
20262      minify_test(
20263        &format!(
20264          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30), {0}(50% 60 70)) }}",
20265          color_space
20266        ),
20267        &format!(".foo{{color:{}(30% 40 50)}}", color_space),
20268      );
20269      minify_test(
20270        &format!(
20271          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30) 25%, {0}(50% 60 70)) }}",
20272          color_space
20273        ),
20274        &format!(".foo{{color:{}(40% 50 60)}}", color_space),
20275      );
20276      minify_test(
20277        &format!(
20278          ".foo {{ color: color-mix(in {0}, 25% {0}(10% 20 30), {0}(50% 60 70)) }}",
20279          color_space
20280        ),
20281        &format!(".foo{{color:{}(40% 50 60)}}", color_space),
20282      );
20283      minify_test(
20284        &format!(
20285          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30), 25% {0}(50% 60 70)) }}",
20286          color_space
20287        ),
20288        &format!(".foo{{color:{}(20% 30 40)}}", color_space),
20289      );
20290      minify_test(
20291        &format!(
20292          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30), {0}(50% 60 70) 25%) }}",
20293          color_space
20294        ),
20295        &format!(".foo{{color:{}(20% 30 40)}}", color_space),
20296      );
20297      minify_test(
20298        &format!(
20299          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30) 25%, {0}(50% 60 70) 75%) }}",
20300          color_space
20301        ),
20302        &format!(".foo{{color:{}(40% 50 60)}}", color_space),
20303      );
20304      minify_test(
20305        &format!(
20306          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30) 30%, {0}(50% 60 70) 90%) }}",
20307          color_space
20308        ),
20309        &format!(".foo{{color:{}(40% 50 60)}}", color_space),
20310      ); // Scale down > 100% sum.
20311      minify_test(
20312        &format!(
20313          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30) 12.5%, {0}(50% 60 70) 37.5%) }}",
20314          color_space
20315        ),
20316        &format!(".foo{{color:{}(40% 50 60/.5)}}", color_space),
20317      ); // Scale up < 100% sum, causes alpha multiplication.
20318      minify_test(
20319        &format!(
20320          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30) 0%, {0}(50% 60 70)) }}",
20321          color_space
20322        ),
20323        &format!(".foo{{color:{}(50% 60 70)}}", color_space),
20324      );
20325
20326      minify_test(
20327        &format!(
20328          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / .4), {0}(50% 60 70 / .8)) }}",
20329          color_space
20330        ),
20331        &format!(".foo{{color:{}(36.6667% 46.6667 56.6667/.6)}}", color_space),
20332      );
20333      minify_test(
20334        &format!(
20335          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / .4) 25%, {0}(50% 60 70 / .8)) }}",
20336          color_space
20337        ),
20338        &format!(".foo{{color:{}(44.2857% 54.2857 64.2857/.7)}}", color_space),
20339      );
20340      minify_test(
20341        &format!(
20342          ".foo {{ color: color-mix(in {0}, 25% {0}(10% 20 30 / .4), {0}(50% 60 70 / .8)) }}",
20343          color_space
20344        ),
20345        &format!(".foo{{color:{}(44.2857% 54.2857 64.2857/.7)}}", color_space),
20346      );
20347      minify_test(
20348        &format!(
20349          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / .4), 25% {0}(50% 60 70 / .8)) }}",
20350          color_space
20351        ),
20352        &format!(".foo{{color:{}(26% 36 46/.5)}}", color_space),
20353      );
20354      minify_test(
20355        &format!(
20356          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / .4), {0}(50% 60 70 / .8) 25%) }}",
20357          color_space
20358        ),
20359        &format!(".foo{{color:{}(26% 36 46/.5)}}", color_space),
20360      );
20361      minify_test(
20362        &format!(
20363          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / .4) 25%, {0}(50% 60 70 / .8) 75%) }}",
20364          color_space
20365        ),
20366        &format!(".foo{{color:{}(44.2857% 54.2857 64.2857/.7)}}", color_space),
20367      );
20368      minify_test(
20369        &format!(
20370          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / .4) 30%, {0}(50% 60 70 / .8) 90%) }}",
20371          color_space
20372        ),
20373        &format!(".foo{{color:{}(44.2857% 54.2857 64.2857/.7)}}", color_space),
20374      ); // Scale down > 100% sum.
20375      minify_test(
20376        &format!(
20377          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / .4) 12.5%, {0}(50% 60 70 / .8) 37.5%) }}",
20378          color_space
20379        ),
20380        &format!(".foo{{color:{}(44.2857% 54.2857 64.2857/.35)}}", color_space),
20381      ); // Scale up < 100% sum, causes alpha multiplication.
20382      minify_test(
20383        &format!(
20384          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / .4) 0%, {0}(50% 60 70 / .8)) }}",
20385          color_space
20386        ),
20387        &format!(".foo{{color:{}(50% 60 70/.8)}}", color_space),
20388      );
20389
20390      minify_test(
20391        &format!(
20392          ".foo {{ color: color-mix(in {0}, {0}(none none none), {0}(none none none)) }}",
20393          color_space
20394        ),
20395        &format!(".foo{{color:{}(none none none)}}", color_space),
20396      );
20397      minify_test(
20398        &format!(
20399          ".foo {{ color: color-mix(in {0}, {0}(none none none), {0}(50% 60 70)) }}",
20400          color_space
20401        ),
20402        &format!(".foo{{color:{}(50% 60 70)}}", color_space),
20403      );
20404      minify_test(
20405        &format!(
20406          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30), {0}(none none none)) }}",
20407          color_space
20408        ),
20409        &format!(".foo{{color:{}(10% 20 30)}}", color_space),
20410      );
20411      minify_test(
20412        &format!(
20413          ".foo {{ color: color-mix(in {0}, {0}(10% 20 none), {0}(50% 60 70)) }}",
20414          color_space
20415        ),
20416        &format!(".foo{{color:{}(30% 40 70)}}", color_space),
20417      );
20418      minify_test(
20419        &format!(
20420          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30), {0}(50% 60 none)) }}",
20421          color_space
20422        ),
20423        &format!(".foo{{color:{}(30% 40 30)}}", color_space),
20424      );
20425      minify_test(
20426        &format!(
20427          ".foo {{ color: color-mix(in {0}, {0}(none 20 30), {0}(50% none 70)) }}",
20428          color_space
20429        ),
20430        &format!(".foo{{color:{}(50% 20 50)}}", color_space),
20431      );
20432      minify_test(
20433        &format!(
20434          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / none), {0}(50% 60 70)) }}",
20435          color_space
20436        ),
20437        &format!(".foo{{color:{}(30% 40 50)}}", color_space),
20438      );
20439      minify_test(
20440        &format!(
20441          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / none), {0}(50% 60 70 / 0.5)) }}",
20442          color_space
20443        ),
20444        &format!(".foo{{color:{}(30% 40 50/.5)}}", color_space),
20445      );
20446      minify_test(
20447        &format!(
20448          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / none), {0}(50% 60 70 / none)) }}",
20449          color_space
20450        ),
20451        &format!(".foo{{color:{}(30% 40 50/none)}}", color_space),
20452      );
20453    }
20454
20455    for color_space in [/*"srgb", */ "srgb-linear", "xyz", "xyz-d50", "xyz-d65"] {
20456      // regex for converting web platform tests:
20457      // test_computed_value\(.*?, `color-mix\(in \$\{colorSpace\}(.*?), (.*?)color\(\$\{colorSpace\}(.*?) color\(\$\{colorSpace\}(.*?)`, `color\(\$\{resultColorSpace\}(.*?)`\);
20458      // minify_test(&format!(".foo {{ color: color-mix(in {0}$1, $2color({0}$3 color({0}$4 }}", color_space), &format!(".foo{{color:color({}$5}}", result_color_space));
20459
20460      let result_color_space = if color_space == "xyz-d65" { "xyz" } else { color_space };
20461
20462      minify_test(
20463        &format!(
20464          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3), color({0} .5 .6 .7)) }}",
20465          color_space
20466        ),
20467        &format!(".foo{{color:color({} .3 .4 .5)}}", result_color_space),
20468      );
20469      minify_test(
20470        &format!(
20471          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3) 25%, color({0} .5 .6 .7)) }}",
20472          color_space
20473        ),
20474        &format!(".foo{{color:color({} .4 .5 .6)}}", result_color_space),
20475      );
20476      minify_test(
20477        &format!(
20478          ".foo {{ color: color-mix(in {0}, 25% color({0} .1 .2 .3), color({0} .5 .6 .7)) }}",
20479          color_space
20480        ),
20481        &format!(".foo{{color:color({} .4 .5 .6)}}", result_color_space),
20482      );
20483      minify_test(
20484        &format!(
20485          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3), color({0} .5 .6 .7) 25%) }}",
20486          color_space
20487        ),
20488        &format!(".foo{{color:color({} .2 .3 .4)}}", result_color_space),
20489      );
20490      minify_test(
20491        &format!(
20492          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3), 25% color({0} .5 .6 .7)) }}",
20493          color_space
20494        ),
20495        &format!(".foo{{color:color({} .2 .3 .4)}}", result_color_space),
20496      );
20497      minify_test(
20498        &format!(
20499          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3) 25%, color({0} .5 .6 .7) 75%) }}",
20500          color_space
20501        ),
20502        &format!(".foo{{color:color({} .4 .5 .6)}}", result_color_space),
20503      );
20504      minify_test(
20505        &format!(
20506          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3) 30%, color({0} .5 .6 .7) 90%) }}",
20507          color_space
20508        ),
20509        &format!(".foo{{color:color({} .4 .5 .6)}}", result_color_space),
20510      ); // Scale down > 100% sum.
20511      minify_test(
20512        &format!(
20513          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3) 12.5%, color({0} .5 .6 .7) 37.5%) }}",
20514          color_space
20515        ),
20516        &format!(".foo{{color:color({} .4 .5 .6/.5)}}", result_color_space),
20517      ); // Scale up < 100% sum, causes alpha multiplication.
20518      minify_test(
20519        &format!(
20520          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3) 0%, color({0} .5 .6 .7)) }}",
20521          color_space
20522        ),
20523        &format!(".foo{{color:color({} .5 .6 .7)}}", result_color_space),
20524      );
20525
20526      minify_test(
20527        &format!(
20528          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / .5), color({0} .5 .6 .7 / .8)) }}",
20529          color_space
20530        ),
20531        &format!(
20532          ".foo{{color:color({} .346154 .446154 .546154/.65)}}",
20533          result_color_space
20534        ),
20535      );
20536      minify_test(
20537        &format!(
20538          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / .4) 25%, color({0} .5 .6 .7 / .8)) }}",
20539          color_space
20540        ),
20541        &format!(".foo{{color:color({} .442857 .542857 .642857/.7)}}", result_color_space),
20542      );
20543      minify_test(
20544        &format!(
20545          ".foo {{ color: color-mix(in {0}, 25% color({0} .1 .2 .3 / .4), color({0} .5 .6 .7 / .8)) }}",
20546          color_space
20547        ),
20548        &format!(".foo{{color:color({} .442857 .542857 .642857/.7)}}", result_color_space),
20549      );
20550      minify_test(
20551        &format!(
20552          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / .4), color({0} .5 .6 .7 / .8) 25%) }}",
20553          color_space
20554        ),
20555        &format!(".foo{{color:color({} .26 .36 .46/.5)}}", result_color_space),
20556      );
20557      minify_test(
20558        &format!(
20559          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / .4), 25% color({0} .5 .6 .7 / .8)) }}",
20560          color_space
20561        ),
20562        &format!(".foo{{color:color({} .26 .36 .46/.5)}}", result_color_space),
20563      );
20564      minify_test(
20565        &format!(
20566          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / .4) 25%, color({0} .5 .6 .7 / .8) 75%) }}",
20567          color_space
20568        ),
20569        &format!(".foo{{color:color({} .442857 .542857 .642857/.7)}}", result_color_space),
20570      );
20571      minify_test(
20572        &format!(
20573          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / .4) 30%, color({0} .5 .6 .7 / .8) 90%) }}",
20574          color_space
20575        ),
20576        &format!(".foo{{color:color({} .442857 .542857 .642857/.7)}}", result_color_space),
20577      ); // Scale down > 100% sum.
20578      minify_test(
20579        &format!(
20580          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / .4) 12.5%, color({0} .5 .6 .7 / .8) 37.5%) }}",
20581          color_space
20582        ),
20583        &format!(
20584          ".foo{{color:color({} .442857 .542857 .642857/.35)}}",
20585          result_color_space
20586        ),
20587      ); // Scale up < 100% sum, causes alpha multiplication.
20588      minify_test(
20589        &format!(
20590          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / .4) 0%, color({0} .5 .6 .7 / .8)) }}",
20591          color_space
20592        ),
20593        &format!(".foo{{color:color({} .5 .6 .7/.8)}}", result_color_space),
20594      );
20595
20596      minify_test(
20597        &format!(
20598          ".foo {{ color: color-mix(in {0}, color({0} 2 3 4 / 5), color({0} 4 6 8 / 10)) }}",
20599          color_space
20600        ),
20601        &format!(".foo{{color:color({} 3 4.5 6)}}", result_color_space),
20602      );
20603      minify_test(
20604        &format!(
20605          ".foo {{ color: color-mix(in {0}, color({0} -2 -3 -4), color({0} -4 -6 -8)) }}",
20606          color_space
20607        ),
20608        &format!(".foo{{color:color({} -3 -4.5 -6)}}", result_color_space),
20609      );
20610      minify_test(
20611        &format!(
20612          ".foo {{ color: color-mix(in {0}, color({0} -2 -3 -4 / -5), color({0} -4 -6 -8 / -10)) }}",
20613          color_space
20614        ),
20615        &format!(".foo{{color:color({} 0 0 0/0)}}", result_color_space),
20616      );
20617
20618      minify_test(
20619        &format!(
20620          ".foo {{ color: color-mix(in {0}, color({0} none none none), color({0} none none none)) }}",
20621          color_space
20622        ),
20623        &format!(".foo{{color:color({} none none none)}}", result_color_space),
20624      );
20625      minify_test(
20626        &format!(
20627          ".foo {{ color: color-mix(in {0}, color({0} none none none), color({0} .5 .6 .7)) }}",
20628          color_space
20629        ),
20630        &format!(".foo{{color:color({} .5 .6 .7)}}", result_color_space),
20631      );
20632      minify_test(
20633        &format!(
20634          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3), color({0} none none none)) }}",
20635          color_space
20636        ),
20637        &format!(".foo{{color:color({} .1 .2 .3)}}", result_color_space),
20638      );
20639      minify_test(
20640        &format!(
20641          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 none), color({0} .5 .6 .7)) }}",
20642          color_space
20643        ),
20644        &format!(".foo{{color:color({} .3 .4 .7)}}", result_color_space),
20645      );
20646      minify_test(
20647        &format!(
20648          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3), color({0} .5 .6 none)) }}",
20649          color_space
20650        ),
20651        &format!(".foo{{color:color({} .3 .4 .3)}}", result_color_space),
20652      );
20653      minify_test(
20654        &format!(
20655          ".foo {{ color: color-mix(in {0}, color({0} none .2 .3), color({0} .5 none .7)) }}",
20656          color_space
20657        ),
20658        &format!(".foo{{color:color({} .5 .2 .5)}}", result_color_space),
20659      );
20660      minify_test(
20661        &format!(
20662          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / none), color({0} .5 .6 .7)) }}",
20663          color_space
20664        ),
20665        &format!(".foo{{color:color({} .3 .4 .5)}}", result_color_space),
20666      );
20667      minify_test(
20668        &format!(
20669          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / none), color({0} .5 .6 .7 / 0.5)) }}",
20670          color_space
20671        ),
20672        &format!(".foo{{color:color({} .3 .4 .5/.5)}}", result_color_space),
20673      );
20674      minify_test(
20675        &format!(
20676          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / none), color({0} .5 .6 .7 / none)) }}",
20677          color_space
20678        ),
20679        &format!(".foo{{color:color({} .3 .4 .5/none)}}", result_color_space),
20680      );
20681    }
20682  }
20683
20684  #[cfg(feature = "grid")]
20685  #[test]
20686  fn test_grid() {
20687    minify_test(
20688      ".foo { grid-template-columns: [first nav-start]  150px [main-start] 1fr [last]; }",
20689      ".foo{grid-template-columns:[first nav-start]150px[main-start]1fr[last]}",
20690    );
20691    minify_test(
20692      ".foo { grid-template-columns: 150px 1fr; }",
20693      ".foo{grid-template-columns:150px 1fr}",
20694    );
20695    minify_test(
20696      ".foo { grid-template-columns: repeat(4, 1fr); }",
20697      ".foo{grid-template-columns:repeat(4,1fr)}",
20698    );
20699    minify_test(
20700      ".foo { grid-template-columns: repeat(2, [e] 40px); }",
20701      ".foo{grid-template-columns:repeat(2,[e]40px)}",
20702    );
20703    minify_test(
20704      ".foo { grid-template-columns: repeat(4, [col-start] 250px [col-end]); }",
20705      ".foo{grid-template-columns:repeat(4,[col-start]250px[col-end])}",
20706    );
20707    minify_test(
20708      ".foo { grid-template-columns: repeat(4, [col-start] 60% [col-end]); }",
20709      ".foo{grid-template-columns:repeat(4,[col-start]60%[col-end])}",
20710    );
20711    minify_test(
20712      ".foo { grid-template-columns: repeat(4, [col-start] 1fr [col-end]); }",
20713      ".foo{grid-template-columns:repeat(4,[col-start]1fr[col-end])}",
20714    );
20715    minify_test(
20716      ".foo { grid-template-columns: repeat(4, [col-start] min-content [col-end]); }",
20717      ".foo{grid-template-columns:repeat(4,[col-start]min-content[col-end])}",
20718    );
20719    minify_test(
20720      ".foo { grid-template-columns: repeat(4, [col-start] max-content [col-end]); }",
20721      ".foo{grid-template-columns:repeat(4,[col-start]max-content[col-end])}",
20722    );
20723    minify_test(
20724      ".foo { grid-template-columns: repeat(4, [col-start] auto [col-end]); }",
20725      ".foo{grid-template-columns:repeat(4,[col-start]auto[col-end])}",
20726    );
20727    minify_test(
20728      ".foo { grid-template-columns: repeat(4, [col-start] minmax(100px, 1fr) [col-end]); }",
20729      ".foo{grid-template-columns:repeat(4,[col-start]minmax(100px,1fr)[col-end])}",
20730    );
20731    minify_test(
20732      ".foo { grid-template-columns: repeat(4, [col-start] fit-content(200px) [col-end]); }",
20733      ".foo{grid-template-columns:repeat(4,[col-start]fit-content(200px)[col-end])}",
20734    );
20735    minify_test(
20736      ".foo { grid-template-columns: repeat(4, 10px [col-start] 30% [col-middle] auto [col-end]); }",
20737      ".foo{grid-template-columns:repeat(4,10px[col-start]30%[col-middle]auto[col-end])}",
20738    );
20739    minify_test(
20740      ".foo { grid-template-columns: repeat(5, auto); }",
20741      ".foo{grid-template-columns:repeat(5,auto)}",
20742    );
20743    minify_test(
20744      ".foo { grid-template-columns: repeat(auto-fill, 250px); }",
20745      ".foo{grid-template-columns:repeat(auto-fill,250px)}",
20746    );
20747    minify_test(
20748      ".foo { grid-template-columns: repeat(auto-fit, 250px); }",
20749      ".foo{grid-template-columns:repeat(auto-fit,250px)}",
20750    );
20751    minify_test(
20752      ".foo { grid-template-columns: repeat(auto-fill, [col-start] 250px [col-end]); }",
20753      ".foo{grid-template-columns:repeat(auto-fill,[col-start]250px[col-end])}",
20754    );
20755    minify_test(
20756      ".foo { grid-template-columns: repeat(auto-fill, [col-start] minmax(100px, 1fr) [col-end]); }",
20757      ".foo{grid-template-columns:repeat(auto-fill,[col-start]minmax(100px,1fr)[col-end])}",
20758    );
20759    minify_test(
20760      ".foo { grid-template-columns: minmax(min-content, 1fr); }",
20761      ".foo{grid-template-columns:minmax(min-content,1fr)}",
20762    );
20763    minify_test(
20764      ".foo { grid-template-columns: 200px repeat(auto-fill, 100px) 300px; }",
20765      ".foo{grid-template-columns:200px repeat(auto-fill,100px) 300px}",
20766    );
20767    minify_test(".foo { grid-template-columns: [linename1 linename2] 100px repeat(auto-fit, [linename1] 300px) [linename3]; }", ".foo{grid-template-columns:[linename1 linename2]100px repeat(auto-fit,[linename1]300px)[linename3]}");
20768    minify_test(
20769      ".foo { grid-template-rows: [linename1 linename2] 100px repeat(auto-fit, [linename1] 300px) [linename3]; }",
20770      ".foo{grid-template-rows:[linename1 linename2]100px repeat(auto-fit,[linename1]300px)[linename3]}",
20771    );
20772
20773    minify_test(".foo { grid-auto-rows: auto; }", ".foo{grid-auto-rows:auto}");
20774    minify_test(".foo { grid-auto-rows: 1fr; }", ".foo{grid-auto-rows:1fr}");
20775    minify_test(".foo { grid-auto-rows: 100px; }", ".foo{grid-auto-rows:100px}");
20776    minify_test(
20777      ".foo { grid-auto-rows: min-content; }",
20778      ".foo{grid-auto-rows:min-content}",
20779    );
20780    minify_test(
20781      ".foo { grid-auto-rows: max-content; }",
20782      ".foo{grid-auto-rows:max-content}",
20783    );
20784    minify_test(
20785      ".foo { grid-auto-rows: minmax(100px,auto); }",
20786      ".foo{grid-auto-rows:minmax(100px,auto)}",
20787    );
20788    minify_test(
20789      ".foo { grid-auto-rows: fit-content(20%); }",
20790      ".foo{grid-auto-rows:fit-content(20%)}",
20791    );
20792    minify_test(
20793      ".foo { grid-auto-rows: 100px minmax(100px, auto) 10% 0.5fr fit-content(400px); }",
20794      ".foo{grid-auto-rows:100px minmax(100px,auto) 10% .5fr fit-content(400px)}",
20795    );
20796    minify_test(
20797      ".foo { grid-auto-columns: 100px minmax(100px, auto) 10% 0.5fr fit-content(400px); }",
20798      ".foo{grid-auto-columns:100px minmax(100px,auto) 10% .5fr fit-content(400px)}",
20799    );
20800
20801    minify_test(
20802      r#"
20803      .foo {
20804        grid-template-areas: "head head"
20805                             "nav  main"
20806                             "foot ....";
20807      }
20808    "#,
20809      ".foo{grid-template-areas:\"head head\"\"nav main\"\"foot.\"}",
20810    );
20811    minify_test(
20812      r#"
20813      .foo {
20814        grid-template-areas: "head head"
20815                             "nav  main"
20816                             ".... foot";
20817      }
20818    "#,
20819      ".foo{grid-template-areas:\"head head\"\"nav main\"\".foot\"}",
20820    );
20821    minify_test(
20822      r#"
20823      .foo {
20824        grid-template-areas: "head head"
20825                             "nav  main"
20826                             ".... ....";
20827      }
20828    "#,
20829      ".foo{grid-template-areas:\"head head\"\"nav main\"\". .\"}",
20830    );
20831
20832    test(
20833      r#"
20834      .foo {
20835        grid-template-areas: "head head" "nav  main" "foot ....";
20836      }
20837    "#,
20838      indoc! { r#"
20839      .foo {
20840        grid-template-areas: "head head"
20841                             "nav main"
20842                             "foot .";
20843      }
20844    "#},
20845    );
20846
20847    minify_test(
20848      r#"
20849      .foo {
20850        grid-template: [header-top] "a   a   a"     [header-bottom]
20851                       [main-top] "b   b   b" 1fr [main-bottom];
20852      }
20853    "#,
20854      ".foo{grid-template:[header-top]\"a a a\"[header-bottom main-top]\"b b b\"1fr[main-bottom]}",
20855    );
20856    minify_test(
20857      r#"
20858      .foo {
20859        grid-template: "head head"
20860                       "nav  main" 1fr
20861                       "foot ....";
20862      }
20863    "#,
20864      ".foo{grid-template:\"head head\"\"nav main\"1fr\"foot.\"}",
20865    );
20866    minify_test(
20867      r#"
20868      .foo {
20869        grid-template: [header-top] "a   a   a"     [header-bottom]
20870                         [main-top] "b   b   b" 1fr [main-bottom]
20871                                  / auto 1fr auto;
20872      }
20873    "#,
20874      ".foo{grid-template:[header-top]\"a a a\"[header-bottom main-top]\"b b b\"1fr[main-bottom]/auto 1fr auto}",
20875    );
20876
20877    minify_test(
20878      ".foo { grid-template: auto 1fr / auto 1fr auto; }",
20879      ".foo{grid-template:auto 1fr/auto 1fr auto}",
20880    );
20881    minify_test(
20882      ".foo { grid-template: [linename1 linename2] 100px repeat(auto-fit, [linename1] 300px) [linename3] / [linename1 linename2] 100px repeat(auto-fit, [linename1] 300px) [linename3]; }",
20883      ".foo{grid-template:[linename1 linename2]100px repeat(auto-fit,[linename1]300px)[linename3]/[linename1 linename2]100px repeat(auto-fit,[linename1]300px)[linename3]}"
20884    );
20885
20886    test(
20887      ".foo{grid-template:[header-top]\"a a a\"[header-bottom main-top]\"b b b\"1fr[main-bottom]/auto 1fr auto}",
20888      indoc! {r#"
20889        .foo {
20890          grid-template: [header-top] "a a a" [header-bottom]
20891                         [main-top] "b b b" 1fr [main-bottom]
20892                         / auto 1fr auto;
20893        }
20894      "#},
20895    );
20896    test(
20897      ".foo{grid-template:[header-top]\"a a a\"[main-top]\"b b b\"1fr/auto 1fr auto}",
20898      indoc! {r#"
20899        .foo {
20900          grid-template: [header-top] "a a a"
20901                         [main-top] "b b b" 1fr
20902                         / auto 1fr auto;
20903        }
20904      "#},
20905    );
20906
20907    minify_test(".foo { grid-auto-flow: row }", ".foo{grid-auto-flow:row}");
20908    minify_test(".foo { grid-auto-flow: column }", ".foo{grid-auto-flow:column}");
20909    minify_test(".foo { grid-auto-flow: row dense }", ".foo{grid-auto-flow:dense}");
20910    minify_test(".foo { grid-auto-flow: dense row }", ".foo{grid-auto-flow:dense}");
20911    minify_test(
20912      ".foo { grid-auto-flow: column dense }",
20913      ".foo{grid-auto-flow:column dense}",
20914    );
20915    minify_test(
20916      ".foo { grid-auto-flow: dense column }",
20917      ".foo{grid-auto-flow:column dense}",
20918    );
20919
20920    minify_test(".foo { grid: none }", ".foo{grid:none}");
20921    minify_test(".foo { grid: \"a\" 100px \"b\" 1fr }", ".foo{grid:\"a\"100px\"b\"1fr}");
20922    minify_test(
20923      ".foo { grid: [linename1] \"a\" 100px [linename2] }",
20924      ".foo{grid:[linename1]\"a\"100px[linename2]}",
20925    );
20926    minify_test(
20927      ".foo { grid: \"a\" 200px \"b\" min-content }",
20928      ".foo{grid:\"a\"200px\"b\"min-content}",
20929    );
20930    minify_test(
20931      ".foo { grid: \"a\" minmax(100px, max-content) \"b\" 20% }",
20932      ".foo{grid:\"a\"minmax(100px,max-content)\"b\"20%}",
20933    );
20934    minify_test(".foo { grid: 100px / 200px }", ".foo{grid:100px/200px}");
20935    minify_test(
20936      ".foo { grid: minmax(400px, min-content) / repeat(auto-fill, 50px) }",
20937      ".foo{grid:minmax(400px,min-content)/repeat(auto-fill,50px)}",
20938    );
20939
20940    minify_test(".foo { grid: 200px / auto-flow }", ".foo{grid:200px/auto-flow}");
20941    minify_test(".foo { grid: 30% / auto-flow dense }", ".foo{grid:30%/auto-flow dense}");
20942    minify_test(".foo { grid: 30% / dense auto-flow }", ".foo{grid:30%/auto-flow dense}");
20943    minify_test(
20944      ".foo { grid: repeat(3, [line1 line2 line3] 200px) / auto-flow 300px }",
20945      ".foo{grid:repeat(3,[line1 line2 line3]200px)/auto-flow 300px}",
20946    );
20947    minify_test(
20948      ".foo { grid: [line1] minmax(20em, max-content) / auto-flow dense 40% }",
20949      ".foo{grid:[line1]minmax(20em,max-content)/auto-flow dense 40%}",
20950    );
20951    minify_test(".foo { grid: none / auto-flow 1fr }", ".foo{grid:none/auto-flow 1fr}");
20952
20953    minify_test(".foo { grid: auto-flow / 200px }", ".foo{grid:none/200px}");
20954    minify_test(".foo { grid: auto-flow dense / 30% }", ".foo{grid:auto-flow dense/30%}");
20955    minify_test(".foo { grid: dense auto-flow / 30% }", ".foo{grid:auto-flow dense/30%}");
20956    minify_test(
20957      ".foo { grid: auto-flow 300px / repeat(3, [line1 line2 line3] 200px) }",
20958      ".foo{grid:auto-flow 300px/repeat(3,[line1 line2 line3]200px)}",
20959    );
20960    minify_test(
20961      ".foo { grid: auto-flow dense 40% / [line1] minmax(20em, max-content) }",
20962      ".foo{grid:auto-flow dense 40%/[line1]minmax(20em,max-content)}",
20963    );
20964
20965    minify_test(".foo { grid-row-start: auto }", ".foo{grid-row-start:auto}");
20966    minify_test(".foo { grid-row-start: some-area }", ".foo{grid-row-start:some-area}");
20967    minify_test(".foo { grid-row-start: 2 }", ".foo{grid-row-start:2}");
20968    minify_test(
20969      ".foo { grid-row-start: 2 some-line }",
20970      ".foo{grid-row-start:2 some-line}",
20971    );
20972    minify_test(
20973      ".foo { grid-row-start: some-line 2 }",
20974      ".foo{grid-row-start:2 some-line}",
20975    );
20976    minify_test(".foo { grid-row-start: span 3 }", ".foo{grid-row-start:span 3}");
20977    minify_test(
20978      ".foo { grid-row-start: span some-line }",
20979      ".foo{grid-row-start:span some-line}",
20980    );
20981    minify_test(
20982      ".foo { grid-row-start: span some-line 1 }",
20983      ".foo{grid-row-start:span some-line}",
20984    );
20985    minify_test(
20986      ".foo { grid-row-start: span 1 some-line }",
20987      ".foo{grid-row-start:span some-line}",
20988    );
20989    minify_test(
20990      ".foo { grid-row-start: span 5 some-line }",
20991      ".foo{grid-row-start:span 5 some-line}",
20992    );
20993    minify_test(
20994      ".foo { grid-row-start: span some-line 5 }",
20995      ".foo{grid-row-start:span 5 some-line}",
20996    );
20997
20998    minify_test(
20999      ".foo { grid-row-end: span 1 some-line }",
21000      ".foo{grid-row-end:span some-line}",
21001    );
21002    minify_test(
21003      ".foo { grid-column-start: span 1 some-line }",
21004      ".foo{grid-column-start:span some-line}",
21005    );
21006    minify_test(
21007      ".foo { grid-column-end: span 1 some-line }",
21008      ".foo{grid-column-end:span some-line}",
21009    );
21010
21011    minify_test(".foo { grid-row: 1 }", ".foo{grid-row:1}");
21012    minify_test(".foo { grid-row: 1 / auto }", ".foo{grid-row:1}");
21013    minify_test(".foo { grid-row: 1 / 1 }", ".foo{grid-row:1/1}");
21014    minify_test(".foo { grid-row: 1 / 3 }", ".foo{grid-row:1/3}");
21015    minify_test(".foo { grid-row: 1 / span 2 }", ".foo{grid-row:1/span 2}");
21016    minify_test(".foo { grid-row: main-start }", ".foo{grid-row:main-start}");
21017    minify_test(
21018      ".foo { grid-row: main-start / main-end }",
21019      ".foo{grid-row:main-start/main-end}",
21020    );
21021    minify_test(
21022      ".foo { grid-row: main-start / main-start }",
21023      ".foo{grid-row:main-start}",
21024    );
21025    minify_test(".foo { grid-column: 1 / auto }", ".foo{grid-column:1}");
21026
21027    minify_test(".foo { grid-area: a }", ".foo{grid-area:a}");
21028    minify_test(".foo { grid-area: a / a / a / a }", ".foo{grid-area:a}");
21029    minify_test(".foo { grid-area: a / b / a / b }", ".foo{grid-area:a/b}");
21030    minify_test(".foo { grid-area: a / b / c / b }", ".foo{grid-area:a/b/c}");
21031    minify_test(".foo { grid-area: a / b / c / d }", ".foo{grid-area:a/b/c/d}");
21032
21033    minify_test(".foo { grid-area: auto / auto / auto / auto }", ".foo{grid-area:auto}");
21034    minify_test(".foo { grid-area: 1 / auto }", ".foo{grid-area:1}");
21035    minify_test(".foo { grid-area: 1 / 2 / 3 / 4 }", ".foo{grid-area:1/2/3/4}");
21036    minify_test(".foo { grid-area: 1 / 1 / 1 / 1 }", ".foo{grid-area:1/1/1/1}");
21037
21038    test(
21039      r#"
21040        .foo{
21041          grid-template-rows: auto 1fr;
21042          grid-template-columns: auto 1fr auto;
21043          grid-template-areas: none;
21044        }
21045      "#,
21046      indoc! {r#"
21047        .foo {
21048          grid-template: auto 1fr / auto 1fr auto;
21049        }
21050      "#},
21051    );
21052
21053    test(
21054      r#"
21055        .foo{
21056          grid-template-areas: "a a a"
21057                               "b b b";
21058          grid-template-rows: [header-top] auto [header-bottom main-top] 1fr [main-bottom];
21059          grid-template-columns: auto 1fr auto;
21060        }
21061      "#,
21062      indoc! {r#"
21063        .foo {
21064          grid-template: [header-top] "a a a" [header-bottom]
21065                         [main-top] "b b b" 1fr [main-bottom]
21066                         / auto 1fr auto;
21067        }
21068      "#},
21069    );
21070
21071    test(
21072      r#"
21073        .foo{
21074          grid-template-areas: "a a a"
21075                               "b b b";
21076          grid-template-columns: repeat(3, 1fr);
21077          grid-template-rows: auto 1fr;
21078        }
21079      "#,
21080      indoc! {r#"
21081        .foo {
21082          grid-template-rows: auto 1fr;
21083          grid-template-columns: repeat(3, 1fr);
21084          grid-template-areas: "a a a"
21085                               "b b b";
21086        }
21087      "#},
21088    );
21089
21090    test(
21091      r#"
21092        .foo{
21093          grid-template-areas: "a a a"
21094                               "b b b";
21095          grid-template-columns: auto 1fr auto;
21096          grid-template-rows: repeat(2, 1fr);
21097        }
21098      "#,
21099      indoc! {r#"
21100        .foo {
21101          grid-template-rows: repeat(2, 1fr);
21102          grid-template-columns: auto 1fr auto;
21103          grid-template-areas: "a a a"
21104                               "b b b";
21105        }
21106      "#},
21107    );
21108
21109    test(
21110      r#"
21111        .foo{
21112          grid-template-areas: ". a a ."
21113                               ". b b .";
21114          grid-template-rows: auto 1fr;
21115          grid-template-columns: 10px 1fr 1fr 10px;
21116        }
21117      "#,
21118      indoc! {r#"
21119        .foo {
21120          grid-template: ". a a ."
21121                         ". b b ." 1fr
21122                         / 10px 1fr 1fr 10px;
21123        }
21124      "#},
21125    );
21126
21127    test(
21128      r#"
21129        .foo{
21130          grid-template-areas: none;
21131          grid-template-columns: auto 1fr auto;
21132          grid-template-rows: repeat(2, 1fr);
21133        }
21134      "#,
21135      indoc! {r#"
21136        .foo {
21137          grid-template: repeat(2, 1fr) / auto 1fr auto;
21138        }
21139      "#},
21140    );
21141
21142    test(
21143      r#"
21144        .foo{
21145          grid-template-areas: none;
21146          grid-template-columns: none;
21147          grid-template-rows: none;
21148        }
21149      "#,
21150      indoc! {r#"
21151        .foo {
21152          grid-template: none;
21153        }
21154      "#},
21155    );
21156
21157    test(
21158      r#"
21159        .foo{
21160          grid-template-areas: "a a a"
21161                               "b b b";
21162          grid-template-rows: [header-top] auto [header-bottom main-top] 1fr [main-bottom];
21163          grid-template-columns: auto 1fr auto;
21164          grid-auto-flow: row;
21165          grid-auto-rows: auto;
21166          grid-auto-columns: auto;
21167        }
21168      "#,
21169      indoc! {r#"
21170        .foo {
21171          grid: [header-top] "a a a" [header-bottom]
21172                [main-top] "b b b" 1fr [main-bottom]
21173                / auto 1fr auto;
21174        }
21175      "#},
21176    );
21177
21178    test(
21179      r#"
21180        .foo{
21181          grid-template-areas: none;
21182          grid-template-columns: auto 1fr auto;
21183          grid-template-rows: repeat(2, 1fr);
21184          grid-auto-flow: row;
21185          grid-auto-rows: auto;
21186          grid-auto-columns: auto;
21187        }
21188      "#,
21189      indoc! {r#"
21190        .foo {
21191          grid: repeat(2, 1fr) / auto 1fr auto;
21192        }
21193      "#},
21194    );
21195
21196    test(
21197      r#"
21198        .foo{
21199          grid-template-areas: none;
21200          grid-template-columns: none;
21201          grid-template-rows: none;
21202          grid-auto-flow: row;
21203          grid-auto-rows: auto;
21204          grid-auto-columns: auto;
21205        }
21206      "#,
21207      indoc! {r#"
21208        .foo {
21209          grid: none;
21210        }
21211      "#},
21212    );
21213
21214    test(
21215      r#"
21216        .foo{
21217          grid-template-areas: "a a a"
21218                               "b b b";
21219          grid-template-rows: [header-top] auto [header-bottom main-top] 1fr [main-bottom];
21220          grid-template-columns: auto 1fr auto;
21221          grid-auto-flow: column;
21222          grid-auto-rows: 1fr;
21223          grid-auto-columns: 1fr;
21224        }
21225      "#,
21226      indoc! {r#"
21227        .foo {
21228          grid-template: [header-top] "a a a" [header-bottom]
21229                         [main-top] "b b b" 1fr [main-bottom]
21230                         / auto 1fr auto;
21231          grid-auto-rows: 1fr;
21232          grid-auto-columns: 1fr;
21233          grid-auto-flow: column;
21234        }
21235      "#},
21236    );
21237
21238    test(
21239      r#"
21240        .foo{
21241          grid-template-rows: auto 1fr;
21242          grid-template-columns: auto 1fr auto;
21243          grid-template-areas: none;
21244          grid-auto-flow: row;
21245          grid-auto-rows: auto;
21246          grid-auto-columns: auto;
21247        }
21248      "#,
21249      indoc! {r#"
21250        .foo {
21251          grid: auto 1fr / auto 1fr auto;
21252        }
21253      "#},
21254    );
21255
21256    test(
21257      r#"
21258        .foo{
21259          grid-template-rows: auto 1fr;
21260          grid-template-columns: auto 1fr auto;
21261          grid-template-areas: none;
21262          grid-auto-flow: column;
21263          grid-auto-rows: 1fr;
21264          grid-auto-columns: 1fr;
21265        }
21266      "#,
21267      indoc! {r#"
21268        .foo {
21269          grid-template: auto 1fr / auto 1fr auto;
21270          grid-auto-rows: 1fr;
21271          grid-auto-columns: 1fr;
21272          grid-auto-flow: column;
21273        }
21274      "#},
21275    );
21276
21277    test(
21278      r#"
21279        .foo{
21280          grid-template-rows: none;
21281          grid-template-columns: auto 1fr auto;
21282          grid-template-areas: none;
21283          grid-auto-flow: column;
21284          grid-auto-rows: 1fr;
21285          grid-auto-columns: 1fr;
21286        }
21287      "#,
21288      indoc! {r#"
21289        .foo {
21290          grid-template: none / auto 1fr auto;
21291          grid-auto-rows: 1fr;
21292          grid-auto-columns: 1fr;
21293          grid-auto-flow: column;
21294        }
21295      "#},
21296    );
21297
21298    test(
21299      r#"
21300        .foo{
21301          grid-template-rows: none;
21302          grid-template-columns: auto 1fr auto;
21303          grid-template-areas: none;
21304          grid-auto-flow: row;
21305          grid-auto-rows: 1fr;
21306          grid-auto-columns: auto;
21307        }
21308      "#,
21309      indoc! {r#"
21310        .foo {
21311          grid: auto-flow 1fr / auto 1fr auto;
21312        }
21313      "#},
21314    );
21315
21316    test(
21317      r#"
21318        .foo{
21319          grid-template-rows: none;
21320          grid-template-columns: auto 1fr auto;
21321          grid-template-areas: none;
21322          grid-auto-flow: row dense;
21323          grid-auto-rows: 1fr;
21324          grid-auto-columns: auto;
21325        }
21326      "#,
21327      indoc! {r#"
21328        .foo {
21329          grid: auto-flow dense 1fr / auto 1fr auto;
21330        }
21331      "#},
21332    );
21333
21334    test(
21335      r#"
21336        .foo{
21337          grid-template-rows: auto 1fr auto;
21338          grid-template-columns: none;
21339          grid-template-areas: none;
21340          grid-auto-flow: column;
21341          grid-auto-rows: auto;
21342          grid-auto-columns: 1fr;
21343        }
21344      "#,
21345      indoc! {r#"
21346        .foo {
21347          grid: auto 1fr auto / auto-flow 1fr;
21348        }
21349      "#},
21350    );
21351
21352    test(
21353      r#"
21354        .foo{
21355          grid-template-rows: auto 1fr auto;
21356          grid-template-columns: none;
21357          grid-template-areas: none;
21358          grid-auto-flow: column dense;
21359          grid-auto-rows: auto;
21360          grid-auto-columns: 1fr;
21361        }
21362      "#,
21363      indoc! {r#"
21364        .foo {
21365          grid: auto 1fr auto / auto-flow dense 1fr;
21366        }
21367      "#},
21368    );
21369
21370    test(
21371      r#"
21372        .foo{
21373          grid-template-rows: auto 1fr auto;
21374          grid-template-columns: none;
21375          grid-template-areas: none;
21376          grid-auto-flow: var(--auto-flow);
21377          grid-auto-rows: auto;
21378          grid-auto-columns: 1fr;
21379        }
21380      "#,
21381      indoc! {r#"
21382        .foo {
21383          grid-template: auto 1fr auto / none;
21384          grid-auto-flow: var(--auto-flow);
21385          grid-auto-rows: auto;
21386          grid-auto-columns: 1fr;
21387        }
21388      "#},
21389    );
21390
21391    test(
21392      r#"
21393        .foo{
21394          grid: auto 1fr auto / auto-flow dense 1fr;
21395          grid-template-rows: 1fr 1fr 1fr;
21396        }
21397      "#,
21398      indoc! {r#"
21399        .foo {
21400          grid: 1fr 1fr 1fr / auto-flow dense 1fr;
21401        }
21402      "#},
21403    );
21404
21405    test(
21406      r#"
21407        .foo{
21408          grid-row-start: a;
21409          grid-row-end: a;
21410          grid-column-start: a;
21411          grid-column-end: a;
21412        }
21413      "#,
21414      indoc! {r#"
21415        .foo {
21416          grid-area: a;
21417        }
21418      "#},
21419    );
21420
21421    test(
21422      r#"
21423        .foo{
21424          grid-row-start: 1;
21425          grid-row-end: 2;
21426          grid-column-start: 3;
21427          grid-column-end: 4;
21428        }
21429      "#,
21430      indoc! {r#"
21431        .foo {
21432          grid-area: 1 / 3 / 2 / 4;
21433        }
21434      "#},
21435    );
21436
21437    test(
21438      r#"
21439        .foo{
21440          grid-row-start: a;
21441          grid-row-end: a;
21442        }
21443      "#,
21444      indoc! {r#"
21445        .foo {
21446          grid-row: a;
21447        }
21448      "#},
21449    );
21450
21451    test(
21452      r#"
21453        .foo{
21454          grid-column-start: a;
21455          grid-column-end: a;
21456        }
21457      "#,
21458      indoc! {r#"
21459        .foo {
21460          grid-column: a;
21461        }
21462      "#},
21463    );
21464  }
21465
21466  #[test]
21467  fn test_moz_document() {
21468    minify_test(
21469      r#"
21470      @-moz-document url-prefix() {
21471        h1 {
21472          color: yellow;
21473        }
21474      }
21475    "#,
21476      "@-moz-document url-prefix(){h1{color:#ff0}}",
21477    );
21478    minify_test(
21479      r#"
21480      @-moz-document url-prefix("") {
21481        h1 {
21482          color: yellow;
21483        }
21484      }
21485    "#,
21486      "@-moz-document url-prefix(){h1{color:#ff0}}",
21487    );
21488    error_test(
21489      "@-moz-document url-prefix(foo) {}",
21490      ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("foo".into())),
21491    );
21492    error_test(
21493      "@-moz-document url-prefix(\"foo\") {}",
21494      ParserError::UnexpectedToken(crate::properties::custom::Token::String("foo".into())),
21495    );
21496  }
21497
21498  #[test]
21499  fn test_custom_properties() {
21500    minify_test(".foo { --test: ; }", ".foo{--test: }");
21501    minify_test(".foo { --test:  ; }", ".foo{--test: }");
21502    minify_test(".foo { --test: foo; }", ".foo{--test:foo}");
21503    minify_test(".foo { --test:  foo; }", ".foo{--test:foo}");
21504    minify_test(".foo { --test: foo ; }", ".foo{--test:foo}");
21505    minify_test(".foo { --test: foo  ; }", ".foo{--test:foo}");
21506    minify_test(".foo { --test:foo; }", ".foo{--test:foo}");
21507    minify_test(".foo { --test:foo ; }", ".foo{--test:foo}");
21508    minify_test(".foo { --test: var(--foo, 20px); }", ".foo{--test:var(--foo,20px)}");
21509    minify_test(
21510      ".foo { transition: var(--foo, 20px),\nvar(--bar, 40px); }",
21511      ".foo{transition:var(--foo,20px),var(--bar,40px)}",
21512    );
21513    minify_test(
21514      ".foo { background: var(--color) var(--image); }",
21515      ".foo{background:var(--color)var(--image)}",
21516    );
21517    minify_test(
21518      ".foo { height: calc(var(--spectrum-global-dimension-size-300) / 2);",
21519      ".foo{height:calc(var(--spectrum-global-dimension-size-300)/2)}",
21520    );
21521    minify_test(
21522      ".foo { color: var(--color, rgb(255, 255, 0)); }",
21523      ".foo{color:var(--color,#ff0)}",
21524    );
21525    minify_test(
21526      ".foo { color: var(--color, #ffff00); }",
21527      ".foo{color:var(--color,#ff0)}",
21528    );
21529    minify_test(
21530      ".foo { color: var(--color, rgb(var(--red), var(--green), 0)); }",
21531      ".foo{color:var(--color,rgb(var(--red),var(--green),0))}",
21532    );
21533    minify_test(".foo { --test: .5s; }", ".foo{--test:.5s}");
21534    minify_test(".foo { --theme-sizes-1\\/12: 2 }", ".foo{--theme-sizes-1\\/12:2}");
21535    minify_test(".foo { --test: 0px; }", ".foo{--test:0px}");
21536
21537    prefix_test(
21538      r#"
21539      .foo {
21540        --custom: lab(40% 56.6 39);
21541      }
21542    "#,
21543      indoc! {r#"
21544      .foo {
21545        --custom: #b32323;
21546      }
21547
21548      @supports (color: lab(0% 0 0)) {
21549        .foo {
21550          --custom: lab(40% 56.6 39);
21551        }
21552      }
21553    "#},
21554      Browsers {
21555        chrome: Some(90 << 16),
21556        ..Browsers::default()
21557      },
21558    );
21559
21560    prefix_test(
21561      r#"
21562      .foo {
21563        --custom: lab(40% 56.6 39) !important;
21564      }
21565    "#,
21566      indoc! {r#"
21567      .foo {
21568        --custom: #b32323 !important;
21569      }
21570
21571      @supports (color: lab(0% 0 0)) {
21572        .foo {
21573          --custom: lab(40% 56.6 39) !important;
21574        }
21575      }
21576    "#},
21577      Browsers {
21578        chrome: Some(90 << 16),
21579        ..Browsers::default()
21580      },
21581    );
21582
21583    prefix_test(
21584      r#"
21585      .foo {
21586        --custom: lab(40% 56.6 39);
21587      }
21588    "#,
21589      indoc! {r#"
21590      .foo {
21591        --custom: #b32323;
21592      }
21593
21594      @supports (color: color(display-p3 0 0 0)) {
21595        .foo {
21596          --custom: color(display-p3 .643308 .192455 .167712);
21597        }
21598      }
21599
21600      @supports (color: lab(0% 0 0)) {
21601        .foo {
21602          --custom: lab(40% 56.6 39);
21603        }
21604      }
21605    "#},
21606      Browsers {
21607        chrome: Some(90 << 16),
21608        safari: Some(14 << 16),
21609        ..Browsers::default()
21610      },
21611    );
21612
21613    prefix_test(
21614      r#"
21615      .foo {
21616        --custom: lab(40% 56.6 39);
21617      }
21618    "#,
21619      indoc! {r#"
21620      .foo {
21621        --custom: color(display-p3 .643308 .192455 .167712);
21622      }
21623
21624      @supports (color: lab(0% 0 0)) {
21625        .foo {
21626          --custom: lab(40% 56.6 39);
21627        }
21628      }
21629    "#},
21630      Browsers {
21631        safari: Some(14 << 16),
21632        ..Browsers::default()
21633      },
21634    );
21635
21636    prefix_test(
21637      r#"
21638      .foo {
21639        --custom: lab(40% 56.6 39);
21640      }
21641    "#,
21642      indoc! {r#"
21643      .foo {
21644        --custom: lab(40% 56.6 39);
21645      }
21646    "#},
21647      Browsers {
21648        safari: Some(15 << 16),
21649        ..Browsers::default()
21650      },
21651    );
21652
21653    prefix_test(
21654      r#"
21655      .foo {
21656        --custom: oklab(59.686% 0.1009 0.1192);
21657      }
21658    "#,
21659      indoc! {r#"
21660      .foo {
21661        --custom: lab(52.2319% 40.1449 59.9171);
21662      }
21663    "#},
21664      Browsers {
21665        safari: Some(15 << 16),
21666        ..Browsers::default()
21667      },
21668    );
21669
21670    prefix_test(
21671      r#"
21672      .foo {
21673        --custom: oklab(59.686% 0.1009 0.1192);
21674      }
21675    "#,
21676      indoc! {r#"
21677      .foo {
21678        --custom: color(display-p3 .724144 .386777 .148795);
21679      }
21680
21681      @supports (color: lab(0% 0 0)) {
21682        .foo {
21683          --custom: lab(52.2319% 40.1449 59.9171);
21684        }
21685      }
21686    "#},
21687      Browsers {
21688        safari: Some(14 << 16),
21689        ..Browsers::default()
21690      },
21691    );
21692
21693    prefix_test(
21694      r#"
21695      .foo {
21696        --custom: oklab(59.686% 0.1009 0.1192);
21697      }
21698    "#,
21699      indoc! {r#"
21700      .foo {
21701        --custom: #c65d07;
21702      }
21703
21704      @supports (color: color(display-p3 0 0 0)) {
21705        .foo {
21706          --custom: color(display-p3 .724144 .386777 .148795);
21707        }
21708      }
21709
21710      @supports (color: lab(0% 0 0)) {
21711        .foo {
21712          --custom: lab(52.2319% 40.1449 59.9171);
21713        }
21714      }
21715    "#},
21716      Browsers {
21717        safari: Some(14 << 16),
21718        chrome: Some(90 << 16),
21719        ..Browsers::default()
21720      },
21721    );
21722
21723    prefix_test(
21724      r#"
21725      .foo {
21726        --foo: oklab(59.686% 0.1009 0.1192);
21727        --bar: lab(40% 56.6 39);
21728      }
21729    "#,
21730      indoc! {r#"
21731      .foo {
21732        --foo: #c65d07;
21733        --bar: #b32323;
21734      }
21735
21736      @supports (color: color(display-p3 0 0 0)) {
21737        .foo {
21738          --foo: color(display-p3 .724144 .386777 .148795);
21739          --bar: color(display-p3 .643308 .192455 .167712);
21740        }
21741      }
21742
21743      @supports (color: lab(0% 0 0)) {
21744        .foo {
21745          --foo: lab(52.2319% 40.1449 59.9171);
21746          --bar: lab(40% 56.6 39);
21747        }
21748      }
21749    "#},
21750      Browsers {
21751        safari: Some(14 << 16),
21752        chrome: Some(90 << 16),
21753        ..Browsers::default()
21754      },
21755    );
21756
21757    prefix_test(
21758      r#"
21759      .foo {
21760        --foo: color(display-p3 0 1 0);
21761      }
21762    "#,
21763      indoc! {r#"
21764      .foo {
21765        --foo: #00f942;
21766      }
21767
21768      @supports (color: color(display-p3 0 0 0)) {
21769        .foo {
21770          --foo: color(display-p3 0 1 0);
21771        }
21772      }
21773    "#},
21774      Browsers {
21775        safari: Some(14 << 16),
21776        chrome: Some(90 << 16),
21777        ..Browsers::default()
21778      },
21779    );
21780
21781    prefix_test(
21782      r#"
21783      .foo {
21784        --foo: color(display-p3 0 1 0);
21785      }
21786    "#,
21787      indoc! {r#"
21788      .foo {
21789        --foo: color(display-p3 0 1 0);
21790      }
21791    "#},
21792      Browsers {
21793        safari: Some(14 << 16),
21794        ..Browsers::default()
21795      },
21796    );
21797
21798    prefix_test(
21799      r#"
21800      .foo {
21801        --foo: color(display-p3 0 1 0);
21802      }
21803    "#,
21804      indoc! {r#"
21805      .foo {
21806        --foo: #00f942;
21807      }
21808
21809      @supports (color: color(display-p3 0 0 0)) {
21810        .foo {
21811          --foo: color(display-p3 0 1 0);
21812        }
21813      }
21814    "#},
21815      Browsers {
21816        safari: Some(15 << 16),
21817        chrome: Some(90 << 16),
21818        ..Browsers::default()
21819      },
21820    );
21821
21822    prefix_test(
21823      r#"
21824      .foo {
21825        --foo: color(display-p3 0 1 0);
21826      }
21827    "#,
21828      indoc! {r#"
21829      .foo {
21830        --foo: #00f942;
21831      }
21832
21833      @supports (color: color(display-p3 0 0 0)) {
21834        .foo {
21835          --foo: color(display-p3 0 1 0);
21836        }
21837      }
21838    "#},
21839      Browsers {
21840        chrome: Some(90 << 16),
21841        ..Browsers::default()
21842      },
21843    );
21844
21845    prefix_test(
21846      r#"
21847      .foo {
21848        text-decoration: underline;
21849      }
21850
21851      .foo {
21852        --custom: lab(40% 56.6 39);
21853      }
21854    "#,
21855      indoc! {r#"
21856      .foo {
21857        --custom: #b32323;
21858        text-decoration: underline;
21859      }
21860
21861      @supports (color: lab(0% 0 0)) {
21862        .foo {
21863          --custom: lab(40% 56.6 39);
21864        }
21865      }
21866    "#},
21867      Browsers {
21868        chrome: Some(90 << 16),
21869        ..Browsers::default()
21870      },
21871    );
21872
21873    prefix_test(
21874      r#"
21875      .foo {
21876        --custom: lab(40% 56.6 39);
21877      }
21878
21879      .foo {
21880        text-decoration: underline;
21881      }
21882    "#,
21883      indoc! {r#"
21884      .foo {
21885        --custom: #b32323;
21886      }
21887
21888      @supports (color: lab(0% 0 0)) {
21889        .foo {
21890          --custom: lab(40% 56.6 39);
21891        }
21892      }
21893
21894      .foo {
21895        text-decoration: underline;
21896      }
21897    "#},
21898      Browsers {
21899        chrome: Some(90 << 16),
21900        ..Browsers::default()
21901      },
21902    );
21903
21904    prefix_test(
21905      r#"
21906      @keyframes foo {
21907        from {
21908          --custom: lab(40% 56.6 39);
21909        }
21910
21911        to {
21912          --custom: lch(50.998% 135.363 338);
21913        }
21914      }
21915    "#,
21916      indoc! {r#"
21917      @keyframes foo {
21918        from {
21919          --custom: #b32323;
21920        }
21921
21922        to {
21923          --custom: #ee00be;
21924        }
21925      }
21926
21927      @supports (color: lab(0% 0 0)) {
21928        @keyframes foo {
21929          from {
21930            --custom: lab(40% 56.6 39);
21931          }
21932
21933          to {
21934            --custom: lab(50.998% 125.506 -50.7078);
21935          }
21936        }
21937      }
21938    "#},
21939      Browsers {
21940        chrome: Some(90 << 16),
21941        ..Browsers::default()
21942      },
21943    );
21944
21945    prefix_test(
21946      r#"
21947      @keyframes foo {
21948        from {
21949          --custom: lab(40% 56.6 39);
21950        }
21951
21952        to {
21953          --custom: lch(50.998% 135.363 338);
21954        }
21955      }
21956    "#,
21957      indoc! {r#"
21958      @keyframes foo {
21959        from {
21960          --custom: #b32323;
21961        }
21962
21963        to {
21964          --custom: #ee00be;
21965        }
21966      }
21967
21968      @supports (color: color(display-p3 0 0 0)) {
21969        @keyframes foo {
21970          from {
21971            --custom: color(display-p3 .643308 .192455 .167712);
21972          }
21973
21974          to {
21975            --custom: color(display-p3 .972962 -.362078 .804206);
21976          }
21977        }
21978      }
21979
21980      @supports (color: lab(0% 0 0)) {
21981        @keyframes foo {
21982          from {
21983            --custom: lab(40% 56.6 39);
21984          }
21985
21986          to {
21987            --custom: lab(50.998% 125.506 -50.7078);
21988          }
21989        }
21990      }
21991    "#},
21992      Browsers {
21993        chrome: Some(90 << 16),
21994        safari: Some(14 << 16),
21995        ..Browsers::default()
21996      },
21997    );
21998
21999    prefix_test(
22000      r#"
22001      @keyframes foo {
22002        from {
22003          --custom: #ff0;
22004          opacity: 0;
22005        }
22006
22007        to {
22008          --custom: lch(50.998% 135.363 338);
22009          opacity: 1;
22010        }
22011      }
22012    "#,
22013      indoc! {r#"
22014      @keyframes foo {
22015        from {
22016          --custom: #ff0;
22017          opacity: 0;
22018        }
22019
22020        to {
22021          --custom: #ee00be;
22022          opacity: 1;
22023        }
22024      }
22025
22026      @supports (color: lab(0% 0 0)) {
22027        @keyframes foo {
22028          from {
22029            --custom: #ff0;
22030            opacity: 0;
22031          }
22032
22033          to {
22034            --custom: lab(50.998% 125.506 -50.7078);
22035            opacity: 1;
22036          }
22037        }
22038      }
22039    "#},
22040      Browsers {
22041        chrome: Some(90 << 16),
22042        ..Browsers::default()
22043      },
22044    );
22045
22046    prefix_test(
22047      r#"
22048      @keyframes foo {
22049        from {
22050          text-decoration: var(--foo) lab(29.2345% 39.3825 20.0664);
22051        }
22052      }
22053    "#,
22054      indoc! {r#"
22055      @keyframes foo {
22056        from {
22057          text-decoration: var(--foo) #7d2329;
22058        }
22059      }
22060
22061      @supports (color: lab(0% 0 0)) {
22062        @keyframes foo {
22063          from {
22064            text-decoration: var(--foo) lab(29.2345% 39.3825 20.0664);
22065          }
22066        }
22067      }
22068    "#},
22069      Browsers {
22070        chrome: Some(90 << 16),
22071        ..Browsers::default()
22072      },
22073    );
22074  }
22075
22076  #[test]
22077  fn test_charset() {
22078    test(
22079      r#"
22080      @charset "UTF-8";
22081
22082      .foo {
22083        color: red;
22084      }
22085
22086      @charset "UTF-8";
22087
22088      .bar {
22089        color: yellow;
22090      }
22091    "#,
22092      indoc! { r#"
22093      .foo {
22094        color: red;
22095      }
22096
22097      .bar {
22098        color: #ff0;
22099      }
22100    "#},
22101    )
22102  }
22103
22104  #[test]
22105  fn test_style_attr() {
22106    attr_test("color: yellow; flex: 1 1 auto", "color: #ff0; flex: auto", false, None);
22107    attr_test("color: yellow; flex: 1 1 auto", "color:#ff0;flex:auto", true, None);
22108    attr_test(
22109      "border-inline-start: 2px solid red",
22110      "border-inline-start: 2px solid red",
22111      false,
22112      Some(Browsers {
22113        safari: Some(12 << 16),
22114        ..Browsers::default()
22115      }),
22116    );
22117    attr_test(
22118      "color: lab(40% 56.6 39);",
22119      "color:#b32323;color:lab(40% 56.6 39)",
22120      true,
22121      Some(Browsers {
22122        safari: Some(8 << 16),
22123        ..Browsers::default()
22124      }),
22125    );
22126    attr_test(
22127      "--foo: lab(40% 56.6 39);",
22128      "--foo:#b32323",
22129      true,
22130      Some(Browsers {
22131        safari: Some(8 << 16),
22132        ..Browsers::default()
22133      }),
22134    );
22135    attr_test(
22136      "text-decoration: var(--foo) lab(40% 56.6 39);",
22137      "text-decoration:var(--foo)#b32323",
22138      true,
22139      Some(Browsers {
22140        chrome: Some(90 << 16),
22141        ..Browsers::default()
22142      }),
22143    );
22144  }
22145
22146  #[test]
22147  fn test_nesting() {
22148    nesting_test(
22149      r#"
22150        .foo {
22151          color: blue;
22152          & > .bar { color: red; }
22153        }
22154      "#,
22155      indoc! {r#"
22156        .foo {
22157          color: #00f;
22158        }
22159
22160        .foo > .bar {
22161          color: red;
22162        }
22163      "#},
22164    );
22165
22166    nesting_test(
22167      r#"
22168        .foo {
22169          color: blue;
22170          &.bar { color: red; }
22171        }
22172      "#,
22173      indoc! {r#"
22174        .foo {
22175          color: #00f;
22176        }
22177
22178        .foo.bar {
22179          color: red;
22180        }
22181      "#},
22182    );
22183
22184    nesting_test(
22185      r#"
22186        .foo, .bar {
22187          color: blue;
22188          & + .baz, &.qux { color: red; }
22189        }
22190      "#,
22191      indoc! {r#"
22192        .foo, .bar {
22193          color: #00f;
22194        }
22195
22196        :is(.foo, .bar) + .baz, :is(.foo, .bar).qux {
22197          color: red;
22198        }
22199      "#},
22200    );
22201
22202    nesting_test(
22203      r#"
22204        .foo {
22205          color: blue;
22206          & .bar & .baz & .qux { color: red; }
22207        }
22208      "#,
22209      indoc! {r#"
22210        .foo {
22211          color: #00f;
22212        }
22213
22214        .foo .bar .foo .baz .foo .qux {
22215          color: red;
22216        }
22217      "#},
22218    );
22219
22220    nesting_test(
22221      r#"
22222        .foo {
22223          color: blue;
22224          & { padding: 2ch; }
22225        }
22226      "#,
22227      indoc! {r#"
22228        .foo {
22229          color: #00f;
22230        }
22231
22232        .foo {
22233          padding: 2ch;
22234        }
22235      "#},
22236    );
22237
22238    nesting_test(
22239      r#"
22240        .foo {
22241          color: blue;
22242          && { padding: 2ch; }
22243        }
22244      "#,
22245      indoc! {r#"
22246        .foo {
22247          color: #00f;
22248        }
22249
22250        .foo.foo {
22251          padding: 2ch;
22252        }
22253      "#},
22254    );
22255
22256    nesting_test(
22257      r#"
22258        .error, .invalid {
22259          &:hover > .baz { color: red; }
22260        }
22261      "#,
22262      indoc! {r#"
22263        :is(.error, .invalid):hover > .baz {
22264          color: red;
22265        }
22266      "#},
22267    );
22268
22269    nesting_test(
22270      r#"
22271        .foo {
22272          &:is(.bar, &.baz) { color: red; }
22273        }
22274      "#,
22275      indoc! {r#"
22276        .foo:is(.bar, .foo.baz) {
22277          color: red;
22278        }
22279      "#},
22280    );
22281
22282    nesting_test(
22283      r#"
22284        figure {
22285          margin: 0;
22286
22287          & > figcaption {
22288            background: hsl(0 0% 0% / 50%);
22289
22290            & > p {
22291              font-size: .9rem;
22292            }
22293          }
22294        }
22295      "#,
22296      indoc! {r#"
22297        figure {
22298          margin: 0;
22299        }
22300
22301        figure > figcaption {
22302          background: #00000080;
22303        }
22304
22305        figure > figcaption > p {
22306          font-size: .9rem;
22307        }
22308      "#},
22309    );
22310
22311    nesting_test(
22312      r#"
22313        .foo {
22314          display: grid;
22315
22316          @media (orientation: landscape) {
22317            grid-auto-flow: column;
22318          }
22319        }
22320      "#,
22321      indoc! {r#"
22322        .foo {
22323          display: grid;
22324        }
22325
22326        @media (orientation: landscape) {
22327          .foo {
22328            grid-auto-flow: column;
22329          }
22330        }
22331      "#},
22332    );
22333
22334    nesting_test(
22335      r#"
22336        .foo {
22337          display: grid;
22338
22339          @media (orientation: landscape) {
22340            grid-auto-flow: column;
22341
22342            @media (width > 1024px) {
22343              max-inline-size: 1024px;
22344            }
22345          }
22346        }
22347      "#,
22348      indoc! {r#"
22349        .foo {
22350          display: grid;
22351        }
22352
22353        @media (orientation: landscape) {
22354          .foo {
22355            grid-auto-flow: column;
22356          }
22357
22358          @media (min-width: 1024px) {
22359            .foo {
22360              max-inline-size: 1024px;
22361            }
22362          }
22363        }
22364      "#},
22365    );
22366
22367    nesting_test(
22368      r#"
22369        .foo {
22370          @media (min-width: 640px) {
22371            color: red !important;
22372          }
22373        }
22374      "#,
22375      indoc! {r#"
22376        @media (min-width: 640px) {
22377          .foo {
22378            color: red !important;
22379          }
22380        }
22381      "#},
22382    );
22383
22384    nesting_test(
22385      r#"
22386        .foo {
22387          display: grid;
22388
22389          @supports (foo: bar) {
22390            grid-auto-flow: column;
22391          }
22392        }
22393      "#,
22394      indoc! {r#"
22395        .foo {
22396          display: grid;
22397        }
22398
22399        @supports (foo: bar) {
22400          .foo {
22401            grid-auto-flow: column;
22402          }
22403        }
22404      "#},
22405    );
22406
22407    nesting_test(
22408      r#"
22409        .foo {
22410          display: grid;
22411
22412          @container (min-width: 100px) {
22413            grid-auto-flow: column;
22414          }
22415        }
22416      "#,
22417      indoc! {r#"
22418        .foo {
22419          display: grid;
22420        }
22421
22422        @container (width >= 100px) {
22423          .foo {
22424            grid-auto-flow: column;
22425          }
22426        }
22427      "#},
22428    );
22429
22430    nesting_test(
22431      r#"
22432        .foo {
22433          display: grid;
22434
22435          @layer test {
22436            grid-auto-flow: column;
22437          }
22438        }
22439      "#,
22440      indoc! {r#"
22441        .foo {
22442          display: grid;
22443        }
22444
22445        @layer test {
22446          .foo {
22447            grid-auto-flow: column;
22448          }
22449        }
22450      "#},
22451    );
22452
22453    nesting_test(
22454      r#"
22455        .foo {
22456          display: grid;
22457
22458          @layer {
22459            grid-auto-flow: column;
22460          }
22461        }
22462      "#,
22463      indoc! {r#"
22464        .foo {
22465          display: grid;
22466        }
22467
22468        @layer {
22469          .foo {
22470            grid-auto-flow: column;
22471          }
22472        }
22473      "#},
22474    );
22475
22476    nesting_test(
22477      r#"
22478        @namespace "http://example.com/foo";
22479        @namespace toto "http://toto.example.org";
22480
22481        .foo {
22482          &div {
22483            color: red;
22484          }
22485
22486          &* {
22487            color: green;
22488          }
22489
22490          &|x {
22491            color: red;
22492          }
22493
22494          &*|x {
22495            color: green;
22496          }
22497
22498          &toto|x {
22499            color: red;
22500          }
22501        }
22502      "#,
22503      indoc! {r#"
22504        @namespace "http://example.com/foo";
22505        @namespace toto "http://toto.example.org";
22506
22507        div.foo {
22508          color: red;
22509        }
22510
22511        *.foo {
22512          color: green;
22513        }
22514
22515        |x.foo {
22516          color: red;
22517        }
22518
22519        *|x.foo {
22520          color: green;
22521        }
22522
22523        toto|x.foo {
22524          color: red;
22525        }
22526      "#},
22527    );
22528
22529    nesting_test(
22530      r#"
22531        .foo {
22532          &article > figure {
22533            color: red;
22534          }
22535        }
22536      "#,
22537      indoc! {r#"
22538        article.foo > figure {
22539          color: red;
22540        }
22541      "#},
22542    );
22543
22544    nesting_test(
22545      r#"
22546        div {
22547          &.bar {
22548            background: green;
22549          }
22550        }
22551      "#,
22552      indoc! {r#"
22553        div.bar {
22554          background: green;
22555        }
22556      "#},
22557    );
22558
22559    nesting_test(
22560      r#"
22561        div > .foo {
22562          &span {
22563            background: green;
22564          }
22565        }
22566      "#,
22567      indoc! {r#"
22568        span:is(div > .foo) {
22569          background: green;
22570        }
22571      "#},
22572    );
22573
22574    nesting_test(
22575      r#"
22576        .foo {
22577          & h1 {
22578            background: green;
22579          }
22580        }
22581      "#,
22582      indoc! {r#"
22583        .foo h1 {
22584          background: green;
22585        }
22586      "#},
22587    );
22588
22589    nesting_test(
22590      r#"
22591        .foo .bar {
22592          &h1 {
22593            background: green;
22594          }
22595        }
22596      "#,
22597      indoc! {r#"
22598        h1:is(.foo .bar) {
22599          background: green;
22600        }
22601      "#},
22602    );
22603
22604    nesting_test(
22605      r#"
22606        .foo.bar {
22607          &h1 {
22608            background: green;
22609          }
22610        }
22611      "#,
22612      indoc! {r#"
22613        h1.foo.bar {
22614          background: green;
22615        }
22616      "#},
22617    );
22618
22619    nesting_test(
22620      r#"
22621        .foo .bar {
22622          &h1 .baz {
22623            background: green;
22624          }
22625        }
22626      "#,
22627      indoc! {r#"
22628        h1:is(.foo .bar) .baz {
22629          background: green;
22630        }
22631      "#},
22632    );
22633
22634    nesting_test(
22635      r#"
22636        .foo .bar {
22637          &.baz {
22638            background: green;
22639          }
22640        }
22641      "#,
22642      indoc! {r#"
22643        .foo .bar.baz {
22644          background: green;
22645        }
22646      "#},
22647    );
22648
22649    nesting_test(
22650      r#"
22651        .foo {
22652          color: red;
22653          @nest .parent & {
22654            color: blue;
22655          }
22656        }
22657      "#,
22658      indoc! {r#"
22659        .foo {
22660          color: red;
22661        }
22662
22663        .parent .foo {
22664          color: #00f;
22665        }
22666      "#},
22667    );
22668
22669    nesting_test(
22670      r#"
22671        .foo {
22672          color: red;
22673          @nest :not(&) {
22674            color: blue;
22675          }
22676        }
22677      "#,
22678      indoc! {r#"
22679        .foo {
22680          color: red;
22681        }
22682
22683        :not(.foo) {
22684          color: #00f;
22685        }
22686      "#},
22687    );
22688
22689    nesting_test(
22690      r#"
22691        .foo {
22692          color: blue;
22693          @nest .bar & {
22694            color: red;
22695            &.baz {
22696              color: green;
22697            }
22698          }
22699        }
22700      "#,
22701      indoc! {r#"
22702        .foo {
22703          color: #00f;
22704        }
22705
22706        .bar .foo {
22707          color: red;
22708        }
22709
22710        .bar .foo.baz {
22711          color: green;
22712        }
22713      "#},
22714    );
22715
22716    nesting_test(
22717      r#"
22718        .foo {
22719          @nest :not(&) {
22720            color: red;
22721          }
22722
22723          & h1 {
22724            background: green;
22725          }
22726        }
22727      "#,
22728      indoc! {r#"
22729        :not(.foo) {
22730          color: red;
22731        }
22732
22733        .foo h1 {
22734          background: green;
22735        }
22736      "#},
22737    );
22738
22739    nesting_test(
22740      r#"
22741        .foo {
22742          & h1 {
22743            background: green;
22744          }
22745
22746          @nest :not(&) {
22747            color: red;
22748          }
22749        }
22750      "#,
22751      indoc! {r#"
22752        .foo h1 {
22753          background: green;
22754        }
22755
22756        :not(.foo) {
22757          color: red;
22758        }
22759      "#},
22760    );
22761
22762    nesting_test(
22763      r#"
22764        .foo .bar {
22765          @nest h1& {
22766            background: green;
22767          }
22768        }
22769      "#,
22770      indoc! {r#"
22771        h1:is(.foo .bar) {
22772          background: green;
22773        }
22774      "#},
22775    );
22776
22777    nesting_test(
22778      r#"
22779        @namespace "http://example.com/foo";
22780        @namespace toto "http://toto.example.org";
22781
22782        div {
22783          @nest .foo& {
22784            color: red;
22785          }
22786        }
22787
22788        * {
22789          @nest .foo& {
22790            color: red;
22791          }
22792        }
22793
22794        |x {
22795          @nest .foo& {
22796            color: red;
22797          }
22798        }
22799
22800        *|x {
22801          @nest .foo& {
22802            color: red;
22803          }
22804        }
22805
22806        toto|x {
22807          @nest .foo& {
22808            color: red;
22809          }
22810        }
22811      "#,
22812      indoc! {r#"
22813        @namespace "http://example.com/foo";
22814        @namespace toto "http://toto.example.org";
22815
22816        .foo:is(div) {
22817          color: red;
22818        }
22819
22820        .foo:is(*) {
22821          color: red;
22822        }
22823
22824        .foo:is(|x) {
22825          color: red;
22826        }
22827
22828        .foo:is(*|x) {
22829          color: red;
22830        }
22831
22832        .foo:is(toto|x) {
22833          color: red;
22834        }
22835      "#},
22836    );
22837
22838    nesting_test(
22839      r#"
22840        .foo .bar {
22841          @nest h1 .baz& {
22842            background: green;
22843          }
22844        }
22845      "#,
22846      indoc! {r#"
22847        h1 .baz:is(.foo .bar) {
22848          background: green;
22849        }
22850      "#},
22851    );
22852
22853    nesting_test(
22854      r#"
22855        .foo .bar {
22856          @nest .baz& {
22857            background: green;
22858          }
22859        }
22860      "#,
22861      indoc! {r#"
22862        .baz:is(.foo .bar) {
22863          background: green;
22864        }
22865      "#},
22866    );
22867
22868    nesting_test(
22869      r#"
22870        .foo .bar {
22871          @nest .baz & {
22872            background: green;
22873          }
22874        }
22875      "#,
22876      indoc! {r#"
22877        .baz :is(.foo .bar) {
22878          background: green;
22879        }
22880      "#},
22881    );
22882
22883    nesting_test(
22884      r#"
22885        .foo {
22886          color: red;
22887          @nest & > .bar {
22888            color: blue;
22889          }
22890        }
22891      "#,
22892      indoc! {r#"
22893        .foo {
22894          color: red;
22895        }
22896
22897        .foo > .bar {
22898          color: #00f;
22899        }
22900      "#},
22901    );
22902
22903    nesting_test(
22904      r#"
22905      .foo {
22906        color: red;
22907        .bar {
22908          color: blue;
22909        }
22910      }
22911      "#,
22912      indoc! {r#"
22913      .foo {
22914        color: red;
22915      }
22916
22917      .foo .bar {
22918        color: #00f;
22919      }
22920      "#},
22921    );
22922
22923    nesting_test(
22924      r#"
22925      .foo {
22926        color: red;
22927        .bar & {
22928          color: blue;
22929        }
22930      }
22931      "#,
22932      indoc! {r#"
22933      .foo {
22934        color: red;
22935      }
22936
22937      .bar .foo {
22938        color: #00f;
22939      }
22940      "#},
22941    );
22942
22943    nesting_test(
22944      r#"
22945      .foo {
22946        color: red;
22947        + .bar + & { color: blue; }
22948      }
22949      "#,
22950      indoc! {r#"
22951      .foo {
22952        color: red;
22953      }
22954
22955      .foo + .bar + .foo {
22956        color: #00f;
22957      }
22958      "#},
22959    );
22960
22961    nesting_test(
22962      r#"
22963      .foo {
22964        color: red;
22965        .bar & {
22966          color: blue;
22967        }
22968      }
22969      "#,
22970      indoc! {r#"
22971      .foo {
22972        color: red;
22973      }
22974
22975      .bar .foo {
22976        color: #00f;
22977      }
22978      "#},
22979    );
22980
22981    nesting_test(
22982      r#"
22983        .foo {
22984          color: red;
22985          .parent & {
22986            color: blue;
22987          }
22988        }
22989      "#,
22990      indoc! {r#"
22991        .foo {
22992          color: red;
22993        }
22994
22995        .parent .foo {
22996          color: #00f;
22997        }
22998      "#},
22999    );
23000
23001    nesting_test(
23002      r#"
23003        .foo {
23004          color: red;
23005          :not(&) {
23006            color: blue;
23007          }
23008        }
23009      "#,
23010      indoc! {r#"
23011        .foo {
23012          color: red;
23013        }
23014
23015        :not(.foo) {
23016          color: #00f;
23017        }
23018      "#},
23019    );
23020
23021    nesting_test(
23022      r#"
23023        .foo {
23024          color: blue;
23025          .bar & {
23026            color: red;
23027            &.baz {
23028              color: green;
23029            }
23030          }
23031        }
23032      "#,
23033      indoc! {r#"
23034        .foo {
23035          color: #00f;
23036        }
23037
23038        .bar .foo {
23039          color: red;
23040        }
23041
23042        .bar .foo.baz {
23043          color: green;
23044        }
23045      "#},
23046    );
23047
23048    nesting_test(
23049      r#"
23050        .foo {
23051          :not(&) {
23052            color: red;
23053          }
23054
23055          & h1 {
23056            background: green;
23057          }
23058        }
23059      "#,
23060      indoc! {r#"
23061        :not(.foo) {
23062          color: red;
23063        }
23064
23065        .foo h1 {
23066          background: green;
23067        }
23068      "#},
23069    );
23070
23071    nesting_test(
23072      r#"
23073        .foo {
23074          & h1 {
23075            background: green;
23076          }
23077
23078          :not(&) {
23079            color: red;
23080          }
23081        }
23082      "#,
23083      indoc! {r#"
23084        .foo h1 {
23085          background: green;
23086        }
23087
23088        :not(.foo) {
23089          color: red;
23090        }
23091      "#},
23092    );
23093
23094    nesting_test(
23095      r#"
23096        .foo .bar {
23097          :is(h1)& {
23098            background: green;
23099          }
23100        }
23101      "#,
23102      indoc! {r#"
23103        :is(h1):is(.foo .bar) {
23104          background: green;
23105        }
23106      "#},
23107    );
23108
23109    nesting_test(
23110      r#"
23111        @namespace "http://example.com/foo";
23112        @namespace toto "http://toto.example.org";
23113
23114        div {
23115          .foo& {
23116            color: red;
23117          }
23118        }
23119
23120        * {
23121          .foo& {
23122            color: red;
23123          }
23124        }
23125
23126        |x {
23127          .foo& {
23128            color: red;
23129          }
23130        }
23131
23132        *|x {
23133          .foo& {
23134            color: red;
23135          }
23136        }
23137
23138        toto|x {
23139          .foo& {
23140            color: red;
23141          }
23142        }
23143      "#,
23144      indoc! {r#"
23145        @namespace "http://example.com/foo";
23146        @namespace toto "http://toto.example.org";
23147
23148        .foo:is(div) {
23149          color: red;
23150        }
23151
23152        .foo:is(*) {
23153          color: red;
23154        }
23155
23156        .foo:is(|x) {
23157          color: red;
23158        }
23159
23160        .foo:is(*|x) {
23161          color: red;
23162        }
23163
23164        .foo:is(toto|x) {
23165          color: red;
23166        }
23167      "#},
23168    );
23169
23170    nesting_test(
23171      r#"
23172        .foo .bar {
23173          :is(h1) .baz& {
23174            background: green;
23175          }
23176        }
23177      "#,
23178      indoc! {r#"
23179        :is(h1) .baz:is(.foo .bar) {
23180          background: green;
23181        }
23182      "#},
23183    );
23184
23185    nesting_test(
23186      r#"
23187        .foo .bar {
23188          .baz& {
23189            background: green;
23190          }
23191        }
23192      "#,
23193      indoc! {r#"
23194        .baz:is(.foo .bar) {
23195          background: green;
23196        }
23197      "#},
23198    );
23199
23200    nesting_test(
23201      r#"
23202        .foo .bar {
23203          .baz & {
23204            background: green;
23205          }
23206        }
23207      "#,
23208      indoc! {r#"
23209        .baz :is(.foo .bar) {
23210          background: green;
23211        }
23212      "#},
23213    );
23214
23215    nesting_test(
23216      r#"
23217        .foo {
23218          .bar {
23219            color: blue;
23220          }
23221          color: red;
23222        }
23223      "#,
23224      indoc! {r#"
23225        .foo {
23226          color: red;
23227        }
23228
23229        .foo .bar {
23230          color: #00f;
23231        }
23232      "#},
23233    );
23234
23235    nesting_test(
23236      r#"
23237        article {
23238          color: green;
23239          & { color: blue; }
23240          color: red;
23241        }
23242      "#,
23243      indoc! {r#"
23244        article {
23245          color: red;
23246        }
23247
23248        article {
23249          color: #00f;
23250        }
23251      "#},
23252    );
23253
23254    nesting_test(
23255      r#"
23256        & .foo {
23257          color: red;
23258        }
23259      "#,
23260      indoc! {r#"
23261        :scope .foo {
23262          color: red;
23263        }
23264      "#},
23265    );
23266
23267    nesting_test(
23268      r#"
23269        &.foo {
23270          color: red;
23271        }
23272      "#,
23273      indoc! {r#"
23274        :scope.foo {
23275          color: red;
23276        }
23277      "#},
23278    );
23279
23280    nesting_test(
23281      r#"
23282        .foo& {
23283          color: red;
23284        }
23285      "#,
23286      indoc! {r#"
23287        .foo:scope {
23288          color: red;
23289        }
23290      "#},
23291    );
23292
23293    nesting_test(
23294      r#"
23295        &html {
23296          color: red;
23297        }
23298      "#,
23299      indoc! {r#"
23300        html:scope {
23301          color: red;
23302        }
23303      "#},
23304    );
23305
23306    nesting_test(
23307      r#"
23308        .foo {
23309          color: blue;
23310          div {
23311            color: red;
23312          }
23313        }
23314      "#,
23315      indoc! {r#"
23316        .foo {
23317          color: #00f;
23318        }
23319
23320        .foo div {
23321          color: red;
23322        }
23323      "#},
23324    );
23325
23326    nesting_test(
23327      r#"
23328        div {
23329          color: blue;
23330
23331          button:focus {
23332            color: red;
23333          }
23334        }
23335      "#,
23336      indoc! {r#"
23337        div {
23338          color: #00f;
23339        }
23340
23341        div button:focus {
23342          color: red;
23343        }
23344      "#},
23345    );
23346    nesting_test(
23347      r#"
23348        div {
23349          color: blue;
23350
23351          --button:focus {
23352            color: red;
23353          }
23354        }
23355      "#,
23356      indoc! {r#"
23357        div {
23358          color: #00f;
23359          --button: focus { color: red; };
23360        }
23361      "#},
23362    );
23363
23364    nesting_test_no_targets(
23365      r#"
23366        .foo {
23367          color: blue;
23368          @nest .bar & {
23369            color: red;
23370            &.baz {
23371              color: green;
23372            }
23373          }
23374        }
23375      "#,
23376      indoc! {r#"
23377        .foo {
23378          color: #00f;
23379
23380          @nest .bar & {
23381            color: red;
23382
23383            &.baz {
23384              color: green;
23385            }
23386          }
23387        }
23388      "#},
23389    );
23390
23391    nesting_test_no_targets(
23392      r#"
23393        .foo {
23394          color: blue;
23395          &div {
23396            color: red;
23397          }
23398
23399          &span {
23400            color: purple;
23401          }
23402        }
23403      "#,
23404      indoc! {r#"
23405        .foo {
23406          color: #00f;
23407
23408          &div {
23409            color: red;
23410          }
23411
23412          &span {
23413            color: purple;
23414          }
23415        }
23416      "#},
23417    );
23418
23419    nesting_test_no_targets(
23420      r#"
23421        .error, .invalid {
23422          &:hover > .baz { color: red; }
23423        }
23424      "#,
23425      indoc! {r#"
23426        .error, .invalid {
23427          &:hover > .baz {
23428            color: red;
23429          }
23430        }
23431      "#},
23432    );
23433
23434    nesting_test_with_targets(
23435      r#"
23436        .foo {
23437          color: blue;
23438          & > .bar { color: red; }
23439        }
23440      "#,
23441      indoc! {r#"
23442        .foo {
23443          color: #00f;
23444        }
23445
23446        .foo > .bar {
23447          color: red;
23448        }
23449      "#},
23450      Targets {
23451        browsers: Some(Browsers {
23452          chrome: Some(112 << 16),
23453          ..Browsers::default()
23454        }),
23455        include: Features::Nesting,
23456        exclude: Features::empty(),
23457      },
23458    );
23459    nesting_test_with_targets(
23460      r#"
23461        .foo {
23462          color: blue;
23463          & > .bar { color: red; }
23464        }
23465      "#,
23466      indoc! {r#"
23467        .foo {
23468          color: #00f;
23469
23470          & > .bar {
23471            color: red;
23472          }
23473        }
23474      "#},
23475      Targets {
23476        browsers: Some(Browsers {
23477          chrome: Some(50 << 16),
23478          ..Browsers::default()
23479        }),
23480        include: Features::empty(),
23481        exclude: Features::Nesting,
23482      },
23483    );
23484
23485    let mut stylesheet = StyleSheet::parse(
23486      r#"
23487      .foo {
23488        color: blue;
23489        .bar {
23490          color: red;
23491        }
23492      }
23493      "#,
23494      ParserOptions::default(),
23495    )
23496    .unwrap();
23497    stylesheet.minify(MinifyOptions::default()).unwrap();
23498    let res = stylesheet
23499      .to_css(PrinterOptions {
23500        minify: true,
23501        ..PrinterOptions::default()
23502      })
23503      .unwrap();
23504    assert_eq!(res.code, ".foo{color:#00f;& .bar{color:red}}");
23505
23506    nesting_test_with_targets(
23507      r#"
23508        .a {
23509          &.b,
23510          &.c {
23511            &.d {
23512              color: red;
23513            }
23514          }
23515        }
23516      "#,
23517      indoc! {r#"
23518        .a.b.d {
23519          color: red;
23520        }
23521
23522        .a.c.d {
23523          color: red;
23524        }
23525      "#},
23526      Targets {
23527        browsers: Some(Browsers {
23528          safari: Some(13 << 16),
23529          ..Browsers::default()
23530        }),
23531        include: Features::Nesting,
23532        exclude: Features::empty(),
23533      },
23534    );
23535  }
23536
23537  #[test]
23538  fn test_css_modules() {
23539    css_modules_test(
23540      r#"
23541      .foo {
23542        color: red;
23543      }
23544
23545      #id {
23546        animation: 2s test;
23547      }
23548
23549      @keyframes test {
23550        from { color: red }
23551        to { color: yellow }
23552      }
23553
23554      @counter-style circles {
23555        symbols: Ⓐ Ⓑ Ⓒ;
23556      }
23557
23558      ul {
23559        list-style: circles;
23560      }
23561
23562      ol {
23563        list-style-type: none;
23564      }
23565
23566      li {
23567        list-style-type: disc;
23568      }
23569
23570      @keyframes fade {
23571        from { opacity: 0 }
23572        to { opacity: 1 }
23573      }
23574    "#,
23575      indoc! {r#"
23576      .EgL3uq_foo {
23577        color: red;
23578      }
23579
23580      #EgL3uq_id {
23581        animation: 2s EgL3uq_test;
23582      }
23583
23584      @keyframes EgL3uq_test {
23585        from {
23586          color: red;
23587        }
23588
23589        to {
23590          color: #ff0;
23591        }
23592      }
23593
23594      @counter-style EgL3uq_circles {
23595        symbols: Ⓐ Ⓑ Ⓒ;
23596      }
23597
23598      ul {
23599        list-style: EgL3uq_circles;
23600      }
23601
23602      ol {
23603        list-style-type: none;
23604      }
23605
23606      li {
23607        list-style-type: disc;
23608      }
23609
23610      @keyframes EgL3uq_fade {
23611        from {
23612          opacity: 0;
23613        }
23614
23615        to {
23616          opacity: 1;
23617        }
23618      }
23619    "#},
23620      map! {
23621        "foo" => "EgL3uq_foo",
23622        "id" => "EgL3uq_id",
23623        "test" => "EgL3uq_test" referenced: true,
23624        "circles" => "EgL3uq_circles" referenced: true,
23625        "fade" => "EgL3uq_fade"
23626      },
23627      HashMap::new(),
23628      Default::default(),
23629    );
23630
23631    css_modules_test(
23632      r#"
23633      .foo {
23634        color: red;
23635      }
23636
23637      #id {
23638        animation: 2s test;
23639      }
23640
23641      @keyframes test {
23642        from { color: red }
23643        to { color: yellow }
23644      }
23645    "#,
23646      indoc! {r#"
23647      .EgL3uq_foo {
23648        color: red;
23649      }
23650
23651      #EgL3uq_id {
23652        animation: 2s test;
23653      }
23654
23655      @keyframes test {
23656        from {
23657          color: red;
23658        }
23659
23660        to {
23661          color: #ff0;
23662        }
23663      }
23664    "#},
23665      map! {
23666        "foo" => "EgL3uq_foo",
23667        "id" => "EgL3uq_id"
23668      },
23669      HashMap::new(),
23670      crate::css_modules::Config {
23671        animation: false,
23672        // custom_idents: false,
23673        ..Default::default()
23674      },
23675    );
23676
23677    css_modules_test(
23678      r#"
23679      @counter-style circles {
23680        symbols: Ⓐ Ⓑ Ⓒ;
23681      }
23682
23683      ul {
23684        list-style: circles;
23685      }
23686
23687      ol {
23688        list-style-type: none;
23689      }
23690
23691      li {
23692        list-style-type: disc;
23693      }
23694    "#,
23695      indoc! {r#"
23696      @counter-style circles {
23697        symbols: Ⓐ Ⓑ Ⓒ;
23698      }
23699
23700      ul {
23701        list-style: circles;
23702      }
23703
23704      ol {
23705        list-style-type: none;
23706      }
23707
23708      li {
23709        list-style-type: disc;
23710      }
23711    "#},
23712      map! {
23713        "circles" => "EgL3uq_circles" referenced: true
23714      },
23715      HashMap::new(),
23716      crate::css_modules::Config {
23717        custom_idents: false,
23718        ..Default::default()
23719      },
23720    );
23721
23722    #[cfg(feature = "grid")]
23723    css_modules_test(
23724      r#"
23725      body {
23726        grid: [header-top] "a a a" [header-bottom]
23727              [main-top] "b b b" 1fr [main-bottom]
23728              / auto 1fr auto;
23729      }
23730
23731      header {
23732        grid-area: a;
23733      }
23734
23735      main {
23736        grid-row: main-top / main-bottom;
23737      }
23738    "#,
23739      indoc! {r#"
23740      body {
23741        grid: [EgL3uq_header-top] "EgL3uq_a EgL3uq_a EgL3uq_a" [EgL3uq_header-bottom]
23742              [EgL3uq_main-top] "EgL3uq_b EgL3uq_b EgL3uq_b" 1fr [EgL3uq_main-bottom]
23743              / auto 1fr auto;
23744      }
23745
23746      header {
23747        grid-area: EgL3uq_a;
23748      }
23749
23750      main {
23751        grid-row: EgL3uq_main-top / EgL3uq_main-bottom;
23752      }
23753    "#},
23754      map! {
23755        "header-top" => "EgL3uq_header-top",
23756        "header-bottom" => "EgL3uq_header-bottom",
23757        "main-top" => "EgL3uq_main-top",
23758        "main-bottom" => "EgL3uq_main-bottom",
23759        "a" => "EgL3uq_a",
23760        "b" => "EgL3uq_b"
23761      },
23762      HashMap::new(),
23763      Default::default(),
23764    );
23765
23766    #[cfg(feature = "grid")]
23767    css_modules_test(
23768      r#"
23769        .grid {
23770          grid-template-areas: "foo";
23771        }
23772
23773        .foo {
23774          grid-area: foo;
23775        }
23776
23777        .bar {
23778          grid-column-start: foo-start;
23779        }
23780      "#,
23781      indoc! {r#"
23782        .EgL3uq_grid {
23783          grid-template-areas: "EgL3uq_foo";
23784        }
23785
23786        .EgL3uq_foo {
23787          grid-area: EgL3uq_foo;
23788        }
23789
23790        .EgL3uq_bar {
23791          grid-column-start: EgL3uq_foo-start;
23792        }
23793      "#},
23794      map! {
23795        "foo" => "EgL3uq_foo",
23796        "foo-start" => "EgL3uq_foo-start",
23797        "grid" => "EgL3uq_grid",
23798        "bar" => "EgL3uq_bar"
23799      },
23800      HashMap::new(),
23801      Default::default(),
23802    );
23803
23804    #[cfg(feature = "grid")]
23805    css_modules_test(
23806      r#"
23807        .grid {
23808          grid-template-areas: "foo";
23809        }
23810
23811        .foo {
23812          grid-area: foo;
23813        }
23814
23815        .bar {
23816          grid-column-start: foo-start;
23817        }
23818      "#,
23819      indoc! {r#"
23820        .EgL3uq_grid {
23821          grid-template-areas: "foo";
23822        }
23823
23824        .EgL3uq_foo {
23825          grid-area: foo;
23826        }
23827
23828        .EgL3uq_bar {
23829          grid-column-start: foo-start;
23830        }
23831      "#},
23832      map! {
23833        "foo" => "EgL3uq_foo",
23834        "grid" => "EgL3uq_grid",
23835        "bar" => "EgL3uq_bar"
23836      },
23837      HashMap::new(),
23838      crate::css_modules::Config {
23839        grid: false,
23840        ..Default::default()
23841      },
23842    );
23843
23844    css_modules_test(
23845      r#"
23846      test {
23847        transition-property: opacity;
23848      }
23849    "#,
23850      indoc! {r#"
23851      test {
23852        transition-property: opacity;
23853      }
23854    "#},
23855      map! {},
23856      HashMap::new(),
23857      Default::default(),
23858    );
23859
23860    css_modules_test(
23861      r#"
23862      :global(.foo) {
23863        color: red;
23864      }
23865
23866      :local(.bar) {
23867        color: yellow;
23868      }
23869
23870      .bar :global(.baz) {
23871        color: purple;
23872      }
23873    "#,
23874      indoc! {r#"
23875      .foo {
23876        color: red;
23877      }
23878
23879      .EgL3uq_bar {
23880        color: #ff0;
23881      }
23882
23883      .EgL3uq_bar .baz {
23884        color: purple;
23885      }
23886    "#},
23887      map! {
23888        "bar" => "EgL3uq_bar"
23889      },
23890      HashMap::new(),
23891      Default::default(),
23892    );
23893
23894    // :global(:local(.hi)) {
23895    //   color: green;
23896    // }
23897
23898    css_modules_test(
23899      r#"
23900      .test {
23901        composes: foo;
23902        background: white;
23903      }
23904
23905      .foo {
23906        color: red;
23907      }
23908    "#,
23909      indoc! {r#"
23910      .EgL3uq_test {
23911        background: #fff;
23912      }
23913
23914      .EgL3uq_foo {
23915        color: red;
23916      }
23917    "#},
23918      map! {
23919        "test" => "EgL3uq_test" "EgL3uq_foo",
23920        "foo" => "EgL3uq_foo"
23921      },
23922      HashMap::new(),
23923      Default::default(),
23924    );
23925
23926    css_modules_test(
23927      r#"
23928      .a, .b {
23929        composes: foo;
23930        background: white;
23931      }
23932
23933      .foo {
23934        color: red;
23935      }
23936    "#,
23937      indoc! {r#"
23938      .EgL3uq_a, .EgL3uq_b {
23939        background: #fff;
23940      }
23941
23942      .EgL3uq_foo {
23943        color: red;
23944      }
23945    "#},
23946      map! {
23947        "a" => "EgL3uq_a" "EgL3uq_foo",
23948        "b" => "EgL3uq_b" "EgL3uq_foo",
23949        "foo" => "EgL3uq_foo"
23950      },
23951      HashMap::new(),
23952      Default::default(),
23953    );
23954
23955    css_modules_test(
23956      r#"
23957      .test {
23958        composes: foo bar;
23959        background: white;
23960      }
23961
23962      .foo {
23963        color: red;
23964      }
23965
23966      .bar {
23967        color: yellow;
23968      }
23969    "#,
23970      indoc! {r#"
23971      .EgL3uq_test {
23972        background: #fff;
23973      }
23974
23975      .EgL3uq_foo {
23976        color: red;
23977      }
23978
23979      .EgL3uq_bar {
23980        color: #ff0;
23981      }
23982    "#},
23983      map! {
23984        "test" => "EgL3uq_test" "EgL3uq_foo" "EgL3uq_bar",
23985        "foo" => "EgL3uq_foo",
23986        "bar" => "EgL3uq_bar"
23987      },
23988      HashMap::new(),
23989      Default::default(),
23990    );
23991
23992    css_modules_test(
23993      r#"
23994      .test {
23995        composes: foo from global;
23996        background: white;
23997      }
23998    "#,
23999      indoc! {r#"
24000      .EgL3uq_test {
24001        background: #fff;
24002      }
24003    "#},
24004      map! {
24005        "test" => "EgL3uq_test" "foo" global: true
24006      },
24007      HashMap::new(),
24008      Default::default(),
24009    );
24010
24011    css_modules_test(
24012      r#"
24013      .test {
24014        composes: foo bar from global;
24015        background: white;
24016      }
24017    "#,
24018      indoc! {r#"
24019      .EgL3uq_test {
24020        background: #fff;
24021      }
24022    "#},
24023      map! {
24024        "test" => "EgL3uq_test" "foo" global: true "bar" global: true
24025      },
24026      HashMap::new(),
24027      Default::default(),
24028    );
24029
24030    css_modules_test(
24031      r#"
24032      .test {
24033        composes: foo from "foo.css";
24034        background: white;
24035      }
24036    "#,
24037      indoc! {r#"
24038      .EgL3uq_test {
24039        background: #fff;
24040      }
24041    "#},
24042      map! {
24043        "test" => "EgL3uq_test" "foo" from "foo.css"
24044      },
24045      HashMap::new(),
24046      Default::default(),
24047    );
24048
24049    css_modules_test(
24050      r#"
24051      .test {
24052        composes: foo bar from "foo.css";
24053        background: white;
24054      }
24055    "#,
24056      indoc! {r#"
24057      .EgL3uq_test {
24058        background: #fff;
24059      }
24060    "#},
24061      map! {
24062        "test" => "EgL3uq_test" "foo" from "foo.css" "bar" from "foo.css"
24063      },
24064      HashMap::new(),
24065      Default::default(),
24066    );
24067
24068    css_modules_test(
24069      r#"
24070      .test {
24071        composes: foo;
24072        composes: foo from "foo.css";
24073        composes: bar from "bar.css";
24074        background: white;
24075      }
24076
24077      .foo {
24078        color: red;
24079      }
24080    "#,
24081      indoc! {r#"
24082      .EgL3uq_test {
24083        background: #fff;
24084      }
24085
24086      .EgL3uq_foo {
24087        color: red;
24088      }
24089    "#},
24090      map! {
24091        "test" => "EgL3uq_test" "EgL3uq_foo" "foo" from "foo.css" "bar" from "bar.css",
24092        "foo" => "EgL3uq_foo"
24093      },
24094      HashMap::new(),
24095      Default::default(),
24096    );
24097
24098    css_modules_test(
24099      r#"
24100      .foo {
24101        color: red;
24102      }
24103    "#,
24104      indoc! {r#"
24105      .test-EgL3uq-foo {
24106        color: red;
24107      }
24108    "#},
24109      map! {
24110        "foo" => "test-EgL3uq-foo"
24111      },
24112      HashMap::new(),
24113      crate::css_modules::Config {
24114        pattern: crate::css_modules::Pattern::parse("test-[hash]-[local]").unwrap(),
24115        ..Default::default()
24116      },
24117    );
24118
24119    let stylesheet = StyleSheet::parse(
24120      r#"
24121        .grid {
24122          grid-template-areas: "foo";
24123        }
24124
24125        .foo {
24126          grid-area: foo;
24127        }
24128
24129        .bar {
24130          grid-column-start: foo-start;
24131        }
24132      "#,
24133      ParserOptions {
24134        css_modules: Some(crate::css_modules::Config {
24135          pattern: crate::css_modules::Pattern::parse("test-[local]-[hash]").unwrap(),
24136          ..Default::default()
24137        }),
24138        ..ParserOptions::default()
24139      },
24140    )
24141    .unwrap();
24142    if let Err(err) = stylesheet.to_css(PrinterOptions::default()) {
24143      assert_eq!(err.kind, PrinterErrorKind::InvalidCssModulesPatternInGrid);
24144    } else {
24145      unreachable!()
24146    }
24147
24148    css_modules_test(
24149      r#"
24150      @property --foo {
24151        syntax: '<color>';
24152        inherits: false;
24153        initial-value: yellow;
24154      }
24155
24156      .foo {
24157        --foo: red;
24158        color: var(--foo);
24159      }
24160    "#,
24161      indoc! {r#"
24162      @property --foo {
24163        syntax: "<color>";
24164        inherits: false;
24165        initial-value: #ff0;
24166      }
24167
24168      .EgL3uq_foo {
24169        --foo: red;
24170        color: var(--foo);
24171      }
24172    "#},
24173      map! {
24174        "foo" => "EgL3uq_foo"
24175      },
24176      HashMap::new(),
24177      Default::default(),
24178    );
24179
24180    css_modules_test(
24181      r#"
24182      @property --foo {
24183        syntax: '<color>';
24184        inherits: false;
24185        initial-value: yellow;
24186      }
24187
24188      @font-palette-values --Cooler {
24189        font-family: Bixa;
24190        base-palette: 1;
24191        override-colors: 1 #7EB7E4;
24192      }
24193
24194      .foo {
24195        --foo: red;
24196        --bar: green;
24197        color: var(--foo);
24198        font-palette: --Cooler;
24199      }
24200
24201      .bar {
24202        color: var(--color from "./b.css");
24203      }
24204    "#,
24205      indoc! {r#"
24206      @property --EgL3uq_foo {
24207        syntax: "<color>";
24208        inherits: false;
24209        initial-value: #ff0;
24210      }
24211
24212      @font-palette-values --EgL3uq_Cooler {
24213        font-family: Bixa;
24214        base-palette: 1;
24215        override-colors: 1 #7eb7e4;
24216      }
24217
24218      .EgL3uq_foo {
24219        --EgL3uq_foo: red;
24220        --EgL3uq_bar: green;
24221        color: var(--EgL3uq_foo);
24222        font-palette: --EgL3uq_Cooler;
24223      }
24224
24225      .EgL3uq_bar {
24226        color: var(--ma1CsG);
24227      }
24228    "#},
24229      map! {
24230        "foo" => "EgL3uq_foo",
24231        "--foo" => "--EgL3uq_foo" referenced: true,
24232        "--bar" => "--EgL3uq_bar",
24233        "bar" => "EgL3uq_bar",
24234        "--Cooler" => "--EgL3uq_Cooler" referenced: true
24235      },
24236      HashMap::from([(
24237        "--ma1CsG".into(),
24238        CssModuleReference::Dependency {
24239          name: "--color".into(),
24240          specifier: "./b.css".into(),
24241        },
24242      )]),
24243      crate::css_modules::Config {
24244        dashed_idents: true,
24245        ..Default::default()
24246      },
24247    );
24248
24249    css_modules_test(
24250      r#"
24251      .test {
24252        animation: rotate var(--duration) linear infinite;
24253      }
24254    "#,
24255      indoc! {r#"
24256      .EgL3uq_test {
24257        animation: EgL3uq_rotate var(--duration) linear infinite;
24258      }
24259    "#},
24260      map! {
24261        "test" => "EgL3uq_test",
24262        "rotate" => "EgL3uq_rotate" referenced: true
24263      },
24264      HashMap::new(),
24265      Default::default(),
24266    );
24267    css_modules_test(
24268      r#"
24269      .test {
24270        animation: none var(--duration);
24271      }
24272    "#,
24273      indoc! {r#"
24274      .EgL3uq_test {
24275        animation: none var(--duration);
24276      }
24277    "#},
24278      map! {
24279        "test" => "EgL3uq_test"
24280      },
24281      HashMap::new(),
24282      Default::default(),
24283    );
24284    css_modules_test(
24285      r#"
24286      .test {
24287        animation: var(--animation);
24288      }
24289    "#,
24290      indoc! {r#"
24291      .EgL3uq_test {
24292        animation: var(--animation);
24293      }
24294    "#},
24295      map! {
24296        "test" => "EgL3uq_test"
24297      },
24298      HashMap::new(),
24299      Default::default(),
24300    );
24301    css_modules_test(
24302      r#"
24303      .test {
24304        animation: rotate var(--duration);
24305      }
24306    "#,
24307      indoc! {r#"
24308      .EgL3uq_test {
24309        animation: rotate var(--duration);
24310      }
24311    "#},
24312      map! {
24313        "test" => "EgL3uq_test"
24314      },
24315      HashMap::new(),
24316      crate::css_modules::Config {
24317        animation: false,
24318        ..Default::default()
24319      },
24320    );
24321    css_modules_test(
24322      r#"
24323      .test {
24324        animation: "rotate" var(--duration);
24325      }
24326    "#,
24327      indoc! {r#"
24328      .EgL3uq_test {
24329        animation: EgL3uq_rotate var(--duration);
24330      }
24331    "#},
24332      map! {
24333        "test" => "EgL3uq_test",
24334        "rotate" => "EgL3uq_rotate" referenced: true
24335      },
24336      HashMap::new(),
24337      crate::css_modules::Config { ..Default::default() },
24338    );
24339
24340    css_modules_test(
24341      r#"
24342      .test {
24343        composes: foo bar from "foo.css";
24344        background: white;
24345      }
24346    "#,
24347      indoc! {r#"
24348      ._5h2kwG-test {
24349        background: #fff;
24350      }
24351    "#},
24352      map! {
24353        "test" => "_5h2kwG-test" "foo" from "foo.css" "bar" from "foo.css"
24354      },
24355      HashMap::new(),
24356      crate::css_modules::Config {
24357        pattern: crate::css_modules::Pattern::parse("[content-hash]-[local]").unwrap(),
24358        ..Default::default()
24359      },
24360    );
24361
24362    // Stable hashes between project roots.
24363    fn test_project_root(project_root: &str, filename: &str, hash: &str) {
24364      let stylesheet = StyleSheet::parse(
24365        r#"
24366        .foo {
24367          background: red;
24368        }
24369        "#,
24370        ParserOptions {
24371          filename: filename.into(),
24372          css_modules: Some(Default::default()),
24373          ..ParserOptions::default()
24374        },
24375      )
24376      .unwrap();
24377      let res = stylesheet
24378        .to_css(PrinterOptions {
24379          project_root: Some(project_root),
24380          ..PrinterOptions::default()
24381        })
24382        .unwrap();
24383      assert_eq!(
24384        res.code,
24385        format!(
24386          indoc! {r#"
24387      .{}_foo {{
24388        background: red;
24389      }}
24390      "#},
24391          hash
24392        )
24393      );
24394    }
24395
24396    test_project_root("/foo/bar", "/foo/bar/test.css", "EgL3uq");
24397    test_project_root("/foo", "/foo/test.css", "EgL3uq");
24398    test_project_root("/foo/bar", "/foo/bar/baz/test.css", "xLEkNW");
24399    test_project_root("/foo", "/foo/baz/test.css", "xLEkNW");
24400  }
24401
24402  #[test]
24403  fn test_pseudo_replacement() {
24404    let source = r#"
24405      .foo:hover {
24406        color: red;
24407      }
24408
24409      .foo:active {
24410        color: yellow;
24411      }
24412
24413      .foo:focus-visible {
24414        color: purple;
24415      }
24416    "#;
24417
24418    let expected = indoc! { r#"
24419      .foo.is-hovered {
24420        color: red;
24421      }
24422
24423      .foo.is-active {
24424        color: #ff0;
24425      }
24426
24427      .foo.focus-visible {
24428        color: purple;
24429      }
24430    "#};
24431
24432    let stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
24433    let res = stylesheet
24434      .to_css(PrinterOptions {
24435        pseudo_classes: Some(PseudoClasses {
24436          hover: Some("is-hovered"),
24437          active: Some("is-active"),
24438          focus_visible: Some("focus-visible"),
24439          ..PseudoClasses::default()
24440        }),
24441        ..PrinterOptions::default()
24442      })
24443      .unwrap();
24444    assert_eq!(res.code, expected);
24445
24446    let source = r#"
24447      .foo:hover {
24448        color: red;
24449      }
24450    "#;
24451
24452    let expected = indoc! { r#"
24453      .EgL3uq_foo.EgL3uq_is-hovered {
24454        color: red;
24455      }
24456    "#};
24457
24458    let stylesheet = StyleSheet::parse(
24459      &source,
24460      ParserOptions {
24461        filename: "test.css".into(),
24462        css_modules: Some(Default::default()),
24463        ..ParserOptions::default()
24464      },
24465    )
24466    .unwrap();
24467    let res = stylesheet
24468      .to_css(PrinterOptions {
24469        pseudo_classes: Some(PseudoClasses {
24470          hover: Some("is-hovered"),
24471          ..PseudoClasses::default()
24472        }),
24473        ..PrinterOptions::default()
24474      })
24475      .unwrap();
24476    assert_eq!(res.code, expected);
24477  }
24478
24479  #[test]
24480  fn test_unused_symbols() {
24481    let source = r#"
24482      .foo {
24483        color: red;
24484      }
24485
24486      .bar {
24487        color: green;
24488      }
24489
24490      .bar:hover {
24491        color: purple;
24492      }
24493
24494      .bar .baz {
24495        background: red;
24496      }
24497
24498      .baz:is(.bar) {
24499        background: green;
24500      }
24501
24502      #id {
24503        animation: 2s test;
24504      }
24505
24506      #other_id {
24507        color: red;
24508      }
24509
24510      @keyframes test {
24511        from { color: red }
24512        to { color: yellow }
24513      }
24514
24515      @counter-style circles {
24516        symbols: Ⓐ Ⓑ Ⓒ;
24517      }
24518
24519      @keyframes fade {
24520        from { opacity: 0 }
24521        to { opacity: 1 }
24522      }
24523    "#;
24524
24525    let expected = indoc! {r#"
24526      .foo {
24527        color: red;
24528      }
24529
24530      #id {
24531        animation: 2s test;
24532      }
24533
24534      @keyframes test {
24535        from {
24536          color: red;
24537        }
24538
24539        to {
24540          color: #ff0;
24541        }
24542      }
24543    "#};
24544
24545    let mut stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
24546    stylesheet
24547      .minify(MinifyOptions {
24548        unused_symbols: vec!["bar", "other_id", "fade", "circles"]
24549          .iter()
24550          .map(|s| String::from(*s))
24551          .collect(),
24552        ..MinifyOptions::default()
24553      })
24554      .unwrap();
24555    let res = stylesheet.to_css(PrinterOptions::default()).unwrap();
24556    assert_eq!(res.code, expected);
24557
24558    let source = r#"
24559      .foo {
24560        color: red;
24561
24562        &.bar {
24563          color: green;
24564        }
24565      }
24566    "#;
24567
24568    let expected = indoc! {r#"
24569      .foo {
24570        color: red;
24571      }
24572    "#};
24573
24574    let mut stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
24575    stylesheet
24576      .minify(MinifyOptions {
24577        unused_symbols: vec!["bar"].iter().map(|s| String::from(*s)).collect(),
24578        ..MinifyOptions::default()
24579      })
24580      .unwrap();
24581    let res = stylesheet.to_css(PrinterOptions::default()).unwrap();
24582    assert_eq!(res.code, expected);
24583
24584    let source = r#"
24585      .foo {
24586        color: red;
24587
24588        &.bar {
24589          color: purple;
24590        }
24591
24592        @nest &.bar {
24593          color: orange;
24594        }
24595
24596        @nest :not(&) {
24597          color: green;
24598        }
24599
24600        @media (orientation: portrait) {
24601          color: brown;
24602        }
24603      }
24604
24605      .x {
24606        color: purple;
24607
24608        &.y {
24609          color: green;
24610        }
24611      }
24612    "#;
24613
24614    let expected = indoc! {r#"
24615      :not(.foo) {
24616        color: green;
24617      }
24618    "#};
24619
24620    let mut stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
24621    stylesheet
24622      .minify(MinifyOptions {
24623        unused_symbols: vec!["foo", "x"].iter().map(|s| String::from(*s)).collect(),
24624        ..MinifyOptions::default()
24625      })
24626      .unwrap();
24627    let res = stylesheet
24628      .to_css(PrinterOptions {
24629        targets: Browsers {
24630          chrome: Some(95 << 16),
24631          ..Browsers::default()
24632        }
24633        .into(),
24634        ..PrinterOptions::default()
24635      })
24636      .unwrap();
24637    assert_eq!(res.code, expected);
24638
24639    let source = r#"
24640      @property --EgL3uq_foo {
24641        syntax: "<color>";
24642        inherits: false;
24643        initial-value: #ff0;
24644      }
24645
24646      @font-palette-values --EgL3uq_Cooler {
24647        font-family: Bixa;
24648        base-palette: 1;
24649        override-colors: 1 #7EB7E4;
24650      }
24651
24652      .EgL3uq_foo {
24653        --EgL3uq_foo: red;
24654      }
24655
24656      .EgL3uq_bar {
24657        color: green;
24658      }
24659    "#;
24660
24661    let expected = indoc! {r#"
24662      .EgL3uq_bar {
24663        color: green;
24664      }
24665    "#};
24666
24667    let mut stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
24668    stylesheet
24669      .minify(MinifyOptions {
24670        unused_symbols: vec!["--EgL3uq_foo", "--EgL3uq_Cooler"]
24671          .iter()
24672          .map(|s| String::from(*s))
24673          .collect(),
24674        ..MinifyOptions::default()
24675      })
24676      .unwrap();
24677    let res = stylesheet.to_css(PrinterOptions::default()).unwrap();
24678    assert_eq!(res.code, expected);
24679  }
24680
24681  #[test]
24682  fn test_svg() {
24683    minify_test(".foo { fill: yellow; }", ".foo{fill:#ff0}");
24684    minify_test(".foo { fill: url(#foo); }", ".foo{fill:url(#foo)}");
24685    minify_test(".foo { fill: url(#foo) none; }", ".foo{fill:url(#foo) none}");
24686    minify_test(".foo { fill: url(#foo) yellow; }", ".foo{fill:url(#foo) #ff0}");
24687    minify_test(".foo { fill: none; }", ".foo{fill:none}");
24688    minify_test(".foo { fill: context-fill; }", ".foo{fill:context-fill}");
24689    minify_test(".foo { fill: context-stroke; }", ".foo{fill:context-stroke}");
24690
24691    minify_test(".foo { stroke: yellow; }", ".foo{stroke:#ff0}");
24692    minify_test(".foo { stroke: url(#foo); }", ".foo{stroke:url(#foo)}");
24693    minify_test(".foo { stroke: url(#foo) none; }", ".foo{stroke:url(#foo) none}");
24694    minify_test(".foo { stroke: url(#foo) yellow; }", ".foo{stroke:url(#foo) #ff0}");
24695    minify_test(".foo { stroke: none; }", ".foo{stroke:none}");
24696    minify_test(".foo { stroke: context-fill; }", ".foo{stroke:context-fill}");
24697    minify_test(".foo { stroke: context-stroke; }", ".foo{stroke:context-stroke}");
24698
24699    minify_test(".foo { marker-start: url(#foo); }", ".foo{marker-start:url(#foo)}");
24700
24701    minify_test(".foo { stroke-dasharray: 4 1 2; }", ".foo{stroke-dasharray:4 1 2}");
24702    minify_test(".foo { stroke-dasharray: 4,1,2; }", ".foo{stroke-dasharray:4 1 2}");
24703    minify_test(".foo { stroke-dasharray: 4, 1, 2; }", ".foo{stroke-dasharray:4 1 2}");
24704    minify_test(
24705      ".foo { stroke-dasharray: 4px, 1px, 2px; }",
24706      ".foo{stroke-dasharray:4 1 2}",
24707    );
24708
24709    minify_test(".foo { mask: url('foo.svg'); }", ".foo{mask:url(foo.svg)}");
24710    minify_test(
24711      ".foo { mask: url(masks.svg#star) luminance }",
24712      ".foo{mask:url(masks.svg#star) luminance}",
24713    );
24714    minify_test(
24715      ".foo { mask: url(masks.svg#star) 40px 20px }",
24716      ".foo{mask:url(masks.svg#star) 40px 20px}",
24717    );
24718    minify_test(
24719      ".foo { mask: url(masks.svg#star) 0 0 / 50px 50px }",
24720      ".foo{mask:url(masks.svg#star) 0 0/50px 50px}",
24721    );
24722    minify_test(
24723      ".foo { mask: url(masks.svg#star) repeat-x }",
24724      ".foo{mask:url(masks.svg#star) repeat-x}",
24725    );
24726    minify_test(
24727      ".foo { mask: url(masks.svg#star) stroke-box }",
24728      ".foo{mask:url(masks.svg#star) stroke-box}",
24729    );
24730    minify_test(
24731      ".foo { mask: url(masks.svg#star) stroke-box stroke-box }",
24732      ".foo{mask:url(masks.svg#star) stroke-box}",
24733    );
24734    minify_test(
24735      ".foo { mask: url(masks.svg#star) border-box }",
24736      ".foo{mask:url(masks.svg#star)}",
24737    );
24738    minify_test(
24739      ".foo { mask: url(masks.svg#star) left / 16px repeat-y, url(masks.svg#circle) right / 16px repeat-y }",
24740      ".foo{mask:url(masks.svg#star) 0/16px repeat-y,url(masks.svg#circle) 100%/16px repeat-y}",
24741    );
24742
24743    minify_test(
24744      ".foo { mask-border: url('border-mask.png') 25; }",
24745      ".foo{mask-border:url(border-mask.png) 25}",
24746    );
24747    minify_test(
24748      ".foo { mask-border: url('border-mask.png') 25 / 35px / 12px space alpha; }",
24749      ".foo{mask-border:url(border-mask.png) 25/35px/12px space}",
24750    );
24751    minify_test(
24752      ".foo { mask-border: url('border-mask.png') 25 / 35px / 12px space luminance; }",
24753      ".foo{mask-border:url(border-mask.png) 25/35px/12px space luminance}",
24754    );
24755    minify_test(
24756      ".foo { mask-border: url('border-mask.png') luminance 25 / 35px / 12px space; }",
24757      ".foo{mask-border:url(border-mask.png) 25/35px/12px space luminance}",
24758    );
24759
24760    minify_test(
24761      ".foo { clip-path: url('clip.svg#star'); }",
24762      ".foo{clip-path:url(clip.svg#star)}",
24763    );
24764    minify_test(".foo { clip-path: margin-box; }", ".foo{clip-path:margin-box}");
24765    minify_test(
24766      ".foo { clip-path: inset(100px 50px); }",
24767      ".foo{clip-path:inset(100px 50px)}",
24768    );
24769    minify_test(
24770      ".foo { clip-path: inset(100px 50px round 5px); }",
24771      ".foo{clip-path:inset(100px 50px round 5px)}",
24772    );
24773    minify_test(
24774      ".foo { clip-path: inset(100px 50px round 5px 5px 5px 5px); }",
24775      ".foo{clip-path:inset(100px 50px round 5px)}",
24776    );
24777    minify_test(".foo { clip-path: circle(50px); }", ".foo{clip-path:circle(50px)}");
24778    minify_test(
24779      ".foo { clip-path: circle(50px at center center); }",
24780      ".foo{clip-path:circle(50px)}",
24781    );
24782    minify_test(
24783      ".foo { clip-path: circle(50px at 50% 50%); }",
24784      ".foo{clip-path:circle(50px)}",
24785    );
24786    minify_test(
24787      ".foo { clip-path: circle(50px at 0 100px); }",
24788      ".foo{clip-path:circle(50px at 0 100px)}",
24789    );
24790    minify_test(
24791      ".foo { clip-path: circle(closest-side at 0 100px); }",
24792      ".foo{clip-path:circle(at 0 100px)}",
24793    );
24794    minify_test(
24795      ".foo { clip-path: circle(farthest-side at 0 100px); }",
24796      ".foo{clip-path:circle(farthest-side at 0 100px)}",
24797    );
24798    minify_test(
24799      ".foo { clip-path: circle(closest-side at 50% 50%); }",
24800      ".foo{clip-path:circle()}",
24801    );
24802    minify_test(
24803      ".foo { clip-path: ellipse(50px 60px at 0 10% 20%); }",
24804      ".foo{clip-path:ellipse(50px 60px at 0 10% 20%)}",
24805    );
24806    minify_test(
24807      ".foo { clip-path: ellipse(50px 60px at center center); }",
24808      ".foo{clip-path:ellipse(50px 60px)}",
24809    );
24810    minify_test(
24811      ".foo { clip-path: ellipse(closest-side closest-side at 50% 50%); }",
24812      ".foo{clip-path:ellipse()}",
24813    );
24814    minify_test(
24815      ".foo { clip-path: ellipse(closest-side closest-side at 10% 20%); }",
24816      ".foo{clip-path:ellipse(at 10% 20%)}",
24817    );
24818    minify_test(
24819      ".foo { clip-path: ellipse(farthest-side closest-side at 10% 20%); }",
24820      ".foo{clip-path:ellipse(farthest-side closest-side at 10% 20%)}",
24821    );
24822    minify_test(
24823      ".foo { clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); }",
24824      ".foo{clip-path:polygon(50% 0%,100% 50%,50% 100%,0% 50%)}",
24825    );
24826    minify_test(
24827      ".foo { clip-path: polygon(nonzero, 50% 0%, 100% 50%, 50% 100%, 0% 50%); }",
24828      ".foo{clip-path:polygon(50% 0%,100% 50%,50% 100%,0% 50%)}",
24829    );
24830    minify_test(
24831      ".foo { clip-path: polygon(evenodd, 50% 0%, 100% 50%, 50% 100%, 0% 50%); }",
24832      ".foo{clip-path:polygon(evenodd,50% 0%,100% 50%,50% 100%,0% 50%)}",
24833    );
24834    minify_test(
24835      ".foo { clip-path: padding-box circle(50px at 0 100px); }",
24836      ".foo{clip-path:circle(50px at 0 100px) padding-box}",
24837    );
24838    minify_test(
24839      ".foo { clip-path: circle(50px at 0 100px) padding-box; }",
24840      ".foo{clip-path:circle(50px at 0 100px) padding-box}",
24841    );
24842    minify_test(
24843      ".foo { clip-path: circle(50px at 0 100px) border-box; }",
24844      ".foo{clip-path:circle(50px at 0 100px)}",
24845    );
24846
24847    prefix_test(
24848      ".foo { clip-path: circle(50px); }",
24849      indoc! { r#"
24850        .foo {
24851          -webkit-clip-path: circle(50px);
24852          clip-path: circle(50px);
24853        }
24854      "#},
24855      Browsers {
24856        chrome: Some(30 << 16),
24857        ..Browsers::default()
24858      },
24859    );
24860
24861    prefix_test(
24862      ".foo { clip-path: circle(50px); }",
24863      indoc! { r#"
24864        .foo {
24865          clip-path: circle(50px);
24866        }
24867      "#},
24868      Browsers {
24869        chrome: Some(80 << 16),
24870        ..Browsers::default()
24871      },
24872    );
24873
24874    prefix_test(
24875      ".foo { clip-path: circle(50px); }",
24876      indoc! { r#"
24877        .foo {
24878          -webkit-clip-path: circle(50px);
24879          clip-path: circle(50px);
24880        }
24881      "#},
24882      Browsers {
24883        safari: Some(8 << 16),
24884        ..Browsers::default()
24885      },
24886    );
24887
24888    prefix_test(
24889      ".foo { clip-path: circle(50px); }",
24890      indoc! { r#"
24891        .foo {
24892          clip-path: circle(50px);
24893        }
24894      "#},
24895      Browsers {
24896        safari: Some(14 << 16),
24897        ..Browsers::default()
24898      },
24899    );
24900
24901    prefix_test(
24902      ".foo { fill: lch(50.998% 135.363 338) }",
24903      indoc! { r#"
24904        .foo {
24905          fill: #ee00be;
24906          fill: color(display-p3 .972962 -.362078 .804206);
24907          fill: lch(50.998% 135.363 338);
24908        }
24909      "#},
24910      Browsers {
24911        chrome: Some(90 << 16),
24912        safari: Some(14 << 16),
24913        ..Browsers::default()
24914      },
24915    );
24916
24917    prefix_test(
24918      ".foo { stroke: lch(50.998% 135.363 338) }",
24919      indoc! { r#"
24920        .foo {
24921          stroke: #ee00be;
24922          stroke: color(display-p3 .972962 -.362078 .804206);
24923          stroke: lch(50.998% 135.363 338);
24924        }
24925      "#},
24926      Browsers {
24927        chrome: Some(90 << 16),
24928        safari: Some(14 << 16),
24929        ..Browsers::default()
24930      },
24931    );
24932
24933    prefix_test(
24934      ".foo { fill: url(#foo) lch(50.998% 135.363 338) }",
24935      indoc! { r##"
24936        .foo {
24937          fill: url("#foo") #ee00be;
24938          fill: url("#foo") color(display-p3 .972962 -.362078 .804206);
24939          fill: url("#foo") lch(50.998% 135.363 338);
24940        }
24941      "##},
24942      Browsers {
24943        chrome: Some(90 << 16),
24944        safari: Some(14 << 16),
24945        ..Browsers::default()
24946      },
24947    );
24948
24949    prefix_test(
24950      ".foo { fill: var(--url) lch(50.998% 135.363 338) }",
24951      indoc! { r#"
24952        .foo {
24953          fill: var(--url) #ee00be;
24954        }
24955
24956        @supports (color: lab(0% 0 0)) {
24957          .foo {
24958            fill: var(--url) lab(50.998% 125.506 -50.7078);
24959          }
24960        }
24961      "#},
24962      Browsers {
24963        chrome: Some(90 << 16),
24964        ..Browsers::default()
24965      },
24966    );
24967
24968    prefix_test(
24969      ".foo { mask-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
24970      indoc! { r#"
24971        .foo {
24972          -webkit-mask-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0f0e), to(#7773ff));
24973          -webkit-mask-image: -webkit-linear-gradient(#ff0f0e, #7773ff);
24974          -webkit-mask-image: linear-gradient(#ff0f0e, #7773ff);
24975          mask-image: linear-gradient(#ff0f0e, #7773ff);
24976          -webkit-mask-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
24977          mask-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
24978        }
24979      "#},
24980      Browsers {
24981        chrome: Some(8 << 16),
24982        ..Browsers::default()
24983      },
24984    );
24985
24986    prefix_test(
24987      ".foo { mask-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
24988      indoc! { r#"
24989        .foo {
24990          -webkit-mask-image: linear-gradient(#ff0f0e, #7773ff);
24991          mask-image: linear-gradient(#ff0f0e, #7773ff);
24992          -webkit-mask-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
24993          mask-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
24994        }
24995      "#},
24996      Browsers {
24997        chrome: Some(95 << 16),
24998        ..Browsers::default()
24999      },
25000    );
25001
25002    prefix_test(
25003      ".foo { mask-image: linear-gradient(red, green) }",
25004      indoc! { r#"
25005        .foo {
25006          -webkit-mask-image: linear-gradient(red, green);
25007          mask-image: linear-gradient(red, green);
25008        }
25009      "#},
25010      Browsers {
25011        chrome: Some(95 << 16),
25012        ..Browsers::default()
25013      },
25014    );
25015
25016    prefix_test(
25017      ".foo { -webkit-mask-image: url(x.svg); mask-image: url(x.svg); }",
25018      indoc! { r#"
25019        .foo {
25020          -webkit-mask-image: url("x.svg");
25021          mask-image: url("x.svg");
25022        }
25023      "#},
25024      Browsers {
25025        chrome: Some(95 << 16),
25026        ..Browsers::default()
25027      },
25028    );
25029
25030    prefix_test(
25031      ".foo { mask: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 40px 20px }",
25032      indoc! { r#"
25033        .foo {
25034          -webkit-mask: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0f0e), to(#7773ff)) 40px 20px;
25035          -webkit-mask: -webkit-linear-gradient(#ff0f0e, #7773ff) 40px 20px;
25036          -webkit-mask: linear-gradient(#ff0f0e, #7773ff) 40px 20px;
25037          mask: linear-gradient(#ff0f0e, #7773ff) 40px 20px;
25038          -webkit-mask: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 40px 20px;
25039          mask: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 40px 20px;
25040        }
25041      "#},
25042      Browsers {
25043        chrome: Some(8 << 16),
25044        ..Browsers::default()
25045      },
25046    );
25047
25048    prefix_test(
25049      ".foo { mask: -webkit-linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 40px 20px }",
25050      indoc! { r#"
25051        .foo {
25052          -webkit-mask: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0f0e), to(#7773ff)) 40px 20px;
25053          -webkit-mask: -webkit-linear-gradient(#ff0f0e, #7773ff) 40px 20px;
25054        }
25055      "#},
25056      Browsers {
25057        chrome: Some(8 << 16),
25058        ..Browsers::default()
25059      },
25060    );
25061
25062    prefix_test(
25063      ".foo { mask: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 40px var(--foo) }",
25064      indoc! { r#"
25065        .foo {
25066          -webkit-mask: linear-gradient(#ff0f0e, #7773ff) 40px var(--foo);
25067          mask: linear-gradient(#ff0f0e, #7773ff) 40px var(--foo);
25068        }
25069
25070        @supports (color: lab(0% 0 0)) {
25071          .foo {
25072            -webkit-mask: linear-gradient(lab(56.208% 94.4644 98.8928), lab(51% 70.4544 -115.586)) 40px var(--foo);
25073            mask: linear-gradient(lab(56.208% 94.4644 98.8928), lab(51% 70.4544 -115.586)) 40px var(--foo);
25074          }
25075        }
25076      "#},
25077      Browsers {
25078        chrome: Some(90 << 16),
25079        ..Browsers::default()
25080      },
25081    );
25082
25083    prefix_test(
25084      ".foo { mask: url(masks.svg#star) luminance }",
25085      indoc! { r#"
25086        .foo {
25087          -webkit-mask: url("masks.svg#star");
25088          -webkit-mask-source-type: luminance;
25089          mask: url("masks.svg#star") luminance;
25090        }
25091    "#},
25092      Browsers {
25093        chrome: Some(90 << 16),
25094        ..Browsers::default()
25095      },
25096    );
25097
25098    prefix_test(
25099      ".foo { mask-image: url(masks.svg#star) }",
25100      indoc! { r#"
25101        .foo {
25102          -webkit-mask-image: url("masks.svg#star");
25103          mask-image: url("masks.svg#star");
25104        }
25105    "#},
25106      Browsers {
25107        chrome: Some(90 << 16),
25108        ..Browsers::default()
25109      },
25110    );
25111
25112    prefix_test(
25113      r#"
25114        .foo {
25115          mask-image: url(masks.svg#star);
25116          mask-position: 25% 75%;
25117          mask-size: cover;
25118          mask-repeat: no-repeat;
25119          mask-clip: padding-box;
25120          mask-origin: content-box;
25121          mask-composite: subtract;
25122          mask-mode: luminance;
25123        }
25124      "#,
25125      indoc! { r#"
25126        .foo {
25127          -webkit-mask: url("masks.svg#star") 25% 75% / cover no-repeat content-box padding-box;
25128          -webkit-mask-composite: source-out;
25129          -webkit-mask-source-type: luminance;
25130          mask: url("masks.svg#star") 25% 75% / cover no-repeat content-box padding-box subtract luminance;
25131        }
25132    "#},
25133      Browsers {
25134        chrome: Some(90 << 16),
25135        ..Browsers::default()
25136      },
25137    );
25138
25139    prefix_test(
25140      r#"
25141        .foo {
25142          mask-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
25143          mask-position: 25% 75%;
25144          mask-size: cover;
25145          mask-repeat: no-repeat;
25146          mask-clip: padding-box;
25147          mask-origin: content-box;
25148          mask-composite: subtract;
25149          mask-mode: luminance;
25150        }
25151      "#,
25152      indoc! { r#"
25153        .foo {
25154          -webkit-mask: linear-gradient(#ff0f0e, #7773ff) 25% 75% / cover no-repeat content-box padding-box;
25155          -webkit-mask-composite: source-out;
25156          -webkit-mask-source-type: luminance;
25157          mask: linear-gradient(#ff0f0e, #7773ff) 25% 75% / cover no-repeat content-box padding-box subtract luminance;
25158          -webkit-mask: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 25% 75% / cover no-repeat content-box padding-box;
25159          -webkit-mask-composite: source-out;
25160          -webkit-mask-source-type: luminance;
25161          mask: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 25% 75% / cover no-repeat content-box padding-box subtract luminance;
25162        }
25163    "#},
25164      Browsers {
25165        chrome: Some(90 << 16),
25166        ..Browsers::default()
25167      },
25168    );
25169
25170    test(
25171      r#"
25172        .foo {
25173          mask: none center / 100% no-repeat;
25174          mask-image: var(--svg);
25175        }
25176      "#,
25177      indoc! { r#"
25178        .foo {
25179          mask: none center / 100% no-repeat;
25180          mask-image: var(--svg);
25181        }
25182      "#},
25183    );
25184
25185    prefix_test(
25186      r#"
25187        .foo {
25188          mask-composite: subtract;
25189        }
25190      "#,
25191      indoc! { r#"
25192        .foo {
25193          -webkit-mask-composite: source-out;
25194          mask-composite: subtract;
25195        }
25196    "#},
25197      Browsers {
25198        chrome: Some(90 << 16),
25199        ..Browsers::default()
25200      },
25201    );
25202
25203    prefix_test(
25204      r#"
25205        .foo {
25206          mask-mode: luminance;
25207        }
25208      "#,
25209      indoc! { r#"
25210        .foo {
25211          -webkit-mask-source-type: luminance;
25212          mask-mode: luminance;
25213        }
25214    "#},
25215      Browsers {
25216        chrome: Some(90 << 16),
25217        ..Browsers::default()
25218      },
25219    );
25220
25221    prefix_test(
25222      r#"
25223        .foo {
25224          mask-border: url('border-mask.png') 25 / 35px / 12px space luminance;
25225        }
25226      "#,
25227      indoc! { r#"
25228        .foo {
25229          -webkit-mask-box-image: url("border-mask.png") 25 / 35px / 12px space;
25230          mask-border: url("border-mask.png") 25 / 35px / 12px space luminance;
25231        }
25232    "#},
25233      Browsers {
25234        chrome: Some(90 << 16),
25235        ..Browsers::default()
25236      },
25237    );
25238
25239    prefix_test(
25240      r#"
25241        .foo {
25242          mask-border: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 25 / 35px / 12px space luminance;
25243        }
25244      "#,
25245      indoc! { r#"
25246        .foo {
25247          -webkit-mask-box-image: linear-gradient(#ff0f0e, #7773ff) 25 / 35px / 12px space;
25248          mask-border: linear-gradient(#ff0f0e, #7773ff) 25 / 35px / 12px space luminance;
25249          -webkit-mask-box-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 25 / 35px / 12px space;
25250          mask-border: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 25 / 35px / 12px space luminance;
25251        }
25252    "#},
25253      Browsers {
25254        chrome: Some(90 << 16),
25255        ..Browsers::default()
25256      },
25257    );
25258
25259    prefix_test(
25260      r#"
25261        .foo {
25262          mask-border-source: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
25263        }
25264      "#,
25265      indoc! { r#"
25266        .foo {
25267          -webkit-mask-box-image-source: linear-gradient(#ff0f0e, #7773ff);
25268          mask-border-source: linear-gradient(#ff0f0e, #7773ff);
25269          -webkit-mask-box-image-source: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
25270          mask-border-source: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
25271        }
25272    "#},
25273      Browsers {
25274        chrome: Some(90 << 16),
25275        ..Browsers::default()
25276      },
25277    );
25278
25279    prefix_test(
25280      r#"
25281        .foo {
25282          mask-border-source: url(foo.png);
25283          mask-border-slice: 10 40 10 40;
25284          mask-border-width: 10px;
25285          mask-border-outset: 0;
25286          mask-border-repeat: round round;
25287          mask-border-mode: luminance;
25288        }
25289      "#,
25290      indoc! { r#"
25291        .foo {
25292          -webkit-mask-box-image: url("foo.png") 10 40 / 10px round;
25293          mask-border: url("foo.png") 10 40 / 10px round luminance;
25294        }
25295    "#},
25296      Browsers {
25297        chrome: Some(90 << 16),
25298        ..Browsers::default()
25299      },
25300    );
25301
25302    prefix_test(
25303      r#"
25304        .foo {
25305          -webkit-mask-box-image-source: url(foo.png);
25306          -webkit-mask-box-image-slice: 10 40 10 40;
25307          -webkit-mask-box-image-width: 10px;
25308          -webkit-mask-box-image-outset: 0;
25309          -webkit-mask-box-image-repeat: round round;
25310        }
25311      "#,
25312      indoc! { r#"
25313        .foo {
25314          -webkit-mask-box-image: url("foo.png") 10 40 / 10px round;
25315        }
25316    "#},
25317      Browsers {
25318        chrome: Some(90 << 16),
25319        ..Browsers::default()
25320      },
25321    );
25322
25323    prefix_test(
25324      r#"
25325        .foo {
25326          mask-border-slice: 10 40 10 40;
25327        }
25328      "#,
25329      indoc! { r#"
25330        .foo {
25331          -webkit-mask-box-image-slice: 10 40;
25332          mask-border-slice: 10 40;
25333        }
25334    "#},
25335      Browsers {
25336        chrome: Some(90 << 16),
25337        ..Browsers::default()
25338      },
25339    );
25340
25341    prefix_test(
25342      r#"
25343        .foo {
25344          mask-border-slice: var(--foo);
25345        }
25346      "#,
25347      indoc! { r#"
25348        .foo {
25349          -webkit-mask-box-image-slice: var(--foo);
25350          mask-border-slice: var(--foo);
25351        }
25352    "#},
25353      Browsers {
25354        chrome: Some(90 << 16),
25355        ..Browsers::default()
25356      },
25357    );
25358
25359    prefix_test(
25360      r#"
25361        .foo {
25362          mask-border: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) var(--foo);
25363        }
25364      "#,
25365      indoc! { r#"
25366        .foo {
25367          -webkit-mask-box-image: linear-gradient(#ff0f0e, #7773ff) var(--foo);
25368          mask-border: linear-gradient(#ff0f0e, #7773ff) var(--foo);
25369        }
25370
25371        @supports (color: lab(0% 0 0)) {
25372          .foo {
25373            -webkit-mask-box-image: linear-gradient(lab(56.208% 94.4644 98.8928), lab(51% 70.4544 -115.586)) var(--foo);
25374            mask-border: linear-gradient(lab(56.208% 94.4644 98.8928), lab(51% 70.4544 -115.586)) var(--foo);
25375          }
25376        }
25377    "#},
25378      Browsers {
25379        chrome: Some(90 << 16),
25380        ..Browsers::default()
25381      },
25382    );
25383
25384    prefix_test(
25385      r#"
25386        .foo {
25387          transition: mask 200ms;
25388        }
25389      "#,
25390      indoc! { r#"
25391        .foo {
25392          transition: -webkit-mask .2s, mask .2s;
25393        }
25394    "#},
25395      Browsers {
25396        chrome: Some(90 << 16),
25397        ..Browsers::default()
25398      },
25399    );
25400
25401    prefix_test(
25402      r#"
25403        .foo {
25404          transition: mask-border 200ms;
25405        }
25406      "#,
25407      indoc! { r#"
25408        .foo {
25409          transition: -webkit-mask-box-image .2s, mask-border .2s;
25410        }
25411    "#},
25412      Browsers {
25413        chrome: Some(90 << 16),
25414        ..Browsers::default()
25415      },
25416    );
25417
25418    prefix_test(
25419      r#"
25420        .foo {
25421          transition-property: mask;
25422        }
25423      "#,
25424      indoc! { r#"
25425        .foo {
25426          transition-property: -webkit-mask, mask;
25427        }
25428    "#},
25429      Browsers {
25430        chrome: Some(90 << 16),
25431        ..Browsers::default()
25432      },
25433    );
25434
25435    prefix_test(
25436      r#"
25437        .foo {
25438          transition-property: mask-border;
25439        }
25440      "#,
25441      indoc! { r#"
25442        .foo {
25443          transition-property: -webkit-mask-box-image, mask-border;
25444        }
25445    "#},
25446      Browsers {
25447        chrome: Some(90 << 16),
25448        ..Browsers::default()
25449      },
25450    );
25451
25452    prefix_test(
25453      r#"
25454        .foo {
25455          transition-property: mask-composite, mask-mode;
25456        }
25457      "#,
25458      indoc! { r#"
25459        .foo {
25460          transition-property: -webkit-mask-composite, mask-composite, -webkit-mask-source-type, mask-mode;
25461        }
25462    "#},
25463      Browsers {
25464        chrome: Some(90 << 16),
25465        ..Browsers::default()
25466      },
25467    );
25468  }
25469
25470  #[test]
25471  fn test_filter() {
25472    minify_test(
25473      ".foo { filter: url('filters.svg#filter-id'); }",
25474      ".foo{filter:url(filters.svg#filter-id)}",
25475    );
25476    minify_test(".foo { filter: blur(5px); }", ".foo{filter:blur(5px)}");
25477    minify_test(".foo { filter: blur(0px); }", ".foo{filter:blur()}");
25478    minify_test(".foo { filter: brightness(10%); }", ".foo{filter:brightness(10%)}");
25479    minify_test(".foo { filter: brightness(100%); }", ".foo{filter:brightness()}");
25480    minify_test(
25481      ".foo { filter: drop-shadow(16px 16px 20px yellow); }",
25482      ".foo{filter:drop-shadow(16px 16px 20px #ff0)}",
25483    );
25484    minify_test(
25485      ".foo { filter: contrast(175%) brightness(3%); }",
25486      ".foo{filter:contrast(175%)brightness(3%)}",
25487    );
25488    minify_test(".foo { filter: hue-rotate(0) }", ".foo{filter:hue-rotate()}");
25489
25490    prefix_test(
25491      ".foo { filter: blur(5px) }",
25492      indoc! { r#"
25493        .foo {
25494          -webkit-filter: blur(5px);
25495          filter: blur(5px);
25496        }
25497      "#},
25498      Browsers {
25499        chrome: Some(20 << 16),
25500        ..Browsers::default()
25501      },
25502    );
25503
25504    prefix_test(
25505      ".foo { filter: blur(5px) }",
25506      indoc! { r#"
25507        .foo {
25508          filter: blur(5px);
25509        }
25510      "#},
25511      Browsers {
25512        chrome: Some(80 << 16),
25513        ..Browsers::default()
25514      },
25515    );
25516
25517    prefix_test(
25518      ".foo { backdrop-filter: blur(5px) }",
25519      indoc! { r#"
25520        .foo {
25521          backdrop-filter: blur(5px);
25522        }
25523      "#},
25524      Browsers {
25525        chrome: Some(80 << 16),
25526        ..Browsers::default()
25527      },
25528    );
25529
25530    prefix_test(
25531      ".foo { backdrop-filter: blur(5px) }",
25532      indoc! { r#"
25533        .foo {
25534          -webkit-backdrop-filter: blur(5px);
25535          backdrop-filter: blur(5px);
25536        }
25537      "#},
25538      Browsers {
25539        safari: Some(15 << 16),
25540        ..Browsers::default()
25541      },
25542    );
25543    prefix_test(
25544      r#"
25545      .foo {
25546        -webkit-backdrop-filter: blur(8px);
25547        backdrop-filter: blur(8px);
25548      }
25549      "#,
25550      indoc! {r#"
25551      .foo {
25552        -webkit-backdrop-filter: blur(8px);
25553        backdrop-filter: blur(8px);
25554      }
25555      "#},
25556      Browsers {
25557        safari: Some(16 << 16),
25558        ..Browsers::default()
25559      },
25560    );
25561
25562    prefix_test(
25563      ".foo { filter: var(--foo) }",
25564      indoc! { r#"
25565        .foo {
25566          -webkit-filter: var(--foo);
25567          filter: var(--foo);
25568        }
25569      "#},
25570      Browsers {
25571        chrome: Some(20 << 16),
25572        ..Browsers::default()
25573      },
25574    );
25575
25576    prefix_test(
25577      ".foo { filter: drop-shadow(16px 16px 20px lab(40% 56.6 39)) }",
25578      indoc! { r#"
25579        .foo {
25580          -webkit-filter: drop-shadow(16px 16px 20px #b32323);
25581          filter: drop-shadow(16px 16px 20px #b32323);
25582          filter: drop-shadow(16px 16px 20px lab(40% 56.6 39));
25583        }
25584      "#},
25585      Browsers {
25586        chrome: Some(20 << 16),
25587        ..Browsers::default()
25588      },
25589    );
25590
25591    prefix_test(
25592      ".foo { filter: contrast(175%) drop-shadow(16px 16px 20px lab(40% 56.6 39)) }",
25593      indoc! { r#"
25594        .foo {
25595          filter: contrast(175%) drop-shadow(16px 16px 20px #b32323);
25596          filter: contrast(175%) drop-shadow(16px 16px 20px lab(40% 56.6 39));
25597        }
25598      "#},
25599      Browsers {
25600        chrome: Some(4 << 16),
25601        ..Browsers::default()
25602      },
25603    );
25604
25605    prefix_test(
25606      ".foo { filter: drop-shadow(16px 16px 20px lab(40% 56.6 39)) drop-shadow(16px 16px 20px yellow) }",
25607      indoc! { r#"
25608        .foo {
25609          filter: drop-shadow(16px 16px 20px #b32323) drop-shadow(16px 16px 20px #ff0);
25610          filter: drop-shadow(16px 16px 20px lab(40% 56.6 39)) drop-shadow(16px 16px 20px #ff0);
25611        }
25612      "#},
25613      Browsers {
25614        chrome: Some(4 << 16),
25615        ..Browsers::default()
25616      },
25617    );
25618
25619    prefix_test(
25620      ".foo { filter: var(--foo) drop-shadow(16px 16px 20px lab(40% 56.6 39)) }",
25621      indoc! { r#"
25622        .foo {
25623          filter: var(--foo) drop-shadow(16px 16px 20px #b32323);
25624        }
25625
25626        @supports (color: lab(0% 0 0)) {
25627          .foo {
25628            filter: var(--foo) drop-shadow(16px 16px 20px lab(40% 56.6 39));
25629          }
25630        }
25631      "#},
25632      Browsers {
25633        chrome: Some(4 << 16),
25634        ..Browsers::default()
25635      },
25636    );
25637  }
25638
25639  #[test]
25640  fn test_viewport() {
25641    minify_test(
25642      r#"
25643    @viewport {
25644      width: 100vw;
25645    }"#,
25646      "@viewport{width:100vw}",
25647    );
25648    minify_test(
25649      r#"
25650    @-ms-viewport {
25651      width: device-width;
25652    }"#,
25653      "@-ms-viewport{width:device-width}",
25654    );
25655  }
25656
25657  #[test]
25658  fn test_at_scope() {
25659    minify_test(
25660      r#"
25661      @scope {
25662        .foo {
25663          display: flex;
25664        }
25665      }
25666      "#,
25667      "@scope{.foo{display:flex}}",
25668    );
25669    minify_test(
25670      r#"
25671      @scope {
25672        :scope {
25673          display: flex;
25674          color: lightblue;
25675        }
25676      }"#,
25677      "@scope{:scope{color:#add8e6;display:flex}}",
25678    );
25679    minify_test(
25680      r#"
25681      @scope (.light-scheme) {
25682        a { color: yellow; }
25683      }
25684      "#,
25685      "@scope(.light-scheme){a{color:#ff0}}",
25686    );
25687    minify_test(
25688      r#"
25689      @scope (.media-object) to (.content > *) {
25690        a { color: yellow; }
25691      }
25692      "#,
25693      "@scope(.media-object) to (.content>*){a{color:#ff0}}",
25694    );
25695    minify_test(
25696      r#"
25697      @scope to (.content > *) {
25698        a { color: yellow; }
25699      }
25700      "#,
25701      "@scope to (.content>*){a{color:#ff0}}",
25702    );
25703    minify_test(
25704      r#"
25705      @scope (#my-component) {
25706        & { color: yellow; }
25707      }
25708      "#,
25709      "@scope(#my-component){&{color:#ff0}}",
25710    );
25711    minify_test(
25712      r#"
25713      @scope (.parent-scope) {
25714        @scope (:scope > .child-scope) to (:scope .limit) {
25715          .content { color: yellow; }
25716        }
25717      }
25718      "#,
25719      "@scope(.parent-scope){@scope(:scope>.child-scope) to (:scope .limit){.content{color:#ff0}}}",
25720    );
25721    minify_test(
25722      r#"
25723      .foo {
25724        @scope (.bar) {
25725          color: yellow;
25726        }
25727      }
25728      "#,
25729      ".foo{@scope(.bar){&{color:#ff0}}}",
25730    );
25731    nesting_test(
25732      r#"
25733      .foo {
25734        @scope (.bar) {
25735          color: yellow;
25736        }
25737      }
25738      "#,
25739      indoc! {r#"
25740        @scope (.bar) {
25741          :scope {
25742            color: #ff0;
25743          }
25744        }
25745      "#},
25746    );
25747    nesting_test(
25748      r#"
25749      .parent {
25750        color: blue;
25751
25752        @scope (& > .scope) to (& .limit) {
25753          & .content {
25754            color: yellow;
25755          }
25756        }
25757      }
25758      "#,
25759      indoc! {r#"
25760        .parent {
25761          color: #00f;
25762        }
25763
25764        @scope (.parent > .scope) to (.parent > .scope .limit) {
25765          :scope .content {
25766            color: #ff0;
25767          }
25768        }
25769      "#},
25770    );
25771  }
25772
25773  #[test]
25774  fn test_custom_media() {
25775    custom_media_test(
25776      r#"
25777      @custom-media --modern (color), (hover);
25778
25779      @media (--modern) and (width > 1024px) {
25780        .a {
25781          color: green;
25782        }
25783      }
25784      "#,
25785      indoc! {r#"
25786      @media ((color) or (hover)) and (width > 1024px) {
25787        .a {
25788          color: green;
25789        }
25790      }
25791      "#},
25792    );
25793
25794    custom_media_test(
25795      r#"
25796      @custom-media --color (color);
25797
25798      @media (--color) and (width > 1024px) {
25799        .a {
25800          color: green;
25801        }
25802      }
25803      "#,
25804      indoc! {r#"
25805      @media (color) and (width > 1024px) {
25806        .a {
25807          color: green;
25808        }
25809      }
25810      "#},
25811    );
25812
25813    custom_media_test(
25814      r#"
25815      @custom-media --a (color);
25816      @custom-media --b (--a);
25817
25818      @media (--b) and (width > 1024px) {
25819        .a {
25820          color: green;
25821        }
25822      }
25823      "#,
25824      indoc! {r#"
25825      @media (color) and (width > 1024px) {
25826        .a {
25827          color: green;
25828        }
25829      }
25830      "#},
25831    );
25832
25833    custom_media_test(
25834      r#"
25835      @custom-media --not-color not (color);
25836
25837      @media not (--not-color) {
25838        .a {
25839          color: green;
25840        }
25841      }
25842      "#,
25843      indoc! {r#"
25844      @media (color) {
25845        .a {
25846          color: green;
25847        }
25848      }
25849      "#},
25850    );
25851
25852    custom_media_test(
25853      r#"
25854      @custom-media --color-print print and (color);
25855
25856      @media (--color-print) {
25857        .a {
25858          color: green;
25859        }
25860      }
25861      "#,
25862      indoc! {r#"
25863      @media print and (color) {
25864        .a {
25865          color: green;
25866        }
25867      }
25868      "#},
25869    );
25870
25871    custom_media_test(
25872      r#"
25873      @custom-media --color-print print and (color);
25874
25875      @media print and (--color-print) {
25876        .a {
25877          color: green;
25878        }
25879      }
25880      "#,
25881      indoc! {r#"
25882      @media print and (color) {
25883        .a {
25884          color: green;
25885        }
25886      }
25887      "#},
25888    );
25889
25890    custom_media_test(
25891      r#"
25892      @custom-media --not-color-print not print and (color);
25893
25894      @media not print and (--not-color-print) {
25895        .a {
25896          color: green;
25897        }
25898      }
25899      "#,
25900      indoc! {r#"
25901      @media not print and (color) {
25902        .a {
25903          color: green;
25904        }
25905      }
25906      "#},
25907    );
25908
25909    custom_media_test(
25910      r#"
25911      @custom-media --print print;
25912
25913      @media (--print) {
25914        .a {
25915          color: green;
25916        }
25917      }
25918      "#,
25919      indoc! {r#"
25920      @media print {
25921        .a {
25922          color: green;
25923        }
25924      }
25925      "#},
25926    );
25927
25928    custom_media_test(
25929      r#"
25930      @custom-media --print print;
25931
25932      @media not (--print) {
25933        .a {
25934          color: green;
25935        }
25936      }
25937      "#,
25938      indoc! {r#"
25939      @media not print {
25940        .a {
25941          color: green;
25942        }
25943      }
25944      "#},
25945    );
25946
25947    custom_media_test(
25948      r#"
25949      @custom-media --print not print;
25950
25951      @media not (--print) {
25952        .a {
25953          color: green;
25954        }
25955      }
25956      "#,
25957      indoc! {r#"
25958      @media print {
25959        .a {
25960          color: green;
25961        }
25962      }
25963      "#},
25964    );
25965
25966    custom_media_test(
25967      r#"
25968      @custom-media --print print;
25969
25970      @media ((--print)) {
25971        .a {
25972          color: green;
25973        }
25974      }
25975      "#,
25976      indoc! {r#"
25977      @media print {
25978        .a {
25979          color: green;
25980        }
25981      }
25982      "#},
25983    );
25984
25985    custom_media_test(
25986      r#"
25987      @custom-media --color (color);
25988      @custom-media --print print;
25989
25990      @media (--print) and (--color) {
25991        .a {
25992          color: green;
25993        }
25994      }
25995      "#,
25996      indoc! {r#"
25997      @media print and (color) {
25998        .a {
25999          color: green;
26000        }
26001      }
26002      "#},
26003    );
26004
26005    custom_media_test(
26006      r#"
26007      @custom-media --color (color);
26008      @custom-media --not-print not print;
26009
26010      @media (--not-print) and (--color) {
26011        .a {
26012          color: green;
26013        }
26014      }
26015      "#,
26016      indoc! {r#"
26017      @media not print and (color) {
26018        .a {
26019          color: green;
26020        }
26021      }
26022      "#},
26023    );
26024
26025    custom_media_test(
26026      r#"
26027      @custom-media --color (color);
26028      @custom-media --screen screen;
26029      @custom-media --print print;
26030
26031      @media (--print) and (--color), (--screen) and (--color) {
26032        .a {
26033          color: green;
26034        }
26035      }
26036      "#,
26037      indoc! {r#"
26038      @media print and (color), screen and (color) {
26039        .a {
26040          color: green;
26041        }
26042      }
26043      "#},
26044    );
26045
26046    custom_media_test(
26047      r#"
26048      @custom-media --color print and (color), print and (script);
26049
26050      @media (--color) {
26051        .a {
26052          color: green;
26053        }
26054      }
26055      "#,
26056      indoc! {r#"
26057      @media print and ((color) or (script)) {
26058        .a {
26059          color: green;
26060        }
26061      }
26062      "#},
26063    );
26064
26065    custom_media_test(
26066      r#"
26067      @custom-media --color (color);
26068      @custom-media --not-color not all and (--color);
26069
26070      @media (--not-color) {
26071        .a {
26072          color: green;
26073        }
26074      }
26075      "#,
26076      indoc! {r#"
26077        @media not all and (color) {
26078          .a {
26079            color: green;
26080          }
26081        }
26082      "#},
26083    );
26084
26085    custom_media_test(
26086      r#"
26087      @custom-media --color (color);
26088
26089      @media not all and (--color) {
26090        .a {
26091          color: green;
26092        }
26093      }
26094      "#,
26095      indoc! {r#"
26096        @media not all and (color) {
26097          .a {
26098            color: green;
26099          }
26100        }
26101      "#},
26102    );
26103
26104    custom_media_test(
26105      r#"
26106      @media (--print) {
26107        .a {
26108          color: green;
26109        }
26110      }
26111
26112      @custom-media --print print;
26113      "#,
26114      indoc! {r#"
26115      @media print {
26116        .a {
26117          color: green;
26118        }
26119      }
26120      "#},
26121    );
26122
26123    custom_media_test(
26124      r#"
26125      @custom-media --not-width not (min-width: 300px);
26126      @media screen and ((prefers-color-scheme: dark) or (--not-width)) {
26127        .foo {
26128          order: 6;
26129        }
26130      }
26131      "#,
26132      indoc! {r#"
26133      @media screen and ((prefers-color-scheme: dark) or (not (width >= 300px))) {
26134        .foo {
26135          order: 6;
26136        }
26137      }
26138      "#},
26139    );
26140
26141    fn custom_media_error_test(source: &str, err: Error<MinifyErrorKind>) {
26142      let mut stylesheet = StyleSheet::parse(
26143        &source,
26144        ParserOptions {
26145          filename: "test.css".into(),
26146          flags: ParserFlags::CUSTOM_MEDIA,
26147          ..ParserOptions::default()
26148        },
26149      )
26150      .unwrap();
26151      let res = stylesheet.minify(MinifyOptions {
26152        targets: Browsers {
26153          chrome: Some(95 << 16),
26154          ..Browsers::default()
26155        }
26156        .into(),
26157        ..MinifyOptions::default()
26158      });
26159      assert_eq!(res, Err(err))
26160    }
26161
26162    custom_media_error_test(
26163      r#"
26164      @custom-media --color-print print and (color);
26165
26166      @media screen and (--color-print) {
26167        .a {
26168          color: green;
26169        }
26170      }
26171      "#,
26172      Error {
26173        kind: MinifyErrorKind::UnsupportedCustomMediaBooleanLogic {
26174          custom_media_loc: Location {
26175            source_index: 0,
26176            line: 1,
26177            column: 7,
26178          },
26179        },
26180        loc: Some(ErrorLocation {
26181          filename: "test.css".into(),
26182          line: 3,
26183          column: 7,
26184        }),
26185      },
26186    );
26187
26188    custom_media_error_test(
26189      r#"
26190      @custom-media --color-print print and (color);
26191
26192      @media not print and (--color-print) {
26193        .a {
26194          color: green;
26195        }
26196      }
26197      "#,
26198      Error {
26199        kind: MinifyErrorKind::UnsupportedCustomMediaBooleanLogic {
26200          custom_media_loc: Location {
26201            source_index: 0,
26202            line: 1,
26203            column: 7,
26204          },
26205        },
26206        loc: Some(ErrorLocation {
26207          filename: "test.css".into(),
26208          line: 3,
26209          column: 7,
26210        }),
26211      },
26212    );
26213
26214    custom_media_error_test(
26215      r#"
26216      @custom-media --color-print print and (color);
26217      @custom-media --color-screen screen and (color);
26218
26219      @media (--color-print) or (--color-screen) {}
26220      "#,
26221      Error {
26222        kind: MinifyErrorKind::UnsupportedCustomMediaBooleanLogic {
26223          custom_media_loc: Location {
26224            source_index: 0,
26225            line: 2,
26226            column: 7,
26227          },
26228        },
26229        loc: Some(ErrorLocation {
26230          filename: "test.css".into(),
26231          line: 4,
26232          column: 7,
26233        }),
26234      },
26235    );
26236
26237    custom_media_error_test(
26238      r#"
26239      @custom-media --color-print print and (color);
26240      @custom-media --color-screen screen and (color);
26241
26242      @media (--color-print) and (--color-screen) {}
26243      "#,
26244      Error {
26245        kind: MinifyErrorKind::UnsupportedCustomMediaBooleanLogic {
26246          custom_media_loc: Location {
26247            source_index: 0,
26248            line: 2,
26249            column: 7,
26250          },
26251        },
26252        loc: Some(ErrorLocation {
26253          filename: "test.css".into(),
26254          line: 4,
26255          column: 7,
26256        }),
26257      },
26258    );
26259
26260    custom_media_error_test(
26261      r#"
26262      @custom-media --screen screen;
26263      @custom-media --print print;
26264
26265      @media (--print) and (--screen) {}
26266      "#,
26267      Error {
26268        kind: MinifyErrorKind::UnsupportedCustomMediaBooleanLogic {
26269          custom_media_loc: Location {
26270            source_index: 0,
26271            line: 1,
26272            column: 7,
26273          },
26274        },
26275        loc: Some(ErrorLocation {
26276          filename: "test.css".into(),
26277          line: 4,
26278          column: 7,
26279        }),
26280      },
26281    );
26282
26283    custom_media_error_test(
26284      r#"
26285      @custom-media --not-print not print and (color);
26286      @custom-media --not-screen not screen and (color);
26287
26288      @media ((script) or ((--not-print) and (--not-screen))) {
26289        .a {
26290          color: green;
26291        }
26292      }
26293      "#,
26294      Error {
26295        kind: MinifyErrorKind::UnsupportedCustomMediaBooleanLogic {
26296          custom_media_loc: Location {
26297            source_index: 0,
26298            line: 2,
26299            column: 7,
26300          },
26301        },
26302        loc: Some(ErrorLocation {
26303          filename: "test.css".into(),
26304          line: 4,
26305          column: 7,
26306        }),
26307      },
26308    );
26309
26310    custom_media_error_test(
26311      r#"
26312      @custom-media --color screen and (color), print and (color);
26313
26314      @media (--color) {
26315        .a {
26316          color: green;
26317        }
26318      }
26319      "#,
26320      Error {
26321        kind: MinifyErrorKind::UnsupportedCustomMediaBooleanLogic {
26322          custom_media_loc: Location {
26323            source_index: 0,
26324            line: 1,
26325            column: 7,
26326          },
26327        },
26328        loc: Some(ErrorLocation {
26329          filename: "test.css".into(),
26330          line: 3,
26331          column: 7,
26332        }),
26333      },
26334    );
26335
26336    custom_media_error_test(
26337      r#"
26338      @media (--not-defined) {
26339        .a {
26340          color: green;
26341        }
26342      }
26343      "#,
26344      Error {
26345        kind: MinifyErrorKind::CustomMediaNotDefined {
26346          name: "--not-defined".into(),
26347        },
26348        loc: Some(ErrorLocation {
26349          filename: "test.css".into(),
26350          line: 1,
26351          column: 7,
26352        }),
26353      },
26354    );
26355
26356    custom_media_error_test(
26357      r#"
26358      @custom-media --circular-mq-a (--circular-mq-b);
26359      @custom-media --circular-mq-b (--circular-mq-a);
26360
26361      @media (--circular-mq-a) {
26362        body {
26363          order: 3;
26364        }
26365      }
26366      "#,
26367      Error {
26368        kind: MinifyErrorKind::CircularCustomMedia {
26369          name: "--circular-mq-a".into(),
26370        },
26371        loc: Some(ErrorLocation {
26372          filename: "test.css".into(),
26373          line: 4,
26374          column: 7,
26375        }),
26376      },
26377    );
26378  }
26379
26380  #[test]
26381  fn test_dependencies() {
26382    fn dep_test(source: &str, expected: &str, deps: Vec<(&str, &str)>) {
26383      let mut stylesheet = StyleSheet::parse(
26384        &source,
26385        ParserOptions {
26386          filename: "test.css".into(),
26387          ..ParserOptions::default()
26388        },
26389      )
26390      .unwrap();
26391      stylesheet.minify(MinifyOptions::default()).unwrap();
26392      let res = stylesheet
26393        .to_css(PrinterOptions {
26394          analyze_dependencies: Some(Default::default()),
26395          minify: true,
26396          ..PrinterOptions::default()
26397        })
26398        .unwrap();
26399      assert_eq!(res.code, expected);
26400      let dependencies = res.dependencies.unwrap();
26401      assert_eq!(dependencies.len(), deps.len());
26402      for (i, (url, placeholder)) in deps.into_iter().enumerate() {
26403        match &dependencies[i] {
26404          Dependency::Url(dep) => {
26405            assert_eq!(dep.url, url);
26406            assert_eq!(dep.placeholder, placeholder);
26407          }
26408          Dependency::Import(dep) => {
26409            assert_eq!(dep.url, url);
26410            assert_eq!(dep.placeholder, placeholder);
26411          }
26412        }
26413      }
26414    }
26415
26416    fn dep_error_test(source: &str, error: PrinterErrorKind) {
26417      let stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
26418      let res = stylesheet.to_css(PrinterOptions {
26419        analyze_dependencies: Some(Default::default()),
26420        ..PrinterOptions::default()
26421      });
26422      match res {
26423        Err(e) => assert_eq!(e.kind, error),
26424        _ => unreachable!(),
26425      }
26426    }
26427
26428    dep_test(
26429      ".foo { background: image-set('./img12x.png', './img21x.png' 2x)}",
26430      ".foo{background:image-set(\"hXFI8W\" 1x,\"5TkpBa\" 2x)}",
26431      vec![("./img12x.png", "hXFI8W"), ("./img21x.png", "5TkpBa")],
26432    );
26433
26434    dep_test(
26435      ".foo { background: image-set(url(./img12x.png), url('./img21x.png') 2x)}",
26436      ".foo{background:image-set(\"hXFI8W\" 1x,\"5TkpBa\" 2x)}",
26437      vec![("./img12x.png", "hXFI8W"), ("./img21x.png", "5TkpBa")],
26438    );
26439
26440    dep_test(
26441      ".foo { --test: url(/foo.png) }",
26442      ".foo{--test:url(\"lDnnrG\")}",
26443      vec![("/foo.png", "lDnnrG")],
26444    );
26445
26446    dep_test(
26447      ".foo { --test: url(\"/foo.png\") }",
26448      ".foo{--test:url(\"lDnnrG\")}",
26449      vec![("/foo.png", "lDnnrG")],
26450    );
26451
26452    dep_test(
26453      ".foo { --test: url(\"http://example.com/foo.png\") }",
26454      ".foo{--test:url(\"3X1zSW\")}",
26455      vec![("http://example.com/foo.png", "3X1zSW")],
26456    );
26457
26458    dep_test(
26459      ".foo { --test: url(\"data:image/svg+xml;utf8,<svg></svg>\") }",
26460      ".foo{--test:url(\"-vl-rG\")}",
26461      vec![("data:image/svg+xml;utf8,<svg></svg>", "-vl-rG")],
26462    );
26463
26464    dep_test(
26465      ".foo { background: url(\"foo.png\") var(--test) }",
26466      ".foo{background:url(\"Vwkwkq\") var(--test)}",
26467      vec![("foo.png", "Vwkwkq")],
26468    );
26469
26470    dep_error_test(
26471      ".foo { --test: url(\"foo.png\") }",
26472      PrinterErrorKind::AmbiguousUrlInCustomProperty { url: "foo.png".into() },
26473    );
26474
26475    dep_error_test(
26476      ".foo { --test: url(foo.png) }",
26477      PrinterErrorKind::AmbiguousUrlInCustomProperty { url: "foo.png".into() },
26478    );
26479
26480    dep_error_test(
26481      ".foo { --test: url(./foo.png) }",
26482      PrinterErrorKind::AmbiguousUrlInCustomProperty {
26483        url: "./foo.png".into(),
26484      },
26485    );
26486
26487    dep_test(
26488      ".foo { behavior: url(#foo) }",
26489      ".foo{behavior:url(\"Zn9-2q\")}",
26490      vec![("#foo", "Zn9-2q")],
26491    );
26492
26493    dep_test(
26494      ".foo { --foo: url(#foo) }",
26495      ".foo{--foo:url(\"Zn9-2q\")}",
26496      vec![("#foo", "Zn9-2q")],
26497    );
26498
26499    dep_test(
26500      "@import \"test.css\"; .foo { color: red }",
26501      "@import \"hHsogW\";.foo{color:red}",
26502      vec![("test.css", "hHsogW")],
26503    );
26504  }
26505
26506  #[test]
26507  fn test_api() {
26508    let stylesheet = StyleSheet::parse(".foo:hover { color: red }", ParserOptions::default()).unwrap();
26509    match &stylesheet.rules.0[0] {
26510      CssRule::Style(s) => {
26511        assert_eq!(&s.selectors.to_string(), ".foo:hover");
26512      }
26513      _ => unreachable!(),
26514    }
26515
26516    let color = CssColor::parse_string("#f0f").unwrap();
26517    assert_eq!(color.to_css_string(PrinterOptions::default()).unwrap(), "#f0f");
26518
26519    let rule = CssRule::parse_string(".foo { color: red }", ParserOptions::default()).unwrap();
26520    assert_eq!(
26521      rule.to_css_string(PrinterOptions::default()).unwrap(),
26522      indoc! {r#"
26523    .foo {
26524      color: red;
26525    }"#}
26526    );
26527
26528    let property = Property::parse_string("color".into(), "#f0f", ParserOptions::default()).unwrap();
26529    assert_eq!(
26530      property.to_css_string(false, PrinterOptions::default()).unwrap(),
26531      "color: #f0f"
26532    );
26533    assert_eq!(
26534      property.to_css_string(true, PrinterOptions::default()).unwrap(),
26535      "color: #f0f !important"
26536    );
26537
26538    let code = indoc! { r#"
26539      .foo {
26540        color: green;
26541      }
26542
26543      .bar {
26544        color: red;
26545        background: pink;
26546      }
26547
26548      @media print {
26549        .baz {
26550          color: green;
26551        }
26552      }
26553    "#};
26554    let stylesheet = StyleSheet::parse(code, ParserOptions::default()).unwrap();
26555    if let CssRule::Style(style) = &stylesheet.rules.0[1] {
26556      let (key, val) = style.property_location(code, 0).unwrap();
26557      assert_eq!(
26558        key,
26559        SourceLocation { line: 5, column: 3 }..SourceLocation { line: 5, column: 8 }
26560      );
26561      assert_eq!(
26562        val,
26563        SourceLocation { line: 5, column: 10 }..SourceLocation { line: 5, column: 13 }
26564      );
26565    }
26566
26567    if let CssRule::Style(style) = &stylesheet.rules.0[1] {
26568      let (key, val) = style.property_location(code, 1).unwrap();
26569      assert_eq!(
26570        key,
26571        SourceLocation { line: 6, column: 3 }..SourceLocation { line: 6, column: 13 }
26572      );
26573      assert_eq!(
26574        val,
26575        SourceLocation { line: 6, column: 15 }..SourceLocation { line: 6, column: 19 }
26576      );
26577    }
26578    if let CssRule::Media(media) = &stylesheet.rules.0[2] {
26579      if let CssRule::Style(style) = &media.rules.0[0] {
26580        let (key, val) = style.property_location(code, 0).unwrap();
26581        assert_eq!(
26582          key,
26583          SourceLocation { line: 11, column: 5 }..SourceLocation { line: 11, column: 10 }
26584        );
26585        assert_eq!(
26586          val,
26587          SourceLocation { line: 11, column: 12 }..SourceLocation { line: 11, column: 17 }
26588        );
26589      }
26590    }
26591
26592    let mut property = Property::Transform(Default::default(), VendorPrefix::WebKit);
26593    property.set_prefix(VendorPrefix::None);
26594    assert_eq!(property, Property::Transform(Default::default(), VendorPrefix::None));
26595    property.set_prefix(VendorPrefix::Moz);
26596    assert_eq!(property, Property::Transform(Default::default(), VendorPrefix::Moz));
26597    property.set_prefix(VendorPrefix::WebKit | VendorPrefix::Moz);
26598    assert_eq!(
26599      property,
26600      Property::Transform(Default::default(), VendorPrefix::WebKit | VendorPrefix::Moz)
26601    );
26602
26603    let mut property = Property::TextDecorationLine(Default::default(), VendorPrefix::None);
26604    property.set_prefix(VendorPrefix::Ms);
26605    assert_eq!(
26606      property,
26607      Property::TextDecorationLine(Default::default(), VendorPrefix::None)
26608    );
26609    property.set_prefix(VendorPrefix::WebKit | VendorPrefix::Moz | VendorPrefix::Ms);
26610    assert_eq!(
26611      property,
26612      Property::TextDecorationLine(Default::default(), VendorPrefix::WebKit | VendorPrefix::Moz)
26613    );
26614
26615    let mut property = Property::AccentColor(Default::default());
26616    property.set_prefix(VendorPrefix::WebKit);
26617    assert_eq!(property, Property::AccentColor(Default::default()));
26618  }
26619
26620  #[cfg(feature = "substitute_variables")]
26621  #[test]
26622  fn test_substitute_vars() {
26623    use crate::properties::custom::TokenList;
26624    use crate::traits::ParseWithOptions;
26625
26626    fn test(property: Property, vars: HashMap<&str, &str>, expected: &str) {
26627      if let Property::Unparsed(unparsed) = property {
26628        let vars = vars
26629          .into_iter()
26630          .map(|(k, v)| {
26631            (
26632              k,
26633              TokenList::parse_string_with_options(v, ParserOptions::default()).unwrap(),
26634            )
26635          })
26636          .collect();
26637        let substituted = unparsed.substitute_variables(&vars).unwrap();
26638        assert_eq!(
26639          substituted.to_css_string(false, PrinterOptions::default()).unwrap(),
26640          expected
26641        );
26642      } else {
26643        panic!("Not an unparsed property");
26644      }
26645    }
26646
26647    let property = Property::parse_string("color".into(), "var(--test)", ParserOptions::default()).unwrap();
26648    test(property, HashMap::from([("--test", "yellow")]), "color: #ff0");
26649
26650    let property =
26651      Property::parse_string("color".into(), "var(--test, var(--foo))", ParserOptions::default()).unwrap();
26652    test(property, HashMap::from([("--foo", "yellow")]), "color: #ff0");
26653    let property = Property::parse_string(
26654      "color".into(),
26655      "var(--test, var(--foo, yellow))",
26656      ParserOptions::default(),
26657    )
26658    .unwrap();
26659    test(property, HashMap::new(), "color: #ff0");
26660
26661    let property =
26662      Property::parse_string("width".into(), "calc(var(--a) + var(--b))", ParserOptions::default()).unwrap();
26663    test(property, HashMap::from([("--a", "2px"), ("--b", "4px")]), "width: 6px");
26664
26665    let property = Property::parse_string("color".into(), "var(--a)", ParserOptions::default()).unwrap();
26666    test(
26667      property,
26668      HashMap::from([("--a", "var(--b)"), ("--b", "yellow")]),
26669      "color: #ff0",
26670    );
26671
26672    let property = Property::parse_string("color".into(), "var(--a)", ParserOptions::default()).unwrap();
26673    test(
26674      property,
26675      HashMap::from([("--a", "var(--b)"), ("--b", "var(--c)"), ("--c", "var(--a)")]),
26676      "color: var(--a)",
26677    );
26678  }
26679
26680  #[test]
26681  fn test_layer() {
26682    minify_test("@layer foo;", "@layer foo;");
26683    minify_test("@layer foo, bar;", "@layer foo,bar;");
26684    minify_test("@layer foo.bar;", "@layer foo.bar;");
26685    minify_test("@layer foo.bar, baz;", "@layer foo.bar,baz;");
26686
26687    minify_test(
26688      r#"
26689      @layer foo {
26690        .bar {
26691          color: red;
26692        }
26693      }
26694    "#,
26695      "@layer foo{.bar{color:red}}",
26696    );
26697    minify_test(
26698      r#"
26699      @layer foo.bar {
26700        .bar {
26701          color: red;
26702        }
26703      }
26704    "#,
26705      "@layer foo.bar{.bar{color:red}}",
26706    );
26707    minify_test(r#"
26708      @layer base {
26709        p { max-width: 70ch; }
26710      }
26711
26712      @layer framework {
26713        @layer base {
26714          p { margin-block: 0.75em; }
26715        }
26716
26717        @layer theme {
26718          p { color: #222; }
26719        }
26720      }
26721    "#, "@layer base{p{max-width:70ch}}@layer framework{@layer base{p{margin-block:.75em}}@layer theme{p{color:#222}}}");
26722    minify_test(
26723      r#"
26724      @layer {
26725        .bar {
26726          color: red;
26727        }
26728      }
26729    "#,
26730      "@layer{.bar{color:red}}",
26731    );
26732    minify_test(
26733      r#"
26734      @layer foo\20 bar, baz;
26735    "#,
26736      "@layer foo\\ bar,baz;",
26737    );
26738    minify_test(
26739      r#"
26740      @layer one.two\20 three\#four\.five {
26741        .bar {
26742          color: red;
26743        }
26744      }
26745    "#,
26746      "@layer one.two\\ three\\#four\\.five{.bar{color:red}}",
26747    );
26748
26749    error_test("@layer;", ParserError::UnexpectedToken(Token::Semicolon));
26750    error_test("@layer foo, bar {};", ParserError::AtRuleBodyInvalid);
26751    minify_test("@import 'test.css' layer;", "@import \"test.css\" layer;");
26752    minify_test("@import 'test.css' layer(foo);", "@import \"test.css\" layer(foo);");
26753    minify_test(
26754      "@import 'test.css' layer(foo.bar);",
26755      "@import \"test.css\" layer(foo.bar);",
26756    );
26757    minify_test(
26758      "@import 'test.css' layer(foo\\20 bar);",
26759      "@import \"test.css\" layer(foo\\ bar);",
26760    );
26761    error_test(
26762      "@import 'test.css' layer(foo, bar) {};",
26763      ParserError::UnexpectedToken(Token::Comma),
26764    );
26765    minify_test(
26766      r#"
26767      @layer one {
26768        body {
26769          background: red;
26770        }
26771      }
26772
26773      body {
26774        background: red;
26775      }
26776
26777      @layer two {
26778        body {
26779          background: green;
26780        }
26781      }
26782
26783      @layer one {
26784        body {
26785          background: yellow;
26786        }
26787      }
26788      "#,
26789      "@layer one{body{background:#ff0}}body{background:red}@layer two{body{background:green}}",
26790    );
26791  }
26792
26793  #[test]
26794  fn test_property() {
26795    minify_test(
26796      r#"
26797      @property --property-name {
26798        syntax: '<color>';
26799        inherits: false;
26800        initial-value: yellow;
26801      }
26802    "#,
26803      "@property --property-name{syntax:\"<color>\";inherits:false;initial-value:#ff0}",
26804    );
26805
26806    test(
26807      r#"
26808      @property --property-name {
26809        syntax: '*';
26810        inherits: false;
26811        initial-value: ;
26812      }
26813    "#,
26814      indoc! {r#"
26815      @property --property-name {
26816        syntax: "*";
26817        inherits: false;
26818        initial-value: ;
26819      }
26820    "#},
26821    );
26822
26823    minify_test(
26824      r#"
26825      @property --property-name {
26826        syntax: '*';
26827        inherits: false;
26828        initial-value: ;
26829      }
26830    "#,
26831      "@property --property-name{syntax:\"*\";inherits:false;initial-value:}",
26832    );
26833
26834    test(
26835      r#"
26836      @property --property-name {
26837        syntax: '*';
26838        inherits: false;
26839        initial-value:;
26840      }
26841    "#,
26842      indoc! {r#"
26843      @property --property-name {
26844        syntax: "*";
26845        inherits: false;
26846        initial-value: ;
26847      }
26848    "#},
26849    );
26850
26851    minify_test(
26852      r#"
26853      @property --property-name {
26854        syntax: '*';
26855        inherits: false;
26856        initial-value:;
26857      }
26858    "#,
26859      "@property --property-name{syntax:\"*\";inherits:false;initial-value:}",
26860    );
26861    minify_test(
26862      r#"
26863      @property --property-name {
26864        syntax: '*';
26865        inherits: false;
26866        initial-value: foo bar;
26867      }
26868    "#,
26869      "@property --property-name{syntax:\"*\";inherits:false;initial-value:foo bar}",
26870    );
26871
26872    minify_test(
26873      r#"
26874      @property --property-name {
26875        syntax: '<length>';
26876        inherits: true;
26877        initial-value: 25px;
26878      }
26879    "#,
26880      "@property --property-name{syntax:\"<length>\";inherits:true;initial-value:25px}",
26881    );
26882
26883    error_test(
26884      r#"
26885      @property --property-name {
26886        syntax: '<color>';
26887        inherits: false;
26888        initial-value: 25px;
26889      }
26890    "#,
26891      ParserError::UnexpectedToken(crate::properties::custom::Token::Dimension {
26892        has_sign: false,
26893        value: 25.0,
26894        int_value: Some(25),
26895        unit: "px".into(),
26896      }),
26897    );
26898
26899    error_test(
26900      r#"
26901      @property --property-name {
26902        syntax: '<length>';
26903        inherits: false;
26904        initial-value: var(--some-value);
26905      }
26906    "#,
26907      ParserError::UnexpectedToken(crate::properties::custom::Token::Function("var".into())),
26908    );
26909
26910    error_test(
26911      r#"
26912      @property --property-name {
26913        syntax: '<color>';
26914        inherits: false;
26915      }
26916    "#,
26917      ParserError::AtRuleBodyInvalid,
26918    );
26919
26920    minify_test(
26921      r#"
26922      @property --property-name {
26923        syntax: '*';
26924        inherits: false;
26925      }
26926    "#,
26927      "@property --property-name{syntax:\"*\";inherits:false}",
26928    );
26929
26930    error_test(
26931      r#"
26932      @property --property-name {
26933        syntax: '*';
26934      }
26935    "#,
26936      ParserError::AtRuleBodyInvalid,
26937    );
26938
26939    error_test(
26940      r#"
26941      @property --property-name {
26942        inherits: false;
26943      }
26944    "#,
26945      ParserError::AtRuleBodyInvalid,
26946    );
26947
26948    error_test(
26949      r#"
26950      @property property-name {
26951        syntax: '*';
26952        inherits: false;
26953      }
26954    "#,
26955      ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("property-name".into())),
26956    );
26957
26958    minify_test(
26959      r#"
26960      @property --property-name {
26961        syntax: 'custom | <color>';
26962        inherits: false;
26963        initial-value: yellow;
26964      }
26965    "#,
26966      "@property --property-name{syntax:\"custom|<color>\";inherits:false;initial-value:#ff0}",
26967    );
26968
26969    // TODO: Re-enable with a better solution
26970    //       See: https://github.com/parcel-bundler/lightningcss/issues/288
26971    // minify_test(r#"
26972    //   @property --property-name {
26973    //     syntax: '<transform-list>';
26974    //     inherits: false;
26975    //     initial-value: translate(200px,300px) translate(100px,200px) scale(2);
26976    //   }
26977    // "#, "@property --property-name{syntax:\"<transform-list>\";inherits:false;initial-value:matrix(2,0,0,2,300,500)}");
26978
26979    minify_test(
26980      r#"
26981      @property --property-name {
26982        syntax: '<time>';
26983        inherits: false;
26984        initial-value: 1000ms;
26985      }
26986    "#,
26987      "@property --property-name{syntax:\"<time>\";inherits:false;initial-value:1s}",
26988    );
26989
26990    minify_test(
26991      r#"
26992      @property --property-name {
26993        syntax: '<url>';
26994        inherits: false;
26995        initial-value: url("foo.png");
26996      }
26997    "#,
26998      "@property --property-name{syntax:\"<url>\";inherits:false;initial-value:url(foo.png)}",
26999    );
27000
27001    minify_test(
27002      r#"
27003      @property --property-name {
27004        syntax: '<image>';
27005        inherits: false;
27006        initial-value: linear-gradient(yellow, blue);
27007      }
27008    "#,
27009      "@property --property-name{syntax:\"<image>\";inherits:false;initial-value:linear-gradient(#ff0,#00f)}",
27010    );
27011
27012    minify_test(
27013      r#"
27014      @property --property-name {
27015        initial-value: linear-gradient(yellow, blue);
27016        inherits: false;
27017        syntax: '<image>';
27018      }
27019    "#,
27020      "@property --property-name{syntax:\"<image>\";inherits:false;initial-value:linear-gradient(#ff0,#00f)}",
27021    );
27022
27023    test(
27024      r#"
27025      @property --property-name {
27026        syntax: '<length>|none';
27027        inherits: false;
27028        initial-value: none;
27029      }
27030    "#,
27031      indoc! {r#"
27032      @property --property-name {
27033        syntax: "<length> | none";
27034        inherits: false;
27035        initial-value: none;
27036      }
27037    "#},
27038    );
27039
27040    minify_test(
27041      r#"
27042      @property --property-name {
27043        syntax: '<color>#';
27044        inherits: false;
27045        initial-value: yellow, blue;
27046      }
27047    "#,
27048      "@property --property-name{syntax:\"<color>#\";inherits:false;initial-value:#ff0,#00f}",
27049    );
27050    minify_test(
27051      r#"
27052      @property --property-name {
27053        syntax: '<color>+';
27054        inherits: false;
27055        initial-value: yellow blue;
27056      }
27057    "#,
27058      "@property --property-name{syntax:\"<color>+\";inherits:false;initial-value:#ff0 #00f}",
27059    );
27060    minify_test(
27061      r#"
27062      @property --property-name {
27063        syntax: '<color>';
27064        inherits: false;
27065        initial-value: yellow;
27066      }
27067      .foo {
27068        color: var(--property-name)
27069      }
27070      @property --property-name {
27071        syntax: '<color>';
27072        inherits: true;
27073        initial-value: blue;
27074      }
27075    "#,
27076      "@property --property-name{syntax:\"<color>\";inherits:true;initial-value:#00f}.foo{color:var(--property-name)}",
27077    );
27078  }
27079
27080  #[test]
27081  fn test_quoting_unquoting_urls() {
27082    // Quotes remain double quotes when not minifying
27083    test(
27084      r#".foo {
27085      background-image: url("0123abcd");
27086    }"#,
27087      r#".foo {
27088  background-image: url("0123abcd");
27089}
27090"#,
27091    );
27092
27093    // Quotes removed when minifying
27094    minify_test(
27095      r#".foo {
27096      background-image: url("0123abcd");
27097    }"#,
27098      r#".foo{background-image:url(0123abcd)}"#,
27099    );
27100
27101    // Doubles quotes added if not present when not minifying
27102    test(
27103      r#".foo {
27104      background-image: url(0123abcd);
27105    }"#,
27106      r#".foo {
27107  background-image: url("0123abcd");
27108}
27109"#,
27110    );
27111
27112    // No quotes changed if not present when not minifying
27113    minify_test(
27114      r#".foo {
27115      background-image: url(0123abcd);
27116    }"#,
27117      r#".foo{background-image:url(0123abcd)}"#,
27118    );
27119  }
27120
27121  #[test]
27122  fn test_zindex() {
27123    minify_test(".foo { z-index: 2 }", ".foo{z-index:2}");
27124    minify_test(".foo { z-index: -2 }", ".foo{z-index:-2}");
27125    minify_test(".foo { z-index: 999999 }", ".foo{z-index:999999}");
27126    minify_test(".foo { z-index: 9999999 }", ".foo{z-index:9999999}");
27127    minify_test(".foo { z-index: -9999999 }", ".foo{z-index:-9999999}");
27128  }
27129
27130  #[test]
27131  #[cfg(feature = "sourcemap")]
27132  fn test_input_source_map() {
27133    let source = r#".imported {
27134      content: "yay, file support!";
27135    }
27136
27137    .selector {
27138      margin: 1em;
27139      background-color: #f60;
27140    }
27141
27142    .selector .nested {
27143      margin: 0.5em;
27144    }
27145
27146    /*# sourceMappingURL=data:application/json;base64,ewoJInZlcnNpb24iOiAzLAoJInNvdXJjZVJvb3QiOiAicm9vdCIsCgkiZmlsZSI6ICJzdGRvdXQiLAoJInNvdXJjZXMiOiBbCgkJInN0ZGluIiwKCQkic2Fzcy9fdmFyaWFibGVzLnNjc3MiLAoJCSJzYXNzL19kZW1vLnNjc3MiCgldLAoJInNvdXJjZXNDb250ZW50IjogWwoJCSJAaW1wb3J0IFwiX3ZhcmlhYmxlc1wiO1xuQGltcG9ydCBcIl9kZW1vXCI7XG5cbi5zZWxlY3RvciB7XG4gIG1hcmdpbjogJHNpemU7XG4gIGJhY2tncm91bmQtY29sb3I6ICRicmFuZENvbG9yO1xuXG4gIC5uZXN0ZWQge1xuICAgIG1hcmdpbjogJHNpemUgLyAyO1xuICB9XG59IiwKCQkiJGJyYW5kQ29sb3I6ICNmNjA7XG4kc2l6ZTogMWVtOyIsCgkJIi5pbXBvcnRlZCB7XG4gIGNvbnRlbnQ6IFwieWF5LCBmaWxlIHN1cHBvcnQhXCI7XG59IgoJXSwKCSJtYXBwaW5ncyI6ICJBRUFBLFNBQVMsQ0FBQztFQUNSLE9BQU8sRUFBRSxvQkFBcUI7Q0FDL0I7O0FGQ0QsU0FBUyxDQUFDO0VBQ1IsTUFBTSxFQ0hELEdBQUc7RURJUixnQkFBZ0IsRUNMTCxJQUFJO0NEVWhCOztBQVBELFNBQVMsQ0FJUCxPQUFPLENBQUM7RUFDTixNQUFNLEVDUEgsS0FBRztDRFFQIiwKCSJuYW1lcyI6IFtdCn0= */"#;
27147
27148    let mut stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
27149    stylesheet.minify(MinifyOptions::default()).unwrap();
27150    let mut sm = parcel_sourcemap::SourceMap::new("/");
27151    stylesheet
27152      .to_css(PrinterOptions {
27153        source_map: Some(&mut sm),
27154        minify: true,
27155        ..PrinterOptions::default()
27156      })
27157      .unwrap();
27158    let map = sm.to_json(None).unwrap();
27159    assert_eq!(
27160      map,
27161      r#"{"version":3,"sourceRoot":null,"mappings":"AAAA,uCCGA,2CAAA","sources":["sass/_demo.scss","stdin"],"sourcesContent":[".imported {\n  content: \"yay, file support!\";\n}","@import \"_variables\";\n@import \"_demo\";\n\n.selector {\n  margin: $size;\n  background-color: $brandColor;\n\n  .nested {\n    margin: $size / 2;\n  }\n}"],"names":[]}"#
27162    );
27163  }
27164
27165  #[test]
27166  fn test_error_recovery() {
27167    use std::sync::{Arc, RwLock};
27168    let warnings = Some(Arc::new(RwLock::new(Vec::new())));
27169    test_with_options(
27170      r#"
27171      h1(>h1) {
27172        color: red;
27173      }
27174
27175      .foo {
27176        color: red;
27177      }
27178
27179      .clearfix {
27180        *zoom: 1;
27181        background: red;
27182      }
27183
27184      @media (hover) {
27185        h1(>h1) {
27186          color: red;
27187        }
27188
27189        .bar {
27190          color: red;
27191        }
27192      }
27193    "#,
27194      indoc! { r#"
27195      .foo {
27196        color: red;
27197      }
27198
27199      .clearfix {
27200        background: red;
27201      }
27202
27203      @media (hover) {
27204        .bar {
27205          color: red;
27206        }
27207      }
27208    "#},
27209      ParserOptions {
27210        filename: "test.css".into(),
27211        error_recovery: true,
27212        warnings: warnings.clone(),
27213        ..ParserOptions::default()
27214      },
27215    );
27216    let w = warnings.unwrap();
27217    let warnings = w.read().unwrap();
27218    assert_eq!(
27219      *warnings,
27220      vec![
27221        Error {
27222          kind: ParserError::SelectorError(SelectorError::EmptySelector),
27223          loc: Some(ErrorLocation {
27224            filename: "test.css".into(),
27225            line: 1,
27226            column: 7
27227          })
27228        },
27229        Error {
27230          kind: ParserError::UnexpectedToken(Token::Semicolon),
27231          loc: Some(ErrorLocation {
27232            filename: "test.css".into(),
27233            line: 10,
27234            column: 17
27235          })
27236        },
27237        Error {
27238          kind: ParserError::SelectorError(SelectorError::EmptySelector),
27239          loc: Some(ErrorLocation {
27240            filename: "test.css".into(),
27241            line: 15,
27242            column: 9
27243          })
27244        },
27245      ]
27246    )
27247  }
27248
27249  #[test]
27250  fn test_invalid() {
27251    error_test(
27252      ".a{color: hsla(120, 62.32%;}",
27253      ParserError::UnexpectedToken(Token::CloseCurlyBracket),
27254    );
27255    error_test(
27256      ".a{--foo: url(foo\\) b\\)ar)}",
27257      ParserError::UnexpectedToken(Token::BadUrl("foo\\) b\\)ar".into())),
27258    );
27259  }
27260
27261  #[test]
27262  fn test_container_queries() {
27263    // with name
27264    minify_test(
27265      r#"
27266      @container my-layout (inline-size > 45em) {
27267        .foo {
27268          color: red;
27269        }
27270      }
27271    "#,
27272      "@container my-layout (inline-size>45em){.foo{color:red}}",
27273    );
27274
27275    minify_test(
27276      r#"
27277      @container my-layout ( not (width > 500px) ) {
27278        .foo {
27279          color: red;
27280        }
27281      }
27282    "#,
27283      "@container my-layout not (width>500px){.foo{color:red}}",
27284    );
27285
27286    minify_test(
27287      r#"
27288      @container my-layout not (width > 500px) {
27289        .foo {
27290          color: red;
27291        }
27292      }
27293    "#,
27294      "@container my-layout not (width>500px){.foo{color:red}}",
27295    );
27296
27297    minify_test(
27298      r#"
27299      @container not (width > 500px) {
27300        .foo {
27301          color: red;
27302        }
27303      }
27304    "#,
27305      "@container not (width>500px){.foo{color:red}}",
27306    );
27307
27308    minify_test(
27309      r#"
27310      @container my-layout ((width: 100px) and (not (height: 100px))) {
27311        .foo {
27312          color: red;
27313        }
27314      }
27315    "#,
27316      "@container my-layout (width:100px) and (not (height:100px)){.foo{color:red}}",
27317    );
27318
27319    minify_test(
27320      r#"
27321      @container my-layout (width = max(10px, 10em)) {
27322        .foo {
27323          color: red;
27324        }
27325      }
27326    "#,
27327      "@container my-layout (width=max(10px,10em)){.foo{color:red}}",
27328    );
27329
27330    // without name
27331    minify_test(
27332      r#"
27333      @container (inline-size > 45em) {
27334        .foo {
27335          color: red;
27336        }
27337      }
27338    "#,
27339      "@container (inline-size>45em){.foo{color:red}}",
27340    );
27341
27342    minify_test(
27343      r#"
27344      @container (inline-size > 45em) and (inline-size < 100em) {
27345        .foo {
27346          color: red;
27347        }
27348      }
27349    "#,
27350      "@container (inline-size>45em) and (inline-size<100em){.foo{color:red}}",
27351    );
27352
27353    // calc()
27354    minify_test(
27355      r#"
27356      @container (width > calc(100vw - 50px)) {
27357        .foo {
27358          color: red;
27359        }
27360      }
27361    "#,
27362      "@container (width>calc(100vw - 50px)){.foo{color:red}}",
27363    );
27364
27365    minify_test(
27366      r#"
27367      @container (calc(100vh - 50px) <= height ) {
27368        .foo {
27369          color: red;
27370        }
27371      }
27372    "#,
27373      "@container (height>=calc(100vh - 50px)){.foo{color:red}}",
27374    );
27375
27376    // merge adjacent
27377    minify_test(
27378      r#"
27379      @container my-layout (inline-size > 45em) {
27380        .foo {
27381          color: red;
27382        }
27383      }
27384
27385      @container my-layout (inline-size > 45em) {
27386        .foo {
27387          background: yellow;
27388        }
27389
27390        .bar {
27391          color: white;
27392        }
27393      }
27394    "#,
27395      "@container my-layout (inline-size>45em){.foo{color:red;background:#ff0}.bar{color:#fff}}",
27396    );
27397
27398    minify_test(
27399      r#"
27400    .foo {
27401      container-name: foo bar;
27402      container-type: size;
27403    }
27404    "#,
27405      ".foo{container:foo bar/size}",
27406    );
27407    minify_test(
27408      r#"
27409    .foo {
27410      container-name: foo bar;
27411      container-type: normal;
27412    }
27413    "#,
27414      ".foo{container:foo bar}",
27415    );
27416    minify_test(
27417      ".foo{ container-type: inline-size }",
27418      ".foo{container-type:inline-size}",
27419    );
27420    minify_test(".foo{ container-name: none; }", ".foo{container-name:none}");
27421    minify_test(".foo{ container-name: foo; }", ".foo{container-name:foo}");
27422    minify_test(".foo{ container: foo / normal; }", ".foo{container:foo}");
27423    minify_test(
27424      ".foo{ container: foo / inline-size; }",
27425      ".foo{container:foo/inline-size}",
27426    );
27427    minify_test(".foo { width: calc(1cqw + 2cqw) }", ".foo{width:3cqw}");
27428    minify_test(".foo { width: calc(1cqh + 2cqh) }", ".foo{width:3cqh}");
27429    minify_test(".foo { width: calc(1cqi + 2cqi) }", ".foo{width:3cqi}");
27430    minify_test(".foo { width: calc(1cqb + 2cqb) }", ".foo{width:3cqb}");
27431    minify_test(".foo { width: calc(1cqmin + 2cqmin) }", ".foo{width:3cqmin}");
27432    minify_test(".foo { width: calc(1cqmax + 2cqmax) }", ".foo{width:3cqmax}");
27433
27434    // Unlike in @media, there is no need to convert the range syntax in @container,
27435    // because browsers all support this syntax.
27436    prefix_test(
27437      r#"
27438      @container (width > 100px) {
27439        .foo { padding: 5px; }
27440      }
27441      "#,
27442      indoc! { r#"
27443        @container (width > 100px) {
27444          .foo {
27445            padding: 5px;
27446          }
27447        }
27448      "#},
27449      Browsers {
27450        chrome: Some(105 << 16),
27451        ..Browsers::default()
27452      },
27453    );
27454    prefix_test(
27455      r#"
27456      @container (min-width: 100px) {
27457        .foo { padding: 5px; }
27458      }
27459      "#,
27460      indoc! { r#"
27461        @container (width >= 100px) {
27462          .foo {
27463            padding: 5px;
27464          }
27465        }
27466      "#},
27467      Browsers {
27468        chrome: Some(105 << 16),
27469        ..Browsers::default()
27470      },
27471    );
27472
27473    minify_test(
27474      r#"
27475      @container style(--responsive: true) {
27476        .foo {
27477          color: red;
27478        }
27479      }
27480    "#,
27481      "@container style(--responsive:true){.foo{color:red}}",
27482    );
27483    minify_test(
27484      r#"
27485      @container style(--responsive: true) and style(color: yellow) {
27486        .foo {
27487          color: red;
27488        }
27489      }
27490    "#,
27491      "@container style(--responsive:true) and style(color:#ff0){.foo{color:red}}",
27492    );
27493    minify_test(
27494      r#"
27495      @container not style(--responsive: true) {
27496        .foo {
27497          color: red;
27498        }
27499      }
27500    "#,
27501      "@container not style(--responsive:true){.foo{color:red}}",
27502    );
27503    minify_test(
27504      r#"
27505      @container (inline-size > 45em) and style(--responsive: true) {
27506        .foo {
27507          color: red;
27508        }
27509      }
27510    "#,
27511      "@container (inline-size>45em) and style(--responsive:true){.foo{color:red}}",
27512    );
27513    minify_test(
27514      r#"
27515      @container style((accent-color: yellow) or (--bar: 10px)) {
27516        .foo {
27517          color: red;
27518        }
27519      }
27520    "#,
27521      "@container style((accent-color:#ff0) or (--bar:10px)){.foo{color:red}}",
27522    );
27523    minify_test(
27524      r#"
27525      @container style(not ((width: calc(10px + 20px)) and ((--bar: url(x))))) {
27526        .foo {
27527          color: red;
27528        }
27529      }
27530    "#,
27531      "@container style(not ((width:30px) and (--bar:url(x)))){.foo{color:red}}",
27532    );
27533    minify_test(
27534      r#"
27535      @container style(color: yellow !important) {
27536        .foo {
27537          color: red;
27538        }
27539      }
27540    "#,
27541      "@container style(color:yellow){.foo{color:red}}",
27542    );
27543    minify_test(
27544      r#"
27545      @container style(--foo:) {
27546        .foo {
27547          color: red;
27548        }
27549      }
27550    "#,
27551      "@container style(--foo:){.foo{color:red}}",
27552    );
27553    minify_test(
27554      r#"
27555      @container style(--foo: ) {
27556        .foo {
27557          color: red;
27558        }
27559      }
27560    "#,
27561      "@container style(--foo:){.foo{color:red}}",
27562    );
27563    minify_test(
27564      r#"
27565      @container style(--my-prop: foo - bar ()) {
27566        .foo {
27567          color: red;
27568        }
27569      }
27570    "#,
27571      "@container style(--my-prop:foo - bar ()){.foo{color:red}}",
27572    );
27573
27574    // Disallow 'none', 'not', 'and', 'or' as a `<container-name>`
27575    // https://github.com/w3c/csswg-drafts/issues/7203#issuecomment-1144257312
27576    // https://chromium-review.googlesource.com/c/chromium/src/+/3698402
27577    error_test(
27578      "@container none (width < 100vw) {}",
27579      ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("none".into())),
27580    );
27581
27582    error_test(
27583      "@container and (width < 100vw) {}",
27584      ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("and".into())),
27585    );
27586
27587    error_test(
27588      "@container or (width < 100vw) {}",
27589      ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("or".into())),
27590    );
27591
27592    // Disallow CSS wide keywords as a `<container-name>`
27593    error_test(
27594      "@container revert-layer (width < 100vw) {}",
27595      ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("revert-layer".into())),
27596    );
27597
27598    error_test(
27599      "@container initial (width < 100vw) {}",
27600      ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("initial".into())),
27601    );
27602
27603    // <ident> contains spaces
27604    // https://github.com/web-platform-tests/wpt/blob/39f0da08fbbe33d0582a35749b6dbf8bd067a52d/css/css-contain/container-queries/at-container-parsing.html#L160-L178
27605    error_test(
27606      "@container foo bar (width < 100vw) {}",
27607      ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("bar".into())),
27608    );
27609
27610    error_test("@container (inline-size <= foo) {}", ParserError::InvalidMediaQuery);
27611    error_test("@container (orientation <= 10px) {}", ParserError::InvalidMediaQuery);
27612
27613    error_test("@container style(width) {}", ParserError::EndOfInput);
27614    error_test(
27615      "@container style(style(--foo: bar)) {}",
27616      ParserError::UnexpectedToken(crate::properties::custom::Token::Function("style".into())),
27617    );
27618  }
27619
27620  #[test]
27621  fn test_unknown_at_rules() {
27622    minify_test("@foo;", "@foo;");
27623    minify_test("@foo bar;", "@foo bar;");
27624    minify_test("@foo (bar: baz);", "@foo (bar: baz);");
27625    test(
27626      r#"@foo test {
27627      div {
27628        color: red;
27629      }
27630    }"#,
27631      indoc! {r#"
27632      @foo test {
27633        div { color: red; }
27634      }
27635      "#},
27636    );
27637    minify_test(
27638      r#"@foo test {
27639      div {
27640        color: red;
27641      }
27642    }"#,
27643      "@foo test{div { color: red; }}",
27644    );
27645    minify_test(
27646      r#"@foo test {
27647        foo: bar;
27648      }"#,
27649      "@foo test{foo: bar;}",
27650    );
27651    test(
27652      r#"@foo {
27653        foo: bar;
27654      }"#,
27655      indoc! {r#"
27656      @foo {
27657        foo: bar;
27658      }
27659      "#},
27660    );
27661    minify_test(
27662      r#"@foo {
27663        foo: bar;
27664      }"#,
27665      "@foo{foo: bar;}",
27666    );
27667  }
27668
27669  #[test]
27670  fn test_resolution() {
27671    prefix_test(
27672      r#"
27673      @media (resolution: 1dppx) {
27674        body {
27675          background: red;
27676        }
27677      }
27678      "#,
27679      indoc! { r#"
27680      @media (resolution: 1dppx) {
27681        body {
27682          background: red;
27683        }
27684      }
27685      "#},
27686      Browsers {
27687        chrome: Some(50 << 16),
27688        ..Browsers::default()
27689      },
27690    );
27691
27692    prefix_test(
27693      r#"
27694      @media (resolution: 1dppx) {
27695        body {
27696          background: red;
27697        }
27698      }
27699      "#,
27700      indoc! { r#"
27701      @media (resolution: 1x) {
27702        body {
27703          background: red;
27704        }
27705      }
27706      "#},
27707      Browsers {
27708        chrome: Some(95 << 16),
27709        ..Browsers::default()
27710      },
27711    );
27712  }
27713
27714  #[test]
27715  fn test_environment() {
27716    minify_test(
27717      r#"
27718      @media (max-width: env(--branding-small)) {
27719        body {
27720          padding: env(--branding-padding);
27721        }
27722      }
27723    "#,
27724      "@media (width<=env(--branding-small)){body{padding:env(--branding-padding)}}",
27725    );
27726
27727    minify_test(
27728      r#"
27729      @media (max-width: env(--branding-small 1)) {
27730        body {
27731          padding: env(--branding-padding 2);
27732        }
27733      }
27734    "#,
27735      "@media (width<=env(--branding-small 1)){body{padding:env(--branding-padding 2)}}",
27736    );
27737
27738    minify_test(
27739      r#"
27740      @media (max-width: env(--branding-small 1, 20px)) {
27741        body {
27742          padding: env(--branding-padding 2, 20px);
27743        }
27744      }
27745    "#,
27746      "@media (width<=env(--branding-small 1,20px)){body{padding:env(--branding-padding 2,20px)}}",
27747    );
27748
27749    minify_test(
27750      r#"
27751      @media (max-width: env(safe-area-inset-top)) {
27752        body {
27753          padding: env(safe-area-inset-top);
27754        }
27755      }
27756    "#,
27757      "@media (width<=env(safe-area-inset-top)){body{padding:env(safe-area-inset-top)}}",
27758    );
27759
27760    minify_test(
27761      r#"
27762      @media (max-width: env(unknown)) {
27763        body {
27764          padding: env(unknown);
27765        }
27766      }
27767    "#,
27768      "@media (width<=env(unknown)){body{padding:env(unknown)}}",
27769    );
27770
27771    prefix_test(
27772      r#"
27773      .foo {
27774        color: env(--brand-color, color(display-p3 0 1 0));
27775      }
27776    "#,
27777      indoc! {r#"
27778      .foo {
27779        color: env(--brand-color, #00f942);
27780      }
27781
27782      @supports (color: color(display-p3 0 0 0)) {
27783        .foo {
27784          color: env(--brand-color, color(display-p3 0 1 0));
27785        }
27786      }
27787    "#},
27788      Browsers {
27789        safari: Some(15 << 16),
27790        chrome: Some(90 << 16),
27791        ..Browsers::default()
27792      },
27793    );
27794
27795    css_modules_test(
27796      r#"
27797      @media (max-width: env(--branding-small)) {
27798        .foo {
27799          color: env(--brand-color);
27800        }
27801      }
27802    "#,
27803      indoc! {r#"
27804      @media (width <= env(--EgL3uq_branding-small)) {
27805        .EgL3uq_foo {
27806          color: env(--EgL3uq_brand-color);
27807        }
27808      }
27809    "#},
27810      map! {
27811        "foo" => "EgL3uq_foo",
27812        "--brand-color" => "--EgL3uq_brand-color" referenced: true,
27813        "--branding-small" => "--EgL3uq_branding-small" referenced: true
27814      },
27815      HashMap::new(),
27816      crate::css_modules::Config {
27817        dashed_idents: true,
27818        ..Default::default()
27819      },
27820    );
27821  }
27822
27823  #[test]
27824  fn test_license_comments() {
27825    minify_test(
27826      r#"
27827      /*! Copyright 2023 Someone awesome */
27828      /* Some other comment */
27829      .foo {
27830        color: red;
27831      }
27832    "#,
27833      indoc! {r#"
27834      /*! Copyright 2023 Someone awesome */
27835      .foo{color:red}"#},
27836    );
27837
27838    minify_test(
27839      r#"
27840      /*! Copyright 2023 Someone awesome */
27841      /*! Copyright 2023 Someone else */
27842      .foo {
27843        color: red;
27844      }
27845    "#,
27846      indoc! {r#"
27847      /*! Copyright 2023 Someone awesome */
27848      /*! Copyright 2023 Someone else */
27849      .foo{color:red}"#},
27850    );
27851  }
27852
27853  #[test]
27854  fn test_starting_style() {
27855    minify_test(
27856      r#"
27857      @starting-style {
27858        h1 {
27859          background: yellow;
27860        }
27861      }
27862      "#,
27863      "@starting-style{h1{background:#ff0}}",
27864    );
27865    minify_test("@starting-style {}", "");
27866
27867    nesting_test(
27868      r#"
27869      h1 {
27870        background: red;
27871        @starting-style {
27872          background: yellow;
27873        }
27874      }
27875      "#,
27876      indoc! {r#"
27877      h1 {
27878        background: red;
27879      }
27880
27881      @starting-style {
27882        h1 {
27883          background: #ff0;
27884        }
27885      }
27886      "#},
27887    );
27888  }
27889
27890  #[test]
27891  fn test_color_scheme() {
27892    minify_test(".foo { color-scheme: normal; }", ".foo{color-scheme:normal}");
27893    minify_test(".foo { color-scheme: light; }", ".foo{color-scheme:light}");
27894    minify_test(".foo { color-scheme: dark; }", ".foo{color-scheme:dark}");
27895    minify_test(".foo { color-scheme: light dark; }", ".foo{color-scheme:light dark}");
27896    minify_test(".foo { color-scheme: dark light; }", ".foo{color-scheme:light dark}");
27897    minify_test(".foo { color-scheme: only light; }", ".foo{color-scheme:light only}");
27898    minify_test(".foo { color-scheme: only dark; }", ".foo{color-scheme:dark only}");
27899    minify_test(
27900      ".foo { color-scheme: dark light only; }",
27901      ".foo{color-scheme:light dark only}",
27902    );
27903    minify_test(".foo { color-scheme: foo bar light; }", ".foo{color-scheme:light}");
27904    minify_test(
27905      ".foo { color-scheme: only foo dark bar; }",
27906      ".foo{color-scheme:dark only}",
27907    );
27908    prefix_test(
27909      ".foo { color-scheme: dark; }",
27910      indoc! { r#"
27911      .foo {
27912        --lightningcss-light: ;
27913        --lightningcss-dark: initial;
27914        color-scheme: dark;
27915      }
27916      "#},
27917      Browsers {
27918        chrome: Some(90 << 16),
27919        ..Browsers::default()
27920      },
27921    );
27922    prefix_test(
27923      ".foo { color-scheme: light; }",
27924      indoc! { r#"
27925      .foo {
27926        --lightningcss-light: initial;
27927        --lightningcss-dark: ;
27928        color-scheme: light;
27929      }
27930      "#},
27931      Browsers {
27932        chrome: Some(90 << 16),
27933        ..Browsers::default()
27934      },
27935    );
27936    prefix_test(
27937      ".foo { color-scheme: light dark; }",
27938      indoc! { r#"
27939      .foo {
27940        --lightningcss-light: initial;
27941        --lightningcss-dark: ;
27942        color-scheme: light dark;
27943      }
27944
27945      @media (prefers-color-scheme: dark) {
27946        .foo {
27947          --lightningcss-light: ;
27948          --lightningcss-dark: initial;
27949        }
27950      }
27951      "#},
27952      Browsers {
27953        chrome: Some(90 << 16),
27954        ..Browsers::default()
27955      },
27956    );
27957    prefix_test(
27958      ".foo { color-scheme: light dark; }",
27959      indoc! { r#"
27960      .foo {
27961        color-scheme: light dark;
27962      }
27963      "#},
27964      Browsers {
27965        firefox: Some(120 << 16),
27966        ..Browsers::default()
27967      },
27968    );
27969
27970    minify_test(
27971      ".foo { color: light-dark(yellow, red); }",
27972      ".foo{color:light-dark(#ff0,red)}",
27973    );
27974    minify_test(
27975      ".foo { color: light-dark(light-dark(yellow, red), light-dark(yellow, red)); }",
27976      ".foo{color:light-dark(#ff0,red)}",
27977    );
27978    minify_test(
27979      ".foo { color: light-dark(rgb(0, 0, 255), hsl(120deg, 50%, 50%)); }",
27980      ".foo{color:light-dark(#00f,#40bf40)}",
27981    );
27982    prefix_test(
27983      ".foo { color: light-dark(oklch(40% 0.1268735435 34.568626), oklab(59.686% 0.1009 0.1192)); }",
27984      indoc! { r#"
27985      .foo {
27986        color: var(--lightningcss-light, #7e250f) var(--lightningcss-dark, #c65d07);
27987        color: var(--lightningcss-light, lab(29.2661% 38.2437 35.3889)) var(--lightningcss-dark, lab(52.2319% 40.1449 59.9171));
27988      }
27989      "#},
27990      Browsers {
27991        chrome: Some(90 << 16),
27992        ..Browsers::default()
27993      },
27994    );
27995    prefix_test(
27996      ".foo { color: light-dark(oklch(40% 0.1268735435 34.568626), oklab(59.686% 0.1009 0.1192)); }",
27997      indoc! { r#"
27998      .foo {
27999        color: light-dark(oklch(40% .126874 34.5686), oklab(59.686% .1009 .1192));
28000      }
28001      "#},
28002      Browsers {
28003        firefox: Some(120 << 16),
28004        ..Browsers::default()
28005      },
28006    );
28007    prefix_test(
28008      r#"
28009      .foo {
28010        box-shadow:
28011            oklch(100% 0 0deg / 50%) 0 0.63rem 0.94rem -0.19rem,
28012            currentColor 0 0.44rem 0.8rem -0.58rem;
28013      }
28014    "#,
28015      indoc! { r#"
28016      .foo {
28017        box-shadow: 0 .63rem .94rem -.19rem #ffffff80, 0 .44rem .8rem -.58rem;
28018        box-shadow: 0 .63rem .94rem -.19rem lab(100% 0 0 / .5), 0 .44rem .8rem -.58rem;
28019      }
28020      "#},
28021      Browsers {
28022        chrome: Some(95 << 16),
28023        ..Browsers::default()
28024      },
28025    );
28026    prefix_test(
28027      r#"
28028      .foo {
28029        box-shadow:
28030            oklch(100% 0 0deg / 50%) 0 0.63rem 0.94rem -0.19rem,
28031            currentColor 0 0.44rem 0.8rem -0.58rem;
28032      }
28033    "#,
28034      indoc! { r#"
28035      .foo {
28036        box-shadow: 0 .63rem .94rem -.19rem color(display-p3 1 1 1 / .5), 0 .44rem .8rem -.58rem;
28037        box-shadow: 0 .63rem .94rem -.19rem lab(100% 0 0 / .5), 0 .44rem .8rem -.58rem;
28038      }
28039      "#},
28040      Browsers {
28041        safari: Some(14 << 16),
28042        ..Browsers::default()
28043      },
28044    );
28045
28046    prefix_test(
28047      ".foo { color: light-dark(var(--light), var(--dark)); }",
28048      indoc! { r#"
28049      .foo {
28050        color: var(--lightningcss-light, var(--light)) var(--lightningcss-dark, var(--dark));
28051      }
28052      "#},
28053      Browsers {
28054        chrome: Some(90 << 16),
28055        ..Browsers::default()
28056      },
28057    );
28058    prefix_test(
28059      ".foo { color: rgb(from light-dark(yellow, red) r g b / 10%); }",
28060      indoc! { r#"
28061      .foo {
28062        color: var(--lightningcss-light, #ffff001a) var(--lightningcss-dark, #ff00001a);
28063      }
28064      "#},
28065      Browsers {
28066        chrome: Some(90 << 16),
28067        ..Browsers::default()
28068      },
28069    );
28070    prefix_test(
28071      ".foo { color: rgb(from light-dark(yellow, red) r g b / var(--alpha)); }",
28072      indoc! { r#"
28073      .foo {
28074        color: var(--lightningcss-light, rgb(255 255 0 / var(--alpha))) var(--lightningcss-dark, rgb(255 0 0 / var(--alpha)));
28075      }
28076      "#},
28077      Browsers {
28078        chrome: Some(90 << 16),
28079        ..Browsers::default()
28080      },
28081    );
28082    prefix_test(
28083      ".foo { color: color(from light-dark(yellow, red) srgb r g b / 10%); }",
28084      indoc! { r#"
28085      .foo {
28086        color: var(--lightningcss-light, #ffff001a) var(--lightningcss-dark, #ff00001a);
28087        color: var(--lightningcss-light, color(srgb 1 1 0 / .1)) var(--lightningcss-dark, color(srgb 1 0 0 / .1));
28088      }
28089      "#},
28090      Browsers {
28091        chrome: Some(90 << 16),
28092        ..Browsers::default()
28093      },
28094    );
28095    prefix_test(
28096      ".foo { color: color-mix(in srgb, light-dark(yellow, red), light-dark(red, pink)); }",
28097      indoc! { r#"
28098      .foo {
28099        color: var(--lightningcss-light, #ff8000) var(--lightningcss-dark, #ff6066);
28100      }
28101      "#},
28102      Browsers {
28103        chrome: Some(90 << 16),
28104        ..Browsers::default()
28105      },
28106    );
28107  }
28108
28109  #[test]
28110  fn test_all() {
28111    minify_test(".foo { all: initial; all: initial }", ".foo{all:initial}");
28112    minify_test(".foo { all: initial; all: revert }", ".foo{all:revert}");
28113    minify_test(".foo { background: red; all: revert-layer }", ".foo{all:revert-layer}");
28114    minify_test(
28115      ".foo { background: red; all: revert-layer; background: green }",
28116      ".foo{all:revert-layer;background:green}",
28117    );
28118    minify_test(
28119      ".foo { --test: red; all: revert-layer }",
28120      ".foo{--test:red;all:revert-layer}",
28121    );
28122    minify_test(
28123      ".foo { unicode-bidi: embed; all: revert-layer }",
28124      ".foo{all:revert-layer;unicode-bidi:embed}",
28125    );
28126    minify_test(
28127      ".foo { direction: rtl; all: revert-layer }",
28128      ".foo{all:revert-layer;direction:rtl}",
28129    );
28130    minify_test(
28131      ".foo { direction: rtl; all: revert-layer; direction: ltr }",
28132      ".foo{all:revert-layer;direction:ltr}",
28133    );
28134    minify_test(".foo { background: var(--foo); all: unset; }", ".foo{all:unset}");
28135    minify_test(
28136      ".foo { all: unset; background: var(--foo); }",
28137      ".foo{all:unset;background:var(--foo)}",
28138    );
28139  }
28140}