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    minify: bool,
186  ) {
187    let mut stylesheet = StyleSheet::parse(
188      &source,
189      ParserOptions {
190        filename: "test.css".into(),
191        css_modules: Some(config),
192        ..ParserOptions::default()
193      },
194    )
195    .unwrap();
196    stylesheet.minify(MinifyOptions::default()).unwrap();
197    let res = stylesheet
198      .to_css(PrinterOptions {
199        minify,
200        ..Default::default()
201      })
202      .unwrap();
203    assert_eq!(res.code, expected);
204    assert_eq!(res.exports.unwrap(), expected_exports);
205    assert_eq!(res.references.unwrap(), expected_references);
206  }
207
208  fn custom_media_test(source: &str, expected: &str) {
209    let mut stylesheet = StyleSheet::parse(
210      &source,
211      ParserOptions {
212        flags: ParserFlags::CUSTOM_MEDIA,
213        ..ParserOptions::default()
214      },
215    )
216    .unwrap();
217    stylesheet
218      .minify(MinifyOptions {
219        targets: Browsers {
220          chrome: Some(95 << 16),
221          ..Browsers::default()
222        }
223        .into(),
224        ..MinifyOptions::default()
225      })
226      .unwrap();
227    let res = stylesheet.to_css(PrinterOptions::default()).unwrap();
228    assert_eq!(res.code, expected);
229  }
230
231  fn error_test(source: &str, error: ParserError) {
232    let res = StyleSheet::parse(&source, ParserOptions::default());
233    match res {
234      Ok(_) => unreachable!(),
235      Err(e) => assert_eq!(e.kind, error),
236    }
237  }
238
239  fn css_modules_error_test(source: &str, error: ParserError) {
240    let res = StyleSheet::parse(
241      &source,
242      ParserOptions {
243        css_modules: Some(Default::default()),
244        ..Default::default()
245      },
246    );
247    match res {
248      Ok(_) => unreachable!(),
249      Err(e) => assert_eq!(e.kind, error),
250    }
251  }
252
253  macro_rules! map(
254    { $($key:expr => $name:literal $(referenced: $referenced: literal)? $($value:literal $(global: $global: literal)? $(from $from:literal)?)*),* } => {
255      {
256        #[allow(unused_mut)]
257        let mut m = HashMap::new();
258        $(
259          #[allow(unused_mut)]
260          let mut v = Vec::new();
261          #[allow(unused_macros)]
262          macro_rules! insert {
263            ($local:literal from $specifier:literal) => {
264              v.push(CssModuleReference::Dependency {
265                name: $local.into(),
266                specifier: $specifier.into()
267              });
268            };
269            ($local:literal global: $is_global: literal) => {
270              v.push(CssModuleReference::Global {
271                name: $local.into()
272              });
273            };
274            ($local:literal) => {
275              v.push(CssModuleReference::Local {
276                name: $local.into()
277              });
278            };
279          }
280          $(
281            insert!($value $(global: $global)? $(from $from)?);
282          )*
283
284          macro_rules! is_referenced {
285            ($ref: literal) => {
286              $ref
287            };
288            () => {
289              false
290            };
291          }
292
293          m.insert($key.into(), CssModuleExport {
294            name: $name.into(),
295            composes: v,
296            is_referenced: is_referenced!($($referenced)?)
297          });
298        )*
299        m
300      }
301    };
302  );
303
304  #[test]
305  pub fn test_border_spacing() {
306    minify_test(
307      r#"
308      .foo {
309        border-spacing: 0px;
310      }
311    "#,
312      indoc! {".foo{border-spacing:0}"
313      },
314    );
315    minify_test(
316      r#"
317      .foo {
318        border-spacing: 0px 0px;
319      }
320    "#,
321      indoc! {".foo{border-spacing:0}"
322      },
323    );
324
325    minify_test(
326      r#"
327      .foo {
328        border-spacing: 12px   0px;
329      }
330    "#,
331      indoc! {".foo{border-spacing:12px 0}"
332      },
333    );
334
335    minify_test(
336      r#"
337      .foo {
338        border-spacing: calc(3px * 2) calc(5px * 0);
339      }
340    "#,
341      indoc! {".foo{border-spacing:6px 0}"
342      },
343    );
344
345    minify_test(
346      r#"
347      .foo {
348        border-spacing: calc(3px * 2) max(0px, 8px);
349      }
350    "#,
351      indoc! {".foo{border-spacing:6px 8px}"
352      },
353    );
354
355    // TODO: The `<length>` in border-spacing cannot have a negative value,
356    // we may need to implement NonNegativeLength like Servo does.
357    // Servo Code: https://github.com/servo/servo/blob/08bc2d53579c9ab85415d4363888881b91df073b/components/style/values/specified/length.rs#L875
358    // CSSWG issue: https://lists.w3.org/Archives/Public/www-style/2008Sep/0161.html
359    // `border-spacing = <length> <length>?`
360    minify_test(
361      r#"
362      .foo {
363        border-spacing: -20px;
364      }
365    "#,
366      indoc! {".foo{border-spacing:-20px}"
367      },
368    );
369  }
370
371  #[test]
372  pub fn test_border() {
373    test(
374      r#"
375      .foo {
376        border-left: 2px solid red;
377        border-right: 2px solid red;
378        border-bottom: 2px solid red;
379        border-top: 2px solid red;
380      }
381    "#,
382      indoc! {r#"
383      .foo {
384        border: 2px solid red;
385      }
386    "#
387      },
388    );
389
390    test(
391      r#"
392      .foo {
393        border-left-color: red;
394        border-right-color: red;
395        border-bottom-color: red;
396        border-top-color: red;
397      }
398    "#,
399      indoc! {r#"
400      .foo {
401        border-color: red;
402      }
403    "#
404      },
405    );
406
407    test(
408      r#"
409      .foo {
410        border-left-width: thin;
411        border-right-width: thin;
412        border-bottom-width: thin;
413        border-top-width: thin;
414      }
415    "#,
416      indoc! {r#"
417      .foo {
418        border-width: thin;
419      }
420    "#
421      },
422    );
423
424    test(
425      r#"
426      .foo {
427        border-left-style: dotted;
428        border-right-style: dotted;
429        border-bottom-style: dotted;
430        border-top-style: dotted;
431      }
432    "#,
433      indoc! {r#"
434      .foo {
435        border-style: dotted;
436      }
437    "#
438      },
439    );
440
441    test(
442      r#"
443      .foo {
444        border-left-width: thin;
445        border-left-style: dotted;
446        border-left-color: red;
447      }
448    "#,
449      indoc! {r#"
450      .foo {
451        border-left: thin dotted red;
452      }
453    "#
454      },
455    );
456
457    test(
458      r#"
459      .foo {
460        border-left-width: thick;
461        border-left: thin dotted red;
462      }
463    "#,
464      indoc! {r#"
465      .foo {
466        border-left: thin dotted red;
467      }
468    "#
469      },
470    );
471
472    test(
473      r#"
474      .foo {
475        border-left-width: thick;
476        border: thin dotted red;
477      }
478    "#,
479      indoc! {r#"
480      .foo {
481        border: thin dotted red;
482      }
483    "#
484      },
485    );
486
487    test(
488      r#"
489      .foo {
490        border: thin dotted red;
491        border-right-width: thick;
492      }
493    "#,
494      indoc! {r#"
495      .foo {
496        border: thin dotted red;
497        border-right-width: thick;
498      }
499    "#
500      },
501    );
502
503    test(
504      r#"
505      .foo {
506        border: thin dotted red;
507        border-right: thick dotted red;
508      }
509    "#,
510      indoc! {r#"
511      .foo {
512        border: thin dotted red;
513        border-right-width: thick;
514      }
515    "#
516      },
517    );
518
519    test(
520      r#"
521      .foo {
522        border: thin dotted red;
523        border-right-width: thick;
524        border-right-style: solid;
525      }
526    "#,
527      indoc! {r#"
528      .foo {
529        border: thin dotted red;
530        border-right: thick solid red;
531      }
532    "#
533      },
534    );
535
536    test(
537      r#"
538      .foo {
539        border-top: thin dotted red;
540        border-block-start: thick solid green;
541      }
542    "#,
543      indoc! {r#"
544      .foo {
545        border-top: thin dotted red;
546        border-block-start: thick solid green;
547      }
548    "#
549      },
550    );
551
552    test(
553      r#"
554      .foo {
555        border: thin dotted red;
556        border-block-start-width: thick;
557        border-left-width: medium;
558      }
559    "#,
560      indoc! {r#"
561      .foo {
562        border: thin dotted red;
563        border-block-start-width: thick;
564        border-left-width: medium;
565      }
566    "#
567      },
568    );
569
570    test(
571      r#"
572      .foo {
573        border-block-start: thin dotted red;
574        border-inline-end: thin dotted red;
575      }
576    "#,
577      indoc! {r#"
578      .foo {
579        border-block-start: thin dotted red;
580        border-inline-end: thin dotted red;
581      }
582    "#
583      },
584    );
585
586    test(
587      r#"
588      .foo {
589        border-block-start-width: thin;
590        border-block-start-style: dotted;
591        border-block-start-color: red;
592        border-inline-end: thin dotted red;
593      }
594    "#,
595      indoc! {r#"
596      .foo {
597        border-block-start: thin dotted red;
598        border-inline-end: thin dotted red;
599      }
600    "#
601      },
602    );
603
604    test(
605      r#"
606      .foo {
607        border-block-start: thin dotted red;
608        border-block-end: thin dotted red;
609      }
610    "#,
611      indoc! {r#"
612      .foo {
613        border-block: thin dotted red;
614      }
615    "#
616      },
617    );
618
619    minify_test(
620      r#"
621      .foo {
622        border: none;
623      }
624    "#,
625      indoc! {".foo{border:none}"
626      },
627    );
628
629    minify_test(".foo { border-width: 0 0 1px; }", ".foo{border-width:0 0 1px}");
630    test(
631      r#"
632      .foo {
633        border-block-width: 1px;
634        border-inline-width: 1px;
635      }
636    "#,
637      indoc! {r#"
638      .foo {
639        border-width: 1px;
640      }
641    "#
642      },
643    );
644    test(
645      r#"
646      .foo {
647        border-block-start-width: 1px;
648        border-block-end-width: 1px;
649        border-inline-start-width: 1px;
650        border-inline-end-width: 1px;
651      }
652    "#,
653      indoc! {r#"
654      .foo {
655        border-width: 1px;
656      }
657    "#
658      },
659    );
660    test(
661      r#"
662      .foo {
663        border-block-start-width: 1px;
664        border-block-end-width: 1px;
665        border-inline-start-width: 2px;
666        border-inline-end-width: 2px;
667      }
668    "#,
669      indoc! {r#"
670      .foo {
671        border-block-width: 1px;
672        border-inline-width: 2px;
673      }
674    "#
675      },
676    );
677    test(
678      r#"
679      .foo {
680        border-block-start-width: 1px;
681        border-block-end-width: 1px;
682        border-inline-start-width: 2px;
683        border-inline-end-width: 3px;
684      }
685    "#,
686      indoc! {r#"
687      .foo {
688        border-block-width: 1px;
689        border-inline-width: 2px 3px;
690      }
691    "#
692      },
693    );
694
695    minify_test(
696      ".foo { border-bottom: 1px solid var(--spectrum-global-color-gray-200)}",
697      ".foo{border-bottom:1px solid var(--spectrum-global-color-gray-200)}",
698    );
699    test(
700      r#"
701      .foo {
702        border-width: 0;
703        border-bottom: var(--test, 1px) solid;
704      }
705    "#,
706      indoc! {r#"
707      .foo {
708        border-width: 0;
709        border-bottom: var(--test, 1px) solid;
710      }
711    "#
712      },
713    );
714
715    test(
716      r#"
717      .foo {
718        border: 1px solid black;
719        border-width: 1px 1px 0 0;
720      }
721    "#,
722      indoc! {r#"
723      .foo {
724        border: 1px solid #000;
725        border-width: 1px 1px 0 0;
726      }
727    "#},
728    );
729
730    test(
731      r#"
732      .foo {
733        border-top: 1px solid black;
734        border-bottom: 1px solid black;
735        border-left: 2px solid black;
736        border-right: 2px solid black;
737      }
738    "#,
739      indoc! {r#"
740      .foo {
741        border: 1px solid #000;
742        border-width: 1px 2px;
743      }
744    "#},
745    );
746
747    test(
748      r#"
749      .foo {
750        border-top: 1px solid black;
751        border-bottom: 1px solid black;
752        border-left: 2px solid black;
753        border-right: 1px solid black;
754      }
755    "#,
756      indoc! {r#"
757      .foo {
758        border: 1px solid #000;
759        border-left-width: 2px;
760      }
761    "#},
762    );
763
764    test(
765      r#"
766      .foo {
767        border-top: 1px solid black;
768        border-bottom: 1px solid black;
769        border-left: 1px solid red;
770        border-right: 1px solid red;
771      }
772    "#,
773      indoc! {r#"
774      .foo {
775        border: 1px solid #000;
776        border-color: #000 red;
777      }
778    "#},
779    );
780
781    test(
782      r#"
783      .foo {
784        border-block-start: 1px solid black;
785        border-block-end: 1px solid black;
786        border-inline-start: 1px solid red;
787        border-inline-end: 1px solid red;
788      }
789    "#,
790      indoc! {r#"
791      .foo {
792        border: 1px solid #000;
793        border-inline-color: red;
794      }
795    "#},
796    );
797
798    test(
799      r#"
800      .foo {
801        border-block-start: 1px solid black;
802        border-block-end: 1px solid black;
803        border-inline-start: 2px solid black;
804        border-inline-end: 2px solid black;
805      }
806    "#,
807      indoc! {r#"
808      .foo {
809        border: 1px solid #000;
810        border-inline-width: 2px;
811      }
812    "#},
813    );
814
815    test(
816      r#"
817      .foo {
818        border-block-start: 1px solid black;
819        border-block-end: 1px solid black;
820        border-inline-start: 2px solid red;
821        border-inline-end: 2px solid red;
822      }
823    "#,
824      indoc! {r#"
825      .foo {
826        border: 1px solid #000;
827        border-inline: 2px solid red;
828      }
829    "#},
830    );
831
832    test(
833      r#"
834      .foo {
835        border-block-start: 1px solid black;
836        border-block-end: 1px solid black;
837        border-inline-start: 2px solid red;
838        border-inline-end: 3px solid red;
839      }
840    "#,
841      indoc! {r#"
842      .foo {
843        border: 1px solid #000;
844        border-inline-start: 2px solid red;
845        border-inline-end: 3px solid red;
846      }
847    "#},
848    );
849
850    test(
851      r#"
852      .foo {
853        border-block-start: 2px solid black;
854        border-block-end: 1px solid black;
855        border-inline-start: 2px solid red;
856        border-inline-end: 2px solid red;
857      }
858    "#,
859      indoc! {r#"
860      .foo {
861        border: 2px solid red;
862        border-block-start-color: #000;
863        border-block-end: 1px solid #000;
864      }
865    "#},
866    );
867
868    test(
869      r#"
870      .foo {
871        border-block-start: 2px solid red;
872        border-block-end: 1px solid red;
873        border-inline-start: 2px solid red;
874        border-inline-end: 2px solid red;
875      }
876    "#,
877      indoc! {r#"
878      .foo {
879        border: 2px solid red;
880        border-block-end-width: 1px;
881      }
882    "#},
883    );
884
885    test(
886      r#"
887      .foo {
888        border-block-start: 2px solid red;
889        border-block-end: 2px solid red;
890        border-inline-start: 2px solid red;
891        border-inline-end: 1px solid red;
892      }
893    "#,
894      indoc! {r#"
895      .foo {
896        border: 2px solid red;
897        border-inline-end-width: 1px;
898      }
899    "#},
900    );
901
902    test(
903      r#"
904      .foo {
905        border: 1px solid currentColor;
906      }
907    "#,
908      indoc! {r#"
909      .foo {
910        border: 1px solid;
911      }
912    "#
913      },
914    );
915
916    minify_test(
917      r#"
918      .foo {
919        border: 1px solid currentColor;
920      }
921    "#,
922      ".foo{border:1px solid}",
923    );
924
925    prefix_test(
926      r#"
927      .foo {
928        border-block: 2px solid red;
929      }
930    "#,
931      indoc! {r#"
932      .foo {
933        border-top: 2px solid red;
934        border-bottom: 2px solid red;
935      }
936    "#
937      },
938      Browsers {
939        safari: Some(8 << 16),
940        ..Browsers::default()
941      },
942    );
943
944    prefix_test(
945      r#"
946      .foo {
947        border-block-start: 2px solid red;
948      }
949    "#,
950      indoc! {r#"
951      .foo {
952        border-top: 2px solid red;
953      }
954    "#
955      },
956      Browsers {
957        safari: Some(8 << 16),
958        ..Browsers::default()
959      },
960    );
961
962    prefix_test(
963      r#"
964      .foo {
965        border-block-end: 2px solid red;
966      }
967    "#,
968      indoc! {r#"
969      .foo {
970        border-bottom: 2px solid red;
971      }
972    "#
973      },
974      Browsers {
975        safari: Some(8 << 16),
976        ..Browsers::default()
977      },
978    );
979
980    prefix_test(
981      r#"
982      .foo {
983        border-inline: 2px solid red;
984      }
985    "#,
986      indoc! {r#"
987      .foo {
988        border-left: 2px solid red;
989        border-right: 2px solid red;
990      }
991    "#
992      },
993      Browsers {
994        safari: Some(8 << 16),
995        ..Browsers::default()
996      },
997    );
998
999    prefix_test(
1000      r#"
1001      .foo {
1002        border-block-width: 2px;
1003      }
1004    "#,
1005      indoc! {r#"
1006      .foo {
1007        border-block-start-width: 2px;
1008        border-block-end-width: 2px;
1009      }
1010    "#
1011      },
1012      Browsers {
1013        safari: Some(13 << 16),
1014        ..Browsers::default()
1015      },
1016    );
1017
1018    prefix_test(
1019      r#"
1020      .foo {
1021        border-block-width: 2px;
1022      }
1023    "#,
1024      indoc! {r#"
1025      .foo {
1026        border-block-width: 2px;
1027      }
1028    "#
1029      },
1030      Browsers {
1031        safari: Some(15 << 16),
1032        ..Browsers::default()
1033      },
1034    );
1035
1036    prefix_test(
1037      r#"
1038      .foo {
1039        border-inline-start: 2px solid red;
1040      }
1041    "#,
1042      indoc! {r#"
1043      .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))) {
1044        border-left: 2px solid red;
1045      }
1046
1047      .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))) {
1048        border-left: 2px solid red;
1049      }
1050
1051      .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)) {
1052        border-right: 2px solid red;
1053      }
1054
1055      .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)) {
1056        border-right: 2px solid red;
1057      }
1058    "#
1059      },
1060      Browsers {
1061        safari: Some(8 << 16),
1062        ..Browsers::default()
1063      },
1064    );
1065
1066    prefix_test(
1067      r#"
1068      .foo {
1069        border-inline-start-width: 2px;
1070      }
1071    "#,
1072      indoc! {r#"
1073      .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))) {
1074        border-left-width: 2px;
1075      }
1076
1077      .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))) {
1078        border-left-width: 2px;
1079      }
1080
1081      .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)) {
1082        border-right-width: 2px;
1083      }
1084
1085      .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)) {
1086        border-right-width: 2px;
1087      }
1088    "#
1089      },
1090      Browsers {
1091        safari: Some(8 << 16),
1092        ..Browsers::default()
1093      },
1094    );
1095
1096    prefix_test(
1097      r#"
1098      .foo {
1099        border-inline-end: 2px solid red;
1100      }
1101    "#,
1102      indoc! {r#"
1103      .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))) {
1104        border-right: 2px solid red;
1105      }
1106
1107      .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))) {
1108        border-right: 2px solid red;
1109      }
1110
1111      .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)) {
1112        border-left: 2px solid red;
1113      }
1114
1115      .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)) {
1116        border-left: 2px solid red;
1117      }
1118    "#
1119      },
1120      Browsers {
1121        safari: Some(8 << 16),
1122        ..Browsers::default()
1123      },
1124    );
1125
1126    prefix_test(
1127      r#"
1128      .foo {
1129        border-inline-start: 2px solid red;
1130        border-inline-end: 5px solid green;
1131      }
1132    "#,
1133      indoc! {r#"
1134      .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))) {
1135        border-left: 2px solid red;
1136        border-right: 5px solid green;
1137      }
1138
1139      .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))) {
1140        border-left: 2px solid red;
1141        border-right: 5px solid green;
1142      }
1143
1144      .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)) {
1145        border-left: 5px solid green;
1146        border-right: 2px solid red;
1147      }
1148
1149      .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)) {
1150        border-left: 5px solid green;
1151        border-right: 2px solid red;
1152      }
1153    "#
1154      },
1155      Browsers {
1156        safari: Some(8 << 16),
1157        ..Browsers::default()
1158      },
1159    );
1160
1161    prefix_test(
1162      r#"
1163      .foo {
1164        border-inline-start: 2px solid red;
1165        border-inline-end: 5px solid green;
1166      }
1167
1168      .bar {
1169        border-inline-start: 1px dotted gray;
1170        border-inline-end: 1px solid black;
1171      }
1172    "#,
1173      indoc! {r#"
1174      .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))) {
1175        border-left: 2px solid red;
1176        border-right: 5px solid green;
1177      }
1178
1179      .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))) {
1180        border-left: 2px solid red;
1181        border-right: 5px solid green;
1182      }
1183
1184      .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)) {
1185        border-left: 5px solid green;
1186        border-right: 2px solid red;
1187      }
1188
1189      .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)) {
1190        border-left: 5px solid green;
1191        border-right: 2px solid red;
1192      }
1193
1194      .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))) {
1195        border-left: 1px dotted gray;
1196        border-right: 1px solid #000;
1197      }
1198
1199      .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))) {
1200        border-left: 1px dotted gray;
1201        border-right: 1px solid #000;
1202      }
1203
1204      .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)) {
1205        border-left: 1px solid #000;
1206        border-right: 1px dotted gray;
1207      }
1208
1209      .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)) {
1210        border-left: 1px solid #000;
1211        border-right: 1px dotted gray;
1212      }
1213    "#
1214      },
1215      Browsers {
1216        safari: Some(8 << 16),
1217        ..Browsers::default()
1218      },
1219    );
1220
1221    prefix_test(
1222      r#"
1223      .foo {
1224        border-inline-width: 2px;
1225      }
1226    "#,
1227      indoc! {r#"
1228      .foo {
1229        border-left-width: 2px;
1230        border-right-width: 2px;
1231      }
1232    "#
1233      },
1234      Browsers {
1235        safari: Some(8 << 16),
1236        ..Browsers::default()
1237      },
1238    );
1239
1240    prefix_test(
1241      r#"
1242      .foo {
1243        border-inline-width: 2px;
1244      }
1245    "#,
1246      indoc! {r#"
1247      .foo {
1248        border-left-width: 2px;
1249        border-right-width: 2px;
1250      }
1251    "#
1252      },
1253      Browsers {
1254        safari: Some(8 << 16),
1255        ..Browsers::default()
1256      },
1257    );
1258
1259    prefix_test(
1260      r#"
1261      .foo {
1262        border-inline-style: solid;
1263      }
1264    "#,
1265      indoc! {r#"
1266      .foo {
1267        border-left-style: solid;
1268        border-right-style: solid;
1269      }
1270    "#
1271      },
1272      Browsers {
1273        safari: Some(8 << 16),
1274        ..Browsers::default()
1275      },
1276    );
1277
1278    prefix_test(
1279      r#"
1280      .foo {
1281        border-inline-color: red;
1282      }
1283    "#,
1284      indoc! {r#"
1285      .foo {
1286        border-left-color: red;
1287        border-right-color: red;
1288      }
1289    "#
1290      },
1291      Browsers {
1292        safari: Some(8 << 16),
1293        ..Browsers::default()
1294      },
1295    );
1296
1297    prefix_test(
1298      r#"
1299      .foo {
1300        border-inline-end: var(--test);
1301      }
1302    "#,
1303      indoc! {r#"
1304      .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))) {
1305        border-right: var(--test);
1306      }
1307
1308      .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))) {
1309        border-right: var(--test);
1310      }
1311
1312      .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)) {
1313        border-left: var(--test);
1314      }
1315
1316      .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)) {
1317        border-left: var(--test);
1318      }
1319    "#
1320      },
1321      Browsers {
1322        safari: Some(8 << 16),
1323        ..Browsers::default()
1324      },
1325    );
1326
1327    prefix_test(
1328      r#"
1329      .foo {
1330        border-inline-start: var(--start);
1331        border-inline-end: var(--end);
1332      }
1333    "#,
1334      indoc! {r#"
1335      .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))) {
1336        border-left: var(--start);
1337        border-right: var(--end);
1338      }
1339
1340      .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))) {
1341        border-left: var(--start);
1342        border-right: var(--end);
1343      }
1344
1345      .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)) {
1346        border-right: var(--start);
1347        border-left: var(--end);
1348      }
1349
1350      .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)) {
1351        border-right: var(--start);
1352        border-left: var(--end);
1353      }
1354    "#
1355      },
1356      Browsers {
1357        safari: Some(8 << 16),
1358        ..Browsers::default()
1359      },
1360    );
1361
1362    for prop in &[
1363      "border-inline-start-color",
1364      "border-inline-end-color",
1365      "border-block-start-color",
1366      "border-block-end-color",
1367      "border-top-color",
1368      "border-bottom-color",
1369      "border-left-color",
1370      "border-right-color",
1371      "border-color",
1372      "border-block-color",
1373      "border-inline-color",
1374    ] {
1375      prefix_test(
1376        &format!(
1377          r#"
1378        .foo {{
1379          {}: lab(40% 56.6 39);
1380        }}
1381      "#,
1382          prop
1383        ),
1384        &format!(
1385          indoc! {r#"
1386        .foo {{
1387          {}: #b32323;
1388          {}: lab(40% 56.6 39);
1389        }}
1390      "#},
1391          prop, prop
1392        ),
1393        Browsers {
1394          chrome: Some(90 << 16),
1395          ..Browsers::default()
1396        },
1397      );
1398    }
1399
1400    for prop in &[
1401      "border",
1402      "border-inline",
1403      "border-block",
1404      "border-left",
1405      "border-right",
1406      "border-top",
1407      "border-bottom",
1408      "border-block-start",
1409      "border-block-end",
1410      "border-inline-start",
1411      "border-inline-end",
1412    ] {
1413      prefix_test(
1414        &format!(
1415          r#"
1416        .foo {{
1417          {}: 2px solid lab(40% 56.6 39);
1418        }}
1419      "#,
1420          prop
1421        ),
1422        &format!(
1423          indoc! {r#"
1424        .foo {{
1425          {}: 2px solid #b32323;
1426          {}: 2px solid lab(40% 56.6 39);
1427        }}
1428      "#},
1429          prop, prop
1430        ),
1431        Browsers {
1432          chrome: Some(90 << 16),
1433          ..Browsers::default()
1434        },
1435      );
1436    }
1437
1438    for prop in &[
1439      "border",
1440      "border-inline",
1441      "border-block",
1442      "border-left",
1443      "border-right",
1444      "border-top",
1445      "border-bottom",
1446      "border-block-start",
1447      "border-block-end",
1448      "border-inline-start",
1449      "border-inline-end",
1450    ] {
1451      prefix_test(
1452        &format!(
1453          r#"
1454        .foo {{
1455          {}: var(--border-width) solid lab(40% 56.6 39);
1456        }}
1457      "#,
1458          prop
1459        ),
1460        &format!(
1461          indoc! {r#"
1462        .foo {{
1463          {}: var(--border-width) solid #b32323;
1464        }}
1465
1466        @supports (color: lab(0% 0 0)) {{
1467          .foo {{
1468            {}: var(--border-width) solid lab(40% 56.6 39);
1469          }}
1470        }}
1471      "#},
1472          prop, prop
1473        ),
1474        Browsers {
1475          chrome: Some(90 << 16),
1476          ..Browsers::default()
1477        },
1478      );
1479    }
1480
1481    prefix_test(
1482      r#"
1483      .foo {
1484        border-inline-start-color: lab(40% 56.6 39);
1485      }
1486    "#,
1487      indoc! {r#"
1488      .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))) {
1489        border-left-color: #b32323;
1490        border-left-color: lab(40% 56.6 39);
1491      }
1492
1493      .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))) {
1494        border-left-color: #b32323;
1495        border-left-color: lab(40% 56.6 39);
1496      }
1497
1498      .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)) {
1499        border-right-color: #b32323;
1500        border-right-color: lab(40% 56.6 39);
1501      }
1502
1503      .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)) {
1504        border-right-color: #b32323;
1505        border-right-color: lab(40% 56.6 39);
1506      }
1507    "#},
1508      Browsers {
1509        safari: Some(8 << 16),
1510        ..Browsers::default()
1511      },
1512    );
1513
1514    prefix_test(
1515      r#"
1516      .foo {
1517        border-inline-end-color: lab(40% 56.6 39);
1518      }
1519    "#,
1520      indoc! {r#"
1521      .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))) {
1522        border-right-color: #b32323;
1523        border-right-color: lab(40% 56.6 39);
1524      }
1525
1526      .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))) {
1527        border-right-color: #b32323;
1528        border-right-color: lab(40% 56.6 39);
1529      }
1530
1531      .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)) {
1532        border-left-color: #b32323;
1533        border-left-color: lab(40% 56.6 39);
1534      }
1535
1536      .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)) {
1537        border-left-color: #b32323;
1538        border-left-color: lab(40% 56.6 39);
1539      }
1540    "#},
1541      Browsers {
1542        safari: Some(8 << 16),
1543        ..Browsers::default()
1544      },
1545    );
1546
1547    prefix_test(
1548      r#"
1549      .foo {
1550        border-inline-start-color: lab(40% 56.6 39);
1551        border-inline-end-color: lch(50.998% 135.363 338);
1552      }
1553    "#,
1554      indoc! {r#"
1555      .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))) {
1556        border-left-color: #b32323;
1557        border-left-color: lab(40% 56.6 39);
1558        border-right-color: #ee00be;
1559        border-right-color: lch(50.998% 135.363 338);
1560      }
1561
1562      .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))) {
1563        border-left-color: #b32323;
1564        border-left-color: lab(40% 56.6 39);
1565        border-right-color: #ee00be;
1566        border-right-color: lch(50.998% 135.363 338);
1567      }
1568
1569      .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)) {
1570        border-left-color: #ee00be;
1571        border-left-color: lch(50.998% 135.363 338);
1572        border-right-color: #b32323;
1573        border-right-color: lab(40% 56.6 39);
1574      }
1575
1576      .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)) {
1577        border-left-color: #ee00be;
1578        border-left-color: lch(50.998% 135.363 338);
1579        border-right-color: #b32323;
1580        border-right-color: lab(40% 56.6 39);
1581      }
1582    "#},
1583      Browsers {
1584        safari: Some(8 << 16),
1585        ..Browsers::default()
1586      },
1587    );
1588
1589    prefix_test(
1590      r#"
1591      .foo {
1592        border-inline-start-color: lab(40% 56.6 39);
1593        border-inline-end-color: lch(50.998% 135.363 338);
1594      }
1595    "#,
1596      indoc! {r#"
1597      .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))) {
1598        border-left-color: #b32323;
1599        border-left-color: color(display-p3 .643308 .192455 .167712);
1600        border-left-color: lab(40% 56.6 39);
1601        border-right-color: #ee00be;
1602        border-right-color: color(display-p3 .972962 -.362078 .804206);
1603        border-right-color: lch(50.998% 135.363 338);
1604      }
1605
1606      .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)) {
1607        border-left-color: #ee00be;
1608        border-left-color: color(display-p3 .972962 -.362078 .804206);
1609        border-left-color: lch(50.998% 135.363 338);
1610        border-right-color: #b32323;
1611        border-right-color: color(display-p3 .643308 .192455 .167712);
1612        border-right-color: lab(40% 56.6 39);
1613      }
1614    "#},
1615      Browsers {
1616        chrome: Some(8 << 16),
1617        safari: Some(14 << 16),
1618        ..Browsers::default()
1619      },
1620    );
1621
1622    prefix_test(
1623      r#"
1624      .foo {
1625        border-inline-start: 2px solid lab(40% 56.6 39);
1626      }
1627    "#,
1628      indoc! {r#"
1629      .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))) {
1630        border-left: 2px solid #b32323;
1631        border-left: 2px solid lab(40% 56.6 39);
1632      }
1633
1634      .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))) {
1635        border-left: 2px solid #b32323;
1636        border-left: 2px solid lab(40% 56.6 39);
1637      }
1638
1639      .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)) {
1640        border-right: 2px solid #b32323;
1641        border-right: 2px solid lab(40% 56.6 39);
1642      }
1643
1644      .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)) {
1645        border-right: 2px solid #b32323;
1646        border-right: 2px solid lab(40% 56.6 39);
1647      }
1648    "#},
1649      Browsers {
1650        safari: Some(8 << 16),
1651        ..Browsers::default()
1652      },
1653    );
1654
1655    prefix_test(
1656      r#"
1657      .foo {
1658        border-inline-end: 2px solid lab(40% 56.6 39);
1659      }
1660    "#,
1661      indoc! {r#"
1662      .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))) {
1663        border-right: 2px solid #b32323;
1664        border-right: 2px solid lab(40% 56.6 39);
1665      }
1666
1667      .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))) {
1668        border-right: 2px solid #b32323;
1669        border-right: 2px solid lab(40% 56.6 39);
1670      }
1671
1672      .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)) {
1673        border-left: 2px solid #b32323;
1674        border-left: 2px solid lab(40% 56.6 39);
1675      }
1676
1677      .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)) {
1678        border-left: 2px solid #b32323;
1679        border-left: 2px solid lab(40% 56.6 39);
1680      }
1681    "#},
1682      Browsers {
1683        safari: Some(8 << 16),
1684        ..Browsers::default()
1685      },
1686    );
1687
1688    prefix_test(
1689      r#"
1690      .foo {
1691        border-inline-end: var(--border-width) solid lab(40% 56.6 39);
1692      }
1693    "#,
1694      indoc! {r#"
1695      .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))) {
1696        border-right: var(--border-width) solid #b32323;
1697      }
1698
1699      .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))) {
1700        border-right: var(--border-width) solid #b32323;
1701      }
1702
1703      @supports (color: lab(0% 0 0)) {
1704        .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))) {
1705          border-right: var(--border-width) solid lab(40% 56.6 39);
1706        }
1707      }
1708
1709      .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)) {
1710        border-left: var(--border-width) solid #b32323;
1711      }
1712
1713      .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)) {
1714        border-left: var(--border-width) solid #b32323;
1715      }
1716
1717      @supports (color: lab(0% 0 0)) {
1718        .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)) {
1719          border-left: var(--border-width) solid lab(40% 56.6 39);
1720        }
1721      }
1722    "#},
1723      Browsers {
1724        safari: Some(8 << 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-start: 2px solid red;
1739        border-inline-end: 2px solid red;
1740      }
1741    "#
1742      },
1743      Browsers {
1744        safari: Some(13 << 16),
1745        ..Browsers::default()
1746      },
1747    );
1748
1749    prefix_test(
1750      r#"
1751      .foo {
1752        border-inline-start: 2px solid red;
1753        border-inline-end: 2px solid red;
1754      }
1755    "#,
1756      indoc! {r#"
1757      .foo {
1758        border-inline: 2px solid red;
1759      }
1760    "#
1761      },
1762      Browsers {
1763        safari: Some(15 << 16),
1764        ..Browsers::default()
1765      },
1766    );
1767
1768    prefix_test(
1769      r#"
1770      .foo {
1771        border-width: 22px;
1772        border-width: max(2cqw, 22px);
1773      }
1774    "#,
1775      indoc! {r#"
1776      .foo {
1777        border-width: 22px;
1778        border-width: max(2cqw, 22px);
1779      }
1780    "#
1781      },
1782      Browsers {
1783        safari: Some(14 << 16),
1784        ..Browsers::default()
1785      },
1786    );
1787    prefix_test(
1788      r#"
1789      .foo {
1790        border-width: 22px;
1791        border-width: max(2cqw, 22px);
1792      }
1793    "#,
1794      indoc! {r#"
1795      .foo {
1796        border-width: max(2cqw, 22px);
1797      }
1798    "#
1799      },
1800      Browsers {
1801        safari: Some(16 << 16),
1802        ..Browsers::default()
1803      },
1804    );
1805    prefix_test(
1806      r#"
1807      .foo {
1808        border-color: #4263eb;
1809        border-color: color(display-p3 0 .5 1);
1810      }
1811    "#,
1812      indoc! {r#"
1813      .foo {
1814        border-color: #4263eb;
1815        border-color: color(display-p3 0 .5 1);
1816      }
1817    "#
1818      },
1819      Browsers {
1820        chrome: Some(99 << 16),
1821        ..Browsers::default()
1822      },
1823    );
1824    prefix_test(
1825      r#"
1826      .foo {
1827        border-color: #4263eb;
1828        border-color: color(display-p3 0 .5 1);
1829      }
1830    "#,
1831      indoc! {r#"
1832      .foo {
1833        border-color: color(display-p3 0 .5 1);
1834      }
1835    "#
1836      },
1837      Browsers {
1838        safari: Some(16 << 16),
1839        ..Browsers::default()
1840      },
1841    );
1842    prefix_test(
1843      r#"
1844      .foo {
1845        border: 1px solid #4263eb;
1846        border-color: color(display-p3 0 .5 1);
1847      }
1848    "#,
1849      indoc! {r#"
1850      .foo {
1851        border: 1px solid #4263eb;
1852        border-color: color(display-p3 0 .5 1);
1853      }
1854    "#
1855      },
1856      Browsers {
1857        chrome: Some(99 << 16),
1858        ..Browsers::default()
1859      },
1860    );
1861    prefix_test(
1862      r#"
1863      .foo {
1864        border: 1px solid #4263eb;
1865        border-color: color(display-p3 0 .5 1);
1866      }
1867    "#,
1868      indoc! {r#"
1869      .foo {
1870        border: 1px solid color(display-p3 0 .5 1);
1871      }
1872    "#
1873      },
1874      Browsers {
1875        safari: Some(16 << 16),
1876        ..Browsers::default()
1877      },
1878    );
1879    prefix_test(
1880      r#"
1881      .foo {
1882        border-color: var(--fallback);
1883        border-color: color(display-p3 0 .5 1);
1884      }
1885    "#,
1886      indoc! {r#"
1887      .foo {
1888        border-color: var(--fallback);
1889        border-color: color(display-p3 0 .5 1);
1890      }
1891    "#
1892      },
1893      Browsers {
1894        chrome: Some(99 << 16),
1895        ..Browsers::default()
1896      },
1897    );
1898  }
1899
1900  #[test]
1901  pub fn test_border_image() {
1902    test(
1903      r#"
1904      .foo {
1905        border-image: url(test.png) 60;
1906      }
1907    "#,
1908      indoc! {r#"
1909      .foo {
1910        border-image: url("test.png") 60;
1911      }
1912    "#
1913      },
1914    );
1915
1916    test(
1917      r#"
1918      .foo {
1919        border-image: url(test.png) 60;
1920        border-image-source: url(foo.png);
1921      }
1922    "#,
1923      indoc! {r#"
1924      .foo {
1925        border-image: url("foo.png") 60;
1926      }
1927    "#
1928      },
1929    );
1930
1931    test(
1932      r#"
1933      .foo {
1934        border-image-source: url(foo.png);
1935        border-image-slice: 10 40 10 40 fill;
1936        border-image-width: 10px;
1937        border-image-outset: 0;
1938        border-image-repeat: round round;
1939      }
1940    "#,
1941      indoc! {r#"
1942      .foo {
1943        border-image: url("foo.png") 10 40 fill / 10px round;
1944      }
1945    "#
1946      },
1947    );
1948
1949    test(
1950      r#"
1951      .foo {
1952        border-image: url(foo.png) 60;
1953        border-image-source: var(--test);
1954      }
1955    "#,
1956      indoc! {r#"
1957      .foo {
1958        border-image: url("foo.png") 60;
1959        border-image-source: var(--test);
1960      }
1961    "#
1962      },
1963    );
1964
1965    test(
1966      r#"
1967      .foo {
1968        -webkit-border-image: url("test.png") 60;
1969      }
1970    "#,
1971      indoc! {r#"
1972      .foo {
1973        -webkit-border-image: url("test.png") 60;
1974      }
1975    "#
1976      },
1977    );
1978
1979    test(
1980      r#"
1981      .foo {
1982        -webkit-border-image: url("test.png") 60;
1983        border-image: url("test.png") 60;
1984      }
1985    "#,
1986      indoc! {r#"
1987      .foo {
1988        -webkit-border-image: url("test.png") 60;
1989        border-image: url("test.png") 60;
1990      }
1991    "#
1992      },
1993    );
1994
1995    test(
1996      r#"
1997      .foo {
1998        -webkit-border-image: url("test.png") 60;
1999        border-image-source: url(foo.png);
2000      }
2001    "#,
2002      indoc! {r#"
2003      .foo {
2004        -webkit-border-image: url("test.png") 60;
2005        border-image-source: url("foo.png");
2006      }
2007    "#
2008      },
2009    );
2010
2011    test(
2012      r#"
2013      .foo {
2014        border: 1px solid red;
2015        border-image: url(test.png) 60;
2016      }
2017    "#,
2018      indoc! {r#"
2019      .foo {
2020        border: 1px solid red;
2021        border-image: url("test.png") 60;
2022      }
2023    "#
2024      },
2025    );
2026
2027    test(
2028      r#"
2029      .foo {
2030        border-image: url(test.png) 60;
2031        border: 1px solid red;
2032      }
2033    "#,
2034      indoc! {r#"
2035      .foo {
2036        border: 1px solid red;
2037      }
2038    "#
2039      },
2040    );
2041
2042    test(
2043      r#"
2044      .foo {
2045        border: 1px solid red;
2046        border-image: var(--border-image);
2047      }
2048    "#,
2049      indoc! {r#"
2050      .foo {
2051        border: 1px solid red;
2052        border-image: var(--border-image);
2053      }
2054    "#
2055      },
2056    );
2057
2058    prefix_test(
2059      r#"
2060      .foo {
2061        border-image: url("test.png") 60;
2062      }
2063    "#,
2064      indoc! {r#"
2065      .foo {
2066        -webkit-border-image: url("test.png") 60;
2067        -moz-border-image: url("test.png") 60;
2068        -o-border-image: url("test.png") 60;
2069        border-image: url("test.png") 60;
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: url(foo.png) 10 40 fill / 10px round;
2085      }
2086    "#,
2087      indoc! {r#"
2088      .foo {
2089        border-image: url("foo.png") 10 40 fill / 10px round;
2090      }
2091    "#
2092      },
2093      Browsers {
2094        safari: Some(4 << 16),
2095        firefox: Some(4 << 16),
2096        opera: Some(12 << 16),
2097        ..Browsers::default()
2098      },
2099    );
2100
2101    prefix_test(
2102      r#"
2103      .foo {
2104        border-image: var(--test) 60;
2105      }
2106    "#,
2107      indoc! {r#"
2108      .foo {
2109        -webkit-border-image: var(--test) 60;
2110        -moz-border-image: var(--test) 60;
2111        -o-border-image: var(--test) 60;
2112        border-image: var(--test) 60;
2113      }
2114    "#
2115      },
2116      Browsers {
2117        safari: Some(4 << 16),
2118        firefox: Some(4 << 16),
2119        opera: Some(12 << 16),
2120        ..Browsers::default()
2121      },
2122    );
2123
2124    prefix_test(
2125      r#"
2126      .foo {
2127        -webkit-border-image: url(foo.png) 60;
2128        -moz-border-image: url(foo.png) 60;
2129        -o-border-image: url(foo.png) 60;
2130        border-image: url(foo.png) 60;
2131      }
2132    "#,
2133      indoc! {r#"
2134      .foo {
2135        border-image: url("foo.png") 60;
2136      }
2137    "#
2138      },
2139      Browsers {
2140        chrome: Some(15 << 16),
2141        ..Browsers::default()
2142      },
2143    );
2144
2145    prefix_test(
2146      r#"
2147      .foo {
2148        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 60;
2149      }
2150    "#,
2151      indoc! {r#"
2152      .foo {
2153        -webkit-border-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0f0e), to(#7773ff)) 60;
2154        -webkit-border-image: -webkit-linear-gradient(#ff0f0e, #7773ff) 60;
2155        border-image: linear-gradient(#ff0f0e, #7773ff) 60;
2156        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 60;
2157      }
2158    "#
2159      },
2160      Browsers {
2161        chrome: Some(8 << 16),
2162        ..Browsers::default()
2163      },
2164    );
2165
2166    prefix_test(
2167      r#"
2168      .foo {
2169        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 60;
2170      }
2171    "#,
2172      indoc! {r#"
2173      .foo {
2174        -webkit-border-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0f0e), to(#7773ff)) 60;
2175        -webkit-border-image: -webkit-linear-gradient(#ff0f0e, #7773ff) 60;
2176        -moz-border-image: -moz-linear-gradient(#ff0f0e, #7773ff) 60;
2177        border-image: linear-gradient(#ff0f0e, #7773ff) 60;
2178        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 60;
2179      }
2180    "#
2181      },
2182      Browsers {
2183        chrome: Some(8 << 16),
2184        firefox: Some(4 << 16),
2185        ..Browsers::default()
2186      },
2187    );
2188
2189    prefix_test(
2190      r#"
2191      .foo {
2192        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 60;
2193      }
2194    "#,
2195      indoc! {r#"
2196      .foo {
2197        border-image: -webkit-linear-gradient(#ff0f0e, #7773ff) 60;
2198        border-image: -moz-linear-gradient(#ff0f0e, #7773ff) 60;
2199        border-image: linear-gradient(#ff0f0e, #7773ff) 60;
2200        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 60;
2201      }
2202    "#
2203      },
2204      Browsers {
2205        chrome: Some(15 << 16),
2206        firefox: Some(15 << 16),
2207        ..Browsers::default()
2208      },
2209    );
2210
2211    prefix_test(
2212      r#"
2213      .foo {
2214        border-image-source: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
2215      }
2216    "#,
2217      indoc! {r#"
2218      .foo {
2219        border-image-source: -webkit-linear-gradient(#ff0f0e, #7773ff);
2220        border-image-source: linear-gradient(#ff0f0e, #7773ff);
2221        border-image-source: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
2222      }
2223    "#
2224      },
2225      Browsers {
2226        chrome: Some(15 << 16),
2227        ..Browsers::default()
2228      },
2229    );
2230
2231    prefix_test(
2232      r#"
2233      .foo {
2234        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) var(--foo);
2235      }
2236    "#,
2237      indoc! {r#"
2238      .foo {
2239        border-image: linear-gradient(#ff0f0e, #7773ff) var(--foo);
2240      }
2241
2242      @supports (color: lab(0% 0 0)) {
2243        .foo {
2244          border-image: linear-gradient(lab(56.208% 94.4644 98.8928), lab(51% 70.4544 -115.586)) var(--foo);
2245        }
2246      }
2247    "#
2248      },
2249      Browsers {
2250        chrome: Some(90 << 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(red, green);
2265        border-image-source: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
2266      }
2267    "#
2268      },
2269      Browsers {
2270        chrome: Some(95 << 16),
2271        ..Browsers::default()
2272      },
2273    );
2274
2275    prefix_test(
2276      r#"
2277      .foo {
2278        border-image-source: linear-gradient(red, green);
2279        border-image-source: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
2280      }
2281    "#,
2282      indoc! {r#"
2283      .foo {
2284        border-image-source: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
2285      }
2286    "#
2287      },
2288      Browsers {
2289        chrome: Some(112 << 16),
2290        ..Browsers::default()
2291      },
2292    );
2293
2294    prefix_test(
2295      r#"
2296      .foo {
2297        border-image: linear-gradient(red, green);
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: linear-gradient(red, green);
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: var(--fallback);
2318        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
2319      }
2320    "#,
2321      indoc! {r#"
2322      .foo {
2323        border-image: var(--fallback);
2324        border-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
2325      }
2326    "#
2327      },
2328      Browsers {
2329        chrome: Some(95 << 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("fallback.png") 10 40 fill / 10px;
2344        border-image: url("main.png") 10 40 fill / 10px space;
2345      }
2346    "#
2347      },
2348      Browsers {
2349        chrome: Some(50 << 16),
2350        ..Browsers::default()
2351      },
2352    );
2353
2354    prefix_test(
2355      r#"
2356      .foo {
2357        border-image: url("fallback.png") 10 40 fill / 10px;
2358        border-image: url("main.png") 10 40 fill / 10px space;
2359      }
2360    "#,
2361      indoc! {r#"
2362      .foo {
2363        border-image: url("main.png") 10 40 fill / 10px space;
2364      }
2365    "#
2366      },
2367      Browsers {
2368        chrome: Some(56 << 16),
2369        ..Browsers::default()
2370      },
2371    );
2372
2373    minify_test(".foo { border: none green }", ".foo{border:green}");
2374  }
2375
2376  #[test]
2377  pub fn test_border_radius() {
2378    test(
2379      r#"
2380      .foo {
2381        border-radius: 10px 100px 10px 100px;
2382      }
2383    "#,
2384      indoc! {r#"
2385      .foo {
2386        border-radius: 10px 100px;
2387      }
2388    "#
2389      },
2390    );
2391
2392    test(
2393      r#"
2394      .foo {
2395        border-radius: 10px 100px 10px 100px / 120px 120px;
2396      }
2397    "#,
2398      indoc! {r#"
2399      .foo {
2400        border-radius: 10px 100px / 120px;
2401      }
2402    "#
2403      },
2404    );
2405
2406    test(
2407      r#"
2408      .foo {
2409        border-top-left-radius: 10px 120px;
2410        border-top-right-radius: 100px 120px;
2411        border-bottom-right-radius: 100px 120px;
2412        border-bottom-left-radius: 10px 120px;
2413      }
2414    "#,
2415      indoc! {r#"
2416      .foo {
2417        border-radius: 10px 100px 100px 10px / 120px;
2418      }
2419    "#
2420      },
2421    );
2422
2423    test(
2424      r#"
2425      .foo {
2426        border-top-left-radius: 4px 2px;
2427        border-top-right-radius: 3px 4px;
2428        border-bottom-right-radius: 6px 2px;
2429        border-bottom-left-radius: 3px 4px;
2430      }
2431    "#,
2432      indoc! {r#"
2433      .foo {
2434        border-radius: 4px 3px 6px / 2px 4px;
2435      }
2436    "#
2437      },
2438    );
2439
2440    test(
2441      r#"
2442      .foo {
2443        border-top-left-radius: 1% 2%;
2444        border-top-right-radius: 3% 4%;
2445        border-bottom-right-radius: 5% 6%;
2446        border-bottom-left-radius: 7% 8%;
2447      }
2448    "#,
2449      indoc! {r#"
2450      .foo {
2451        border-radius: 1% 3% 5% 7% / 2% 4% 6% 8%;
2452      }
2453    "#
2454      },
2455    );
2456
2457    test(
2458      r#"
2459      .foo {
2460        border-radius: 10px 100px 10px 100px / 120px 120px;
2461        border-start-start-radius: 10px;
2462      }
2463    "#,
2464      indoc! {r#"
2465      .foo {
2466        border-radius: 10px 100px / 120px;
2467        border-start-start-radius: 10px;
2468      }
2469    "#
2470      },
2471    );
2472
2473    test(
2474      r#"
2475      .foo {
2476        border-start-start-radius: 10px;
2477        border-radius: 10px 100px 10px 100px / 120px 120px;
2478      }
2479    "#,
2480      indoc! {r#"
2481      .foo {
2482        border-radius: 10px 100px / 120px;
2483      }
2484    "#
2485      },
2486    );
2487
2488    test(
2489      r#"
2490      .foo {
2491        border-top-left-radius: 10px 120px;
2492        border-top-right-radius: 100px 120px;
2493        border-start-start-radius: 10px;
2494        border-bottom-right-radius: 100px 120px;
2495        border-bottom-left-radius: 10px 120px;
2496      }
2497    "#,
2498      indoc! {r#"
2499      .foo {
2500        border-top-left-radius: 10px 120px;
2501        border-top-right-radius: 100px 120px;
2502        border-start-start-radius: 10px;
2503        border-bottom-right-radius: 100px 120px;
2504        border-bottom-left-radius: 10px 120px;
2505      }
2506    "#
2507      },
2508    );
2509
2510    test(
2511      r#"
2512      .foo {
2513        border-radius: 10px;
2514        border-top-left-radius: 20px;
2515      }
2516    "#,
2517      indoc! {r#"
2518      .foo {
2519        border-radius: 20px 10px 10px;
2520      }
2521    "#
2522      },
2523    );
2524
2525    test(
2526      r#"
2527      .foo {
2528        border-radius: 10px;
2529        border-top-left-radius: var(--test);
2530      }
2531    "#,
2532      indoc! {r#"
2533      .foo {
2534        border-radius: 10px;
2535        border-top-left-radius: var(--test);
2536      }
2537    "#
2538      },
2539    );
2540
2541    test(
2542      r#"
2543      .foo {
2544        -webkit-border-radius: 10px 100px 10px 100px;
2545        -moz-border-radius: 10px 100px 10px 100px;
2546        border-radius: 10px 100px 10px 100px;
2547      }
2548    "#,
2549      indoc! {r#"
2550      .foo {
2551        -webkit-border-radius: 10px 100px;
2552        -moz-border-radius: 10px 100px;
2553        border-radius: 10px 100px;
2554      }
2555    "#
2556      },
2557    );
2558
2559    test(
2560      r#"
2561      .foo {
2562        -webkit-border-radius: 10px 100px 10px 100px;
2563        -moz-border-radius: 20px;
2564        border-radius: 30px;
2565      }
2566    "#,
2567      indoc! {r#"
2568      .foo {
2569        -webkit-border-radius: 10px 100px;
2570        -moz-border-radius: 20px;
2571        border-radius: 30px;
2572      }
2573    "#
2574      },
2575    );
2576
2577    test(
2578      r#"
2579      .foo {
2580        -webkit-border-top-left-radius: 10px;
2581        -moz-border-top-left-radius: 10px;
2582        border-top-left-radius: 10px;
2583      }
2584    "#,
2585      indoc! {r#"
2586      .foo {
2587        -webkit-border-top-left-radius: 10px;
2588        -moz-border-top-left-radius: 10px;
2589        border-top-left-radius: 10px;
2590      }
2591    "#
2592      },
2593    );
2594
2595    prefix_test(
2596      r#"
2597      .foo {
2598        border-radius: 30px;
2599      }
2600    "#,
2601      indoc! {r#"
2602      .foo {
2603        -webkit-border-radius: 30px;
2604        -moz-border-radius: 30px;
2605        border-radius: 30px;
2606      }
2607    "#
2608      },
2609      Browsers {
2610        safari: Some(4 << 16),
2611        firefox: Some(3 << 16),
2612        ..Browsers::default()
2613      },
2614    );
2615
2616    prefix_test(
2617      r#"
2618      .foo {
2619        border-top-left-radius: 30px;
2620      }
2621    "#,
2622      indoc! {r#"
2623      .foo {
2624        -webkit-border-top-left-radius: 30px;
2625        -moz-border-top-left-radius: 30px;
2626        border-top-left-radius: 30px;
2627      }
2628    "#
2629      },
2630      Browsers {
2631        safari: Some(4 << 16),
2632        firefox: Some(3 << 16),
2633        ..Browsers::default()
2634      },
2635    );
2636
2637    prefix_test(
2638      r#"
2639      .foo {
2640        -webkit-border-radius: 30px;
2641        -moz-border-radius: 30px;
2642        border-radius: 30px;
2643      }
2644    "#,
2645      indoc! {r#"
2646      .foo {
2647        border-radius: 30px;
2648      }
2649    "#
2650      },
2651      Browsers {
2652        safari: Some(14 << 16),
2653        firefox: Some(46 << 16),
2654        ..Browsers::default()
2655      },
2656    );
2657
2658    prefix_test(
2659      r#"
2660      .foo {
2661        -webkit-border-top-left-radius: 30px;
2662        -moz-border-top-left-radius: 30px;
2663        border-top-left-radius: 30px;
2664      }
2665    "#,
2666      indoc! {r#"
2667      .foo {
2668        border-top-left-radius: 30px;
2669      }
2670    "#
2671      },
2672      Browsers {
2673        safari: Some(14 << 16),
2674        firefox: Some(46 << 16),
2675        ..Browsers::default()
2676      },
2677    );
2678
2679    prefix_test(
2680      r#"
2681      .foo {
2682        -webkit-border-radius: 30px;
2683        -moz-border-radius: 30px;
2684      }
2685    "#,
2686      indoc! {r#"
2687      .foo {
2688        -webkit-border-radius: 30px;
2689        -moz-border-radius: 30px;
2690      }
2691    "#
2692      },
2693      Browsers {
2694        safari: Some(14 << 16),
2695        firefox: Some(46 << 16),
2696        ..Browsers::default()
2697      },
2698    );
2699
2700    prefix_test(
2701      r#"
2702      .foo {
2703        -webkit-border-top-left-radius: 30px;
2704        -moz-border-top-right-radius: 30px;
2705        border-bottom-right-radius: 30px;
2706        border-bottom-left-radius: 30px;
2707      }
2708    "#,
2709      indoc! {r#"
2710      .foo {
2711        -webkit-border-top-left-radius: 30px;
2712        -moz-border-top-right-radius: 30px;
2713        border-bottom-right-radius: 30px;
2714        border-bottom-left-radius: 30px;
2715      }
2716    "#
2717      },
2718      Browsers {
2719        safari: Some(14 << 16),
2720        firefox: Some(46 << 16),
2721        ..Browsers::default()
2722      },
2723    );
2724
2725    prefix_test(
2726      r#"
2727      .foo {
2728        border-radius: var(--test);
2729      }
2730    "#,
2731      indoc! {r#"
2732      .foo {
2733        -webkit-border-radius: var(--test);
2734        -moz-border-radius: var(--test);
2735        border-radius: var(--test);
2736      }
2737    "#
2738      },
2739      Browsers {
2740        safari: Some(4 << 16),
2741        firefox: Some(3 << 16),
2742        ..Browsers::default()
2743      },
2744    );
2745
2746    prefix_test(
2747      r#"
2748      .foo {
2749        border-start-start-radius: 5px;
2750      }
2751    "#,
2752      indoc! {r#"
2753      .foo:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
2754        border-top-left-radius: 5px;
2755      }
2756
2757      .foo:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
2758        border-top-right-radius: 5px;
2759      }
2760    "#
2761      },
2762      Browsers {
2763        safari: Some(12 << 16),
2764        ..Browsers::default()
2765      },
2766    );
2767
2768    prefix_test(
2769      r#"
2770      .foo {
2771        border-start-start-radius: 5px;
2772        border-start-end-radius: 10px;
2773      }
2774    "#,
2775      indoc! {r#"
2776      .foo:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
2777        border-top-left-radius: 5px;
2778        border-top-right-radius: 10px;
2779      }
2780
2781      .foo:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
2782        border-top-left-radius: 10px;
2783        border-top-right-radius: 5px;
2784      }
2785    "#
2786      },
2787      Browsers {
2788        safari: Some(12 << 16),
2789        ..Browsers::default()
2790      },
2791    );
2792
2793    prefix_test(
2794      r#"
2795      .foo {
2796        border-end-end-radius: 10px;
2797        border-end-start-radius: 5px;
2798      }
2799    "#,
2800      indoc! {r#"
2801      .foo:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
2802        border-bottom-right-radius: 10px;
2803        border-bottom-left-radius: 5px;
2804      }
2805
2806      .foo:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
2807        border-bottom-right-radius: 5px;
2808        border-bottom-left-radius: 10px;
2809      }
2810    "#
2811      },
2812      Browsers {
2813        safari: Some(12 << 16),
2814        ..Browsers::default()
2815      },
2816    );
2817
2818    prefix_test(
2819      r#"
2820      .foo {
2821        border-start-start-radius: var(--radius);
2822      }
2823    "#,
2824      indoc! {r#"
2825      .foo:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
2826        border-top-left-radius: var(--radius);
2827      }
2828
2829      .foo:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
2830        border-top-right-radius: var(--radius);
2831      }
2832    "#
2833      },
2834      Browsers {
2835        safari: Some(12 << 16),
2836        ..Browsers::default()
2837      },
2838    );
2839
2840    prefix_test(
2841      r#"
2842      .foo {
2843        border-start-start-radius: var(--start);
2844        border-start-end-radius: var(--end);
2845      }
2846    "#,
2847      indoc! {r#"
2848      .foo:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
2849        border-top-left-radius: var(--start);
2850        border-top-right-radius: var(--end);
2851      }
2852
2853      .foo:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
2854        border-top-right-radius: var(--start);
2855        border-top-left-radius: var(--end);
2856      }
2857    "#
2858      },
2859      Browsers {
2860        safari: Some(12 << 16),
2861        ..Browsers::default()
2862      },
2863    );
2864  }
2865
2866  #[test]
2867  pub fn test_outline() {
2868    test(
2869      r#"
2870      .foo {
2871        outline-width: 2px;
2872        outline-style: solid;
2873        outline-color: blue;
2874      }
2875    "#,
2876      indoc! {r#"
2877      .foo {
2878        outline: 2px solid #00f;
2879      }
2880    "#
2881      },
2882    );
2883
2884    test(
2885      r#"
2886      .foo {
2887        outline: 2px solid blue;
2888      }
2889    "#,
2890      indoc! {r#"
2891      .foo {
2892        outline: 2px solid #00f;
2893      }
2894    "#
2895      },
2896    );
2897
2898    test(
2899      r#"
2900      .foo {
2901        outline: 2px solid red;
2902        outline-color: blue;
2903      }
2904    "#,
2905      indoc! {r#"
2906      .foo {
2907        outline: 2px solid #00f;
2908      }
2909    "#
2910      },
2911    );
2912
2913    test(
2914      r#"
2915      .foo {
2916        outline: 2px solid yellow;
2917        outline-color: var(--color);
2918      }
2919    "#,
2920      indoc! {r#"
2921      .foo {
2922        outline: 2px solid #ff0;
2923        outline-color: var(--color);
2924      }
2925    "#
2926      },
2927    );
2928
2929    prefix_test(
2930      ".foo { outline-color: lab(40% 56.6 39) }",
2931      indoc! { r#"
2932        .foo {
2933          outline-color: #b32323;
2934          outline-color: lab(40% 56.6 39);
2935        }
2936      "#},
2937      Browsers {
2938        chrome: Some(90 << 16),
2939        ..Browsers::default()
2940      },
2941    );
2942
2943    prefix_test(
2944      ".foo { outline: 2px solid lab(40% 56.6 39) }",
2945      indoc! { r#"
2946        .foo {
2947          outline: 2px solid #b32323;
2948          outline: 2px solid lab(40% 56.6 39);
2949        }
2950      "#},
2951      Browsers {
2952        chrome: Some(90 << 16),
2953        ..Browsers::default()
2954      },
2955    );
2956
2957    prefix_test(
2958      ".foo { outline: var(--width) solid lab(40% 56.6 39) }",
2959      indoc! { r#"
2960        .foo {
2961          outline: var(--width) solid #b32323;
2962        }
2963
2964        @supports (color: lab(0% 0 0)) {
2965          .foo {
2966            outline: var(--width) solid lab(40% 56.6 39);
2967          }
2968        }
2969      "#},
2970      Browsers {
2971        chrome: Some(90 << 16),
2972        ..Browsers::default()
2973      },
2974    );
2975  }
2976
2977  #[test]
2978  pub fn test_margin() {
2979    test(
2980      r#"
2981      .foo {
2982        margin-left: 10px;
2983        margin-right: 10px;
2984        margin-top: 20px;
2985        margin-bottom: 20px;
2986      }
2987    "#,
2988      indoc! {r#"
2989      .foo {
2990        margin: 20px 10px;
2991      }
2992    "#
2993      },
2994    );
2995
2996    test(
2997      r#"
2998      .foo {
2999        margin-block-start: 15px;
3000        margin-block-end: 15px;
3001      }
3002    "#,
3003      indoc! {r#"
3004      .foo {
3005        margin-block: 15px;
3006      }
3007    "#
3008      },
3009    );
3010
3011    test(
3012      r#"
3013      .foo {
3014        margin-left: 10px;
3015        margin-right: 10px;
3016        margin-inline-start: 15px;
3017        margin-inline-end: 15px;
3018        margin-top: 20px;
3019        margin-bottom: 20px;
3020
3021      }
3022    "#,
3023      indoc! {r#"
3024      .foo {
3025        margin-left: 10px;
3026        margin-right: 10px;
3027        margin-inline: 15px;
3028        margin-top: 20px;
3029        margin-bottom: 20px;
3030      }
3031    "#
3032      },
3033    );
3034
3035    test(
3036      r#"
3037      .foo {
3038        margin: 10px;
3039        margin-top: 20px;
3040      }
3041    "#,
3042      indoc! {r#"
3043      .foo {
3044        margin: 20px 10px 10px;
3045      }
3046    "#
3047      },
3048    );
3049
3050    test(
3051      r#"
3052      .foo {
3053        margin: 10px;
3054        margin-top: var(--top);
3055      }
3056    "#,
3057      indoc! {r#"
3058      .foo {
3059        margin: 10px;
3060        margin-top: var(--top);
3061      }
3062    "#
3063      },
3064    );
3065
3066    prefix_test(
3067      r#"
3068      .foo {
3069        margin-inline-start: 2px;
3070      }
3071    "#,
3072      indoc! {r#"
3073      .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))) {
3074        margin-left: 2px;
3075      }
3076
3077      .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))) {
3078        margin-left: 2px;
3079      }
3080
3081      .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)) {
3082        margin-right: 2px;
3083      }
3084
3085      .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)) {
3086        margin-right: 2px;
3087      }
3088    "#
3089      },
3090      Browsers {
3091        safari: Some(8 << 16),
3092        ..Browsers::default()
3093      },
3094    );
3095
3096    prefix_test(
3097      r#"
3098      .foo {
3099        margin-inline-start: 2px;
3100        margin-inline-end: 4px;
3101      }
3102    "#,
3103      indoc! {r#"
3104      .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))) {
3105        margin-left: 2px;
3106        margin-right: 4px;
3107      }
3108
3109      .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))) {
3110        margin-left: 2px;
3111        margin-right: 4px;
3112      }
3113
3114      .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)) {
3115        margin-left: 4px;
3116        margin-right: 2px;
3117      }
3118
3119      .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)) {
3120        margin-left: 4px;
3121        margin-right: 2px;
3122      }
3123    "#
3124      },
3125      Browsers {
3126        safari: Some(8 << 16),
3127        ..Browsers::default()
3128      },
3129    );
3130
3131    prefix_test(
3132      r#"
3133      .foo {
3134        margin-inline: 2px;
3135      }
3136    "#,
3137      indoc! {r#"
3138      .foo {
3139        margin-left: 2px;
3140        margin-right: 2px;
3141      }
3142    "#
3143      },
3144      Browsers {
3145        safari: Some(8 << 16),
3146        ..Browsers::default()
3147      },
3148    );
3149
3150    prefix_test(
3151      r#"
3152      .foo {
3153        margin-block-start: 2px;
3154      }
3155    "#,
3156      indoc! {r#"
3157      .foo {
3158        margin-top: 2px;
3159      }
3160    "#
3161      },
3162      Browsers {
3163        safari: Some(8 << 16),
3164        ..Browsers::default()
3165      },
3166    );
3167
3168    prefix_test(
3169      r#"
3170      .foo {
3171        margin-block-end: 2px;
3172      }
3173    "#,
3174      indoc! {r#"
3175      .foo {
3176        margin-bottom: 2px;
3177      }
3178    "#
3179      },
3180      Browsers {
3181        safari: Some(8 << 16),
3182        ..Browsers::default()
3183      },
3184    );
3185
3186    prefix_test(
3187      r#"
3188      .foo {
3189        margin-inline-start: 2px;
3190        margin-inline-end: 2px;
3191      }
3192    "#,
3193      indoc! {r#"
3194      .foo {
3195        margin-inline-start: 2px;
3196        margin-inline-end: 2px;
3197      }
3198    "#
3199      },
3200      Browsers {
3201        safari: Some(13 << 16),
3202        ..Browsers::default()
3203      },
3204    );
3205
3206    prefix_test(
3207      r#"
3208      .foo {
3209        margin-inline: 2px;
3210      }
3211    "#,
3212      indoc! {r#"
3213      .foo {
3214        margin-inline-start: 2px;
3215        margin-inline-end: 2px;
3216      }
3217    "#
3218      },
3219      Browsers {
3220        safari: Some(13 << 16),
3221        ..Browsers::default()
3222      },
3223    );
3224
3225    prefix_test(
3226      r#"
3227      .foo {
3228        margin-inline-start: 2px;
3229        margin-inline-end: 2px;
3230      }
3231    "#,
3232      indoc! {r#"
3233      .foo {
3234        margin-inline: 2px;
3235      }
3236    "#
3237      },
3238      Browsers {
3239        safari: Some(15 << 16),
3240        ..Browsers::default()
3241      },
3242    );
3243
3244    prefix_test(
3245      r#"
3246      .foo {
3247        margin-inline: 2px;
3248      }
3249    "#,
3250      indoc! {r#"
3251      .foo {
3252        margin-inline: 2px;
3253      }
3254    "#
3255      },
3256      Browsers {
3257        safari: Some(15 << 16),
3258        ..Browsers::default()
3259      },
3260    );
3261  }
3262
3263  #[test]
3264  fn test_length() {
3265    for prop in &[
3266      "margin-right",
3267      "margin",
3268      "padding-right",
3269      "padding",
3270      "width",
3271      "height",
3272      "min-height",
3273      "max-height",
3274      "line-height",
3275      "border-radius",
3276    ] {
3277      prefix_test(
3278        &format!(
3279          r#"
3280        .foo {{
3281          {}: 22px;
3282          {}: max(4%, 22px);
3283        }}
3284      "#,
3285          prop, prop
3286        ),
3287        &format!(
3288          indoc! {r#"
3289        .foo {{
3290          {}: 22px;
3291          {}: max(4%, 22px);
3292        }}
3293      "#
3294          },
3295          prop, prop
3296        ),
3297        Browsers {
3298          safari: Some(10 << 16),
3299          ..Browsers::default()
3300        },
3301      );
3302
3303      prefix_test(
3304        &format!(
3305          r#"
3306        .foo {{
3307          {}: 22px;
3308          {}: max(4%, 22px);
3309        }}
3310      "#,
3311          prop, prop
3312        ),
3313        &format!(
3314          indoc! {r#"
3315        .foo {{
3316          {}: max(4%, 22px);
3317        }}
3318      "#
3319          },
3320          prop
3321        ),
3322        Browsers {
3323          safari: Some(14 << 16),
3324          ..Browsers::default()
3325        },
3326      );
3327
3328      prefix_test(
3329        &format!(
3330          r#"
3331        .foo {{
3332          {}: 22px;
3333          {}: max(2cqw, 22px);
3334        }}
3335      "#,
3336          prop, prop
3337        ),
3338        &format!(
3339          indoc! {r#"
3340        .foo {{
3341          {}: 22px;
3342          {}: max(2cqw, 22px);
3343        }}
3344      "#
3345          },
3346          prop, prop
3347        ),
3348        Browsers {
3349          safari: Some(14 << 16),
3350          ..Browsers::default()
3351        },
3352      );
3353      prefix_test(
3354        &format!(
3355          r#"
3356        .foo {{
3357          {}: 22px;
3358          {}: max(2cqw, 22px);
3359        }}
3360      "#,
3361          prop, prop
3362        ),
3363        &format!(
3364          indoc! {r#"
3365        .foo {{
3366          {}: max(2cqw, 22px);
3367        }}
3368      "#
3369          },
3370          prop
3371        ),
3372        Browsers {
3373          safari: Some(16 << 16),
3374          ..Browsers::default()
3375        },
3376      );
3377    }
3378  }
3379
3380  #[test]
3381  pub fn test_padding() {
3382    test(
3383      r#"
3384      .foo {
3385        padding-left: 10px;
3386        padding-right: 10px;
3387        padding-top: 20px;
3388        padding-bottom: 20px;
3389      }
3390    "#,
3391      indoc! {r#"
3392      .foo {
3393        padding: 20px 10px;
3394      }
3395    "#
3396      },
3397    );
3398
3399    test(
3400      r#"
3401      .foo {
3402        padding-block-start: 15px;
3403        padding-block-end: 15px;
3404      }
3405    "#,
3406      indoc! {r#"
3407      .foo {
3408        padding-block: 15px;
3409      }
3410    "#
3411      },
3412    );
3413
3414    test(
3415      r#"
3416      .foo {
3417        padding-left: 10px;
3418        padding-right: 10px;
3419        padding-inline-start: 15px;
3420        padding-inline-end: 15px;
3421        padding-top: 20px;
3422        padding-bottom: 20px;
3423
3424      }
3425    "#,
3426      indoc! {r#"
3427      .foo {
3428        padding-left: 10px;
3429        padding-right: 10px;
3430        padding-inline: 15px;
3431        padding-top: 20px;
3432        padding-bottom: 20px;
3433      }
3434    "#
3435      },
3436    );
3437
3438    prefix_test(
3439      r#"
3440      .foo {
3441        padding-inline-start: 2px;
3442      }
3443    "#,
3444      indoc! {r#"
3445      .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))) {
3446        padding-left: 2px;
3447      }
3448
3449      .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))) {
3450        padding-left: 2px;
3451      }
3452
3453      .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)) {
3454        padding-right: 2px;
3455      }
3456
3457      .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)) {
3458        padding-right: 2px;
3459      }
3460    "#
3461      },
3462      Browsers {
3463        safari: Some(8 << 16),
3464        ..Browsers::default()
3465      },
3466    );
3467
3468    prefix_test(
3469      r#"
3470      .foo {
3471        padding-inline-start: 2px;
3472        padding-inline-end: 4px;
3473      }
3474    "#,
3475      indoc! {r#"
3476      .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))) {
3477        padding-left: 2px;
3478        padding-right: 4px;
3479      }
3480
3481      .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))) {
3482        padding-left: 2px;
3483        padding-right: 4px;
3484      }
3485
3486      .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)) {
3487        padding-left: 4px;
3488        padding-right: 2px;
3489      }
3490
3491      .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)) {
3492        padding-left: 4px;
3493        padding-right: 2px;
3494      }
3495    "#
3496      },
3497      Browsers {
3498        safari: Some(8 << 16),
3499        ..Browsers::default()
3500      },
3501    );
3502
3503    prefix_test(
3504      r#"
3505      .foo {
3506        padding-inline-start: var(--padding);
3507      }
3508    "#,
3509      indoc! {r#"
3510      .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))) {
3511        padding-left: var(--padding);
3512      }
3513
3514      .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))) {
3515        padding-left: var(--padding);
3516      }
3517
3518      .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)) {
3519        padding-right: var(--padding);
3520      }
3521
3522      .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)) {
3523        padding-right: var(--padding);
3524      }
3525    "#
3526      },
3527      Browsers {
3528        safari: Some(8 << 16),
3529        ..Browsers::default()
3530      },
3531    );
3532
3533    prefix_test(
3534      r#"
3535      .foo {
3536        padding-inline: 2px;
3537      }
3538    "#,
3539      indoc! {r#"
3540      .foo {
3541        padding-left: 2px;
3542        padding-right: 2px;
3543      }
3544    "#
3545      },
3546      Browsers {
3547        safari: Some(8 << 16),
3548        ..Browsers::default()
3549      },
3550    );
3551
3552    prefix_test(
3553      r#"
3554      .foo {
3555        padding-block-start: 2px;
3556      }
3557    "#,
3558      indoc! {r#"
3559      .foo {
3560        padding-top: 2px;
3561      }
3562    "#
3563      },
3564      Browsers {
3565        safari: Some(8 << 16),
3566        ..Browsers::default()
3567      },
3568    );
3569
3570    prefix_test(
3571      r#"
3572      .foo {
3573        padding-block-end: 2px;
3574      }
3575    "#,
3576      indoc! {r#"
3577      .foo {
3578        padding-bottom: 2px;
3579      }
3580    "#
3581      },
3582      Browsers {
3583        safari: Some(8 << 16),
3584        ..Browsers::default()
3585      },
3586    );
3587
3588    prefix_test(
3589      r#"
3590      .foo {
3591        padding-top: 1px;
3592        padding-left: 2px;
3593        padding-bottom: 3px;
3594        padding-right: 4px;
3595      }
3596    "#,
3597      indoc! {r#"
3598      .foo {
3599        padding: 1px 4px 3px 2px;
3600      }
3601    "#},
3602      Browsers {
3603        safari: Some(8 << 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-start: 2px;
3618        padding-inline-end: 2px;
3619      }
3620    "#
3621      },
3622      Browsers {
3623        safari: Some(13 << 16),
3624        ..Browsers::default()
3625      },
3626    );
3627
3628    prefix_test(
3629      r#"
3630      .foo {
3631        padding-inline-start: 2px;
3632        padding-inline-end: 2px;
3633      }
3634    "#,
3635      indoc! {r#"
3636      .foo {
3637        padding-inline: 2px;
3638      }
3639    "#
3640      },
3641      Browsers {
3642        safari: Some(15 << 16),
3643        ..Browsers::default()
3644      },
3645    );
3646  }
3647
3648  #[test]
3649  fn test_scroll_padding() {
3650    prefix_test(
3651      r#"
3652      .foo {
3653        scroll-padding-inline: 2px;
3654      }
3655    "#,
3656      indoc! {r#"
3657      .foo {
3658        scroll-padding-inline: 2px;
3659      }
3660    "#
3661      },
3662      Browsers {
3663        safari: Some(8 << 16),
3664        ..Browsers::default()
3665      },
3666    );
3667  }
3668
3669  #[test]
3670  fn test_size() {
3671    prefix_test(
3672      r#"
3673      .foo {
3674        block-size: 25px;
3675        inline-size: 25px;
3676        min-block-size: 25px;
3677        min-inline-size: 25px;
3678      }
3679    "#,
3680      indoc! {r#"
3681      .foo {
3682        height: 25px;
3683        min-height: 25px;
3684        width: 25px;
3685        min-width: 25px;
3686      }
3687    "#},
3688      Browsers {
3689        safari: Some(8 << 16),
3690        ..Browsers::default()
3691      },
3692    );
3693
3694    prefix_test(
3695      r#"
3696      .foo {
3697        block-size: 25px;
3698        min-block-size: 25px;
3699        inline-size: 25px;
3700        min-inline-size: 25px;
3701      }
3702    "#,
3703      indoc! {r#"
3704      .foo {
3705        block-size: 25px;
3706        min-block-size: 25px;
3707        inline-size: 25px;
3708        min-inline-size: 25px;
3709      }
3710    "#},
3711      Browsers {
3712        safari: Some(14 << 16),
3713        ..Browsers::default()
3714      },
3715    );
3716
3717    prefix_test(
3718      r#"
3719      .foo {
3720        block-size: var(--size);
3721        min-block-size: var(--size);
3722        inline-size: var(--size);
3723        min-inline-size: var(--size);
3724      }
3725    "#,
3726      indoc! {r#"
3727      .foo {
3728        height: var(--size);
3729        min-height: var(--size);
3730        width: var(--size);
3731        min-width: var(--size);
3732      }
3733    "#},
3734      Browsers {
3735        safari: Some(8 << 16),
3736        ..Browsers::default()
3737      },
3738    );
3739
3740    for (in_prop, out_prop) in [
3741      ("width", "width"),
3742      ("height", "height"),
3743      ("block-size", "height"),
3744      ("inline-size", "width"),
3745      ("min-width", "min-width"),
3746      ("min-height", "min-height"),
3747      ("min-block-size", "min-height"),
3748      ("min-inline-size", "min-width"),
3749      ("max-width", "max-width"),
3750      ("max-height", "max-height"),
3751      ("max-block-size", "max-height"),
3752      ("max-inline-size", "max-width"),
3753    ] {
3754      prefix_test(
3755        &format!(
3756          r#"
3757        .foo {{
3758          {}: stretch;
3759        }}
3760      "#,
3761          in_prop
3762        ),
3763        &format!(
3764          indoc! {r#"
3765        .foo {{
3766          {}: -webkit-fill-available;
3767          {}: -moz-available;
3768          {}: stretch;
3769        }}
3770      "#},
3771          out_prop, out_prop, out_prop
3772        ),
3773        Browsers {
3774          safari: Some(8 << 16),
3775          firefox: Some(4 << 16),
3776          ..Browsers::default()
3777        },
3778      );
3779
3780      prefix_test(
3781        &format!(
3782          r#"
3783        .foo {{
3784          {}: -webkit-fill-available;
3785        }}
3786      "#,
3787          in_prop
3788        ),
3789        &format!(
3790          indoc! {r#"
3791        .foo {{
3792          {}: -webkit-fill-available;
3793        }}
3794      "#},
3795          out_prop
3796        ),
3797        Browsers {
3798          safari: Some(8 << 16),
3799          firefox: Some(4 << 16),
3800          ..Browsers::default()
3801        },
3802      );
3803
3804      prefix_test(
3805        &format!(
3806          r#"
3807        .foo {{
3808          {}: 100vw;
3809          {}: -webkit-fill-available;
3810        }}
3811      "#,
3812          in_prop, in_prop
3813        ),
3814        &format!(
3815          indoc! {r#"
3816        .foo {{
3817          {}: 100vw;
3818          {}: -webkit-fill-available;
3819        }}
3820      "#},
3821          out_prop, out_prop
3822        ),
3823        Browsers {
3824          safari: Some(8 << 16),
3825          firefox: Some(4 << 16),
3826          ..Browsers::default()
3827        },
3828      );
3829
3830      prefix_test(
3831        &format!(
3832          r#"
3833        .foo {{
3834          {}: fit-content;
3835        }}
3836      "#,
3837          in_prop
3838        ),
3839        &format!(
3840          indoc! {r#"
3841        .foo {{
3842          {}: -webkit-fit-content;
3843          {}: -moz-fit-content;
3844          {}: fit-content;
3845        }}
3846      "#},
3847          out_prop, out_prop, out_prop
3848        ),
3849        Browsers {
3850          safari: Some(8 << 16),
3851          firefox: Some(4 << 16),
3852          ..Browsers::default()
3853        },
3854      );
3855
3856      prefix_test(
3857        &format!(
3858          r#"
3859        .foo {{
3860          {}: fit-content(50%);
3861        }}
3862      "#,
3863          in_prop
3864        ),
3865        &format!(
3866          indoc! {r#"
3867        .foo {{
3868          {}: fit-content(50%);
3869        }}
3870      "#},
3871          out_prop
3872        ),
3873        Browsers {
3874          safari: Some(8 << 16),
3875          firefox: Some(4 << 16),
3876          ..Browsers::default()
3877        },
3878      );
3879
3880      prefix_test(
3881        &format!(
3882          r#"
3883        .foo {{
3884          {}: min-content;
3885        }}
3886      "#,
3887          in_prop
3888        ),
3889        &format!(
3890          indoc! {r#"
3891        .foo {{
3892          {}: -webkit-min-content;
3893          {}: -moz-min-content;
3894          {}: min-content;
3895        }}
3896      "#},
3897          out_prop, out_prop, out_prop
3898        ),
3899        Browsers {
3900          safari: Some(8 << 16),
3901          firefox: Some(4 << 16),
3902          ..Browsers::default()
3903        },
3904      );
3905
3906      prefix_test(
3907        &format!(
3908          r#"
3909        .foo {{
3910          {}: max-content;
3911        }}
3912      "#,
3913          in_prop
3914        ),
3915        &format!(
3916          indoc! {r#"
3917        .foo {{
3918          {}: -webkit-max-content;
3919          {}: -moz-max-content;
3920          {}: max-content;
3921        }}
3922      "#},
3923          out_prop, out_prop, out_prop
3924        ),
3925        Browsers {
3926          safari: Some(8 << 16),
3927          firefox: Some(4 << 16),
3928          ..Browsers::default()
3929        },
3930      );
3931
3932      prefix_test(
3933        &format!(
3934          r#"
3935        .foo {{
3936          {}: 100%;
3937          {}: max-content;
3938        }}
3939      "#,
3940          in_prop, in_prop
3941        ),
3942        &format!(
3943          indoc! {r#"
3944        .foo {{
3945          {}: 100%;
3946          {}: max-content;
3947        }}
3948      "#},
3949          out_prop, out_prop
3950        ),
3951        Browsers {
3952          safari: Some(8 << 16),
3953          firefox: Some(4 << 16),
3954          ..Browsers::default()
3955        },
3956      );
3957
3958      prefix_test(
3959        &format!(
3960          r#"
3961        .foo {{
3962          {}: var(--fallback);
3963          {}: max-content;
3964        }}
3965      "#,
3966          in_prop, in_prop
3967        ),
3968        &format!(
3969          indoc! {r#"
3970        .foo {{
3971          {}: var(--fallback);
3972          {}: max-content;
3973        }}
3974      "#},
3975          out_prop, out_prop
3976        ),
3977        Browsers {
3978          safari: Some(8 << 16),
3979          firefox: Some(4 << 16),
3980          ..Browsers::default()
3981        },
3982      );
3983    }
3984
3985    minify_test(".foo { aspect-ratio: auto }", ".foo{aspect-ratio:auto}");
3986    minify_test(".foo { aspect-ratio: 2 / 3 }", ".foo{aspect-ratio:2/3}");
3987    minify_test(".foo { aspect-ratio: auto 2 / 3 }", ".foo{aspect-ratio:auto 2/3}");
3988    minify_test(".foo { aspect-ratio: 2 / 3 auto }", ".foo{aspect-ratio:auto 2/3}");
3989
3990    minify_test(
3991      ".foo { width: 200px; width: var(--foo); }",
3992      ".foo{width:200px;width:var(--foo)}",
3993    );
3994    minify_test(
3995      ".foo { width: var(--foo); width: 200px; }",
3996      ".foo{width:var(--foo);width:200px}",
3997    );
3998  }
3999
4000  #[test]
4001  pub fn test_background() {
4002    test(
4003      r#"
4004      .foo {
4005        background: url(img.png);
4006        background-position-x: 20px;
4007        background-position-y: 10px;
4008        background-size: 50px 100px;
4009        background-repeat: repeat no-repeat;
4010      }
4011    "#,
4012      indoc! {r#"
4013      .foo {
4014        background: url("img.png") 20px 10px / 50px 100px repeat-x;
4015      }
4016    "#
4017      },
4018    );
4019
4020    test(
4021      r#"
4022      .foo {
4023        background-color: red;
4024        background-position: 0% 0%;
4025        background-size: auto;
4026        background-repeat: repeat;
4027        background-clip: border-box;
4028        background-origin: padding-box;
4029        background-attachment: scroll;
4030        background-image: none
4031      }
4032    "#,
4033      indoc! {r#"
4034      .foo {
4035        background: red;
4036      }
4037    "#
4038      },
4039    );
4040
4041    test(
4042      r#"
4043      .foo {
4044        background-color: gray;
4045        background-position: 40% 50%;
4046        background-size: 10em auto;
4047        background-repeat: round;
4048        background-clip: border-box;
4049        background-origin: border-box;
4050        background-attachment: fixed;
4051        background-image: url('chess.png');
4052      }
4053    "#,
4054      indoc! {r#"
4055      .foo {
4056        background: gray url("chess.png") 40% / 10em round fixed border-box;
4057      }
4058    "#
4059      },
4060    );
4061
4062    test(
4063      r#"
4064      .foo {
4065        background: url(img.png), url(test.jpg) gray;
4066        background-position-x: right 20px, 10px;
4067        background-position-y: top 20px, 15px;
4068        background-size: 50px 50px, auto;
4069        background-repeat: repeat no-repeat, no-repeat;
4070      }
4071    "#,
4072      indoc! {r#"
4073      .foo {
4074        background: url("img.png") right 20px top 20px / 50px 50px repeat-x, gray url("test.jpg") 10px 15px no-repeat;
4075      }
4076    "#
4077      },
4078    );
4079
4080    minify_test(
4081      r#"
4082      .foo {
4083        background-position: center center;
4084      }
4085    "#,
4086      indoc! {".foo{background-position:50%}"
4087      },
4088    );
4089
4090    test(
4091      r#"
4092      .foo {
4093        background: url(img.png) gray;
4094        background-clip: content-box;
4095        -webkit-background-clip: text;
4096      }
4097    "#,
4098      indoc! {r#"
4099      .foo {
4100        background: gray url("img.png") padding-box content-box;
4101        -webkit-background-clip: text;
4102      }
4103    "#
4104      },
4105    );
4106
4107    test(
4108      r#"
4109      .foo {
4110        background: url(img.png) gray;
4111        -webkit-background-clip: text;
4112        background-clip: content-box;
4113      }
4114    "#,
4115      indoc! {r#"
4116      .foo {
4117        background: gray url("img.png");
4118        -webkit-background-clip: text;
4119        background-clip: content-box;
4120      }
4121    "#
4122      },
4123    );
4124
4125    test(
4126      r#"
4127      .foo {
4128        background: url(img.png) gray;
4129        background-position: var(--pos);
4130      }
4131    "#,
4132      indoc! {r#"
4133      .foo {
4134        background: gray url("img.png");
4135        background-position: var(--pos);
4136      }
4137    "#
4138      },
4139    );
4140
4141    minify_test(
4142      ".foo { background-position: bottom left }",
4143      ".foo{background-position:0 100%}",
4144    );
4145    minify_test(
4146      ".foo { background-position: left 10px center }",
4147      ".foo{background-position:10px 50%}",
4148    );
4149    minify_test(
4150      ".foo { background-position: right 10px center }",
4151      ".foo{background-position:right 10px center}",
4152    );
4153    minify_test(
4154      ".foo { background-position: right 10px top 20px }",
4155      ".foo{background-position:right 10px top 20px}",
4156    );
4157    minify_test(
4158      ".foo { background-position: left 10px top 20px }",
4159      ".foo{background-position:10px 20px}",
4160    );
4161    minify_test(
4162      ".foo { background-position: left 10px bottom 20px }",
4163      ".foo{background-position:left 10px bottom 20px}",
4164    );
4165    minify_test(
4166      ".foo { background-position: left 10px top }",
4167      ".foo{background-position:10px 0}",
4168    );
4169    minify_test(
4170      ".foo { background-position: bottom right }",
4171      ".foo{background-position:100% 100%}",
4172    );
4173
4174    minify_test(
4175      ".foo { background: url('img-sprite.png') no-repeat bottom right }",
4176      ".foo{background:url(img-sprite.png) 100% 100% no-repeat}",
4177    );
4178    minify_test(".foo { background: transparent }", ".foo{background:0 0}");
4179
4180    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\")}");
4181
4182    test(
4183      r#"
4184      .foo {
4185        background: url(img.png);
4186        background-clip: text;
4187      }
4188    "#,
4189      indoc! {r#"
4190      .foo {
4191        background: url("img.png") text;
4192      }
4193    "#
4194      },
4195    );
4196
4197    prefix_test(
4198      r#"
4199      .foo {
4200        background: url(img.png);
4201        background-clip: text;
4202      }
4203    "#,
4204      indoc! {r#"
4205      .foo {
4206        background: url("img.png");
4207        -webkit-background-clip: text;
4208        background-clip: text;
4209      }
4210    "#
4211      },
4212      Browsers {
4213        safari: Some(8 << 16),
4214        ..Browsers::default()
4215      },
4216    );
4217
4218    prefix_test(
4219      r#"
4220      .foo {
4221        background: url(img.png);
4222        background-clip: text;
4223      }
4224    "#,
4225      indoc! {r#"
4226      .foo {
4227        background: url("img.png") text;
4228      }
4229    "#
4230      },
4231      Browsers {
4232        safari: Some(14 << 16),
4233        ..Browsers::default()
4234      },
4235    );
4236
4237    prefix_test(
4238      r#"
4239      .foo {
4240        background: url(img.png) text;
4241      }
4242    "#,
4243      indoc! {r#"
4244      .foo {
4245        background: url("img.png");
4246        -webkit-background-clip: text;
4247        background-clip: text;
4248      }
4249    "#
4250      },
4251      Browsers {
4252        chrome: Some(45 << 16),
4253        ..Browsers::default()
4254      },
4255    );
4256
4257    prefix_test(
4258      r#"
4259      .foo {
4260        background: url(img.png);
4261        -webkit-background-clip: text;
4262      }
4263    "#,
4264      indoc! {r#"
4265      .foo {
4266        background: url("img.png");
4267        -webkit-background-clip: text;
4268      }
4269    "#
4270      },
4271      Browsers {
4272        chrome: Some(45 << 16),
4273        ..Browsers::default()
4274      },
4275    );
4276
4277    prefix_test(
4278      r#"
4279      .foo {
4280        background: url(img.png);
4281        background-clip: text;
4282      }
4283    "#,
4284      indoc! {r#"
4285      .foo {
4286        background: url("img.png");
4287        -webkit-background-clip: text;
4288        background-clip: text;
4289      }
4290    "#
4291      },
4292      Browsers {
4293        safari: Some(14 << 16),
4294        chrome: Some(95 << 16),
4295        ..Browsers::default()
4296      },
4297    );
4298
4299    prefix_test(
4300      r#"
4301      .foo {
4302        background-image: url(img.png);
4303        background-clip: text;
4304      }
4305    "#,
4306      indoc! {r#"
4307      .foo {
4308        background-image: url("img.png");
4309        -webkit-background-clip: text;
4310        background-clip: text;
4311      }
4312    "#
4313      },
4314      Browsers {
4315        safari: Some(8 << 16),
4316        ..Browsers::default()
4317      },
4318    );
4319
4320    prefix_test(
4321      r#"
4322      .foo {
4323        -webkit-background-clip: text;
4324        background-clip: text;
4325      }
4326    "#,
4327      indoc! {r#"
4328      .foo {
4329        -webkit-background-clip: text;
4330        background-clip: text;
4331      }
4332    "#
4333      },
4334      Browsers {
4335        chrome: Some(45 << 16),
4336        ..Browsers::default()
4337      },
4338    );
4339
4340    prefix_test(
4341      r#"
4342      .foo {
4343        background-image: url(img.png);
4344        background-clip: text;
4345      }
4346    "#,
4347      indoc! {r#"
4348      .foo {
4349        background-image: url("img.png");
4350        background-clip: text;
4351      }
4352    "#
4353      },
4354      Browsers {
4355        safari: Some(14 << 16),
4356        ..Browsers::default()
4357      },
4358    );
4359
4360    minify_test(".foo { background: none center }", ".foo{background:50%}");
4361    minify_test(".foo { background: none }", ".foo{background:0 0}");
4362
4363    prefix_test(
4364      r#"
4365      .foo {
4366        background: lab(51.5117% 43.3777 -29.0443);
4367      }
4368    "#,
4369      indoc! {r#"
4370      .foo {
4371        background: #af5cae;
4372        background: lab(51.5117% 43.3777 -29.0443);
4373      }
4374    "#
4375      },
4376      Browsers {
4377        chrome: Some(95 << 16),
4378        safari: Some(15 << 16),
4379        ..Browsers::default()
4380      },
4381    );
4382
4383    prefix_test(
4384      r#"
4385      .foo {
4386        background: lab(51.5117% 43.3777 -29.0443) url(foo.png);
4387      }
4388    "#,
4389      indoc! {r#"
4390      .foo {
4391        background: #af5cae url("foo.png");
4392        background: lab(51.5117% 43.3777 -29.0443) url("foo.png");
4393      }
4394    "#
4395      },
4396      Browsers {
4397        chrome: Some(95 << 16),
4398        safari: Some(15 << 16),
4399        ..Browsers::default()
4400      },
4401    );
4402
4403    prefix_test(
4404      r#"
4405      .foo {
4406        background: lab(51.5117% 43.3777 -29.0443) linear-gradient(lab(52.2319% 40.1449 59.9171), lab(47.7776% -34.2947 -7.65904));
4407      }
4408    "#,
4409      indoc! {r#"
4410      .foo {
4411        background: #af5cae linear-gradient(#c65d07, #00807c);
4412        background: lab(51.5117% 43.3777 -29.0443) linear-gradient(lab(52.2319% 40.1449 59.9171), lab(47.7776% -34.2947 -7.65904));
4413      }
4414    "#
4415      },
4416      Browsers {
4417        chrome: Some(95 << 16),
4418        safari: Some(15 << 16),
4419        ..Browsers::default()
4420      },
4421    );
4422
4423    test(
4424      ".foo { background: calc(var(--v) / 0.3)",
4425      indoc! {r#"
4426      .foo {
4427        background: calc(var(--v) / .3);
4428      }
4429    "#},
4430    );
4431
4432    prefix_test(
4433      r#"
4434      .foo {
4435        background-color: #4263eb;
4436        background-color: color(display-p3 0 .5 1);
4437      }
4438    "#,
4439      indoc! {r#"
4440      .foo {
4441        background-color: #4263eb;
4442        background-color: color(display-p3 0 .5 1);
4443      }
4444    "#
4445      },
4446      Browsers {
4447        chrome: Some(99 << 16),
4448        ..Browsers::default()
4449      },
4450    );
4451    prefix_test(
4452      r#"
4453      .foo {
4454        background-color: #4263eb;
4455        background-color: color(display-p3 0 .5 1);
4456      }
4457    "#,
4458      indoc! {r#"
4459      .foo {
4460        background-color: color(display-p3 0 .5 1);
4461      }
4462    "#
4463      },
4464      Browsers {
4465        safari: Some(16 << 16),
4466        ..Browsers::default()
4467      },
4468    );
4469    prefix_test(
4470      r#"
4471      .foo {
4472        background-image: linear-gradient(red, green);
4473        background-image: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4474      }
4475    "#,
4476      indoc! {r#"
4477      .foo {
4478        background-image: linear-gradient(red, green);
4479        background-image: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4480      }
4481    "#
4482      },
4483      Browsers {
4484        chrome: Some(99 << 16),
4485        ..Browsers::default()
4486      },
4487    );
4488    prefix_test(
4489      r#"
4490      .foo {
4491        background-image: linear-gradient(red, green);
4492        background-image: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4493      }
4494    "#,
4495      indoc! {r#"
4496      .foo {
4497        background-image: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4498      }
4499    "#
4500      },
4501      Browsers {
4502        safari: Some(16 << 16),
4503        ..Browsers::default()
4504      },
4505    );
4506    prefix_test(
4507      r#"
4508      .foo {
4509        background: #4263eb;
4510        background: color(display-p3 0 .5 1);
4511      }
4512    "#,
4513      indoc! {r#"
4514      .foo {
4515        background: #4263eb;
4516        background: color(display-p3 0 .5 1);
4517      }
4518    "#
4519      },
4520      Browsers {
4521        chrome: Some(99 << 16),
4522        ..Browsers::default()
4523      },
4524    );
4525    prefix_test(
4526      r#"
4527      .foo {
4528        background: #4263eb;
4529        background: color(display-p3 0 .5 1);
4530      }
4531    "#,
4532      indoc! {r#"
4533      .foo {
4534        background: color(display-p3 0 .5 1);
4535      }
4536    "#
4537      },
4538      Browsers {
4539        safari: Some(16 << 16),
4540        ..Browsers::default()
4541      },
4542    );
4543    prefix_test(
4544      r#"
4545      .foo {
4546        background: linear-gradient(red, green);
4547        background: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4548      }
4549    "#,
4550      indoc! {r#"
4551      .foo {
4552        background: linear-gradient(red, green);
4553        background: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4554      }
4555    "#
4556      },
4557      Browsers {
4558        chrome: Some(99 << 16),
4559        ..Browsers::default()
4560      },
4561    );
4562    prefix_test(
4563      r#"
4564      .foo {
4565        background: red;
4566        background: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4567      }
4568    "#,
4569      indoc! {r#"
4570      .foo {
4571        background: red;
4572        background: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4573      }
4574    "#
4575      },
4576      Browsers {
4577        chrome: Some(99 << 16),
4578        ..Browsers::default()
4579      },
4580    );
4581    prefix_test(
4582      r#"
4583      .foo {
4584        background: linear-gradient(red, green);
4585        background: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4586      }
4587    "#,
4588      indoc! {r#"
4589      .foo {
4590        background: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4591      }
4592    "#
4593      },
4594      Browsers {
4595        safari: Some(16 << 16),
4596        ..Browsers::default()
4597      },
4598    );
4599    prefix_test(
4600      r#"
4601      .foo {
4602        background: var(--fallback);
4603        background: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4604      }
4605    "#,
4606      indoc! {r#"
4607      .foo {
4608        background: var(--fallback);
4609        background: linear-gradient(lch(50% 132 50), lch(50% 130 150));
4610      }
4611    "#
4612      },
4613      Browsers {
4614        chrome: Some(99 << 16),
4615        ..Browsers::default()
4616      },
4617    );
4618    prefix_test(
4619      r#"
4620      .foo {
4621        background: red url(foo.png);
4622        background: lch(50% 132 50) url(foo.png);
4623      }
4624    "#,
4625      indoc! {r#"
4626      .foo {
4627        background: red url("foo.png");
4628        background: lch(50% 132 50) url("foo.png");
4629      }
4630    "#
4631      },
4632      Browsers {
4633        chrome: Some(99 << 16),
4634        ..Browsers::default()
4635      },
4636    );
4637  }
4638
4639  #[test]
4640  pub fn test_flex() {
4641    test(
4642      r#"
4643      .foo {
4644        flex-direction: column;
4645        flex-wrap: wrap;
4646      }
4647    "#,
4648      indoc! {r#"
4649      .foo {
4650        flex-flow: column wrap;
4651      }
4652    "#
4653      },
4654    );
4655
4656    test(
4657      r#"
4658      .foo {
4659        flex-direction: row;
4660        flex-wrap: wrap;
4661      }
4662    "#,
4663      indoc! {r#"
4664      .foo {
4665        flex-flow: wrap;
4666      }
4667    "#
4668      },
4669    );
4670
4671    test(
4672      r#"
4673      .foo {
4674        flex-direction: row;
4675        flex-wrap: nowrap;
4676      }
4677    "#,
4678      indoc! {r#"
4679      .foo {
4680        flex-flow: row;
4681      }
4682    "#
4683      },
4684    );
4685
4686    test(
4687      r#"
4688      .foo {
4689        flex-direction: column;
4690        flex-wrap: nowrap;
4691      }
4692    "#,
4693      indoc! {r#"
4694      .foo {
4695        flex-flow: column;
4696      }
4697    "#
4698      },
4699    );
4700
4701    test(
4702      r#"
4703      .foo {
4704        flex-grow: 1;
4705        flex-shrink: 1;
4706        flex-basis: 0%;
4707      }
4708    "#,
4709      indoc! {r#"
4710      .foo {
4711        flex: 1;
4712      }
4713    "#
4714      },
4715    );
4716
4717    test(
4718      r#"
4719      .foo {
4720        flex-grow: 1;
4721        flex-shrink: 1;
4722        flex-basis: 0;
4723      }
4724    "#,
4725      indoc! {r#"
4726      .foo {
4727        flex: 1 1 0;
4728      }
4729    "#
4730      },
4731    );
4732
4733    test(
4734      r#"
4735      .foo {
4736        flex-grow: 1;
4737        flex-shrink: 1;
4738        flex-basis: 0px;
4739      }
4740    "#,
4741      indoc! {r#"
4742      .foo {
4743        flex: 1 1 0;
4744      }
4745    "#
4746      },
4747    );
4748
4749    test(
4750      r#"
4751      .foo {
4752        flex-grow: 1;
4753        flex-shrink: 2;
4754        flex-basis: 0%;
4755      }
4756    "#,
4757      indoc! {r#"
4758      .foo {
4759        flex: 1 2;
4760      }
4761    "#
4762      },
4763    );
4764
4765    test(
4766      r#"
4767      .foo {
4768        flex-grow: 2;
4769        flex-shrink: 1;
4770        flex-basis: 0%;
4771      }
4772    "#,
4773      indoc! {r#"
4774      .foo {
4775        flex: 2;
4776      }
4777    "#
4778      },
4779    );
4780
4781    test(
4782      r#"
4783      .foo {
4784        flex-grow: 2;
4785        flex-shrink: 2;
4786        flex-basis: 0%;
4787      }
4788    "#,
4789      indoc! {r#"
4790      .foo {
4791        flex: 2 2;
4792      }
4793    "#
4794      },
4795    );
4796
4797    test(
4798      r#"
4799      .foo {
4800        flex-grow: 1;
4801        flex-shrink: 1;
4802        flex-basis: 10px;
4803      }
4804    "#,
4805      indoc! {r#"
4806      .foo {
4807        flex: 10px;
4808      }
4809    "#
4810      },
4811    );
4812
4813    test(
4814      r#"
4815      .foo {
4816        flex-grow: 2;
4817        flex-shrink: 1;
4818        flex-basis: 10px;
4819      }
4820    "#,
4821      indoc! {r#"
4822      .foo {
4823        flex: 2 10px;
4824      }
4825    "#
4826      },
4827    );
4828
4829    test(
4830      r#"
4831      .foo {
4832        flex-grow: 1;
4833        flex-shrink: 0;
4834        flex-basis: 0%;
4835      }
4836    "#,
4837      indoc! {r#"
4838      .foo {
4839        flex: 1 0;
4840      }
4841    "#
4842      },
4843    );
4844
4845    test(
4846      r#"
4847      .foo {
4848        flex-grow: 1;
4849        flex-shrink: 0;
4850        flex-basis: auto;
4851      }
4852    "#,
4853      indoc! {r#"
4854      .foo {
4855        flex: 1 0 auto;
4856      }
4857    "#
4858      },
4859    );
4860
4861    test(
4862      r#"
4863      .foo {
4864        flex-grow: 1;
4865        flex-shrink: 1;
4866        flex-basis: auto;
4867      }
4868    "#,
4869      indoc! {r#"
4870      .foo {
4871        flex: auto;
4872      }
4873    "#
4874      },
4875    );
4876
4877    test(
4878      r#"
4879      .foo {
4880        flex: 0 0;
4881        flex-grow: 1;
4882      }
4883    "#,
4884      indoc! {r#"
4885      .foo {
4886        flex: 1 0;
4887      }
4888    "#
4889      },
4890    );
4891
4892    test(
4893      r#"
4894      .foo {
4895        flex: 0 0;
4896        flex-grow: var(--grow);
4897      }
4898    "#,
4899      indoc! {r#"
4900      .foo {
4901        flex: 0 0;
4902        flex-grow: var(--grow);
4903      }
4904    "#
4905      },
4906    );
4907
4908    test(
4909      r#"
4910      .foo {
4911        align-content: center;
4912        justify-content: center;
4913      }
4914    "#,
4915      indoc! {r#"
4916      .foo {
4917        place-content: center;
4918      }
4919    "#
4920      },
4921    );
4922
4923    test(
4924      r#"
4925      .foo {
4926        align-content: first baseline;
4927        justify-content: safe right;
4928      }
4929    "#,
4930      indoc! {r#"
4931      .foo {
4932        place-content: baseline safe right;
4933      }
4934    "#
4935      },
4936    );
4937
4938    test(
4939      r#"
4940      .foo {
4941        place-content: first baseline unsafe left;
4942      }
4943    "#,
4944      indoc! {r#"
4945      .foo {
4946        place-content: baseline unsafe left;
4947      }
4948    "#
4949      },
4950    );
4951
4952    test(
4953      r#"
4954      .foo {
4955        place-content: center center;
4956      }
4957    "#,
4958      indoc! {r#"
4959      .foo {
4960        place-content: center;
4961      }
4962    "#
4963      },
4964    );
4965
4966    test(
4967      r#"
4968      .foo {
4969        align-self: center;
4970        justify-self: center;
4971      }
4972    "#,
4973      indoc! {r#"
4974      .foo {
4975        place-self: center;
4976      }
4977    "#
4978      },
4979    );
4980
4981    test(
4982      r#"
4983      .foo {
4984        align-self: center;
4985        justify-self: unsafe left;
4986      }
4987    "#,
4988      indoc! {r#"
4989      .foo {
4990        place-self: center unsafe left;
4991      }
4992    "#
4993      },
4994    );
4995
4996    test(
4997      r#"
4998      .foo {
4999        align-items: center;
5000        justify-items: center;
5001      }
5002    "#,
5003      indoc! {r#"
5004      .foo {
5005        place-items: center;
5006      }
5007    "#
5008      },
5009    );
5010
5011    test(
5012      r#"
5013      .foo {
5014        align-items: center;
5015        justify-items: legacy left;
5016      }
5017    "#,
5018      indoc! {r#"
5019      .foo {
5020        place-items: center legacy left;
5021      }
5022    "#
5023      },
5024    );
5025
5026    test(
5027      r#"
5028      .foo {
5029        place-items: center;
5030        justify-items: var(--justify);
5031      }
5032    "#,
5033      indoc! {r#"
5034      .foo {
5035        place-items: center;
5036        justify-items: var(--justify);
5037      }
5038    "#
5039      },
5040    );
5041
5042    test(
5043      r#"
5044      .foo {
5045        row-gap: 10px;
5046        column-gap: 20px;
5047      }
5048    "#,
5049      indoc! {r#"
5050      .foo {
5051        gap: 10px 20px;
5052      }
5053    "#
5054      },
5055    );
5056
5057    test(
5058      r#"
5059      .foo {
5060        row-gap: 10px;
5061        column-gap: 10px;
5062      }
5063    "#,
5064      indoc! {r#"
5065      .foo {
5066        gap: 10px;
5067      }
5068    "#
5069      },
5070    );
5071
5072    test(
5073      r#"
5074      .foo {
5075        gap: 10px;
5076        column-gap: 20px;
5077      }
5078    "#,
5079      indoc! {r#"
5080      .foo {
5081        gap: 10px 20px;
5082      }
5083    "#
5084      },
5085    );
5086
5087    test(
5088      r#"
5089      .foo {
5090        column-gap: 20px;
5091        gap: 10px;
5092      }
5093    "#,
5094      indoc! {r#"
5095      .foo {
5096        gap: 10px;
5097      }
5098    "#
5099      },
5100    );
5101
5102    test(
5103      r#"
5104      .foo {
5105        row-gap: normal;
5106        column-gap: 20px;
5107      }
5108    "#,
5109      indoc! {r#"
5110      .foo {
5111        gap: normal 20px;
5112      }
5113    "#
5114      },
5115    );
5116
5117    test(
5118      r#"
5119      .foo {
5120        -webkit-flex-grow: 1;
5121        -webkit-flex-shrink: 1;
5122        -webkit-flex-basis: auto;
5123      }
5124    "#,
5125      indoc! {r#"
5126      .foo {
5127        -webkit-flex: auto;
5128      }
5129    "#
5130      },
5131    );
5132    test(
5133      r#"
5134      .foo {
5135        -webkit-flex-grow: 1;
5136        -webkit-flex-shrink: 1;
5137        -webkit-flex-basis: auto;
5138        flex-grow: 1;
5139        flex-shrink: 1;
5140        flex-basis: auto;
5141      }
5142    "#,
5143      indoc! {r#"
5144      .foo {
5145        -webkit-flex: auto;
5146        flex: auto;
5147      }
5148    "#
5149      },
5150    );
5151    prefix_test(
5152      r#"
5153      .foo {
5154        -webkit-box-orient: horizontal;
5155        -webkit-box-direction: normal;
5156        flex-direction: row;
5157      }
5158    "#,
5159      indoc! {r#"
5160      .foo {
5161        -webkit-box-orient: horizontal;
5162        -webkit-box-direction: normal;
5163        -webkit-flex-direction: row;
5164        flex-direction: row;
5165      }
5166    "#},
5167      Browsers {
5168        safari: Some(4 << 16),
5169        ..Browsers::default()
5170      },
5171    );
5172    prefix_test(
5173      r#"
5174      .foo {
5175        flex-direction: row;
5176      }
5177    "#,
5178      indoc! {r#"
5179      .foo {
5180        -webkit-box-orient: horizontal;
5181        -moz-box-orient: horizontal;
5182        -webkit-box-direction: normal;
5183        -moz-box-direction: normal;
5184        -webkit-flex-direction: row;
5185        -ms-flex-direction: row;
5186        flex-direction: row;
5187      }
5188    "#},
5189      Browsers {
5190        safari: Some(4 << 16),
5191        firefox: Some(4 << 16),
5192        ie: Some(10 << 16),
5193        ..Browsers::default()
5194      },
5195    );
5196    prefix_test(
5197      r#"
5198      .foo {
5199        -webkit-box-orient: horizontal;
5200        -webkit-box-direction: normal;
5201        -moz-box-orient: horizontal;
5202        -moz-box-direction: normal;
5203        -webkit-flex-direction: row;
5204        -ms-flex-direction: row;
5205        flex-direction: row;
5206      }
5207    "#,
5208      indoc! {r#"
5209      .foo {
5210        flex-direction: row;
5211      }
5212    "#},
5213      Browsers {
5214        safari: Some(14 << 16),
5215        ..Browsers::default()
5216      },
5217    );
5218    prefix_test(
5219      r#"
5220      .foo {
5221        flex-wrap: wrap;
5222      }
5223    "#,
5224      indoc! {r#"
5225      .foo {
5226        -webkit-box-lines: multiple;
5227        -moz-box-lines: multiple;
5228        -webkit-flex-wrap: wrap;
5229        -ms-flex-wrap: wrap;
5230        flex-wrap: wrap;
5231      }
5232    "#},
5233      Browsers {
5234        safari: Some(4 << 16),
5235        firefox: Some(4 << 16),
5236        ie: Some(10 << 16),
5237        ..Browsers::default()
5238      },
5239    );
5240    prefix_test(
5241      r#"
5242      .foo {
5243        -webkit-box-lines: multiple;
5244        -moz-box-lines: multiple;
5245        -webkit-flex-wrap: wrap;
5246        -ms-flex-wrap: wrap;
5247        flex-wrap: wrap;
5248      }
5249    "#,
5250      indoc! {r#"
5251      .foo {
5252        flex-wrap: wrap;
5253      }
5254    "#},
5255      Browsers {
5256        safari: Some(11 << 16),
5257        ..Browsers::default()
5258      },
5259    );
5260    prefix_test(
5261      r#"
5262      .foo {
5263        flex-flow: row wrap;
5264      }
5265    "#,
5266      indoc! {r#"
5267      .foo {
5268        -webkit-box-orient: horizontal;
5269        -moz-box-orient: horizontal;
5270        -webkit-box-direction: normal;
5271        -moz-box-direction: normal;
5272        -webkit-flex-flow: wrap;
5273        -ms-flex-flow: wrap;
5274        flex-flow: wrap;
5275      }
5276    "#},
5277      Browsers {
5278        safari: Some(4 << 16),
5279        firefox: Some(4 << 16),
5280        ie: Some(10 << 16),
5281        ..Browsers::default()
5282      },
5283    );
5284    prefix_test(
5285      r#"
5286      .foo {
5287        -webkit-box-orient: horizontal;
5288        -moz-box-orient: horizontal;
5289        -webkit-box-direction: normal;
5290        -moz-box-direction: normal;
5291        -webkit-flex-flow: wrap;
5292        -ms-flex-flow: wrap;
5293        flex-flow: wrap;
5294      }
5295    "#,
5296      indoc! {r#"
5297      .foo {
5298        flex-flow: wrap;
5299      }
5300    "#},
5301      Browsers {
5302        safari: Some(11 << 16),
5303        ..Browsers::default()
5304      },
5305    );
5306    prefix_test(
5307      r#"
5308      .foo {
5309        flex-grow: 1;
5310      }
5311    "#,
5312      indoc! {r#"
5313      .foo {
5314        -webkit-box-flex: 1;
5315        -moz-box-flex: 1;
5316        -ms-flex-positive: 1;
5317        -webkit-flex-grow: 1;
5318        flex-grow: 1;
5319      }
5320    "#},
5321      Browsers {
5322        safari: Some(4 << 16),
5323        firefox: Some(4 << 16),
5324        ie: Some(10 << 16),
5325        ..Browsers::default()
5326      },
5327    );
5328    prefix_test(
5329      r#"
5330      .foo {
5331        -webkit-box-flex: 1;
5332        -moz-box-flex: 1;
5333        -ms-flex-positive: 1;
5334        -webkit-flex-grow: 1;
5335        flex-grow: 1;
5336      }
5337    "#,
5338      indoc! {r#"
5339      .foo {
5340        flex-grow: 1;
5341      }
5342    "#},
5343      Browsers {
5344        safari: Some(11 << 16),
5345        ..Browsers::default()
5346      },
5347    );
5348    prefix_test(
5349      r#"
5350      .foo {
5351        flex-shrink: 1;
5352      }
5353    "#,
5354      indoc! {r#"
5355      .foo {
5356        -ms-flex-negative: 1;
5357        -webkit-flex-shrink: 1;
5358        flex-shrink: 1;
5359      }
5360    "#},
5361      Browsers {
5362        safari: Some(4 << 16),
5363        firefox: Some(4 << 16),
5364        ie: Some(10 << 16),
5365        ..Browsers::default()
5366      },
5367    );
5368    prefix_test(
5369      r#"
5370      .foo {
5371        -ms-flex-negative: 1;
5372        -webkit-flex-shrink: 1;
5373        flex-shrink: 1;
5374      }
5375    "#,
5376      indoc! {r#"
5377      .foo {
5378        flex-shrink: 1;
5379      }
5380    "#},
5381      Browsers {
5382        safari: Some(11 << 16),
5383        ..Browsers::default()
5384      },
5385    );
5386    prefix_test(
5387      r#"
5388      .foo {
5389        flex-basis: 1px;
5390      }
5391    "#,
5392      indoc! {r#"
5393      .foo {
5394        -ms-flex-preferred-size: 1px;
5395        -webkit-flex-basis: 1px;
5396        flex-basis: 1px;
5397      }
5398    "#},
5399      Browsers {
5400        safari: Some(4 << 16),
5401        firefox: Some(4 << 16),
5402        ie: Some(10 << 16),
5403        ..Browsers::default()
5404      },
5405    );
5406    prefix_test(
5407      r#"
5408      .foo {
5409        -ms-flex-preferred-size: 1px;
5410        -webkit-flex-basis: 1px;
5411        flex-basis: 1px;
5412      }
5413    "#,
5414      indoc! {r#"
5415      .foo {
5416        flex-basis: 1px;
5417      }
5418    "#},
5419      Browsers {
5420        safari: Some(11 << 16),
5421        ..Browsers::default()
5422      },
5423    );
5424    prefix_test(
5425      r#"
5426      .foo {
5427        flex: 1;
5428      }
5429    "#,
5430      indoc! {r#"
5431      .foo {
5432        -webkit-box-flex: 1;
5433        -moz-box-flex: 1;
5434        -webkit-flex: 1;
5435        -ms-flex: 1;
5436        flex: 1;
5437      }
5438    "#},
5439      Browsers {
5440        safari: Some(4 << 16),
5441        firefox: Some(4 << 16),
5442        ie: Some(10 << 16),
5443        ..Browsers::default()
5444      },
5445    );
5446    prefix_test(
5447      r#"
5448      .foo {
5449        -webkit-box-flex: 1;
5450        -moz-box-flex: 1;
5451        -webkit-flex: 1;
5452        -ms-flex: 1;
5453        flex: 1;
5454      }
5455    "#,
5456      indoc! {r#"
5457      .foo {
5458        flex: 1;
5459      }
5460    "#},
5461      Browsers {
5462        safari: Some(11 << 16),
5463        ..Browsers::default()
5464      },
5465    );
5466    prefix_test(
5467      r#"
5468      .foo {
5469        align-content: space-between;
5470      }
5471    "#,
5472      indoc! {r#"
5473      .foo {
5474        -ms-flex-line-pack: justify;
5475        -webkit-align-content: space-between;
5476        align-content: space-between;
5477      }
5478    "#},
5479      Browsers {
5480        safari: Some(4 << 16),
5481        firefox: Some(4 << 16),
5482        ie: Some(10 << 16),
5483        ..Browsers::default()
5484      },
5485    );
5486    prefix_test(
5487      r#"
5488      .foo {
5489        -ms-flex-line-pack: justify;
5490        -webkit-align-content: space-between;
5491        align-content: space-between;
5492      }
5493    "#,
5494      indoc! {r#"
5495      .foo {
5496        align-content: space-between;
5497      }
5498    "#},
5499      Browsers {
5500        safari: Some(11 << 16),
5501        ..Browsers::default()
5502      },
5503    );
5504    prefix_test(
5505      r#"
5506      .foo {
5507        justify-content: space-between;
5508      }
5509    "#,
5510      indoc! {r#"
5511      .foo {
5512        -webkit-box-pack: justify;
5513        -moz-box-pack: justify;
5514        -ms-flex-pack: justify;
5515        -webkit-justify-content: space-between;
5516        justify-content: space-between;
5517      }
5518    "#},
5519      Browsers {
5520        safari: Some(4 << 16),
5521        firefox: Some(4 << 16),
5522        ie: Some(10 << 16),
5523        ..Browsers::default()
5524      },
5525    );
5526    prefix_test(
5527      r#"
5528      .foo {
5529        -webkit-box-pack: justify;
5530        -moz-box-pack: justify;
5531        -ms-flex-pack: justify;
5532        -webkit-justify-content: space-between;
5533        justify-content: space-between;
5534      }
5535    "#,
5536      indoc! {r#"
5537      .foo {
5538        justify-content: space-between;
5539      }
5540    "#},
5541      Browsers {
5542        safari: Some(11 << 16),
5543        ..Browsers::default()
5544      },
5545    );
5546    prefix_test(
5547      r#"
5548      .foo {
5549        place-content: space-between flex-end;
5550      }
5551    "#,
5552      indoc! {r#"
5553      .foo {
5554        -ms-flex-line-pack: justify;
5555        -webkit-box-pack: end;
5556        -moz-box-pack: end;
5557        -ms-flex-pack: end;
5558        -webkit-align-content: space-between;
5559        align-content: space-between;
5560        -webkit-justify-content: flex-end;
5561        justify-content: flex-end;
5562      }
5563    "#},
5564      Browsers {
5565        safari: Some(4 << 16),
5566        firefox: Some(4 << 16),
5567        ie: Some(10 << 16),
5568        ..Browsers::default()
5569      },
5570    );
5571    prefix_test(
5572      r#"
5573      .foo {
5574        -ms-flex-line-pack: justify;
5575        -webkit-box-pack: end;
5576        -moz-box-pack: end;
5577        -ms-flex-pack: end;
5578        -webkit-align-content: space-between;
5579        -webkit-justify-content: flex-end;
5580        place-content: space-between flex-end;
5581      }
5582    "#,
5583      indoc! {r#"
5584      .foo {
5585        place-content: space-between flex-end;
5586      }
5587    "#},
5588      Browsers {
5589        safari: Some(11 << 16),
5590        ..Browsers::default()
5591      },
5592    );
5593    prefix_test(
5594      r#"
5595      .foo {
5596        place-content: space-between flex-end;
5597      }
5598    "#,
5599      indoc! {r#"
5600      .foo {
5601        align-content: space-between;
5602        justify-content: flex-end;
5603      }
5604    "#},
5605      Browsers {
5606        chrome: Some(30 << 16),
5607        ..Browsers::default()
5608      },
5609    );
5610    prefix_test(
5611      r#"
5612      .foo {
5613        place-content: space-between flex-end;
5614      }
5615    "#,
5616      indoc! {r#"
5617      .foo {
5618        place-content: space-between flex-end;
5619      }
5620    "#},
5621      Browsers {
5622        chrome: Some(60 << 16),
5623        ..Browsers::default()
5624      },
5625    );
5626    prefix_test(
5627      r#"
5628      .foo {
5629        align-self: flex-end;
5630      }
5631    "#,
5632      indoc! {r#"
5633      .foo {
5634        -ms-flex-item-align: end;
5635        -webkit-align-self: flex-end;
5636        align-self: flex-end;
5637      }
5638    "#},
5639      Browsers {
5640        safari: Some(4 << 16),
5641        firefox: Some(4 << 16),
5642        ie: Some(10 << 16),
5643        ..Browsers::default()
5644      },
5645    );
5646    prefix_test(
5647      r#"
5648      .foo {
5649        -ms-flex-item-align: end;
5650        -webkit-align-self: flex-end;
5651        align-self: flex-end;
5652      }
5653    "#,
5654      indoc! {r#"
5655      .foo {
5656        align-self: flex-end;
5657      }
5658    "#},
5659      Browsers {
5660        safari: Some(11 << 16),
5661        ..Browsers::default()
5662      },
5663    );
5664    prefix_test(
5665      r#"
5666      .foo {
5667        place-self: center flex-end;
5668      }
5669    "#,
5670      indoc! {r#"
5671      .foo {
5672        -ms-flex-item-align: center;
5673        -webkit-align-self: center;
5674        align-self: center;
5675        justify-self: flex-end;
5676      }
5677    "#},
5678      Browsers {
5679        safari: Some(4 << 16),
5680        firefox: Some(4 << 16),
5681        ie: Some(10 << 16),
5682        ..Browsers::default()
5683      },
5684    );
5685    prefix_test(
5686      r#"
5687      .foo {
5688        -ms-flex-item-align: center;
5689        -webkit-align-self: center;
5690        place-self: center flex-end;
5691      }
5692    "#,
5693      indoc! {r#"
5694      .foo {
5695        place-self: center flex-end;
5696      }
5697    "#},
5698      Browsers {
5699        safari: Some(11 << 16),
5700        ..Browsers::default()
5701      },
5702    );
5703    prefix_test(
5704      r#"
5705      .foo {
5706        place-self: center flex-end;
5707      }
5708    "#,
5709      indoc! {r#"
5710      .foo {
5711        align-self: center;
5712        justify-self: flex-end;
5713      }
5714    "#},
5715      Browsers {
5716        chrome: Some(57 << 16),
5717        ..Browsers::default()
5718      },
5719    );
5720    prefix_test(
5721      r#"
5722      .foo {
5723        place-self: center flex-end;
5724      }
5725    "#,
5726      indoc! {r#"
5727      .foo {
5728        place-self: center flex-end;
5729      }
5730    "#},
5731      Browsers {
5732        chrome: Some(59 << 16),
5733        ..Browsers::default()
5734      },
5735    );
5736    prefix_test(
5737      r#"
5738      .foo {
5739        align-items: flex-end;
5740      }
5741    "#,
5742      indoc! {r#"
5743      .foo {
5744        -webkit-box-align: end;
5745        -moz-box-align: end;
5746        -ms-flex-align: end;
5747        -webkit-align-items: flex-end;
5748        align-items: flex-end;
5749      }
5750    "#},
5751      Browsers {
5752        safari: Some(4 << 16),
5753        firefox: Some(4 << 16),
5754        ie: Some(10 << 16),
5755        ..Browsers::default()
5756      },
5757    );
5758    prefix_test(
5759      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      }
5767    "#,
5768      indoc! {r#"
5769      .foo {
5770        align-items: flex-end;
5771      }
5772    "#},
5773      Browsers {
5774        safari: Some(11 << 16),
5775        ..Browsers::default()
5776      },
5777    );
5778    prefix_test(
5779      r#"
5780      .foo {
5781        place-items: flex-end center;
5782      }
5783    "#,
5784      indoc! {r#"
5785      .foo {
5786        -webkit-box-align: end;
5787        -moz-box-align: end;
5788        -ms-flex-align: end;
5789        -webkit-align-items: flex-end;
5790        align-items: flex-end;
5791        justify-items: center;
5792      }
5793    "#},
5794      Browsers {
5795        safari: Some(4 << 16),
5796        firefox: Some(4 << 16),
5797        ie: Some(10 << 16),
5798        ..Browsers::default()
5799      },
5800    );
5801    prefix_test(
5802      r#"
5803      .foo {
5804        -webkit-box-align: end;
5805        -moz-box-align: end;
5806        -ms-flex-align: end;
5807        -webkit-align-items: flex-end;
5808        place-items: flex-end center;
5809      }
5810    "#,
5811      indoc! {r#"
5812      .foo {
5813        place-items: flex-end center;
5814      }
5815    "#},
5816      Browsers {
5817        safari: Some(11 << 16),
5818        ..Browsers::default()
5819      },
5820    );
5821    prefix_test(
5822      r#"
5823      .foo {
5824        place-items: flex-end center;
5825      }
5826    "#,
5827      indoc! {r#"
5828      .foo {
5829        align-items: flex-end;
5830        justify-items: center;
5831      }
5832    "#},
5833      Browsers {
5834        safari: Some(10 << 16),
5835        ..Browsers::default()
5836      },
5837    );
5838    prefix_test(
5839      r#"
5840      .foo {
5841        order: 1;
5842      }
5843    "#,
5844      indoc! {r#"
5845      .foo {
5846        -webkit-box-ordinal-group: 1;
5847        -moz-box-ordinal-group: 1;
5848        -ms-flex-order: 1;
5849        -webkit-order: 1;
5850        order: 1;
5851      }
5852    "#},
5853      Browsers {
5854        safari: Some(4 << 16),
5855        firefox: Some(4 << 16),
5856        ie: Some(10 << 16),
5857        ..Browsers::default()
5858      },
5859    );
5860    prefix_test(
5861      r#"
5862      .foo {
5863        -webkit-box-ordinal-group: 1;
5864        -moz-box-ordinal-group: 1;
5865        -ms-flex-order: 1;
5866        -webkit-order: 1;
5867        order: 1;
5868      }
5869    "#,
5870      indoc! {r#"
5871      .foo {
5872        order: 1;
5873      }
5874    "#},
5875      Browsers {
5876        safari: Some(11 << 16),
5877        ..Browsers::default()
5878      },
5879    );
5880    prefix_test(
5881      r#"
5882      .foo {
5883        -ms-flex: 0 0 8%;
5884        flex: 0 0 5%;
5885      }
5886    "#,
5887      indoc! {r#"
5888      .foo {
5889        -ms-flex: 0 0 8%;
5890        flex: 0 0 5%;
5891      }
5892    "#},
5893      Browsers {
5894        safari: Some(11 << 16),
5895        ..Browsers::default()
5896      },
5897    );
5898  }
5899
5900  #[test]
5901  fn test_font() {
5902    test(
5903      r#"
5904      .foo {
5905        font-family: "Helvetica", "Times New Roman", sans-serif;
5906        font-size: 12px;
5907        font-weight: bold;
5908        font-style: italic;
5909        font-stretch: expanded;
5910        font-variant-caps: small-caps;
5911        line-height: 1.2em;
5912      }
5913    "#,
5914      indoc! {r#"
5915      .foo {
5916        font: italic small-caps bold expanded 12px / 1.2em Helvetica, Times New Roman, sans-serif;
5917      }
5918    "#
5919      },
5920    );
5921
5922    minify_test(
5923      r#"
5924      .foo {
5925        font-family: "Helvetica", "Times New Roman", sans-serif;
5926        font-size: 12px;
5927        font-weight: bold;
5928        font-style: italic;
5929        font-stretch: expanded;
5930        font-variant-caps: small-caps;
5931        line-height: 1.2em;
5932      }
5933    "#,
5934      indoc! {".foo{font:italic small-caps 700 125% 12px/1.2em Helvetica,Times New Roman,sans-serif}"
5935      },
5936    );
5937
5938    test(
5939      r#"
5940      .foo {
5941        font: 12px "Helvetica", "Times New Roman", sans-serif;
5942        line-height: 1.2em;
5943      }
5944    "#,
5945      indoc! {r#"
5946      .foo {
5947        font: 12px / 1.2em Helvetica, Times New Roman, sans-serif;
5948      }
5949    "#
5950      },
5951    );
5952
5953    test(
5954      r#"
5955      .foo {
5956        font: 12px "Helvetica", "Times New Roman", sans-serif;
5957        line-height: var(--lh);
5958      }
5959    "#,
5960      indoc! {r#"
5961      .foo {
5962        font: 12px Helvetica, Times New Roman, sans-serif;
5963        line-height: var(--lh);
5964      }
5965    "#
5966      },
5967    );
5968
5969    minify_test(
5970      r#"
5971      .foo {
5972        font-family: "Helvetica", "Times New Roman", sans-serif;
5973        font-size: 12px;
5974        font-stretch: expanded;
5975      }
5976    "#,
5977      indoc! {".foo{font-family:Helvetica,Times New Roman,sans-serif;font-size:12px;font-stretch:125%}"
5978      },
5979    );
5980
5981    test(
5982      r#"
5983      .foo {
5984        font-family: "Helvetica", "Times New Roman", sans-serif;
5985        font-size: 12px;
5986        font-weight: bold;
5987        font-style: italic;
5988        font-stretch: expanded;
5989        font-variant-caps: all-small-caps;
5990        line-height: 1.2em;
5991      }
5992    "#,
5993      indoc! {r#"
5994      .foo {
5995        font: italic bold expanded 12px / 1.2em Helvetica, Times New Roman, sans-serif;
5996        font-variant-caps: all-small-caps;
5997      }
5998    "#
5999      },
6000    );
6001
6002    minify_test(
6003      ".foo { font: normal normal 600 9px/normal Charcoal; }",
6004      ".foo{font:600 9px Charcoal}",
6005    );
6006    minify_test(
6007      ".foo { font: normal normal 500 medium/normal Charcoal; }",
6008      ".foo{font:500 medium Charcoal}",
6009    );
6010    minify_test(
6011      ".foo { font: normal normal 400 medium Charcoal; }",
6012      ".foo{font:400 medium Charcoal}",
6013    );
6014    minify_test(
6015      ".foo { font: normal normal 500 medium/10px Charcoal; }",
6016      ".foo{font:500 medium/10px Charcoal}",
6017    );
6018    minify_test(
6019      ".foo { font-family: 'sans-serif'; }",
6020      ".foo{font-family:\"sans-serif\"}",
6021    );
6022    minify_test(".foo { font-family: sans-serif; }", ".foo{font-family:sans-serif}");
6023    minify_test(".foo { font-family: 'default'; }", ".foo{font-family:\"default\"}");
6024    minify_test(".foo { font-family: default; }", ".foo{font-family:default}");
6025    minify_test(".foo { font-family: 'inherit'; }", ".foo{font-family:\"inherit\"}");
6026    minify_test(".foo { font-family: inherit; }", ".foo{font-family:inherit}");
6027    minify_test(".foo { font-family: inherit test; }", ".foo{font-family:inherit test}");
6028    minify_test(
6029      ".foo { font-family: 'inherit test'; }",
6030      ".foo{font-family:inherit test}",
6031    );
6032    minify_test(".foo { font-family: revert; }", ".foo{font-family:revert}");
6033    minify_test(".foo { font-family: 'revert'; }", ".foo{font-family:\"revert\"}");
6034    minify_test(".foo { font-family: revert-layer; }", ".foo{font-family:revert-layer}");
6035    minify_test(
6036      ".foo { font-family: revert-layer, serif; }",
6037      ".foo{font-family:revert-layer,serif}",
6038    );
6039    minify_test(
6040      ".foo { font-family: 'revert', sans-serif; }",
6041      ".foo{font-family:\"revert\",sans-serif}",
6042    );
6043    minify_test(
6044      ".foo { font-family: 'revert', foo, sans-serif; }",
6045      ".foo{font-family:\"revert\",foo,sans-serif}",
6046    );
6047    minify_test(".foo { font-family: ''; }", ".foo{font-family:\"\"}");
6048
6049    // font-family in @font-face
6050    minify_test(
6051      "@font-face { font-family: 'revert'; }",
6052      "@font-face{font-family:\"revert\"}",
6053    );
6054    minify_test(
6055      "@font-face { font-family: 'revert-layer'; }",
6056      "@font-face{font-family:\"revert-layer\"}",
6057    );
6058
6059    prefix_test(
6060      r#"
6061      .foo {
6062        font-family: Helvetica, system-ui, sans-serif;
6063      }
6064    "#,
6065      indoc! {r#"
6066      .foo {
6067        font-family: Helvetica, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Noto Sans, Ubuntu, Cantarell, Helvetica Neue, sans-serif;
6068      }
6069    "#
6070      },
6071      Browsers {
6072        safari: Some(8 << 16),
6073        ..Browsers::default()
6074      },
6075    );
6076
6077    prefix_test(
6078      r#"
6079      .foo {
6080        font: 100%/1.5 Helvetica, system-ui, sans-serif;
6081      }
6082    "#,
6083      indoc! {r#"
6084      .foo {
6085        font: 100% / 1.5 Helvetica, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Noto Sans, Ubuntu, Cantarell, Helvetica Neue, sans-serif;
6086      }
6087    "#
6088      },
6089      Browsers {
6090        safari: Some(8 << 16),
6091        ..Browsers::default()
6092      },
6093    );
6094
6095    prefix_test(
6096      r#"
6097      .foo {
6098        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";
6099      }
6100    "#,
6101      indoc! {r#"
6102      .foo {
6103        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;
6104      }
6105    "#
6106      },
6107      Browsers {
6108        firefox: Some(91 << 16),
6109        ..Browsers::default()
6110      },
6111    );
6112
6113    prefix_test(
6114      r#"
6115      .foo {
6116        font-size: 22px;
6117        font-size: max(2cqw, 22px);
6118      }
6119    "#,
6120      indoc! {r#"
6121      .foo {
6122        font-size: 22px;
6123        font-size: max(2cqw, 22px);
6124      }
6125    "#
6126      },
6127      Browsers {
6128        safari: Some(14 << 16),
6129        ..Browsers::default()
6130      },
6131    );
6132    prefix_test(
6133      r#"
6134      .foo {
6135        font-size: 22px;
6136        font-size: max(2cqw, 22px);
6137      }
6138    "#,
6139      indoc! {r#"
6140      .foo {
6141        font-size: max(2cqw, 22px);
6142      }
6143    "#
6144      },
6145      Browsers {
6146        safari: Some(16 << 16),
6147        ..Browsers::default()
6148      },
6149    );
6150
6151    prefix_test(
6152      r#"
6153      .foo {
6154        font-size: 22px;
6155        font-size: xxx-large;
6156      }
6157    "#,
6158      indoc! {r#"
6159      .foo {
6160        font-size: 22px;
6161        font-size: xxx-large;
6162      }
6163    "#
6164      },
6165      Browsers {
6166        chrome: Some(70 << 16),
6167        ..Browsers::default()
6168      },
6169    );
6170    prefix_test(
6171      r#"
6172      .foo {
6173        font-size: 22px;
6174        font-size: xxx-large;
6175      }
6176    "#,
6177      indoc! {r#"
6178      .foo {
6179        font-size: xxx-large;
6180      }
6181    "#
6182      },
6183      Browsers {
6184        chrome: Some(80 << 16),
6185        ..Browsers::default()
6186      },
6187    );
6188
6189    prefix_test(
6190      r#"
6191      .foo {
6192        font-weight: 700;
6193        font-weight: 789;
6194      }
6195    "#,
6196      indoc! {r#"
6197      .foo {
6198        font-weight: 700;
6199        font-weight: 789;
6200      }
6201    "#
6202      },
6203      Browsers {
6204        chrome: Some(60 << 16),
6205        ..Browsers::default()
6206      },
6207    );
6208    prefix_test(
6209      r#"
6210      .foo {
6211        font-weight: 700;
6212        font-weight: 789;
6213      }
6214    "#,
6215      indoc! {r#"
6216      .foo {
6217        font-weight: 789;
6218      }
6219    "#
6220      },
6221      Browsers {
6222        chrome: Some(80 << 16),
6223        ..Browsers::default()
6224      },
6225    );
6226
6227    prefix_test(
6228      r#"
6229      .foo {
6230        font-family: Helvetica;
6231        font-family: system-ui;
6232      }
6233    "#,
6234      indoc! {r#"
6235      .foo {
6236        font-family: Helvetica;
6237        font-family: system-ui;
6238      }
6239    "#
6240      },
6241      Browsers {
6242        chrome: Some(50 << 16),
6243        ..Browsers::default()
6244      },
6245    );
6246    prefix_test(
6247      r#"
6248      .foo {
6249        font-family: Helvetica;
6250        font-family: system-ui;
6251      }
6252    "#,
6253      indoc! {r#"
6254      .foo {
6255        font-family: system-ui;
6256      }
6257    "#
6258      },
6259      Browsers {
6260        chrome: Some(80 << 16),
6261        ..Browsers::default()
6262      },
6263    );
6264
6265    prefix_test(
6266      r#"
6267      .foo {
6268        font-style: oblique;
6269        font-style: oblique 40deg;
6270      }
6271    "#,
6272      indoc! {r#"
6273      .foo {
6274        font-style: oblique;
6275        font-style: oblique 40deg;
6276      }
6277    "#
6278      },
6279      Browsers {
6280        firefox: Some(50 << 16),
6281        ..Browsers::default()
6282      },
6283    );
6284    prefix_test(
6285      r#"
6286      .foo {
6287        font-style: oblique;
6288        font-style: oblique 40deg;
6289      }
6290    "#,
6291      indoc! {r#"
6292      .foo {
6293        font-style: oblique 40deg;
6294      }
6295    "#
6296      },
6297      Browsers {
6298        firefox: Some(80 << 16),
6299        ..Browsers::default()
6300      },
6301    );
6302
6303    prefix_test(
6304      r#"
6305      .foo {
6306        font: 22px Helvetica;
6307        font: xxx-large system-ui;
6308      }
6309    "#,
6310      indoc! {r#"
6311      .foo {
6312        font: 22px Helvetica;
6313        font: xxx-large system-ui;
6314      }
6315    "#
6316      },
6317      Browsers {
6318        chrome: Some(70 << 16),
6319        ..Browsers::default()
6320      },
6321    );
6322    prefix_test(
6323      r#"
6324      .foo {
6325        font: 22px Helvetica;
6326        font: xxx-large system-ui;
6327      }
6328    "#,
6329      indoc! {r#"
6330      .foo {
6331        font: xxx-large system-ui;
6332      }
6333    "#
6334      },
6335      Browsers {
6336        chrome: Some(80 << 16),
6337        ..Browsers::default()
6338      },
6339    );
6340
6341    prefix_test(
6342      r#"
6343      .foo {
6344        font: var(--fallback);
6345        font: xxx-large system-ui;
6346      }
6347    "#,
6348      indoc! {r#"
6349      .foo {
6350        font: var(--fallback);
6351        font: xxx-large system-ui;
6352      }
6353    "#
6354      },
6355      Browsers {
6356        chrome: Some(50 << 16),
6357        ..Browsers::default()
6358      },
6359    );
6360  }
6361
6362  #[test]
6363  fn test_vertical_align() {
6364    minify_test(".foo { vertical-align: middle }", ".foo{vertical-align:middle}");
6365    minify_test(".foo { vertical-align: 0.3em }", ".foo{vertical-align:.3em}");
6366  }
6367
6368  #[test]
6369  fn test_selectors() {
6370    minify_test(":nth-col(2n) {width: 20px}", ":nth-col(2n){width:20px}");
6371    minify_test(":nth-col(10n-1) {width: 20px}", ":nth-col(10n-1){width:20px}");
6372    minify_test(":nth-col(-n+2) {width: 20px}", ":nth-col(-n+2){width:20px}");
6373    minify_test(":nth-col(even) {width: 20px}", ":nth-col(2n){width:20px}");
6374    minify_test(":nth-col(odd) {width: 20px}", ":nth-col(odd){width:20px}");
6375    minify_test(":nth-last-col(2n) {width: 20px}", ":nth-last-col(2n){width:20px}");
6376    minify_test(":nth-last-col(10n-1) {width: 20px}", ":nth-last-col(10n-1){width:20px}");
6377    minify_test(":nth-last-col(-n+2) {width: 20px}", ":nth-last-col(-n+2){width:20px}");
6378    minify_test(":nth-last-col(even) {width: 20px}", ":nth-last-col(2n){width:20px}");
6379    minify_test(":nth-last-col(odd) {width: 20px}", ":nth-last-col(odd){width:20px}");
6380    minify_test(":nth-child(odd) {width: 20px}", ":nth-child(odd){width:20px}");
6381    minify_test(":nth-child(2n) {width: 20px}", ":nth-child(2n){width:20px}");
6382    minify_test(":nth-child(2n+1) {width: 20px}", ":nth-child(odd){width:20px}");
6383    minify_test(":first-child {width: 20px}", ":first-child{width:20px}");
6384    minify_test(":nth-child(1) {width: 20px}", ":first-child{width:20px}");
6385    minify_test(":nth-last-child(1) {width: 20px}", ":last-child{width:20px}");
6386    minify_test(":nth-of-type(1) {width: 20px}", ":first-of-type{width:20px}");
6387    minify_test(":nth-last-of-type(1) {width: 20px}", ":last-of-type{width:20px}");
6388    minify_test(
6389      ":nth-child(even of li.important) {width: 20px}",
6390      ":nth-child(2n of li.important){width:20px}",
6391    );
6392    minify_test(
6393      ":nth-child(1 of li.important) {width: 20px}",
6394      ":nth-child(1 of li.important){width:20px}",
6395    );
6396    minify_test(
6397      ":nth-last-child(even of li.important) {width: 20px}",
6398      ":nth-last-child(2n of li.important){width:20px}",
6399    );
6400    minify_test(
6401      ":nth-last-child(1 of li.important) {width: 20px}",
6402      ":nth-last-child(1 of li.important){width:20px}",
6403    );
6404    minify_test(
6405      ":nth-last-child(1 of.important) {width: 20px}",
6406      ":nth-last-child(1 of .important){width:20px}",
6407    );
6408
6409    minify_test("[foo=\"baz\"] {color:red}", "[foo=baz]{color:red}");
6410    minify_test("[foo=\"foo bar\"] {color:red}", "[foo=foo\\ bar]{color:red}");
6411    minify_test("[foo=\"foo bar baz\"] {color:red}", "[foo=\"foo bar baz\"]{color:red}");
6412    minify_test("[foo=\"\"] {color:red}", "[foo=\"\"]{color:red}");
6413    minify_test(
6414      ".test:not([foo=\"bar\"]) {color:red}",
6415      ".test:not([foo=bar]){color:red}",
6416    );
6417    minify_test(".test + .foo {color:red}", ".test+.foo{color:red}");
6418    minify_test(".test ~ .foo {color:red}", ".test~.foo{color:red}");
6419    minify_test(".test .foo {color:red}", ".test .foo{color:red}");
6420    minify_test(
6421      ".custom-range::-webkit-slider-thumb:active {color:red}",
6422      ".custom-range::-webkit-slider-thumb:active{color:red}",
6423    );
6424    minify_test(".test:not(.foo, .bar) {color:red}", ".test:not(.foo,.bar){color:red}");
6425    minify_test(".test:is(.foo, .bar) {color:red}", ".test:is(.foo,.bar){color:red}");
6426    minify_test(
6427      ".test:where(.foo, .bar) {color:red}",
6428      ".test:where(.foo,.bar){color:red}",
6429    );
6430    minify_test(
6431      ".test:where(.foo, .bar) {color:red}",
6432      ".test:where(.foo,.bar){color:red}",
6433    );
6434    minify_test(":host {color:red}", ":host{color:red}");
6435    minify_test(":host(.foo) {color:red}", ":host(.foo){color:red}");
6436    minify_test("::slotted(span) {color:red", "::slotted(span){color:red}");
6437    minify_test(
6438      "custom-element::part(foo) {color:red}",
6439      "custom-element::part(foo){color:red}",
6440    );
6441    minify_test(".sm\\:text-5xl { font-size: 3rem }", ".sm\\:text-5xl{font-size:3rem}");
6442    minify_test("a:has(> img) {color:red}", "a:has(>img){color:red}");
6443    minify_test("dt:has(+ dt) {color:red}", "dt:has(+dt){color:red}");
6444    minify_test(
6445      "section:not(:has(h1, h2, h3, h4, h5, h6)) {color:red}",
6446      "section:not(:has(h1,h2,h3,h4,h5,h6)){color:red}",
6447    );
6448    minify_test(
6449      ":has(.sibling ~ .target) {color:red}",
6450      ":has(.sibling~.target){color:red}",
6451    );
6452    minify_test(".x:has(> .a > .b) {color:red}", ".x:has(>.a>.b){color:red}");
6453    minify_test(".x:has(.bar, #foo) {color:red}", ".x:has(.bar,#foo){color:red}");
6454    minify_test(".x:has(span + span) {color:red}", ".x:has(span+span){color:red}");
6455    minify_test("a:has(:visited) {color:red}", "a:has(:visited){color:red}");
6456    for element in [
6457      "-webkit-scrollbar",
6458      "-webkit-scrollbar-button",
6459      "-webkit-scrollbar-track",
6460      "-webkit-scrollbar-track-piece",
6461      "-webkit-scrollbar-thumb",
6462      "-webkit-scrollbar-corner",
6463      "-webkit-resizer",
6464    ] {
6465      for class in [
6466        "enabled",
6467        "disabled",
6468        "hover",
6469        "active",
6470        "horizontal",
6471        "vertical",
6472        "decrement",
6473        "increment",
6474        "start",
6475        "end",
6476        "double-button",
6477        "single-button",
6478        "no-button",
6479        "corner-present",
6480        "window-inactive",
6481      ] {
6482        minify_test(
6483          &format!("::{}:{} {{color:red}}", element, class),
6484          &format!("::{}:{}{{color:red}}", element, class),
6485        );
6486      }
6487    }
6488    for class in [
6489      "horizontal",
6490      "vertical",
6491      "decrement",
6492      "increment",
6493      "start",
6494      "end",
6495      "double-button",
6496      "single-button",
6497      "no-button",
6498      "corner-present",
6499      "window-inactive",
6500    ] {
6501      error_test(
6502        &format!(":{} {{color:red}}", class),
6503        ParserError::SelectorError(SelectorError::InvalidPseudoClassBeforeWebKitScrollbar),
6504      );
6505    }
6506    for element in [
6507      "-webkit-scrollbar",
6508      "-webkit-scrollbar-button",
6509      "-webkit-scrollbar-track",
6510      "-webkit-scrollbar-track-piece",
6511      "-webkit-scrollbar-thumb",
6512      "-webkit-scrollbar-corner",
6513      "-webkit-resizer",
6514    ] {
6515      error_test(
6516        &format!("::{}:focus {{color:red}}", element),
6517        ParserError::SelectorError(SelectorError::InvalidPseudoClassAfterWebKitScrollbar),
6518      );
6519    }
6520
6521    error_test(
6522      "a::first-letter:last-child {color:red}",
6523      ParserError::SelectorError(SelectorError::InvalidPseudoClassAfterPseudoElement),
6524    );
6525    minify_test(
6526      "a:last-child::first-letter {color:red}",
6527      "a:last-child:first-letter{color:red}",
6528    );
6529
6530    prefix_test(
6531      ".test:not(.foo, .bar) {color:red}",
6532      indoc! {r#"
6533      .test:not(:-webkit-any(.foo, .bar)) {
6534        color: red;
6535      }
6536
6537      .test:not(:is(.foo, .bar)) {
6538        color: red;
6539      }
6540      "#},
6541      Browsers {
6542        safari: Some(8 << 16),
6543        ..Browsers::default()
6544      },
6545    );
6546    prefix_test(
6547      ".test:not(.foo, .bar) {color:red}",
6548      indoc! {r#"
6549      .test:not(.foo, .bar) {
6550        color: red;
6551      }
6552      "#},
6553      Browsers {
6554        safari: Some(11 << 16),
6555        ..Browsers::default()
6556      },
6557    );
6558
6559    minify_test("a:lang(en) {color:red}", "a:lang(en){color:red}");
6560    minify_test("a:lang(en, fr) {color:red}", "a:lang(en,fr){color:red}");
6561    minify_test("a:lang('en') {color:red}", "a:lang(en){color:red}");
6562    minify_test(
6563      "a:-webkit-any(.foo, .bar) {color:red}",
6564      "a:-webkit-any(.foo,.bar){color:red}",
6565    );
6566    minify_test("a:-moz-any(.foo, .bar) {color:red}", "a:-moz-any(.foo,.bar){color:red}");
6567
6568    prefix_test(
6569      "a:is(.foo, .bar) {color:red}",
6570      indoc! {r#"
6571      a:-webkit-any(.foo, .bar) {
6572        color: red;
6573      }
6574
6575      a:-moz-any(.foo, .bar) {
6576        color: red;
6577      }
6578
6579      a:is(.foo, .bar) {
6580        color: red;
6581      }
6582      "#},
6583      Browsers {
6584        safari: Some(11 << 16),
6585        firefox: Some(50 << 16),
6586        ..Browsers::default()
6587      },
6588    );
6589
6590    prefix_test(
6591      "a:is(.foo > .bar) {color:red}",
6592      indoc! {r#"
6593      a:is(.foo > .bar) {
6594        color: red;
6595      }
6596      "#},
6597      Browsers {
6598        safari: Some(11 << 16),
6599        firefox: Some(50 << 16),
6600        ..Browsers::default()
6601      },
6602    );
6603
6604    prefix_test(
6605      "a:lang(en, fr) {color:red}",
6606      indoc! {r#"
6607      a:-webkit-any(:lang(en), :lang(fr)) {
6608        color: red;
6609      }
6610
6611      a:-moz-any(:lang(en), :lang(fr)) {
6612        color: red;
6613      }
6614
6615      a:is(:lang(en), :lang(fr)) {
6616        color: red;
6617      }
6618      "#},
6619      Browsers {
6620        safari: Some(11 << 16),
6621        firefox: Some(50 << 16),
6622        ..Browsers::default()
6623      },
6624    );
6625
6626    prefix_test(
6627      "a:lang(en, fr) {color:red}",
6628      indoc! {r#"
6629      a:is(:lang(en), :lang(fr)) {
6630        color: red;
6631      }
6632      "#},
6633      Browsers {
6634        safari: Some(14 << 16),
6635        firefox: Some(88 << 16),
6636        ..Browsers::default()
6637      },
6638    );
6639
6640    prefix_test(
6641      "a:lang(en, fr) {color:red}",
6642      indoc! {r#"
6643      a:lang(en, fr) {
6644        color: red;
6645      }
6646      "#},
6647      Browsers {
6648        safari: Some(14 << 16),
6649        ..Browsers::default()
6650      },
6651    );
6652
6653    prefix_test(
6654      "a:dir(rtl) {color:red}",
6655      indoc! {r#"
6656      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)) {
6657        color: red;
6658      }
6659
6660      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)) {
6661        color: red;
6662      }
6663
6664      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)) {
6665        color: red;
6666      }
6667      "#},
6668      Browsers {
6669        safari: Some(11 << 16),
6670        firefox: Some(50 << 16),
6671        ..Browsers::default()
6672      },
6673    );
6674
6675    prefix_test(
6676      "a:dir(ltr) {color:red}",
6677      indoc! {r#"
6678      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))) {
6679        color: red;
6680      }
6681
6682      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))) {
6683        color: red;
6684      }
6685
6686      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))) {
6687        color: red;
6688      }
6689      "#},
6690      Browsers {
6691        safari: Some(11 << 16),
6692        firefox: Some(50 << 16),
6693        ..Browsers::default()
6694      },
6695    );
6696
6697    prefix_test(
6698      "a:dir(rtl) {color:red}",
6699      indoc! {r#"
6700      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)) {
6701        color: red;
6702      }
6703      "#},
6704      Browsers {
6705        safari: Some(14 << 16),
6706        firefox: Some(88 << 16),
6707        ..Browsers::default()
6708      },
6709    );
6710
6711    prefix_test(
6712      "a:dir(ltr) {color:red}",
6713      indoc! {r#"
6714      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)) {
6715        color: red;
6716      }
6717      "#},
6718      Browsers {
6719        safari: Some(14 << 16),
6720        firefox: Some(88 << 16),
6721        ..Browsers::default()
6722      },
6723    );
6724
6725    prefix_test(
6726      "a:dir(rtl) {color:red}",
6727      indoc! {r#"
6728      a:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
6729        color: red;
6730      }
6731      "#},
6732      Browsers {
6733        safari: Some(14 << 16),
6734        ..Browsers::default()
6735      },
6736    );
6737
6738    prefix_test(
6739      "a:dir(ltr) {color:red}",
6740      indoc! {r#"
6741      a:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
6742        color: red;
6743      }
6744      "#},
6745      Browsers {
6746        safari: Some(14 << 16),
6747        ..Browsers::default()
6748      },
6749    );
6750
6751    prefix_test(
6752      "a:is(:dir(rtl)) {color:red}",
6753      indoc! {r#"
6754      a:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
6755        color: red;
6756      }
6757      "#},
6758      Browsers {
6759        safari: Some(14 << 16),
6760        ..Browsers::default()
6761      },
6762    );
6763
6764    prefix_test(
6765      "a:where(:dir(rtl)) {color:red}",
6766      indoc! {r#"
6767      a:where(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
6768        color: red;
6769      }
6770      "#},
6771      Browsers {
6772        safari: Some(14 << 16),
6773        ..Browsers::default()
6774      },
6775    );
6776
6777    prefix_test(
6778      "a:has(:dir(rtl)) {color:red}",
6779      indoc! {r#"
6780      a:has(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
6781        color: red;
6782      }
6783      "#},
6784      Browsers {
6785        safari: Some(14 << 16),
6786        ..Browsers::default()
6787      },
6788    );
6789
6790    prefix_test(
6791      "a:not(:dir(rtl)) {color:red}",
6792      indoc! {r#"
6793      a:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
6794        color: red;
6795      }
6796      "#},
6797      Browsers {
6798        safari: Some(14 << 16),
6799        ..Browsers::default()
6800      },
6801    );
6802
6803    prefix_test(
6804      "a:dir(rtl)::after {color:red}",
6805      indoc! {r#"
6806      a:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi):after {
6807        color: red;
6808      }
6809      "#},
6810      Browsers {
6811        safari: Some(14 << 16),
6812        ..Browsers::default()
6813      },
6814    );
6815
6816    prefix_test(
6817      "a:dir(rtl) div {color:red}",
6818      indoc! {r#"
6819      a:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) div {
6820        color: red;
6821      }
6822      "#},
6823      Browsers {
6824        safari: Some(14 << 16),
6825        ..Browsers::default()
6826      },
6827    );
6828
6829    minify_test(".foo::cue {color: red}", ".foo::cue{color:red}");
6830    minify_test(".foo::cue-region {color: red}", ".foo::cue-region{color:red}");
6831    minify_test(".foo::cue(b) {color: red}", ".foo::cue(b){color:red}");
6832    minify_test(".foo::cue-region(b) {color: red}", ".foo::cue-region(b){color:red}");
6833    minify_test(
6834      "::cue(v[voice='active']) {color: yellow;}",
6835      "::cue(v[voice=active]){color:#ff0}",
6836    );
6837    minify_test(":foo(bar) { color: yellow }", ":foo(bar){color:#ff0}");
6838    minify_test("::foo(bar) { color: yellow }", "::foo(bar){color:#ff0}");
6839    minify_test("::foo(*) { color: yellow }", "::foo(*){color:#ff0}");
6840
6841    minify_test(":is(.foo) { color: yellow }", ".foo{color:#ff0}");
6842    minify_test(":is(#foo) { color: yellow }", "#foo{color:#ff0}");
6843    minify_test("a:is(.foo) { color: yellow }", "a.foo{color:#ff0}");
6844    minify_test("a:is([data-test]) { color: yellow }", "a[data-test]{color:#ff0}");
6845    minify_test(".foo:is(a) { color: yellow }", ".foo:is(a){color:#ff0}");
6846    minify_test(".foo:is(*|a) { color: yellow }", ".foo:is(*|a){color:#ff0}");
6847    minify_test(".foo:is(*) { color: yellow }", ".foo:is(*){color:#ff0}");
6848    minify_test(
6849      "@namespace svg url(http://www.w3.org/2000/svg); .foo:is(svg|a) { color: yellow }",
6850      "@namespace svg \"http://www.w3.org/2000/svg\";.foo:is(svg|a){color:#ff0}",
6851    );
6852    minify_test("a:is(.foo .bar) { color: yellow }", "a:is(.foo .bar){color:#ff0}");
6853    minify_test(":is(.foo, .bar) { color: yellow }", ":is(.foo,.bar){color:#ff0}");
6854    minify_test("a:is(:not(.foo)) { color: yellow }", "a:not(.foo){color:#ff0}");
6855    minify_test("a:is(:first-child) { color: yellow }", "a:first-child{color:#ff0}");
6856    minify_test("a:is(:has(.foo)) { color: yellow }", "a:has(.foo){color:#ff0}");
6857    minify_test("a:is(:is(.foo)) { color: yellow }", "a.foo{color:#ff0}");
6858    minify_test(":host(:hover) {color: red}", ":host(:hover){color:red}");
6859    minify_test("::slotted(:hover) {color: red}", "::slotted(:hover){color:red}");
6860
6861    minify_test(
6862      ":root::view-transition {position: fixed}",
6863      ":root::view-transition{position:fixed}",
6864    );
6865    minify_test(
6866      ":root:active-view-transition {position: fixed}",
6867      ":root:active-view-transition{position:fixed}",
6868    );
6869    minify_test(
6870      ":root:active-view-transition-type(slide-in) {position: fixed}",
6871      ":root:active-view-transition-type(slide-in){position:fixed}",
6872    );
6873    minify_test(
6874      ":root:active-view-transition-type(slide-in, reverse) {position: fixed}",
6875      ":root:active-view-transition-type(slide-in,reverse){position:fixed}",
6876    );
6877
6878    for name in &[
6879      "view-transition-group",
6880      "view-transition-image-pair",
6881      "view-transition-new",
6882      "view-transition-old",
6883    ] {
6884      minify_test(
6885        &format!(":root::{}(*) {{position: fixed}}", name),
6886        &format!(":root::{}(*){{position:fixed}}", name),
6887      );
6888      minify_test(
6889        &format!(":root::{}(*.class) {{position: fixed}}", name),
6890        &format!(":root::{}(*.class){{position:fixed}}", name),
6891      );
6892      minify_test(
6893        &format!(":root::{}(*.class.class) {{position: fixed}}", name),
6894        &format!(":root::{}(*.class.class){{position:fixed}}", name),
6895      );
6896      minify_test(
6897        &format!(":root::{}(foo) {{position: fixed}}", name),
6898        &format!(":root::{}(foo){{position:fixed}}", name),
6899      );
6900      minify_test(
6901        &format!(":root::{}(foo.class) {{position: fixed}}", name),
6902        &format!(":root::{}(foo.class){{position:fixed}}", name),
6903      );
6904      minify_test(
6905        &format!(":root::{}(foo.bar.baz) {{position: fixed}}", name),
6906        &format!(":root::{}(foo.bar.baz){{position:fixed}}", name),
6907      );
6908      minify_test(
6909        &format!(":root::{}(foo):only-child {{position: fixed}}", name),
6910        &format!(":root::{}(foo):only-child{{position:fixed}}", name),
6911      );
6912      minify_test(
6913        &format!(":root::{}(foo.bar.baz):only-child {{position: fixed}}", name),
6914        &format!(":root::{}(foo.bar.baz):only-child{{position:fixed}}", name),
6915      );
6916      minify_test(
6917        &format!(":root::{}(.foo) {{position: fixed}}", name),
6918        &format!(":root::{}(.foo){{position:fixed}}", name),
6919      );
6920      minify_test(
6921        &format!(":root::{}(.foo.bar) {{position: fixed}}", name),
6922        &format!(":root::{}(.foo.bar){{position:fixed}}", name),
6923      );
6924      error_test(
6925        &format!(":root::{}(foo):first-child {{position: fixed}}", name),
6926        ParserError::SelectorError(SelectorError::InvalidPseudoClassAfterPseudoElement),
6927      );
6928      error_test(
6929        &format!(":root::{}(foo)::before {{position: fixed}}", name),
6930        ParserError::SelectorError(SelectorError::InvalidState),
6931      );
6932      error_test(
6933        &format!(":root::{}(*.*) {{position: fixed}}", name),
6934        ParserError::SelectorError(SelectorError::InvalidState),
6935      );
6936      error_test(
6937        &format!(":root::{}(*. cls) {{position: fixed}}", name),
6938        ParserError::SelectorError(SelectorError::InvalidState),
6939      );
6940      error_test(
6941        &format!(":root::{}(foo .bar) {{position: fixed}}", name),
6942        ParserError::SelectorError(SelectorError::InvalidState),
6943      );
6944      error_test(
6945        &format!(":root::{}(*.cls. c) {{position: fixed}}", name),
6946        ParserError::SelectorError(SelectorError::InvalidState),
6947      );
6948      error_test(
6949        &format!(":root::{}(*.cls>cls) {{position: fixed}}", name),
6950        ParserError::SelectorError(SelectorError::InvalidState),
6951      );
6952      error_test(
6953        &format!(":root::{}(*.cls.foo.*) {{position: fixed}}", name),
6954        ParserError::SelectorError(SelectorError::InvalidState),
6955      );
6956    }
6957
6958    minify_test(".foo ::deep .bar {width: 20px}", ".foo ::deep .bar{width:20px}");
6959    minify_test(".foo::deep .bar {width: 20px}", ".foo::deep .bar{width:20px}");
6960    minify_test(".foo ::deep.bar {width: 20px}", ".foo ::deep.bar{width:20px}");
6961    minify_test(".foo ::unknown .bar {width: 20px}", ".foo ::unknown .bar{width:20px}");
6962    minify_test(
6963      ".foo ::unknown(foo) .bar {width: 20px}",
6964      ".foo ::unknown(foo) .bar{width:20px}",
6965    );
6966    minify_test(
6967      ".foo ::unknown:only-child {width: 20px}",
6968      ".foo ::unknown:only-child{width:20px}",
6969    );
6970    minify_test(
6971      ".foo ::unknown(.foo) .bar {width: 20px}",
6972      ".foo ::unknown(.foo) .bar{width:20px}",
6973    );
6974    minify_test(
6975      ".foo ::unknown(.foo .bar / .baz) .bar {width: 20px}",
6976      ".foo ::unknown(.foo .bar / .baz) .bar{width:20px}",
6977    );
6978    minify_test(
6979      ".foo ::unknown(something(foo)) .bar {width: 20px}",
6980      ".foo ::unknown(something(foo)) .bar{width:20px}",
6981    );
6982    minify_test(
6983      ".foo ::unknown([abc]) .bar {width: 20px}",
6984      ".foo ::unknown([abc]) .bar{width:20px}",
6985    );
6986
6987    let deep_options = ParserOptions {
6988      flags: ParserFlags::DEEP_SELECTOR_COMBINATOR,
6989      ..ParserOptions::default()
6990    };
6991
6992    error_test(
6993      ".foo >>> .bar {width: 20px}",
6994      ParserError::SelectorError(SelectorError::DanglingCombinator),
6995    );
6996    error_test(
6997      ".foo /deep/ .bar {width: 20px}",
6998      ParserError::SelectorError(SelectorError::DanglingCombinator),
6999    );
7000    minify_test_with_options(
7001      ".foo >>> .bar {width: 20px}",
7002      ".foo>>>.bar{width:20px}",
7003      deep_options.clone(),
7004    );
7005    minify_test_with_options(
7006      ".foo /deep/ .bar {width: 20px}",
7007      ".foo /deep/ .bar{width:20px}",
7008      deep_options.clone(),
7009    );
7010
7011    let pure_css_module_options = ParserOptions {
7012      css_modules: Some(crate::css_modules::Config {
7013        pure: true,
7014        ..Default::default()
7015      }),
7016      ..ParserOptions::default()
7017    };
7018
7019    minify_error_test_with_options(
7020      "div {width: 20px}",
7021      MinifyErrorKind::ImpureCSSModuleSelector,
7022      pure_css_module_options.clone(),
7023    );
7024    minify_error_test_with_options(
7025      ":global(.foo) {width: 20px}",
7026      MinifyErrorKind::ImpureCSSModuleSelector,
7027      pure_css_module_options.clone(),
7028    );
7029    minify_error_test_with_options(
7030      "[foo=bar] {width: 20px}",
7031      MinifyErrorKind::ImpureCSSModuleSelector,
7032      pure_css_module_options.clone(),
7033    );
7034    minify_error_test_with_options(
7035      "div, .foo {width: 20px}",
7036      MinifyErrorKind::ImpureCSSModuleSelector,
7037      pure_css_module_options.clone(),
7038    );
7039    minify_test_with_options(
7040      ":local(.foo) {width: 20px}",
7041      "._8Z4fiW_foo{width:20px}",
7042      pure_css_module_options.clone(),
7043    );
7044    minify_test_with_options(
7045      "div.my-class {color: red;}",
7046      "div._8Z4fiW_my-class{color:red}",
7047      pure_css_module_options.clone(),
7048    );
7049    minify_test_with_options(
7050      "#id {color: red;}",
7051      "#_8Z4fiW_id{color:red}",
7052      pure_css_module_options.clone(),
7053    );
7054    minify_test_with_options(
7055      "a .my-class{color: red;}",
7056      "a ._8Z4fiW_my-class{color:red}",
7057      pure_css_module_options.clone(),
7058    );
7059    minify_test_with_options(
7060      ".my-class a {color: red;}",
7061      "._8Z4fiW_my-class a{color:red}",
7062      pure_css_module_options.clone(),
7063    );
7064    minify_test_with_options(
7065      ".my-class:is(a) {color: red;}",
7066      "._8Z4fiW_my-class:is(a){color:red}",
7067      pure_css_module_options.clone(),
7068    );
7069    minify_test_with_options(
7070      "div:has(.my-class) {color: red;}",
7071      "div:has(._8Z4fiW_my-class){color:red}",
7072      pure_css_module_options.clone(),
7073    );
7074    minify_test_with_options(
7075      ".foo { html &:hover { a_value: some-value; } }",
7076      "._8Z4fiW_foo{html &:hover{a_value:some-value}}",
7077      pure_css_module_options.clone(),
7078    );
7079    minify_test_with_options(
7080      ".foo { span { color: red; } }",
7081      "._8Z4fiW_foo{& span{color:red}}",
7082      pure_css_module_options.clone(),
7083    );
7084    minify_error_test_with_options(
7085      "html { .foo { span { color: red; } } }",
7086      MinifyErrorKind::ImpureCSSModuleSelector,
7087      pure_css_module_options.clone(),
7088    );
7089    minify_test_with_options(
7090      ".foo { div { span { color: red; } } }",
7091      "._8Z4fiW_foo{& div{& span{color:red}}}",
7092      pure_css_module_options.clone(),
7093    );
7094    minify_error_test_with_options(
7095      "@scope (div) { .foo { color: red } }",
7096      MinifyErrorKind::ImpureCSSModuleSelector,
7097      pure_css_module_options.clone(),
7098    );
7099    minify_error_test_with_options(
7100      "@scope (.a) to (div) { .foo { color: red } }",
7101      MinifyErrorKind::ImpureCSSModuleSelector,
7102      pure_css_module_options.clone(),
7103    );
7104    minify_error_test_with_options(
7105      "@scope (.a) to (.b) { div { color: red } }",
7106      MinifyErrorKind::ImpureCSSModuleSelector,
7107      pure_css_module_options.clone(),
7108    );
7109    minify_test_with_options(
7110      "@scope (.a) to (.b) { .foo { color: red } }",
7111      "@scope(._8Z4fiW_a) to (._8Z4fiW_b){._8Z4fiW_foo{color:red}}",
7112      pure_css_module_options.clone(),
7113    );
7114
7115    error_test(
7116      "input.defaultCheckbox::before h1 {width: 20px}",
7117      ParserError::SelectorError(SelectorError::UnexpectedSelectorAfterPseudoElement(Token::Ident(
7118        "h1".into(),
7119      ))),
7120    );
7121    error_test(
7122      "input.defaultCheckbox::before .my-class {width: 20px}",
7123      ParserError::SelectorError(SelectorError::UnexpectedSelectorAfterPseudoElement(Token::Delim('.'))),
7124    );
7125    error_test(
7126      "input.defaultCheckbox::before.my-class {width: 20px}",
7127      ParserError::SelectorError(SelectorError::UnexpectedSelectorAfterPseudoElement(Token::Delim('.'))),
7128    );
7129    error_test(
7130      "input.defaultCheckbox::before #id {width: 20px}",
7131      ParserError::SelectorError(SelectorError::UnexpectedSelectorAfterPseudoElement(Token::IDHash(
7132        "id".into(),
7133      ))),
7134    );
7135    error_test(
7136      "input.defaultCheckbox::before#id {width: 20px}",
7137      ParserError::SelectorError(SelectorError::UnexpectedSelectorAfterPseudoElement(Token::IDHash(
7138        "id".into(),
7139      ))),
7140    );
7141    error_test(
7142      "input.defaultCheckbox::before [attr] {width: 20px}",
7143      ParserError::SelectorError(SelectorError::UnexpectedSelectorAfterPseudoElement(
7144        Token::SquareBracketBlock,
7145      )),
7146    );
7147    error_test(
7148      "input.defaultCheckbox::before[attr] {width: 20px}",
7149      ParserError::SelectorError(SelectorError::UnexpectedSelectorAfterPseudoElement(
7150        Token::SquareBracketBlock,
7151      )),
7152    );
7153  }
7154
7155  #[test]
7156  fn test_keyframes() {
7157    minify_test(
7158      r#"
7159      @keyframes "test" {
7160        100% {
7161          background: blue
7162        }
7163      }
7164    "#,
7165      "@keyframes test{to{background:#00f}}",
7166    );
7167    minify_test(
7168      r#"
7169      @keyframes test {
7170        100% {
7171          background: blue
7172        }
7173      }
7174    "#,
7175      "@keyframes test{to{background:#00f}}",
7176    );
7177
7178    // named animation range percentages
7179    minify_test(
7180      r#"
7181      @keyframes test {
7182        entry 0% {
7183          background: blue
7184        }
7185        exit 100% {
7186          background: green
7187        }
7188      }
7189    "#,
7190      "@keyframes test{entry 0%{background:#00f}exit 100%{background:green}}",
7191    );
7192
7193    // CSS-wide keywords and `none` cannot remove quotes.
7194    minify_test(
7195      r#"
7196      @keyframes "revert" {
7197        from {
7198          background: green;
7199        }
7200      }
7201    "#,
7202      "@keyframes \"revert\"{0%{background:green}}",
7203    );
7204
7205    minify_test(
7206      r#"
7207      @keyframes "none" {
7208        from {
7209          background: green;
7210        }
7211      }
7212    "#,
7213      "@keyframes \"none\"{0%{background:green}}",
7214    );
7215
7216    // named animation ranges cannot be used with to or from
7217    minify_test(
7218      r#"
7219      @keyframes test {
7220        entry to {
7221          background: blue
7222        }
7223      }
7224    "#,
7225      "@keyframes test{}",
7226    );
7227
7228    // CSS-wide keywords without quotes throws an error.
7229    error_test(
7230      r#"
7231      @keyframes revert {}
7232    "#,
7233      ParserError::UnexpectedToken(Token::Ident("revert".into())),
7234    );
7235
7236    error_test(
7237      r#"
7238      @keyframes revert-layer {}
7239    "#,
7240      ParserError::UnexpectedToken(Token::Ident("revert-layer".into())),
7241    );
7242
7243    error_test(
7244      r#"
7245      @keyframes none {}
7246    "#,
7247      ParserError::UnexpectedToken(Token::Ident("none".into())),
7248    );
7249
7250    error_test(
7251      r#"
7252      @keyframes NONE {}
7253    "#,
7254      ParserError::UnexpectedToken(Token::Ident("NONE".into())),
7255    );
7256
7257    minify_test(
7258      r#"
7259      @-webkit-keyframes test {
7260        from {
7261          background: green;
7262          background-color: red;
7263        }
7264
7265        100% {
7266          background: blue
7267        }
7268      }
7269    "#,
7270      "@-webkit-keyframes test{0%{background:red}to{background:#00f}}",
7271    );
7272    minify_test(
7273      r#"
7274      @-moz-keyframes test {
7275        from {
7276          background: green;
7277          background-color: red;
7278        }
7279
7280        100% {
7281          background: blue
7282        }
7283      }
7284    "#,
7285      "@-moz-keyframes test{0%{background:red}to{background:#00f}}",
7286    );
7287    minify_test(r#"
7288      @-webkit-keyframes test {
7289        from {
7290          background: green;
7291          background-color: red;
7292        }
7293
7294        100% {
7295          background: blue
7296        }
7297      }
7298      @-moz-keyframes test {
7299        from {
7300          background: green;
7301          background-color: red;
7302        }
7303
7304        100% {
7305          background: blue
7306        }
7307      }
7308    "#, "@-webkit-keyframes test{0%{background:red}to{background:#00f}}@-moz-keyframes test{0%{background:red}to{background:#00f}}");
7309
7310    prefix_test(
7311      r#"
7312      @keyframes test {
7313        from {
7314          background: green;
7315        }
7316        to {
7317          background: blue
7318        }
7319      }
7320    "#,
7321      indoc! { r#"
7322      @-webkit-keyframes test {
7323        from {
7324          background: green;
7325        }
7326
7327        to {
7328          background: #00f;
7329        }
7330      }
7331
7332      @-moz-keyframes test {
7333        from {
7334          background: green;
7335        }
7336
7337        to {
7338          background: #00f;
7339        }
7340      }
7341
7342      @keyframes test {
7343        from {
7344          background: green;
7345        }
7346
7347        to {
7348          background: #00f;
7349        }
7350      }
7351    "#},
7352      Browsers {
7353        safari: Some(5 << 16),
7354        firefox: Some(6 << 16),
7355        ..Browsers::default()
7356      },
7357    );
7358    prefix_test(
7359      r#"
7360      @-webkit-keyframes test {
7361        from {
7362          background: green;
7363        }
7364
7365        to {
7366          background: blue;
7367        }
7368      }
7369      @-moz-keyframes test {
7370        from {
7371          background: green;
7372        }
7373
7374        to {
7375          background: blue;
7376        }
7377      }
7378      @keyframes test {
7379        from {
7380          background: green;
7381        }
7382        to {
7383          background: blue
7384        }
7385      }
7386    "#,
7387      indoc! { r#"
7388      @keyframes test {
7389        from {
7390          background: green;
7391        }
7392
7393        to {
7394          background: #00f;
7395        }
7396      }
7397    "#},
7398      Browsers {
7399        safari: Some(10 << 16),
7400        firefox: Some(17 << 16),
7401        ..Browsers::default()
7402      },
7403    );
7404    prefix_test(
7405      r#"
7406      @-webkit-keyframes test1 {
7407        from {
7408          background: green;
7409        }
7410
7411        to {
7412          background: blue;
7413        }
7414      }
7415
7416      @-moz-keyframes test2 {
7417        from {
7418          background: green;
7419        }
7420
7421        to {
7422          background: blue;
7423        }
7424      }
7425
7426      @keyframes test3 {
7427        from {
7428          background: green;
7429        }
7430        to {
7431          background: blue
7432        }
7433      }
7434    "#,
7435      indoc! { r#"
7436      @-webkit-keyframes test1 {
7437        from {
7438          background: green;
7439        }
7440
7441        to {
7442          background: #00f;
7443        }
7444      }
7445
7446      @-moz-keyframes test2 {
7447        from {
7448          background: green;
7449        }
7450
7451        to {
7452          background: #00f;
7453        }
7454      }
7455
7456      @keyframes test3 {
7457        from {
7458          background: green;
7459        }
7460
7461        to {
7462          background: #00f;
7463        }
7464      }
7465    "#},
7466      Browsers {
7467        safari: Some(10 << 16),
7468        firefox: Some(17 << 16),
7469        ..Browsers::default()
7470      },
7471    );
7472    prefix_test(
7473      r#"
7474      @-webkit-keyframes test {
7475        from {
7476          background: green;
7477        }
7478
7479        to {
7480          background: red;
7481        }
7482      }
7483      @-moz-keyframes test {
7484        from {
7485          background: green;
7486        }
7487
7488        to {
7489          background: pink;
7490        }
7491      }
7492      @keyframes test {
7493        from {
7494          background: green;
7495        }
7496        to {
7497          background: blue
7498        }
7499      }
7500    "#,
7501      indoc! { r#"
7502      @-webkit-keyframes test {
7503        from {
7504          background: green;
7505        }
7506
7507        to {
7508          background: red;
7509        }
7510      }
7511
7512      @-moz-keyframes test {
7513        from {
7514          background: green;
7515        }
7516
7517        to {
7518          background: pink;
7519        }
7520      }
7521
7522      @keyframes test {
7523        from {
7524          background: green;
7525        }
7526
7527        to {
7528          background: #00f;
7529        }
7530      }
7531    "#},
7532      Browsers {
7533        safari: Some(10 << 16),
7534        firefox: Some(17 << 16),
7535        ..Browsers::default()
7536      },
7537    );
7538
7539    minify_test(
7540      r#"
7541      @keyframes test {
7542        100% {
7543          background: blue
7544        }
7545      }
7546
7547      @keyframes test {
7548        100% {
7549          background: red
7550        }
7551      }
7552    "#,
7553      "@keyframes test{to{background:red}}",
7554    );
7555    minify_test(
7556      r#"
7557      @keyframes test {
7558        100% {
7559          background: blue
7560        }
7561      }
7562
7563      @-webkit-keyframes test {
7564        100% {
7565          background: red
7566        }
7567      }
7568    "#,
7569      "@keyframes test{to{background:#00f}}@-webkit-keyframes test{to{background:red}}",
7570    );
7571  }
7572
7573  #[test]
7574  fn test_important() {
7575    test(
7576      r#"
7577      .foo {
7578        align-items: center;
7579        justify-items: center !important;
7580      }
7581    "#,
7582      indoc! {r#"
7583      .foo {
7584        align-items: center;
7585        justify-items: center !important;
7586      }
7587    "#},
7588    );
7589
7590    test(
7591      r#"
7592      .foo {
7593        justify-items: center !important;
7594        align-items: center;
7595      }
7596    "#,
7597      indoc! {r#"
7598      .foo {
7599        align-items: center;
7600        justify-items: center !important;
7601      }
7602    "#},
7603    );
7604
7605    minify_test(
7606      r#"
7607      .foo {
7608        font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !important;
7609      }
7610    "#,
7611      ".foo{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important}",
7612    );
7613  }
7614
7615  #[test]
7616  fn test_calc() {
7617    minify_test(".foo { width: calc(20px * 2) }", ".foo{width:40px}");
7618    minify_test(".foo { font-size: calc(100vw / 35) }", ".foo{font-size:2.85714vw}");
7619    minify_test(".foo { width: calc(20px * 2 * 3) }", ".foo{width:120px}");
7620    minify_test(".foo { width: calc(20px + 30px) }", ".foo{width:50px}");
7621    minify_test(".foo { width: calc(20px + 30px + 40px) }", ".foo{width:90px}");
7622    minify_test(".foo { width: calc(100% - 30px) }", ".foo{width:calc(100% - 30px)}");
7623    minify_test(
7624      ".foo { width: calc(100% - 30px + 20px) }",
7625      ".foo{width:calc(100% - 10px)}",
7626    );
7627    minify_test(
7628      ".foo { width: calc(20px + 100% - 30px) }",
7629      ".foo{width:calc(100% - 10px)}",
7630    );
7631    minify_test(
7632      ".foo { width: calc(20px + 100% + 10vw - 30px) }",
7633      ".foo{width:calc(100% - 10px + 10vw)}",
7634    );
7635    minify_test(
7636      ".foo { width: calc(20px + 100% - 30px) }",
7637      ".foo{width:calc(100% - 10px)}",
7638    );
7639    minify_test(
7640      ".foo { width: calc(2 * (100% - 20px)) }",
7641      ".foo{width:calc(200% - 40px)}",
7642    );
7643    minify_test(
7644      ".foo { width: calc((100% - 20px) * 2) }",
7645      ".foo{width:calc(200% - 40px)}",
7646    );
7647    minify_test(".foo { width: calc(100% - 20px * 2) }", ".foo{width:calc(100% - 40px)}");
7648    minify_test(".foo { width: calc(1px + 1px) }", ".foo{width:2px}");
7649    minify_test(".foo { width: calc(100vw / 2) }", ".foo{width:50vw}");
7650    minify_test(".foo { width: calc(50px - (20px - 30px)) }", ".foo{width:60px}");
7651    minify_test(".foo { width: calc(100px - (100px - 100%)) }", ".foo{width:100%}");
7652    minify_test(
7653      ".foo { width: calc(100px + (100px - 100%)) }",
7654      ".foo{width:calc(200px - 100%)}",
7655    );
7656    minify_test(
7657      ".foo { width: calc(1px - (2em + 3%)) }",
7658      ".foo{width:calc(1px + -2em - 3%)}",
7659    ); // TODO: fix sign
7660    minify_test(
7661      ".foo { width: calc((100vw - 50em) / 2) }",
7662      ".foo{width:calc(50vw - 25em)}",
7663    );
7664    minify_test(
7665      ".foo { width: calc(1px - (2em + 4vh + 3%)) }",
7666      ".foo{width:calc(1px + -2em - 4vh - 3%)}",
7667    ); // TODO
7668    minify_test(
7669      ".foo { width: calc(1px + (2em + (3vh + 4px))) }",
7670      ".foo{width:calc(2em + 3vh + 5px)}",
7671    );
7672    minify_test(
7673      ".foo { width: calc(1px - (2em + 4px - 6vh) / 2) }",
7674      ".foo{width:calc(-1em - 1px + 3vh)}",
7675    );
7676    minify_test(
7677      ".foo { width: calc(100% - calc(50% + 25px)) }",
7678      ".foo{width:calc(50% - 25px)}",
7679    );
7680    minify_test(".foo { width: calc(1px/100) }", ".foo{width:.01px}");
7681    minify_test(
7682      ".foo { width: calc(100vw / 2 - 6px + 0px) }",
7683      ".foo{width:calc(50vw - 6px)}",
7684    );
7685    minify_test(".foo { width: calc(1px + 1) }", ".foo{width:calc(1px + 1)}");
7686    minify_test(
7687      ".foo { width: calc( (1em - calc( 10px + 1em)) / 2) }",
7688      ".foo{width:-5px}",
7689    );
7690    minify_test(
7691      ".foo { width: calc((100px - 1em) + (-50px + 1em)) }",
7692      ".foo{width:50px}",
7693    );
7694    minify_test(
7695      ".foo { width: calc(100% + (2 * 100px) - ((75.37% - 63.5px) - 900px)) }",
7696      ".foo{width:calc(24.63% + 1163.5px)}",
7697    );
7698    minify_test(
7699      ".foo { width: calc(((((100% + (2 * 30px) + 63.5px) / 0.7537) - (100vw - 60px)) / 2) + 30px) }",
7700      ".foo{width:calc(66.3394% + 141.929px - 50vw)}",
7701    );
7702    minify_test(
7703      ".foo { width: calc(((75.37% - 63.5px) - 900px) + (2 * 100px)) }",
7704      ".foo{width:calc(75.37% - 763.5px)}",
7705    );
7706    minify_test(
7707      ".foo { width: calc((900px - (10% - 63.5px)) + (2 * 100px)) }",
7708      ".foo{width:calc(1163.5px - 10%)}",
7709    );
7710    minify_test(".foo { width: calc(500px/0) }", ".foo{width:calc(500px/0)}");
7711    minify_test(".foo { width: calc(500px/2px) }", ".foo{width:calc(500px/2px)}");
7712    minify_test(".foo { width: calc(100% / 3 * 3) }", ".foo{width:100%}");
7713    minify_test(".foo { width: calc(+100px + +100px) }", ".foo{width:200px}");
7714    minify_test(".foo { width: calc(+100px - +100px) }", ".foo{width:0}");
7715    minify_test(".foo { width: calc(200px * +1) }", ".foo{width:200px}");
7716    minify_test(".foo { width: calc(200px / +1) }", ".foo{width:200px}");
7717    minify_test(".foo { width: calc(1.1e+1px + 1.1e+1px) }", ".foo{width:22px}");
7718    minify_test(".foo { border-width: calc(1px + 2px) }", ".foo{border-width:3px}");
7719    minify_test(
7720      ".foo { border-width: calc(1em + 2px + 2em + 3px) }",
7721      ".foo{border-width:calc(3em + 5px)}",
7722    );
7723
7724    minify_test(
7725      ".foo { border-width: min(1em, 2px) }",
7726      ".foo{border-width:min(1em,2px)}",
7727    );
7728    minify_test(
7729      ".foo { border-width: min(1em + 2em, 2px + 2px) }",
7730      ".foo{border-width:min(3em,4px)}",
7731    );
7732    minify_test(
7733      ".foo { border-width: min(1em + 2px, 2px + 1em) }",
7734      ".foo{border-width:min(1em + 2px,2px + 1em)}",
7735    );
7736    minify_test(
7737      ".foo { border-width: min(1em + 2px + 2px, 2px + 1em + 1px) }",
7738      ".foo{border-width:min(1em + 4px,3px + 1em)}",
7739    );
7740    minify_test(
7741      ".foo { border-width: min(2px + 1px, 3px + 4px) }",
7742      ".foo{border-width:3px}",
7743    );
7744    minify_test(
7745      ".foo { border-width: min(1px, 1em, 2px, 3in) }",
7746      ".foo{border-width:min(1px,1em)}",
7747    );
7748
7749    minify_test(
7750      ".foo { border-width: max(1em, 2px) }",
7751      ".foo{border-width:max(1em,2px)}",
7752    );
7753    minify_test(
7754      ".foo { border-width: max(1em + 2em, 2px + 2px) }",
7755      ".foo{border-width:max(3em,4px)}",
7756    );
7757    minify_test(
7758      ".foo { border-width: max(1em + 2px, 2px + 1em) }",
7759      ".foo{border-width:max(1em + 2px,2px + 1em)}",
7760    );
7761    minify_test(
7762      ".foo { border-width: max(1em + 2px + 2px, 2px + 1em + 1px) }",
7763      ".foo{border-width:max(1em + 4px,3px + 1em)}",
7764    );
7765    minify_test(
7766      ".foo { border-width: max(2px + 1px, 3px + 4px) }",
7767      ".foo{border-width:7px}",
7768    );
7769    minify_test(
7770      ".foo { border-width: max(1px, 1em, 2px, 3in) }",
7771      ".foo{border-width:max(3in,1em)}",
7772    );
7773
7774    minify_test(".foo { border-width: clamp(1px, 2px, 3px) }", ".foo{border-width:2px}");
7775    minify_test(".foo { border-width: clamp(1px, 10px, 3px) }", ".foo{border-width:3px}");
7776    minify_test(".foo { border-width: clamp(5px, 2px, 10px) }", ".foo{border-width:5px}");
7777    minify_test(
7778      ".foo { border-width: clamp(100px, 2px, 10px) }",
7779      ".foo{border-width:100px}",
7780    );
7781    minify_test(
7782      ".foo { border-width: clamp(5px + 5px, 5px + 7px, 10px + 20px) }",
7783      ".foo{border-width:12px}",
7784    );
7785
7786    minify_test(
7787      ".foo { border-width: clamp(1em, 2px, 4vh) }",
7788      ".foo{border-width:clamp(1em,2px,4vh)}",
7789    );
7790    minify_test(
7791      ".foo { border-width: clamp(1em, 2em, 4vh) }",
7792      ".foo{border-width:clamp(1em,2em,4vh)}",
7793    );
7794    minify_test(
7795      ".foo { border-width: clamp(1em, 2vh, 4vh) }",
7796      ".foo{border-width:max(1em,2vh)}",
7797    );
7798    minify_test(
7799      ".foo { border-width: clamp(1px, 1px + 2em, 4px) }",
7800      ".foo{border-width:clamp(1px,1px + 2em,4px)}",
7801    );
7802    minify_test(".foo { border-width: clamp(1px, 2pt, 1in) }", ".foo{border-width:2pt}");
7803    minify_test(
7804      ".foo { width: clamp(-100px, 0px, 50% - 50vw); }",
7805      ".foo{width:clamp(-100px,0px,50% - 50vw)}",
7806    );
7807
7808    minify_test(
7809      ".foo { top: calc(-1 * clamp(1.75rem, 8vw, 4rem)) }",
7810      ".foo{top:calc(-1*clamp(1.75rem,8vw,4rem))}",
7811    );
7812    minify_test(
7813      ".foo { top: calc(-1 * min(1.75rem, 8vw, 4rem)) }",
7814      ".foo{top:calc(-1*min(1.75rem,8vw))}",
7815    );
7816    minify_test(
7817      ".foo { top: calc(-1 * max(1.75rem, 8vw, 4rem)) }",
7818      ".foo{top:calc(-1*max(4rem,8vw))}",
7819    );
7820    minify_test(
7821      ".foo { top: calc(clamp(1.75rem, 8vw, 4rem) * -1) }",
7822      ".foo{top:calc(-1*clamp(1.75rem,8vw,4rem))}",
7823    );
7824    minify_test(
7825      ".foo { top: calc(min(1.75rem, 8vw, 4rem) * -1) }",
7826      ".foo{top:calc(-1*min(1.75rem,8vw))}",
7827    );
7828    minify_test(
7829      ".foo { top: calc(max(1.75rem, 8vw, 4rem) * -1) }",
7830      ".foo{top:calc(-1*max(4rem,8vw))}",
7831    );
7832    minify_test(
7833      ".foo { top: calc(clamp(1.75rem, 8vw, 4rem) / 2) }",
7834      ".foo{top:calc(clamp(1.75rem,8vw,4rem)/2)}",
7835    );
7836    minify_test(
7837      ".foo { top: calc(min(1.75rem, 8vw, 4rem) / 2) }",
7838      ".foo{top:calc(min(1.75rem,8vw)/2)}",
7839    );
7840    minify_test(
7841      ".foo { top: calc(max(1.75rem, 8vw, 4rem) / 2) }",
7842      ".foo{top:calc(max(4rem,8vw)/2)}",
7843    );
7844    minify_test(
7845      ".foo { top: calc(0.5 * clamp(1.75rem, 8vw, 4rem)) }",
7846      ".foo{top:calc(clamp(1.75rem,8vw,4rem)/2)}",
7847    );
7848    minify_test(
7849      ".foo { top: calc(1 * clamp(1.75rem, 8vw, 4rem)) }",
7850      ".foo{top:calc(clamp(1.75rem,8vw,4rem))}",
7851    );
7852    minify_test(
7853      ".foo { top: calc(2 * clamp(1.75rem, 8vw, 4rem) / 2) }",
7854      ".foo{top:calc(clamp(1.75rem,8vw,4rem))}",
7855    );
7856
7857    minify_test(".foo { width: max(0px, 1vw) }", ".foo{width:max(0px,1vw)}");
7858
7859    prefix_test(
7860      ".foo { border-width: clamp(1em, 2px, 4vh) }",
7861      indoc! { r#"
7862        .foo {
7863          border-width: max(1em, min(2px, 4vh));
7864        }
7865      "#},
7866      Browsers {
7867        safari: Some(12 << 16),
7868        ..Browsers::default()
7869      },
7870    );
7871
7872    prefix_test(
7873      ".foo { border-width: clamp(1em, 2px, 4vh) }",
7874      indoc! { r#"
7875        .foo {
7876          border-width: clamp(1em, 2px, 4vh);
7877        }
7878      "#},
7879      Browsers {
7880        safari: Some(14 << 16),
7881        ..Browsers::default()
7882      },
7883    );
7884
7885    minify_test(".foo { width: calc(1vh + 2vh) }", ".foo{width:3vh}");
7886    minify_test(".foo { width: calc(1dvh + 2dvh) }", ".foo{width:3dvh}");
7887    minify_test(".foo { width: calc(1lvh + 2lvh) }", ".foo{width:3lvh}");
7888    minify_test(".foo { width: calc(1svh + 2svh) }", ".foo{width:3svh}");
7889    minify_test(".foo { width: calc(1sVmin + 2Svmin) }", ".foo{width:3svmin}");
7890    minify_test(".foo { width: calc(1ic + 2ic) }", ".foo{width:3ic}");
7891    minify_test(".foo { width: calc(1ric + 2ric) }", ".foo{width:3ric}");
7892    minify_test(".foo { width: calc(1cap + 2cap) }", ".foo{width:3cap}");
7893    minify_test(".foo { width: calc(1lh + 2lh) }", ".foo{width:3lh}");
7894    minify_test(".foo { width: calc(1x + 2x) }", ".foo{width:calc(1x + 2x)}");
7895    minify_test(
7896      ".foo { left: calc(50% - 100px + clamp(0px, calc(50vw - 50px), 100px)) }",
7897      ".foo{left:calc(50% - 100px + clamp(0px,50vw - 50px,100px))}",
7898    );
7899    minify_test(
7900      ".foo { left: calc(10px + min(10px, 1rem) + max(2px, 1vw)) }",
7901      ".foo{left:calc(10px + min(10px,1rem) + max(2px,1vw))}",
7902    );
7903    minify_test(".foo { width: round(22px, 5px) }", ".foo{width:20px}");
7904    minify_test(".foo { width: round(nearest, 22px, 5px) }", ".foo{width:20px}");
7905    minify_test(".foo { width: round(down, 22px, 5px) }", ".foo{width:20px}");
7906    minify_test(".foo { width: round(to-zero, 22px, 5px) }", ".foo{width:20px}");
7907    minify_test(".foo { width: round(up, 22px, 5px) }", ".foo{width:25px}");
7908    minify_test(".foo { width: round(23px, 5px) }", ".foo{width:25px}");
7909    minify_test(".foo { width: round(nearest, 23px, 5px) }", ".foo{width:25px}");
7910    minify_test(".foo { width: round(down, 23px, 5px) }", ".foo{width:20px}");
7911    minify_test(".foo { width: round(to-zero, 23px, 5px) }", ".foo{width:20px}");
7912    minify_test(".foo { width: round(up, 23px, 5px) }", ".foo{width:25px}");
7913    minify_test(".foo { width: round(22px, 5vw) }", ".foo{width:round(22px,5vw)}");
7914    minify_test(".foo { rotate: round(22deg, 5deg) }", ".foo{rotate:20deg}");
7915    minify_test(".foo { rotate: round(22deg, 5deg) }", ".foo{rotate:20deg}");
7916    minify_test(
7917      ".foo { transition-duration: round(22ms, 5ms) }",
7918      ".foo{transition-duration:20ms}",
7919    );
7920    minify_test(".foo { margin: round(to-zero, -23px, 5px) }", ".foo{margin:-20px}");
7921    minify_test(".foo { margin: round(nearest, -23px, 5px) }", ".foo{margin:-25px}");
7922    minify_test(".foo { margin: calc(10px * round(22, 5)) }", ".foo{margin:200px}");
7923    minify_test(".foo { width: rem(18px, 5px) }", ".foo{width:3px}");
7924    minify_test(".foo { width: rem(-18px, 5px) }", ".foo{width:-3px}");
7925    minify_test(".foo { width: rem(18px, 5vw) }", ".foo{width:rem(18px,5vw)}");
7926    minify_test(".foo { rotate: rem(-140deg, -90deg) }", ".foo{rotate:-50deg}");
7927    minify_test(".foo { rotate: rem(140deg, -90deg) }", ".foo{rotate:50deg}");
7928    minify_test(".foo { width: calc(10px * rem(18, 5)) }", ".foo{width:30px}");
7929    minify_test(".foo { width: mod(18px, 5px) }", ".foo{width:3px}");
7930    minify_test(".foo { width: mod(-18px, 5px) }", ".foo{width:2px}");
7931    minify_test(".foo { rotate: mod(-140deg, -90deg) }", ".foo{rotate:-50deg}");
7932    minify_test(".foo { rotate: mod(140deg, -90deg) }", ".foo{rotate:-40deg}");
7933    minify_test(".foo { width: mod(18px, 5vw) }", ".foo{width:mod(18px,5vw)}");
7934    minify_test(
7935      ".foo { transform: rotateX(mod(140deg, -90deg)) rotateY(rem(140deg, -90deg)) }",
7936      ".foo{transform:rotateX(-40deg)rotateY(50deg)}",
7937    );
7938    minify_test(".foo { width: calc(10px * mod(18, 5)) }", ".foo{width:30px}");
7939
7940    minify_test(
7941      ".foo { width: calc(100% - 30px - 0) }",
7942      ".foo{width:calc(100% - 30px - 0)}",
7943    );
7944    minify_test(
7945      ".foo { width: calc(100% - 30px - 1 - 2) }",
7946      ".foo{width:calc(100% - 30px - 3)}",
7947    );
7948    minify_test(
7949      ".foo { width: calc(1 - 2 - 100% - 30px) }",
7950      ".foo{width:calc(-1 - 100% - 30px)}",
7951    );
7952    minify_test(
7953      ".foo { width: calc(2 * min(1px, 1vmin) - min(1px, 1vmin)); }",
7954      ".foo{width:calc(2*min(1px,1vmin) - min(1px,1vmin))}",
7955    );
7956    minify_test(
7957      ".foo { width: calc(100% - clamp(1.125rem, 1.25vw, 1.2375rem) - clamp(1.125rem, 1.25vw, 1.2375rem)); }",
7958      ".foo{width:calc(100% - clamp(1.125rem,1.25vw,1.2375rem) - clamp(1.125rem,1.25vw,1.2375rem))}",
7959    );
7960    minify_test(
7961      ".foo { width: calc(100% - 2 (2 * var(--card-margin))); }",
7962      ".foo{width:calc(100% - 2 (2*var(--card-margin)))}",
7963    );
7964  }
7965
7966  #[test]
7967  fn test_trig() {
7968    minify_test(".foo { width: calc(2px * pi); }", ".foo{width:6.28319px}");
7969    minify_test(".foo { width: calc(2px / pi); }", ".foo{width:.63662px}");
7970    // minify_test(
7971    //   ".foo { width: calc(2px * infinity); }",
7972    //   ".foo{width:calc(2px*infinity)}",
7973    // );
7974    // minify_test(
7975    //   ".foo { width: calc(2px * -infinity); }",
7976    //   ".foo{width:calc(2px*-infinity)}",
7977    // );
7978    minify_test(".foo { width: calc(100px * sin(45deg))", ".foo{width:70.7107px}");
7979    minify_test(".foo { width: calc(100px * sin(.125turn))", ".foo{width:70.7107px}");
7980    minify_test(
7981      ".foo { width: calc(100px * sin(3.14159265 / 4))",
7982      ".foo{width:70.7107px}",
7983    );
7984    minify_test(".foo { width: calc(100px * sin(pi / 4))", ".foo{width:70.7107px}");
7985    minify_test(
7986      ".foo { width: calc(100px * sin(22deg + 23deg))",
7987      ".foo{width:70.7107px}",
7988    );
7989
7990    minify_test(".foo { width: calc(2px * cos(45deg))", ".foo{width:1.41421px}");
7991    minify_test(".foo { width: calc(2px * tan(45deg))", ".foo{width:2px}");
7992
7993    minify_test(".foo { rotate: asin(sin(45deg))", ".foo{rotate:45deg}");
7994    minify_test(".foo { rotate: asin(1)", ".foo{rotate:90deg}");
7995    minify_test(".foo { rotate: asin(-1)", ".foo{rotate:-90deg}");
7996    minify_test(".foo { rotate: asin(0.5)", ".foo{rotate:30deg}");
7997    minify_test(".foo { rotate: asin(45deg)", ".foo{rotate:asin(45deg)}"); // invalid
7998    minify_test(".foo { rotate: asin(-20)", ".foo{rotate:asin(-20)}"); // evaluates to NaN
7999    minify_test(".foo { width: asin(sin(45deg))", ".foo{width:asin(sin(45deg))}"); // invalid
8000
8001    minify_test(".foo { rotate: acos(cos(45deg))", ".foo{rotate:45deg}");
8002    minify_test(".foo { rotate: acos(-1)", ".foo{rotate:180deg}");
8003    minify_test(".foo { rotate: acos(0)", ".foo{rotate:90deg}");
8004    minify_test(".foo { rotate: acos(1)", ".foo{rotate:none}");
8005    minify_test(".foo { rotate: acos(45deg)", ".foo{rotate:acos(45deg)}"); // invalid
8006    minify_test(".foo { rotate: acos(-20)", ".foo{rotate:acos(-20)}"); // evaluates to NaN
8007
8008    minify_test(".foo { rotate: atan(tan(45deg))", ".foo{rotate:45deg}");
8009    minify_test(".foo { rotate: atan(1)", ".foo{rotate:45deg}");
8010    minify_test(".foo { rotate: atan(0)", ".foo{rotate:none}");
8011    minify_test(".foo { rotate: atan(45deg)", ".foo{rotate:atan(45deg)}"); // invalid
8012
8013    minify_test(".foo { rotate: atan2(1px, -1px)", ".foo{rotate:135deg}");
8014    minify_test(".foo { rotate: atan2(1vw, -1vw)", ".foo{rotate:135deg}");
8015    minify_test(".foo { rotate: atan2(1, -1)", ".foo{rotate:135deg}");
8016    minify_test(".foo { rotate: atan2(1ms, -1ms)", ".foo{rotate:135deg}");
8017    minify_test(".foo { rotate: atan2(1%, -1%)", ".foo{rotate:135deg}");
8018    minify_test(".foo { rotate: atan2(1deg, -1deg)", ".foo{rotate:135deg}");
8019    minify_test(".foo { rotate: atan2(1cm, 1mm)", ".foo{rotate:84.2894deg}");
8020    minify_test(".foo { rotate: atan2(0, -1)", ".foo{rotate:180deg}");
8021    minify_test(".foo { rotate: atan2(-1, 1)", ".foo{rotate:-45deg}");
8022    // incompatible units
8023    minify_test(".foo { rotate: atan2(1px, -1vw)", ".foo{rotate:atan2(1px,-1vw)}");
8024  }
8025
8026  #[test]
8027  fn test_exp() {
8028    minify_test(".foo { width: hypot()", ".foo{width:hypot()}");
8029    minify_test(".foo { width: hypot(1px)", ".foo{width:1px}");
8030    minify_test(".foo { width: hypot(1px, 2px)", ".foo{width:2.23607px}");
8031    minify_test(".foo { width: hypot(1px, 2px, 3px)", ".foo{width:3.74166px}");
8032    minify_test(".foo { width: hypot(1px, 2vw)", ".foo{width:hypot(1px,2vw)}");
8033    minify_test(".foo { width: hypot(1px, 2px, 3vw)", ".foo{width:hypot(1px,2px,3vw)}");
8034    minify_test(".foo { width: calc(100px * hypot(3, 4))", ".foo{width:500px}");
8035    minify_test(".foo { width: calc(1px * pow(2, sqrt(100))", ".foo{width:1024px}");
8036    minify_test(".foo { width: calc(100px * pow(2, pow(2, 2)", ".foo{width:1600px}");
8037    minify_test(".foo { width: calc(1px * log(1))", ".foo{width:0}");
8038    minify_test(".foo { width: calc(1px * log(10, 10))", ".foo{width:1px}");
8039    minify_test(".foo { width: calc(1px * exp(0))", ".foo{width:1px}");
8040    minify_test(".foo { width: calc(1px * log(e))", ".foo{width:1px}");
8041    minify_test(".foo { width: calc(1px * (e - exp(1)))", ".foo{width:0}");
8042    minify_test(
8043      ".foo { width: calc(1px * (exp(log(1) + exp(0)*2))",
8044      ".foo{width:7.38906px}",
8045    );
8046  }
8047
8048  #[test]
8049  fn test_sign() {
8050    minify_test(".foo { width: abs(1px)", ".foo{width:1px}");
8051    minify_test(".foo { width: abs(-1px)", ".foo{width:1px}");
8052    minify_test(".foo { width: abs(1%)", ".foo{width:abs(1%)}"); // spec says percentages must be against resolved value
8053
8054    minify_test(".foo { width: calc(10px * sign(-1vw)", ".foo{width:-10px}");
8055    minify_test(".foo { width: calc(10px * sign(1%)", ".foo{width:calc(10px*sign(1%))}");
8056  }
8057
8058  #[test]
8059  fn test_box_shadow() {
8060    minify_test(
8061      ".foo { box-shadow: 64px 64px 12px 40px rgba(0,0,0,0.4) }",
8062      ".foo{box-shadow:64px 64px 12px 40px #0006}",
8063    );
8064    minify_test(
8065      ".foo { box-shadow: 12px 12px 0px 8px rgba(0,0,0,0.4) inset }",
8066      ".foo{box-shadow:inset 12px 12px 0 8px #0006}",
8067    );
8068    minify_test(
8069      ".foo { box-shadow: inset 12px 12px 0px 8px rgba(0,0,0,0.4) }",
8070      ".foo{box-shadow:inset 12px 12px 0 8px #0006}",
8071    );
8072    minify_test(
8073      ".foo { box-shadow: 12px 12px 8px 0px rgba(0,0,0,0.4) }",
8074      ".foo{box-shadow:12px 12px 8px #0006}",
8075    );
8076    minify_test(
8077      ".foo { box-shadow: 12px 12px 0px 0px rgba(0,0,0,0.4) }",
8078      ".foo{box-shadow:12px 12px #0006}",
8079    );
8080    minify_test(
8081      ".foo { box-shadow: 64px 64px 12px 40px rgba(0,0,0,0.4), 12px 12px 0px 8px rgba(0,0,0,0.4) inset }",
8082      ".foo{box-shadow:64px 64px 12px 40px #0006,inset 12px 12px 0 8px #0006}",
8083    );
8084
8085    prefix_test(
8086      ".foo { box-shadow: 12px 12px lab(40% 56.6 39) }",
8087      indoc! { r#"
8088        .foo {
8089          box-shadow: 12px 12px #b32323;
8090          box-shadow: 12px 12px lab(40% 56.6 39);
8091        }
8092      "#},
8093      Browsers {
8094        chrome: Some(90 << 16),
8095        ..Browsers::default()
8096      },
8097    );
8098
8099    prefix_test(
8100      ".foo { box-shadow: 12px 12px lab(40% 56.6 39) }",
8101      indoc! { r#"
8102        .foo {
8103          -webkit-box-shadow: 12px 12px #b32323;
8104          box-shadow: 12px 12px #b32323;
8105          box-shadow: 12px 12px lab(40% 56.6 39);
8106        }
8107      "#},
8108      Browsers {
8109        chrome: Some(4 << 16),
8110        ..Browsers::default()
8111      },
8112    );
8113
8114    prefix_test(
8115      ".foo { box-shadow: 12px 12px lab(40% 56.6 39), 12px 12px yellow }",
8116      indoc! { r#"
8117        .foo {
8118          -webkit-box-shadow: 12px 12px #b32323, 12px 12px #ff0;
8119          box-shadow: 12px 12px #b32323, 12px 12px #ff0;
8120          box-shadow: 12px 12px lab(40% 56.6 39), 12px 12px #ff0;
8121        }
8122      "#},
8123      Browsers {
8124        chrome: Some(4 << 16),
8125        ..Browsers::default()
8126      },
8127    );
8128
8129    prefix_test(
8130      ".foo { -webkit-box-shadow: 12px 12px #0006 }",
8131      indoc! { r#"
8132        .foo {
8133          -webkit-box-shadow: 12px 12px rgba(0, 0, 0, .4);
8134        }
8135      "#},
8136      Browsers {
8137        chrome: Some(4 << 16),
8138        ..Browsers::default()
8139      },
8140    );
8141
8142    prefix_test(
8143      ".foo {
8144        -webkit-box-shadow: 12px 12px #0006;
8145        -moz-box-shadow: 12px 12px #0009;
8146      }",
8147      indoc! { r#"
8148        .foo {
8149          -webkit-box-shadow: 12px 12px rgba(0, 0, 0, .4);
8150          -moz-box-shadow: 12px 12px rgba(0, 0, 0, .6);
8151        }
8152      "#},
8153      Browsers {
8154        chrome: Some(4 << 16),
8155        ..Browsers::default()
8156      },
8157    );
8158
8159    prefix_test(
8160      ".foo {
8161        -webkit-box-shadow: 12px 12px #0006;
8162        -moz-box-shadow: 12px 12px #0006;
8163        box-shadow: 12px 12px #0006;
8164      }",
8165      indoc! { r#"
8166        .foo {
8167          box-shadow: 12px 12px #0006;
8168        }
8169      "#},
8170      Browsers {
8171        chrome: Some(95 << 16),
8172        ..Browsers::default()
8173      },
8174    );
8175
8176    prefix_test(
8177      ".foo { box-shadow: var(--foo) 12px lab(40% 56.6 39) }",
8178      indoc! { r#"
8179        .foo {
8180          box-shadow: var(--foo) 12px #b32323;
8181        }
8182
8183        @supports (color: lab(0% 0 0)) {
8184          .foo {
8185            box-shadow: var(--foo) 12px lab(40% 56.6 39);
8186          }
8187        }
8188      "#},
8189      Browsers {
8190        chrome: Some(90 << 16),
8191        ..Browsers::default()
8192      },
8193    );
8194
8195    prefix_test(
8196      r#"
8197      .foo {
8198        box-shadow: 0px 0px 22px red;
8199        box-shadow: 0px 0px max(2cqw, 22px) red;
8200      }
8201    "#,
8202      indoc! {r#"
8203      .foo {
8204        box-shadow: 0 0 22px red;
8205        box-shadow: 0 0 max(2cqw, 22px) red;
8206      }
8207    "#
8208      },
8209      Browsers {
8210        safari: Some(14 << 16),
8211        ..Browsers::default()
8212      },
8213    );
8214    prefix_test(
8215      r#"
8216      .foo {
8217        box-shadow: 0px 0px 22px red;
8218        box-shadow: 0px 0px max(2cqw, 22px) red;
8219      }
8220    "#,
8221      indoc! {r#"
8222      .foo {
8223        box-shadow: 0 0 max(2cqw, 22px) red;
8224      }
8225    "#
8226      },
8227      Browsers {
8228        safari: Some(16 << 16),
8229        ..Browsers::default()
8230      },
8231    );
8232
8233    prefix_test(
8234      r#"
8235      .foo {
8236        box-shadow: 0px 0px 22px red;
8237        box-shadow: 0px 0px 22px lab(40% 56.6 39);
8238      }
8239    "#,
8240      indoc! {r#"
8241      .foo {
8242        box-shadow: 0 0 22px red;
8243        box-shadow: 0 0 22px lab(40% 56.6 39);
8244      }
8245    "#
8246      },
8247      Browsers {
8248        safari: Some(14 << 16),
8249        ..Browsers::default()
8250      },
8251    );
8252    prefix_test(
8253      r#"
8254      .foo {
8255        box-shadow: 0px 0px 22px red;
8256        box-shadow: 0px 0px 22px lab(40% 56.6 39);
8257      }
8258    "#,
8259      indoc! {r#"
8260      .foo {
8261        box-shadow: 0 0 22px lab(40% 56.6 39);
8262      }
8263    "#
8264      },
8265      Browsers {
8266        safari: Some(16 << 16),
8267        ..Browsers::default()
8268      },
8269    );
8270
8271    prefix_test(
8272      r#"
8273      .foo {
8274        box-shadow: var(--fallback);
8275        box-shadow: 0px 0px 22px lab(40% 56.6 39);
8276      }
8277    "#,
8278      indoc! {r#"
8279      .foo {
8280        box-shadow: var(--fallback);
8281        box-shadow: 0 0 22px lab(40% 56.6 39);
8282      }
8283    "#
8284      },
8285      Browsers {
8286        safari: Some(16 << 16),
8287        ..Browsers::default()
8288      },
8289    );
8290  }
8291
8292  #[test]
8293  fn test_media() {
8294    minify_test(
8295      "@media (min-width: 240px) { .foo { color: chartreuse }}",
8296      "@media (width>=240px){.foo{color:#7fff00}}",
8297    );
8298    minify_test(
8299      "@media (width < 240px) { .foo { color: chartreuse }}",
8300      "@media (width<240px){.foo{color:#7fff00}}",
8301    );
8302    minify_test(
8303      "@media (width <= 240px) { .foo { color: chartreuse }}",
8304      "@media (width<=240px){.foo{color:#7fff00}}",
8305    );
8306    minify_test(
8307      "@media (width > 240px) { .foo { color: chartreuse }}",
8308      "@media (width>240px){.foo{color:#7fff00}}",
8309    );
8310    minify_test(
8311      "@media (width >= 240px) { .foo { color: chartreuse }}",
8312      "@media (width>=240px){.foo{color:#7fff00}}",
8313    );
8314    minify_test(
8315      "@media (240px < width) { .foo { color: chartreuse }}",
8316      "@media (width>240px){.foo{color:#7fff00}}",
8317    );
8318    minify_test(
8319      "@media (240px <= width) { .foo { color: chartreuse }}",
8320      "@media (width>=240px){.foo{color:#7fff00}}",
8321    );
8322    minify_test(
8323      "@media (240px > width) { .foo { color: chartreuse }}",
8324      "@media (width<240px){.foo{color:#7fff00}}",
8325    );
8326    minify_test(
8327      "@media (240px >= width) { .foo { color: chartreuse }}",
8328      "@media (width<=240px){.foo{color:#7fff00}}",
8329    );
8330    minify_test(
8331      "@media (100px < width < 200px) { .foo { color: chartreuse }}",
8332      "@media (100px<width<200px){.foo{color:#7fff00}}",
8333    );
8334    minify_test(
8335      "@media (100px <= width <= 200px) { .foo { color: chartreuse }}",
8336      "@media (100px<=width<=200px){.foo{color:#7fff00}}",
8337    );
8338    minify_test(
8339      "@media (min-width: 30em) and (max-width: 50em) { .foo { color: chartreuse }}",
8340      "@media (width>=30em) and (width<=50em){.foo{color:#7fff00}}",
8341    );
8342    minify_test(
8343      "@media screen, print { .foo { color: chartreuse }}",
8344      "@media screen,print{.foo{color:#7fff00}}",
8345    );
8346    minify_test(
8347      "@media (hover: hover) { .foo { color: chartreuse }}",
8348      "@media (hover:hover){.foo{color:#7fff00}}",
8349    );
8350    minify_test(
8351      "@media (hover) { .foo { color: chartreuse }}",
8352      "@media (hover){.foo{color:#7fff00}}",
8353    );
8354    minify_test(
8355      "@media (aspect-ratio: 11/5) { .foo { color: chartreuse }}",
8356      "@media (aspect-ratio:11/5){.foo{color:#7fff00}}",
8357    );
8358    minify_test(
8359      "@media (aspect-ratio: 2/1) { .foo { color: chartreuse }}",
8360      "@media (aspect-ratio:2){.foo{color:#7fff00}}",
8361    );
8362    minify_test(
8363      "@media (aspect-ratio: 2) { .foo { color: chartreuse }}",
8364      "@media (aspect-ratio:2){.foo{color:#7fff00}}",
8365    );
8366    minify_test(
8367      "@media not screen and (color) { .foo { color: chartreuse }}",
8368      "@media not screen and (color){.foo{color:#7fff00}}",
8369    );
8370    minify_test(
8371      "@media only screen and (color) { .foo { color: chartreuse }}",
8372      "@media only screen and (color){.foo{color:#7fff00}}",
8373    );
8374    minify_test(
8375      "@media (update: slow) or (hover: none) { .foo { color: chartreuse }}",
8376      "@media (update:slow) or (hover:none){.foo{color:#7fff00}}",
8377    );
8378    minify_test(
8379      "@media (width < 600px) and (height < 600px) { .foo { color: chartreuse }}",
8380      "@media (width<600px) and (height<600px){.foo{color:#7fff00}}",
8381    );
8382    minify_test(
8383      "@media (not (color)) or (hover) { .foo { color: chartreuse }}",
8384      "@media (not (color)) or (hover){.foo{color:#7fff00}}",
8385    );
8386    error_test(
8387      "@media (example, all,), speech { .foo { color: chartreuse }}",
8388      ParserError::UnexpectedToken(Token::Comma),
8389    );
8390    error_test(
8391      "@media &test, speech { .foo { color: chartreuse }}",
8392      ParserError::UnexpectedToken(Token::Delim('&')),
8393    );
8394    error_test(
8395      "@media &test { .foo { color: chartreuse }}",
8396      ParserError::UnexpectedToken(Token::Delim('&')),
8397    );
8398    minify_test(
8399      "@media (min-width: calc(200px + 40px)) { .foo { color: chartreuse }}",
8400      "@media (width>=240px){.foo{color:#7fff00}}",
8401    );
8402    minify_test(
8403      "@media (min-width: calc(1em + 5px)) { .foo { color: chartreuse }}",
8404      "@media (width>=calc(1em + 5px)){.foo{color:#7fff00}}",
8405    );
8406    minify_test("@media { .foo { color: chartreuse }}", ".foo{color:#7fff00}");
8407    minify_test("@media all { .foo { color: chartreuse }}", ".foo{color:#7fff00}");
8408    minify_test(
8409      "@media not (((color) or (hover))) { .foo { color: chartreuse }}",
8410      "@media not ((color) or (hover)){.foo{color:#7fff00}}",
8411    );
8412    minify_test(
8413      "@media (hover) and ((color) and (test)) { .foo { color: chartreuse }}",
8414      "@media (hover) and (color) and (test){.foo{color:#7fff00}}",
8415    );
8416    minify_test(
8417      "@media (grid: 1) { .foo { color: chartreuse }}",
8418      "@media (grid:1){.foo{color:#7fff00}}",
8419    );
8420    minify_test(
8421      "@media (width >= calc(2px + 4px)) { .foo { color: chartreuse }}",
8422      "@media (width>=6px){.foo{color:#7fff00}}",
8423    );
8424
8425    prefix_test(
8426      r#"
8427        @media (width >= 240px) {
8428          .foo {
8429            color: chartreuse;
8430          }
8431        }
8432      "#,
8433      indoc! { r#"
8434        @media (min-width: 240px) {
8435          .foo {
8436            color: #7fff00;
8437          }
8438        }
8439      "#},
8440      Browsers {
8441        firefox: Some(60 << 16),
8442        ..Browsers::default()
8443      },
8444    );
8445
8446    prefix_test(
8447      r#"
8448        @media (width >= 240px) {
8449          .foo {
8450            color: chartreuse;
8451          }
8452        }
8453      "#,
8454      indoc! { r#"
8455        @media (width >= 240px) {
8456          .foo {
8457            color: #7fff00;
8458          }
8459        }
8460      "#},
8461      Browsers {
8462        firefox: Some(64 << 16),
8463        ..Browsers::default()
8464      },
8465    );
8466
8467    prefix_test(
8468      r#"
8469        @media (color > 2) {
8470          .foo {
8471            color: chartreuse;
8472          }
8473        }
8474      "#,
8475      indoc! { r#"
8476        @media not (max-color: 2) {
8477          .foo {
8478            color: #7fff00;
8479          }
8480        }
8481      "#},
8482      Browsers {
8483        firefox: Some(60 << 16),
8484        ..Browsers::default()
8485      },
8486    );
8487
8488    prefix_test(
8489      r#"
8490        @media (color < 2) {
8491          .foo {
8492            color: chartreuse;
8493          }
8494        }
8495      "#,
8496      indoc! { r#"
8497        @media not (min-color: 2) {
8498          .foo {
8499            color: #7fff00;
8500          }
8501        }
8502      "#},
8503      Browsers {
8504        firefox: Some(60 << 16),
8505        ..Browsers::default()
8506      },
8507    );
8508
8509    prefix_test(
8510      r#"
8511        @media (width > 240px) {
8512          .foo {
8513            color: chartreuse;
8514          }
8515        }
8516      "#,
8517      indoc! { r#"
8518        @media not (max-width: 240px) {
8519          .foo {
8520            color: #7fff00;
8521          }
8522        }
8523      "#},
8524      Browsers {
8525        firefox: Some(60 << 16),
8526        ..Browsers::default()
8527      },
8528    );
8529
8530    prefix_test(
8531      r#"
8532        @media (width <= 240px) {
8533          .foo {
8534            color: chartreuse;
8535          }
8536        }
8537      "#,
8538      indoc! { r#"
8539        @media (max-width: 240px) {
8540          .foo {
8541            color: #7fff00;
8542          }
8543        }
8544      "#},
8545      Browsers {
8546        firefox: Some(60 << 16),
8547        ..Browsers::default()
8548      },
8549    );
8550
8551    prefix_test(
8552      r#"
8553        @media (width <= 240px) {
8554          .foo {
8555            color: chartreuse;
8556          }
8557        }
8558      "#,
8559      indoc! { r#"
8560        @media (width <= 240px) {
8561          .foo {
8562            color: #7fff00;
8563          }
8564        }
8565      "#},
8566      Browsers {
8567        firefox: Some(64 << 16),
8568        ..Browsers::default()
8569      },
8570    );
8571
8572    prefix_test(
8573      r#"
8574        @media (width < 240px) {
8575          .foo {
8576            color: chartreuse;
8577          }
8578        }
8579      "#,
8580      indoc! { r#"
8581        @media not (min-width: 240px) {
8582          .foo {
8583            color: #7fff00;
8584          }
8585        }
8586      "#},
8587      Browsers {
8588        firefox: Some(60 << 16),
8589        ..Browsers::default()
8590      },
8591    );
8592
8593    prefix_test(
8594      r#"
8595        @media not (width < 240px) {
8596          .foo {
8597            color: chartreuse;
8598          }
8599        }
8600      "#,
8601      indoc! { r#"
8602        @media (min-width: 240px) {
8603          .foo {
8604            color: #7fff00;
8605          }
8606        }
8607      "#},
8608      Browsers {
8609        firefox: Some(60 << 16),
8610        ..Browsers::default()
8611      },
8612    );
8613
8614    test(
8615      r#"
8616        @media not (width < 240px) {
8617          .foo {
8618            color: chartreuse;
8619          }
8620        }
8621      "#,
8622      indoc! { r#"
8623        @media (width >= 240px) {
8624          .foo {
8625            color: #7fff00;
8626          }
8627        }
8628      "#},
8629    );
8630
8631    prefix_test(
8632      r#"
8633        @media (width < 240px) and (hover) {
8634          .foo {
8635            color: chartreuse;
8636          }
8637        }
8638      "#,
8639      indoc! { r#"
8640        @media (not (min-width: 240px)) and (hover) {
8641          .foo {
8642            color: #7fff00;
8643          }
8644        }
8645      "#},
8646      Browsers {
8647        firefox: Some(60 << 16),
8648        ..Browsers::default()
8649      },
8650    );
8651
8652    prefix_test(
8653      r#"
8654        @media (100px <= width <= 200px) {
8655          .foo {
8656            color: chartreuse;
8657          }
8658        }
8659      "#,
8660      indoc! { r#"
8661        @media (min-width: 100px) and (max-width: 200px) {
8662          .foo {
8663            color: #7fff00;
8664          }
8665        }
8666      "#},
8667      Browsers {
8668        firefox: Some(85 << 16),
8669        ..Browsers::default()
8670      },
8671    );
8672
8673    prefix_test(
8674      r#"
8675        @media not (100px <= width <= 200px) {
8676          .foo {
8677            color: chartreuse;
8678          }
8679        }
8680      "#,
8681      indoc! { r#"
8682        @media not ((min-width: 100px) and (max-width: 200px)) {
8683          .foo {
8684            color: #7fff00;
8685          }
8686        }
8687      "#},
8688      Browsers {
8689        firefox: Some(85 << 16),
8690        ..Browsers::default()
8691      },
8692    );
8693
8694    prefix_test(
8695      r#"
8696        @media (hover) and (100px <= width <= 200px) {
8697          .foo {
8698            color: chartreuse;
8699          }
8700        }
8701      "#,
8702      indoc! { r#"
8703        @media (hover) and (min-width: 100px) and (max-width: 200px) {
8704          .foo {
8705            color: #7fff00;
8706          }
8707        }
8708      "#},
8709      Browsers {
8710        firefox: Some(85 << 16),
8711        ..Browsers::default()
8712      },
8713    );
8714
8715    prefix_test(
8716      r#"
8717        @media (hover) or (100px <= width <= 200px) {
8718          .foo {
8719            color: chartreuse;
8720          }
8721        }
8722      "#,
8723      indoc! { r#"
8724        @media (hover) or ((min-width: 100px) and (max-width: 200px)) {
8725          .foo {
8726            color: #7fff00;
8727          }
8728        }
8729      "#},
8730      Browsers {
8731        firefox: Some(85 << 16),
8732        ..Browsers::default()
8733      },
8734    );
8735
8736    prefix_test(
8737      r#"
8738        @media (100px < width < 200px) {
8739          .foo {
8740            color: chartreuse;
8741          }
8742        }
8743      "#,
8744      indoc! { r#"
8745        @media (not (max-width: 100px)) and (not (min-width: 200px)) {
8746          .foo {
8747            color: #7fff00;
8748          }
8749        }
8750      "#},
8751      Browsers {
8752        firefox: Some(85 << 16),
8753        ..Browsers::default()
8754      },
8755    );
8756
8757    prefix_test(
8758      r#"
8759        @media not (100px < width < 200px) {
8760          .foo {
8761            color: chartreuse;
8762          }
8763        }
8764      "#,
8765      indoc! { r#"
8766        @media not ((not (max-width: 100px)) and (not (min-width: 200px))) {
8767          .foo {
8768            color: #7fff00;
8769          }
8770        }
8771      "#},
8772      Browsers {
8773        firefox: Some(85 << 16),
8774        ..Browsers::default()
8775      },
8776    );
8777
8778    prefix_test(
8779      r#"
8780        @media (200px >= width >= 100px) {
8781          .foo {
8782            color: chartreuse;
8783          }
8784        }
8785      "#,
8786      indoc! { r#"
8787        @media (max-width: 200px) and (min-width: 100px) {
8788          .foo {
8789            color: #7fff00;
8790          }
8791        }
8792      "#},
8793      Browsers {
8794        firefox: Some(85 << 16),
8795        ..Browsers::default()
8796      },
8797    );
8798
8799    test(
8800      r#"
8801      @media not all {
8802        .a {
8803          color: green;
8804        }
8805      }
8806      "#,
8807      "\n",
8808    );
8809
8810    prefix_test(
8811      r#"
8812      @media (width > calc(1px + 1rem)) {
8813        .foo { color: yellow; }
8814      }
8815      "#,
8816      indoc! { r#"
8817        @media not (max-width: calc(1px + 1rem)) {
8818          .foo {
8819            color: #ff0;
8820          }
8821        }
8822      "#},
8823      Browsers {
8824        chrome: Some(85 << 16),
8825        ..Browsers::default()
8826      },
8827    );
8828    prefix_test(
8829      r#"
8830      @media (width > max(10px, 1rem)) {
8831        .foo { color: yellow; }
8832      }
8833      "#,
8834      indoc! { r#"
8835        @media not (max-width: max(10px, 1rem)) {
8836          .foo {
8837            color: #ff0;
8838          }
8839        }
8840      "#},
8841      Browsers {
8842        chrome: Some(85 << 16),
8843        ..Browsers::default()
8844      },
8845    );
8846    prefix_test(
8847      r#"
8848      @media (width > 0) {
8849        .foo { color: yellow; }
8850      }
8851      "#,
8852      indoc! { r#"
8853        @media not (max-width: 0) {
8854          .foo {
8855            color: #ff0;
8856          }
8857        }
8858      "#},
8859      Browsers {
8860        chrome: Some(85 << 16),
8861        ..Browsers::default()
8862      },
8863    );
8864    prefix_test(
8865      r#"
8866      @media (min-resolution: 2dppx) {
8867        .foo { color: yellow; }
8868      }
8869      "#,
8870      indoc! { r#"
8871        @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 2dppx) {
8872          .foo {
8873            color: #ff0;
8874          }
8875        }
8876      "#},
8877      Browsers {
8878        safari: Some(15 << 16),
8879        ..Browsers::default()
8880      },
8881    );
8882    prefix_test(
8883      r#"
8884      @media (min-resolution: 2dppx) {
8885        .foo { color: yellow; }
8886      }
8887      "#,
8888      indoc! { r#"
8889        @media (min--moz-device-pixel-ratio: 2), (min-resolution: 2dppx) {
8890          .foo {
8891            color: #ff0;
8892          }
8893        }
8894      "#},
8895      Browsers {
8896        firefox: Some(10 << 16),
8897        ..Browsers::default()
8898      },
8899    );
8900    prefix_test(
8901      r#"
8902      @media (resolution > 2dppx) {
8903        .foo { color: yellow; }
8904      }
8905      "#,
8906      indoc! { r#"
8907        @media not (-webkit-max-device-pixel-ratio: 2), not (max-resolution: 2dppx) {
8908          .foo {
8909            color: #ff0;
8910          }
8911        }
8912      "#},
8913      Browsers {
8914        safari: Some(15 << 16),
8915        ..Browsers::default()
8916      },
8917    );
8918    prefix_test(
8919      r#"
8920      @media (resolution >= 300dpi) {
8921        .foo { color: yellow; }
8922      }
8923      "#,
8924      indoc! { r#"
8925        @media (-webkit-min-device-pixel-ratio: 3.125), (min-resolution: 300dpi) {
8926          .foo {
8927            color: #ff0;
8928          }
8929        }
8930      "#},
8931      Browsers {
8932        safari: Some(15 << 16),
8933        ..Browsers::default()
8934      },
8935    );
8936    prefix_test(
8937      r#"
8938      @media (min-resolution: 113.38dpcm) {
8939        .foo { color: yellow; }
8940      }
8941      "#,
8942      indoc! { r#"
8943        @media (-webkit-min-device-pixel-ratio: 2.99985), (min--moz-device-pixel-ratio: 2.99985), (min-resolution: 113.38dpcm) {
8944          .foo {
8945            color: #ff0;
8946          }
8947        }
8948      "#},
8949      Browsers {
8950        safari: Some(15 << 16),
8951        firefox: Some(10 << 16),
8952        ..Browsers::default()
8953      },
8954    );
8955    prefix_test(
8956      r#"
8957      @media (color) and (min-resolution: 2dppx) {
8958        .foo { color: yellow; }
8959      }
8960      "#,
8961      indoc! { r#"
8962        @media (color) and (-webkit-min-device-pixel-ratio: 2), (color) and (min-resolution: 2dppx) {
8963          .foo {
8964            color: #ff0;
8965          }
8966        }
8967      "#},
8968      Browsers {
8969        safari: Some(15 << 16),
8970        ..Browsers::default()
8971      },
8972    );
8973    prefix_test(
8974      r#"
8975      @media (min-resolution: 2dppx),
8976             (min-resolution: 192dpi) {
8977        .foo { color: yellow; }
8978      }
8979      "#,
8980      indoc! { r#"
8981        @media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (min-resolution: 2dppx), (min-resolution: 192dpi) {
8982          .foo {
8983            color: #ff0;
8984          }
8985        }
8986      "#},
8987      Browsers {
8988        safari: Some(15 << 16),
8989        firefox: Some(10 << 16),
8990        ..Browsers::default()
8991      },
8992    );
8993    prefix_test(
8994      r#"
8995      @media only screen and (min-resolution: 124.8dpi) {
8996        .foo { color: yellow; }
8997      }
8998      "#,
8999      indoc! { r#"
9000        @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) {
9001          .foo {
9002            color: #ff0;
9003          }
9004        }
9005      "#},
9006      Browsers {
9007        safari: Some(15 << 16),
9008        firefox: Some(10 << 16),
9009        ..Browsers::default()
9010      },
9011    );
9012
9013    error_test(
9014      "@media (min-width: hi) { .foo { color: chartreuse }}",
9015      ParserError::InvalidMediaQuery,
9016    );
9017    error_test(
9018      "@media (width >= hi) { .foo { color: chartreuse }}",
9019      ParserError::InvalidMediaQuery,
9020    );
9021    error_test(
9022      "@media (width >= 2/1) { .foo { color: chartreuse }}",
9023      ParserError::UnexpectedToken(Token::Delim('/')),
9024    );
9025    error_test(
9026      "@media (600px <= min-height) { .foo { color: chartreuse }}",
9027      ParserError::InvalidMediaQuery,
9028    );
9029    error_test(
9030      "@media (scan >= 1) { .foo { color: chartreuse }}",
9031      ParserError::InvalidMediaQuery,
9032    );
9033    error_test(
9034      "@media (min-scan: interlace) { .foo { color: chartreuse }}",
9035      ParserError::InvalidMediaQuery,
9036    );
9037    error_test(
9038      "@media (1px <= width <= bar) { .foo { color: chartreuse }}",
9039      ParserError::InvalidMediaQuery,
9040    );
9041    error_test(
9042      "@media (1px <= min-width <= 2px) { .foo { color: chartreuse }}",
9043      ParserError::InvalidMediaQuery,
9044    );
9045    error_test(
9046      "@media (1px <= scan <= 2px) { .foo { color: chartreuse }}",
9047      ParserError::InvalidMediaQuery,
9048    );
9049    error_test(
9050      "@media (grid: 10) { .foo { color: chartreuse }}",
9051      ParserError::InvalidMediaQuery,
9052    );
9053    error_test(
9054      "@media (prefers-color-scheme = dark) { .foo { color: chartreuse }}",
9055      ParserError::InvalidMediaQuery,
9056    );
9057  }
9058
9059  #[test]
9060  fn test_merge_layers() {
9061    test(
9062      r#"
9063      @layer foo {
9064        .foo {
9065          color: red;
9066        }
9067      }
9068      @layer foo {
9069        .foo {
9070          background: #fff;
9071        }
9072
9073        .baz {
9074          color: #fff;
9075        }
9076      }
9077      "#,
9078      indoc! {r#"
9079      @layer foo {
9080        .foo {
9081          color: red;
9082          background: #fff;
9083        }
9084
9085        .baz {
9086          color: #fff;
9087        }
9088      }
9089    "#},
9090    );
9091    test(
9092      r#"
9093      @layer a {}
9094      @layer b {}
9095
9096      @layer b {
9097        foo {
9098          color: red;
9099        }
9100      }
9101
9102      @layer a {
9103        bar {
9104          color: yellow;
9105        }
9106      }
9107      "#,
9108      indoc! {r#"
9109      @layer a {
9110        bar {
9111          color: #ff0;
9112        }
9113      }
9114
9115      @layer b {
9116        foo {
9117          color: red;
9118        }
9119      }
9120    "#},
9121    );
9122
9123    test(
9124      r#"
9125      @layer a {}
9126      @layer b {}
9127
9128      @layer b {
9129        foo {
9130          color: red;
9131        }
9132      }
9133      "#,
9134      indoc! {r#"
9135      @layer a;
9136
9137      @layer b {
9138        foo {
9139          color: red;
9140        }
9141      }
9142    "#},
9143    );
9144
9145    test(
9146      r#"
9147      @layer a;
9148      @layer b;
9149      @layer c;
9150      "#,
9151      indoc! {r#"
9152      @layer a, b, c;
9153    "#},
9154    );
9155
9156    test(
9157      r#"
9158      @layer a {}
9159      @layer b {}
9160      @layer c {}
9161      "#,
9162      indoc! {r#"
9163      @layer a, b, c;
9164    "#},
9165    );
9166
9167    test(
9168      r#"
9169      @layer a;
9170      @layer b {
9171        .foo {
9172          color: red;
9173        }
9174      }
9175      @layer c {}
9176      "#,
9177      indoc! {r#"
9178      @layer a;
9179
9180      @layer b {
9181        .foo {
9182          color: red;
9183        }
9184      }
9185
9186      @layer c;
9187    "#},
9188    );
9189
9190    test(
9191      r#"
9192      @layer a, b;
9193      @layer c {}
9194
9195      @layer d {
9196        foo {
9197          color: red;
9198        }
9199      }
9200      "#,
9201      indoc! {r#"
9202      @layer a, b, c;
9203
9204      @layer d {
9205        foo {
9206          color: red;
9207        }
9208      }
9209    "#},
9210    );
9211
9212    test(
9213      r#"
9214      @layer a;
9215      @layer b;
9216      @import "a.css" layer(x);
9217      @layer c;
9218
9219      @layer d {
9220        foo {
9221          color: red;
9222        }
9223      }
9224      "#,
9225      indoc! {r#"
9226      @layer a, b;
9227      @import "a.css" layer(x);
9228      @layer c;
9229
9230      @layer d {
9231        foo {
9232          color: red;
9233        }
9234      }
9235    "#},
9236    );
9237
9238    test(
9239      r#"
9240      @layer a, b, c;
9241
9242      @layer a {
9243        foo {
9244          color: red;
9245        }
9246      }
9247      "#,
9248      indoc! {r#"
9249      @layer a {
9250        foo {
9251          color: red;
9252        }
9253      }
9254
9255      @layer b, c;
9256    "#},
9257    );
9258  }
9259
9260  #[test]
9261  fn test_merge_rules() {
9262    test(
9263      r#"
9264      .foo {
9265        color: red;
9266      }
9267      .bar {
9268        color: red;
9269      }
9270    "#,
9271      indoc! {r#"
9272      .foo, .bar {
9273        color: red;
9274      }
9275    "#},
9276    );
9277    test(
9278      r#"
9279      .foo {
9280        color: red;
9281      }
9282      .foo {
9283        background: green;
9284      }
9285    "#,
9286      indoc! {r#"
9287      .foo {
9288        color: red;
9289        background: green;
9290      }
9291    "#},
9292    );
9293    test(
9294      r#"
9295      .foo {
9296        color: red;
9297      }
9298      .foo {
9299        background: green !important;
9300      }
9301    "#,
9302      indoc! {r#"
9303      .foo {
9304        color: red;
9305        background: green !important;
9306      }
9307    "#},
9308    );
9309    test(
9310      r#"
9311      .foo {
9312        background: red;
9313      }
9314      .foo {
9315        background: green;
9316      }
9317    "#,
9318      indoc! {r#"
9319      .foo {
9320        background: green;
9321      }
9322    "#},
9323    );
9324    test(
9325      r#"
9326      .foo {
9327        --foo: red;
9328        --foo: purple;
9329      }
9330      .foo {
9331        --foo: green;
9332      }
9333    "#,
9334      indoc! {r#"
9335      .foo {
9336        --foo: green;
9337      }
9338    "#},
9339    );
9340    test(
9341      r#"
9342      .foo {
9343        color: red;
9344      }
9345
9346      .bar {
9347        background: green;
9348      }
9349    "#,
9350      indoc! {r#"
9351      .foo {
9352        color: red;
9353      }
9354
9355      .bar {
9356        background: green;
9357      }
9358    "#},
9359    );
9360    test(
9361      r#"
9362      .foo {
9363        color: red;
9364      }
9365
9366      .baz {
9367        color: blue;
9368      }
9369
9370      .bar {
9371        color: red;
9372      }
9373    "#,
9374      indoc! {r#"
9375      .foo {
9376        color: red;
9377      }
9378
9379      .baz {
9380        color: #00f;
9381      }
9382
9383      .bar {
9384        color: red;
9385      }
9386    "#},
9387    );
9388    test(
9389      r#"
9390      .foo {
9391        background: red;
9392      }
9393      .bar {
9394        background: red;
9395      }
9396      .foo {
9397        color: green;
9398      }
9399      .bar {
9400        color: green;
9401      }
9402    "#,
9403      indoc! {r#"
9404      .foo, .bar {
9405        color: green;
9406        background: red;
9407      }
9408    "#},
9409    );
9410    test(
9411      r#"
9412      .foo, .bar {
9413        background: red;
9414      }
9415      .foo {
9416        color: green;
9417      }
9418      .bar {
9419        color: green;
9420      }
9421    "#,
9422      indoc! {r#"
9423      .foo, .bar {
9424        color: green;
9425        background: red;
9426      }
9427    "#},
9428    );
9429    test(
9430      r#"
9431      .foo {
9432        background: red;
9433      }
9434      .foo {
9435        color: green;
9436      }
9437      .bar {
9438        background: red;
9439      }
9440      .bar {
9441        color: green;
9442      }
9443    "#,
9444      indoc! {r#"
9445      .foo, .bar {
9446        color: green;
9447        background: red;
9448      }
9449    "#},
9450    );
9451    test(
9452      r#"
9453      [foo="bar"] {
9454        color: red;
9455      }
9456      .bar {
9457        color: red;
9458      }
9459    "#,
9460      indoc! {r#"
9461      [foo="bar"], .bar {
9462        color: red;
9463      }
9464    "#},
9465    );
9466    test(
9467      r#"
9468      .a {
9469        color: red;
9470      }
9471      .b {
9472        color: green;
9473      }
9474      .a {
9475        color: red;
9476      }
9477    "#,
9478      indoc! {r#"
9479      .b {
9480        color: green;
9481      }
9482
9483      .a {
9484        color: red;
9485      }
9486    "#},
9487    );
9488    test(
9489      r#"
9490      .a {
9491        color: red;
9492      }
9493      .b {
9494        color: green;
9495      }
9496      .a {
9497        color: pink;
9498      }
9499    "#,
9500      indoc! {r#"
9501      .b {
9502        color: green;
9503      }
9504
9505      .a {
9506        color: pink;
9507      }
9508    "#},
9509    );
9510    test(
9511      r#"
9512      .a:foo(#000) {
9513        color: red;
9514      }
9515      .b {
9516        color: green;
9517      }
9518      .a:foo(#ff0) {
9519        color: pink;
9520      }
9521    "#,
9522      indoc! {r#"
9523      .a:foo(#000) {
9524        color: red;
9525      }
9526
9527      .b {
9528        color: green;
9529      }
9530
9531      .a:foo(#ff0) {
9532        color: pink;
9533      }
9534    "#},
9535    );
9536    test(
9537      r#"
9538      .a {
9539        border-radius: 10px;
9540      }
9541      .b {
9542        color: green;
9543      }
9544      .a {
9545        border-radius: 10px;
9546      }
9547    "#,
9548      indoc! {r#"
9549      .b {
9550        color: green;
9551      }
9552
9553      .a {
9554        border-radius: 10px;
9555      }
9556    "#},
9557    );
9558    test(
9559      r#"
9560      .a {
9561        border-radius: 10px;
9562      }
9563      .b {
9564        color: green;
9565      }
9566      .a {
9567        -webkit-border-radius: 10px;
9568      }
9569    "#,
9570      indoc! {r#"
9571      .a {
9572        border-radius: 10px;
9573      }
9574
9575      .b {
9576        color: green;
9577      }
9578
9579      .a {
9580        -webkit-border-radius: 10px;
9581      }
9582    "#},
9583    );
9584    test(
9585      r#"
9586      .a {
9587        border-radius: 10px;
9588      }
9589      .b {
9590        color: green;
9591      }
9592      .a {
9593        border-radius: var(--foo);
9594      }
9595    "#,
9596      indoc! {r#"
9597      .b {
9598        color: green;
9599      }
9600
9601      .a {
9602        border-radius: var(--foo);
9603      }
9604    "#},
9605    );
9606    test(
9607      r#"
9608      .a {
9609        border-radius: 10px;
9610      }
9611      .b {
9612        color: green;
9613      }
9614      .c {
9615        border-radius: 20px;
9616      }
9617    "#,
9618      indoc! {r#"
9619      .a {
9620        border-radius: 10px;
9621      }
9622
9623      .b {
9624        color: green;
9625      }
9626
9627      .c {
9628        border-radius: 20px;
9629      }
9630    "#},
9631    );
9632    test(
9633      r#"
9634      @media print {
9635        .a {
9636          color: red;
9637        }
9638        .b {
9639          color: green;
9640        }
9641        .a {
9642          color: red;
9643        }
9644      }
9645    "#,
9646      indoc! {r#"
9647      @media print {
9648        .b {
9649          color: green;
9650        }
9651
9652        .a {
9653          color: red;
9654        }
9655      }
9656    "#},
9657    );
9658    test(
9659      r#"
9660      .a {
9661        border-radius: 10px;
9662      }
9663      .b {
9664        color: green;
9665      }
9666      .a {
9667        border-radius: 20px;
9668        color: pink;
9669      }
9670    "#,
9671      indoc! {r#"
9672      .a {
9673        border-radius: 10px;
9674      }
9675
9676      .b {
9677        color: green;
9678      }
9679
9680      .a {
9681        color: pink;
9682        border-radius: 20px;
9683      }
9684    "#},
9685    );
9686    test(
9687      r#"
9688      .a {
9689        color: red;
9690      }
9691      .b {
9692        color: green;
9693      }
9694      .a {
9695        color: red;
9696      }
9697      .b {
9698        color: green;
9699      }
9700    "#,
9701      indoc! {r#"
9702      .a {
9703        color: red;
9704      }
9705
9706      .b {
9707        color: green;
9708      }
9709    "#},
9710    );
9711
9712    prefix_test(
9713      r#"
9714      [foo="bar"] {
9715        color: red;
9716      }
9717      .bar {
9718        color: red;
9719      }
9720    "#,
9721      indoc! {r#"
9722      [foo="bar"] {
9723        color: red;
9724      }
9725
9726      .bar {
9727        color: red;
9728      }
9729    "#},
9730      Browsers {
9731        ie: Some(6 << 16),
9732        ..Browsers::default()
9733      },
9734    );
9735
9736    prefix_test(
9737      r#"
9738      [foo="bar"] {
9739        color: red;
9740      }
9741      .bar {
9742        color: red;
9743      }
9744    "#,
9745      indoc! {r#"
9746      [foo="bar"], .bar {
9747        color: red;
9748      }
9749    "#},
9750      Browsers {
9751        ie: Some(10 << 16),
9752        ..Browsers::default()
9753      },
9754    );
9755
9756    test(
9757      r#"
9758      .foo:-moz-read-only {
9759        color: red;
9760      }
9761    "#,
9762      indoc! {r#"
9763      .foo:-moz-read-only {
9764        color: red;
9765      }
9766    "#},
9767    );
9768
9769    test(
9770      r#"
9771      .foo:-moz-read-only {
9772        color: red;
9773      }
9774
9775      .foo:read-only {
9776        color: red;
9777      }
9778    "#,
9779      indoc! {r#"
9780      .foo:-moz-read-only {
9781        color: red;
9782      }
9783
9784      .foo:read-only {
9785        color: red;
9786      }
9787    "#},
9788    );
9789
9790    prefix_test(
9791      r#"
9792      .foo:-moz-read-only {
9793        color: red;
9794      }
9795
9796      .foo:read-only {
9797        color: red;
9798      }
9799    "#,
9800      indoc! {r#"
9801      .foo:read-only {
9802        color: red;
9803      }
9804    "#},
9805      Browsers {
9806        firefox: Some(85 << 16),
9807        ..Browsers::default()
9808      },
9809    );
9810
9811    prefix_test(
9812      r#"
9813      .foo:-moz-read-only {
9814        color: red;
9815      }
9816
9817      .bar {
9818        color: yellow;
9819      }
9820
9821      .foo:read-only {
9822        color: red;
9823      }
9824    "#,
9825      indoc! {r#"
9826      .foo:-moz-read-only {
9827        color: red;
9828      }
9829
9830      .bar {
9831        color: #ff0;
9832      }
9833
9834      .foo:read-only {
9835        color: red;
9836      }
9837    "#},
9838      Browsers {
9839        firefox: Some(85 << 16),
9840        ..Browsers::default()
9841      },
9842    );
9843
9844    prefix_test(
9845      r#"
9846      .foo:-moz-read-only {
9847        color: red;
9848      }
9849
9850      .foo:read-only {
9851        color: red;
9852      }
9853    "#,
9854      indoc! {r#"
9855      .foo:-moz-read-only {
9856        color: red;
9857      }
9858
9859      .foo:read-only {
9860        color: red;
9861      }
9862    "#},
9863      Browsers {
9864        firefox: Some(36 << 16),
9865        ..Browsers::default()
9866      },
9867    );
9868
9869    prefix_test(
9870      r#"
9871      .foo:read-only {
9872        color: red;
9873      }
9874    "#,
9875      indoc! {r#"
9876      .foo:-moz-read-only {
9877        color: red;
9878      }
9879
9880      .foo:read-only {
9881        color: red;
9882      }
9883    "#},
9884      Browsers {
9885        firefox: Some(36 << 16),
9886        ..Browsers::default()
9887      },
9888    );
9889
9890    prefix_test(
9891      r#"
9892      .foo:-webkit-full-screen {
9893        color: red;
9894      }
9895      .foo:-moz-full-screen {
9896        color: red;
9897      }
9898      .foo:-ms-fullscreen {
9899        color: red;
9900      }
9901      .foo:fullscreen {
9902        color: red;
9903      }
9904    "#,
9905      indoc! {r#"
9906      .foo:fullscreen {
9907        color: red;
9908      }
9909    "#},
9910      Browsers {
9911        chrome: Some(96 << 16),
9912        ..Browsers::default()
9913      },
9914    );
9915
9916    prefix_test(
9917      r#"
9918      .foo:fullscreen {
9919        color: red;
9920      }
9921    "#,
9922      indoc! {r#"
9923      .foo:-webkit-full-screen {
9924        color: red;
9925      }
9926
9927      .foo:-moz-full-screen {
9928        color: red;
9929      }
9930
9931      .foo:-ms-fullscreen {
9932        color: red;
9933      }
9934
9935      .foo:fullscreen {
9936        color: red;
9937      }
9938    "#},
9939      Browsers {
9940        chrome: Some(45 << 16),
9941        firefox: Some(45 << 16),
9942        ie: Some(11 << 16),
9943        ..Browsers::default()
9944      },
9945    );
9946
9947    prefix_test(
9948      r#"
9949      .foo::placeholder {
9950        color: red;
9951      }
9952    "#,
9953      indoc! {r#"
9954      .foo::-webkit-input-placeholder {
9955        color: red;
9956      }
9957
9958      .foo::-moz-placeholder {
9959        color: red;
9960      }
9961
9962      .foo::-ms-input-placeholder {
9963        color: red;
9964      }
9965
9966      .foo::placeholder {
9967        color: red;
9968      }
9969    "#},
9970      Browsers {
9971        chrome: Some(45 << 16),
9972        firefox: Some(45 << 16),
9973        ie: Some(11 << 16),
9974        ..Browsers::default()
9975      },
9976    );
9977
9978    prefix_test(
9979      r#"
9980      .foo::file-selector-button {
9981        color: red;
9982      }
9983    "#,
9984      indoc! {r#"
9985      .foo::-webkit-file-upload-button {
9986        color: red;
9987      }
9988
9989      .foo::-ms-browse {
9990        color: red;
9991      }
9992
9993      .foo::file-selector-button {
9994        color: red;
9995      }
9996    "#},
9997      Browsers {
9998        chrome: Some(84 << 16),
9999        ie: Some(10 << 16),
10000        ..Browsers::default()
10001      },
10002    );
10003
10004    prefix_test(
10005      r#"
10006      .foo::file-selector-button {
10007        margin-inline-start: 2px;
10008      }
10009    "#,
10010      indoc! {r#"
10011      .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 {
10012        margin-left: 2px;
10013      }
10014
10015      .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 {
10016        margin-left: 2px;
10017      }
10018
10019      .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 {
10020        margin-left: 2px;
10021      }
10022
10023      .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 {
10024        margin-right: 2px;
10025      }
10026
10027      .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 {
10028        margin-right: 2px;
10029      }
10030
10031      .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 {
10032        margin-right: 2px;
10033      }
10034    "#},
10035      Browsers {
10036        chrome: Some(84 << 16),
10037        ie: Some(10 << 16),
10038        ..Browsers::default()
10039      },
10040    );
10041
10042    prefix_test(
10043      r#"
10044      .foo:placeholder-shown .bar { color: red; }
10045      .foo:autofill .baz { color: red; }
10046      "#,
10047      indoc! {r#"
10048      .foo:placeholder-shown .bar {
10049        color: red;
10050      }
10051
10052      .foo:-webkit-autofill .baz {
10053        color: red;
10054      }
10055
10056      .foo:autofill .baz {
10057        color: red;
10058      }
10059      "#},
10060      Browsers {
10061        chrome: Some(103 << 16),
10062        ..Browsers::default()
10063      },
10064    );
10065
10066    prefix_test(
10067      r#"
10068      .foo:placeholder-shown .bar,.foo:autofill .baz{color:red}
10069      "#,
10070      indoc! {r#"
10071      :-webkit-any(.foo:placeholder-shown .bar, .foo:-webkit-autofill .baz) {
10072        color: red;
10073      }
10074
10075      :is(.foo:placeholder-shown .bar, .foo:autofill .baz) {
10076        color: red;
10077      }
10078      "#},
10079      Browsers {
10080        chrome: Some(103 << 16),
10081        ..Browsers::default()
10082      },
10083    );
10084
10085    prefix_test(
10086      r#"
10087      .foo:placeholder-shown .bar, .foo:-webkit-autofill .baz {
10088        color: red;
10089      }
10090
10091      .foo:placeholder-shown .bar, .foo:autofill .baz {
10092        color: red;
10093      }
10094      "#,
10095      indoc! {r#"
10096      :-webkit-any(.foo:placeholder-shown .bar, .foo:-webkit-autofill .baz) {
10097        color: red;
10098      }
10099
10100      :is(.foo:placeholder-shown .bar, .foo:autofill .baz) {
10101        color: red;
10102      }
10103      "#},
10104      Browsers {
10105        chrome: Some(103 << 16),
10106        ..Browsers::default()
10107      },
10108    );
10109
10110    test(
10111      r#"
10112      .foo:placeholder-shown .bar, .foo:-webkit-autofill .baz {
10113        color: red;
10114      }
10115
10116      .foo:placeholder-shown .bar, .foo:autofill .baz {
10117        color: red;
10118      }
10119      "#,
10120      indoc! {r#"
10121      .foo:placeholder-shown .bar, .foo:-webkit-autofill .baz {
10122        color: red;
10123      }
10124
10125      .foo:placeholder-shown .bar, .foo:autofill .baz {
10126        color: red;
10127      }
10128      "#},
10129    );
10130
10131    prefix_test(
10132      r#"
10133      :hover, :focus-visible {
10134        color: red;
10135      }
10136      "#,
10137      indoc! {r#"
10138      :hover {
10139        color: red;
10140      }
10141
10142      :focus-visible {
10143        color: red;
10144      }
10145      "#},
10146      Browsers {
10147        safari: Some(13 << 16),
10148        ..Browsers::default()
10149      },
10150    );
10151
10152    prefix_test(
10153      r#"
10154      .foo {
10155        color: red;
10156      }
10157
10158      :hover, :focus-visible {
10159        color: red;
10160      }
10161      "#,
10162      indoc! {r#"
10163      .foo, :hover {
10164        color: red;
10165      }
10166
10167      :focus-visible {
10168        color: red;
10169      }
10170      "#},
10171      Browsers {
10172        safari: Some(13 << 16),
10173        ..Browsers::default()
10174      },
10175    );
10176
10177    prefix_test(
10178      r#"
10179      :hover, :focus-visible {
10180        margin-inline-start: 24px;
10181      }
10182      "#,
10183      indoc! {r#"
10184      :hover:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
10185        margin-left: 24px;
10186      }
10187
10188      :hover:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
10189        margin-right: 24px;
10190      }
10191
10192      :focus-visible:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
10193        margin-left: 24px;
10194      }
10195
10196      :focus-visible:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
10197        margin-right: 24px;
10198      }
10199      "#},
10200      Browsers {
10201        safari: Some(11 << 16),
10202        ..Browsers::default()
10203      },
10204    );
10205
10206    prefix_test(
10207      r#"
10208      :focus-within, :focus-visible {
10209        color: red;
10210      }
10211      "#,
10212      indoc! {r#"
10213      :focus-within {
10214        color: red;
10215      }
10216
10217      :focus-visible {
10218        color: red;
10219      }
10220      "#},
10221      Browsers {
10222        safari: Some(9 << 16),
10223        ..Browsers::default()
10224      },
10225    );
10226
10227    prefix_test(
10228      r#"
10229      :hover, :focus-visible {
10230        color: red;
10231      }
10232      "#,
10233      indoc! {r#"
10234      :is(:hover, :focus-visible) {
10235        color: red;
10236      }
10237      "#},
10238      Browsers {
10239        safari: Some(14 << 16),
10240        ..Browsers::default()
10241      },
10242    );
10243
10244    prefix_test(
10245      r#"
10246      a::after:hover, a::after:focus-visible {
10247        color: red;
10248      }
10249      "#,
10250      indoc! {r#"
10251      a:after:hover {
10252        color: red;
10253      }
10254
10255      a:after:focus-visible {
10256        color: red;
10257      }
10258      "#},
10259      Browsers {
10260        safari: Some(14 << 16),
10261        ..Browsers::default()
10262      },
10263    );
10264
10265    prefix_test(
10266      r#"
10267      a:not(:hover), a:not(:focus-visible) {
10268        color: red;
10269      }
10270      "#,
10271      indoc! {r#"
10272      :is(a:not(:hover), a:not(:focus-visible)) {
10273        color: red;
10274      }
10275      "#},
10276      Browsers {
10277        safari: Some(14 << 16),
10278        ..Browsers::default()
10279      },
10280    );
10281
10282    prefix_test(
10283      r#"
10284      a:has(:hover), a:has(:focus-visible) {
10285        color: red;
10286      }
10287      "#,
10288      indoc! {r#"
10289      :is(a:has(:hover), a:has(:focus-visible)) {
10290        color: red;
10291      }
10292      "#},
10293      Browsers {
10294        safari: Some(14 << 16),
10295        ..Browsers::default()
10296      },
10297    );
10298
10299    prefix_test(
10300      r#"
10301      .foo.foo:hover, .bar:focus-visible {
10302        color: red;
10303      }
10304      "#,
10305      indoc! {r#"
10306      .foo.foo:hover {
10307        color: red;
10308      }
10309
10310      .bar:focus-visible {
10311        color: red;
10312      }
10313      "#},
10314      Browsers {
10315        safari: Some(14 << 16),
10316        ..Browsers::default()
10317      },
10318    );
10319
10320    prefix_test(
10321      r#"
10322      a::unknown-a, a::unknown-b {
10323        color: red;
10324      }
10325      "#,
10326      indoc! {r#"
10327      a::unknown-a {
10328        color: red;
10329      }
10330
10331      a::unknown-b {
10332        color: red;
10333      }
10334      "#},
10335      Browsers {
10336        safari: Some(14 << 16),
10337        ..Browsers::default()
10338      },
10339    );
10340
10341    nesting_test_with_targets(
10342      r#"
10343      .foo {
10344        padding-inline-start: 3px;
10345
10346        .bar {
10347          padding-inline-start: 5px;
10348        }
10349      }
10350      "#,
10351      indoc! {r#"
10352      .foo:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
10353        padding-left: 3px;
10354      }
10355
10356      .foo:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
10357        padding-right: 3px;
10358      }
10359
10360      .foo .bar:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
10361        padding-left: 5px;
10362      }
10363
10364      .foo .bar:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
10365        padding-right: 5px;
10366      }
10367      "#},
10368      Browsers {
10369        safari: Some(12 << 16),
10370        ..Browsers::default()
10371      }
10372      .into(),
10373    );
10374
10375    prefix_test(
10376      r#"
10377      .foo::part(header), .foo::part(body) {
10378        display: none
10379      }
10380      "#,
10381      indoc! {r#"
10382      .foo::part(header), .foo::part(body) {
10383        display: none;
10384      }
10385      "#},
10386      Browsers {
10387        safari: Some(14 << 16),
10388        ..Browsers::default()
10389      },
10390    );
10391
10392    prefix_test(
10393      r#"
10394      .foo :is(.bar) {
10395        color: red;
10396      }
10397      "#,
10398      indoc! {r#"
10399        .foo .bar {
10400          color: red;
10401        }
10402      "#},
10403      Browsers {
10404        chrome: Some(87 << 16),
10405        ..Browsers::default()
10406      },
10407    );
10408
10409    prefix_test(
10410      r#"
10411      .foo :is(.bar), .bar :is(.baz) {
10412        color: red;
10413      }
10414      "#,
10415      indoc! {r#"
10416        .foo .bar, .bar .baz {
10417          color: red;
10418        }
10419      "#},
10420      Browsers {
10421        chrome: Some(87 << 16),
10422        ..Browsers::default()
10423      },
10424    );
10425
10426    prefix_test(
10427      r#"
10428      .foo :is(.bar:focus-visible), .bar :is(.baz:hover) {
10429        color: red;
10430      }
10431      "#,
10432      indoc! {r#"
10433        .bar .baz:hover {
10434          color: red;
10435        }
10436
10437        .foo .bar:focus-visible {
10438          color: red;
10439        }
10440      "#},
10441      Browsers {
10442        chrome: Some(85 << 16),
10443        ..Browsers::default()
10444      },
10445    );
10446
10447    prefix_test(
10448      r#"
10449      *,
10450      ::before,
10451      ::after,
10452      ::backdrop {
10453        padding: 5px;
10454      }
10455      "#,
10456      indoc! {r#"
10457        *, :before, :after {
10458          padding: 5px;
10459        }
10460
10461        ::-webkit-backdrop {
10462          padding: 5px;
10463        }
10464
10465        ::backdrop {
10466          padding: 5px;
10467        }
10468      "#},
10469      Browsers {
10470        chrome: Some(33 << 16),
10471        ..Browsers::default()
10472      },
10473    );
10474
10475    test(
10476      r#"
10477      .foo:-webkit-any(.bar, .baz):after {
10478        color: red;
10479      }
10480
10481      .foo:is(.bar, .baz):after {
10482        color: red;
10483      }
10484      "#,
10485      indoc! {r#"
10486        .foo:-webkit-any(.bar, .baz):after {
10487          color: red;
10488        }
10489
10490        .foo:is(.bar, .baz):after {
10491          color: red;
10492        }
10493      "#},
10494    );
10495
10496    prefix_test(
10497      r#"
10498      .foo:-webkit-any(.bar, .baz):after {
10499        color: red;
10500      }
10501
10502      .foo:is(.bar, .baz):after {
10503        color: red;
10504      }
10505      "#,
10506      indoc! {r#"
10507        .foo:is(.bar, .baz):after {
10508          color: red;
10509        }
10510      "#},
10511      Browsers {
10512        safari: Some(16 << 16),
10513        ..Browsers::default()
10514      },
10515    );
10516
10517    prefix_test(
10518      r#"
10519      .foo:-webkit-any(.bar):after {
10520        color: red;
10521      }
10522
10523      .foo:is(.bar, .baz):after {
10524        color: red;
10525      }
10526      "#,
10527      indoc! {r#"
10528        .foo:-webkit-any(.bar):after {
10529          color: red;
10530        }
10531
10532        .foo:is(.bar, .baz):after {
10533          color: red;
10534        }
10535      "#},
10536      Browsers {
10537        safari: Some(16 << 16),
10538        ..Browsers::default()
10539      },
10540    );
10541
10542    prefix_test(
10543      r#"
10544      .foo:-webkit-any(.bar, .baz):after {
10545        color: red;
10546      }
10547
10548      .foo:is(.bar, .baz):after {
10549        color: red;
10550      }
10551      "#,
10552      indoc! {r#"
10553        .foo:-webkit-any(.bar, .baz):after {
10554          color: red;
10555        }
10556
10557        .foo:is(.bar, .baz):after {
10558          color: red;
10559        }
10560      "#},
10561      Browsers {
10562        safari: Some(12 << 16),
10563        ..Browsers::default()
10564      },
10565    );
10566
10567    prefix_test(
10568      r#"
10569      .foo:-webkit-any(.bar, .baz):after {
10570        color: red;
10571      }
10572
10573      .foo:-moz-any(.bar, .baz):after {
10574        color: red;
10575      }
10576      "#,
10577      indoc! {r#"
10578        .foo:-webkit-any(.bar, .baz):after {
10579          color: red;
10580        }
10581
10582        .foo:-moz-any(.bar, .baz):after {
10583          color: red;
10584        }
10585      "#},
10586      Browsers {
10587        safari: Some(12 << 16),
10588        firefox: Some(67 << 16),
10589        ..Browsers::default()
10590      },
10591    );
10592
10593    prefix_test(
10594      r#"
10595      .a {
10596        padding-inline: var(--foo);
10597      }
10598
10599      .a:-webkit-any(.b, .c) {
10600        padding-inline: var(--foo);
10601      }
10602      "#,
10603      indoc! {r#"
10604        .a {
10605          padding-inline: var(--foo);
10606        }
10607
10608        .a:-webkit-any(.b, .c) {
10609          padding-inline: var(--foo);
10610        }
10611      "#},
10612      Browsers {
10613        safari: Some(12 << 16),
10614        ..Browsers::default()
10615      },
10616    );
10617  }
10618
10619  #[test]
10620  fn test_merge_media_rules() {
10621    test(
10622      r#"
10623      @media (hover) {
10624        .foo {
10625          color: red;
10626        }
10627      }
10628      @media (hover) {
10629        .foo {
10630          background: #fff;
10631        }
10632
10633        .baz {
10634          color: #fff;
10635        }
10636      }
10637      "#,
10638      indoc! {r#"
10639      @media (hover) {
10640        .foo {
10641          color: red;
10642          background: #fff;
10643        }
10644
10645        .baz {
10646          color: #fff;
10647        }
10648      }
10649    "#},
10650    );
10651
10652    test(
10653      r#"
10654      @media (hover) {
10655        .foo {
10656          color: red;
10657        }
10658      }
10659      @media (min-width: 250px) {
10660        .foo {
10661          background: #fff;
10662        }
10663
10664        .baz {
10665          color: #fff;
10666        }
10667      }
10668      "#,
10669      indoc! {r#"
10670      @media (hover) {
10671        .foo {
10672          color: red;
10673        }
10674      }
10675
10676      @media (width >= 250px) {
10677        .foo {
10678          background: #fff;
10679        }
10680
10681        .baz {
10682          color: #fff;
10683        }
10684      }
10685    "#},
10686    );
10687  }
10688
10689  #[test]
10690  fn test_merge_supports() {
10691    test(
10692      r#"
10693      @supports (flex: 1) {
10694        .foo {
10695          color: red;
10696        }
10697      }
10698      @supports (flex: 1) {
10699        .foo {
10700          background: #fff;
10701        }
10702
10703        .baz {
10704          color: #fff;
10705        }
10706      }
10707      "#,
10708      indoc! {r#"
10709      @supports (flex: 1) {
10710        .foo {
10711          color: red;
10712          background: #fff;
10713        }
10714
10715        .baz {
10716          color: #fff;
10717        }
10718      }
10719    "#},
10720    );
10721
10722    test(
10723      r#"
10724      @supports (flex: 1) {
10725        .foo {
10726          color: red;
10727        }
10728      }
10729      @supports (display: grid) {
10730        .foo {
10731          background: #fff;
10732        }
10733
10734        .baz {
10735          color: #fff;
10736        }
10737      }
10738      "#,
10739      indoc! {r#"
10740      @supports (flex: 1) {
10741        .foo {
10742          color: red;
10743        }
10744      }
10745
10746      @supports (display: grid) {
10747        .foo {
10748          background: #fff;
10749        }
10750
10751        .baz {
10752          color: #fff;
10753        }
10754      }
10755    "#},
10756    );
10757  }
10758
10759  #[test]
10760  fn test_opacity() {
10761    minify_test(".foo { opacity: 0 }", ".foo{opacity:0}");
10762    minify_test(".foo { opacity: 0% }", ".foo{opacity:0}");
10763    minify_test(".foo { opacity: 0.5 }", ".foo{opacity:.5}");
10764    minify_test(".foo { opacity: 50% }", ".foo{opacity:.5}");
10765    minify_test(".foo { opacity: 1 }", ".foo{opacity:1}");
10766    minify_test(".foo { opacity: 100% }", ".foo{opacity:1}");
10767  }
10768
10769  #[test]
10770  fn test_transitions() {
10771    minify_test(".foo { transition-duration: 500ms }", ".foo{transition-duration:.5s}");
10772    minify_test(".foo { transition-duration: .5s }", ".foo{transition-duration:.5s}");
10773    minify_test(".foo { transition-duration: 99ms }", ".foo{transition-duration:99ms}");
10774    minify_test(".foo { transition-duration: .099s }", ".foo{transition-duration:99ms}");
10775    minify_test(".foo { transition-duration: 2000ms }", ".foo{transition-duration:2s}");
10776    minify_test(".foo { transition-duration: 2s }", ".foo{transition-duration:2s}");
10777    minify_test(
10778      ".foo { transition-duration: calc(1s - 50ms) }",
10779      ".foo{transition-duration:.95s}",
10780    );
10781    minify_test(
10782      ".foo { transition-duration: calc(1s - 50ms + 2s) }",
10783      ".foo{transition-duration:2.95s}",
10784    );
10785    minify_test(
10786      ".foo { transition-duration: calc((1s - 50ms) * 2) }",
10787      ".foo{transition-duration:1.9s}",
10788    );
10789    minify_test(
10790      ".foo { transition-duration: calc(2 * (1s - 50ms)) }",
10791      ".foo{transition-duration:1.9s}",
10792    );
10793    minify_test(
10794      ".foo { transition-duration: calc((2s + 50ms) - (1s - 50ms)) }",
10795      ".foo{transition-duration:1.1s}",
10796    );
10797    minify_test(
10798      ".foo { transition-duration: 500ms, 50ms }",
10799      ".foo{transition-duration:.5s,50ms}",
10800    );
10801    minify_test(".foo { transition-delay: 500ms }", ".foo{transition-delay:.5s}");
10802    minify_test(
10803      ".foo { transition-property: background }",
10804      ".foo{transition-property:background}",
10805    );
10806    minify_test(
10807      ".foo { transition-property: background, opacity }",
10808      ".foo{transition-property:background,opacity}",
10809    );
10810    minify_test(
10811      ".foo { transition-timing-function: linear }",
10812      ".foo{transition-timing-function:linear}",
10813    );
10814    minify_test(
10815      ".foo { transition-timing-function: ease }",
10816      ".foo{transition-timing-function:ease}",
10817    );
10818    minify_test(
10819      ".foo { transition-timing-function: ease-in }",
10820      ".foo{transition-timing-function:ease-in}",
10821    );
10822    minify_test(
10823      ".foo { transition-timing-function: ease-out }",
10824      ".foo{transition-timing-function:ease-out}",
10825    );
10826    minify_test(
10827      ".foo { transition-timing-function: ease-in-out }",
10828      ".foo{transition-timing-function:ease-in-out}",
10829    );
10830    minify_test(
10831      ".foo { transition-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1) }",
10832      ".foo{transition-timing-function:ease}",
10833    );
10834    minify_test(
10835      ".foo { transition-timing-function: cubic-bezier(0.42, 0, 1, 1) }",
10836      ".foo{transition-timing-function:ease-in}",
10837    );
10838    minify_test(
10839      ".foo { transition-timing-function: cubic-bezier(0, 0, 0.58, 1) }",
10840      ".foo{transition-timing-function:ease-out}",
10841    );
10842    minify_test(
10843      ".foo { transition-timing-function: cubic-bezier(0.42, 0, 0.58, 1) }",
10844      ".foo{transition-timing-function:ease-in-out}",
10845    );
10846    minify_test(
10847      ".foo { transition-timing-function: cubic-bezier(0.58, 0.2, 0.11, 1.2) }",
10848      ".foo{transition-timing-function:cubic-bezier(.58,.2,.11,1.2)}",
10849    );
10850    minify_test(
10851      ".foo { transition-timing-function: step-start }",
10852      ".foo{transition-timing-function:step-start}",
10853    );
10854    minify_test(
10855      ".foo { transition-timing-function: step-end }",
10856      ".foo{transition-timing-function:step-end}",
10857    );
10858    minify_test(
10859      ".foo { transition-timing-function: steps(1, start) }",
10860      ".foo{transition-timing-function:step-start}",
10861    );
10862    minify_test(
10863      ".foo { transition-timing-function: steps(1, jump-start) }",
10864      ".foo{transition-timing-function:step-start}",
10865    );
10866    minify_test(
10867      ".foo { transition-timing-function: steps(1, end) }",
10868      ".foo{transition-timing-function:step-end}",
10869    );
10870    minify_test(
10871      ".foo { transition-timing-function: steps(1, jump-end) }",
10872      ".foo{transition-timing-function:step-end}",
10873    );
10874    minify_test(
10875      ".foo { transition-timing-function: steps(5, jump-start) }",
10876      ".foo{transition-timing-function:steps(5,start)}",
10877    );
10878    minify_test(
10879      ".foo { transition-timing-function: steps(5, jump-end) }",
10880      ".foo{transition-timing-function:steps(5,end)}",
10881    );
10882    minify_test(
10883      ".foo { transition-timing-function: steps(5, jump-both) }",
10884      ".foo{transition-timing-function:steps(5,jump-both)}",
10885    );
10886    minify_test(
10887      ".foo { transition-timing-function: ease-in-out, cubic-bezier(0.42, 0, 1, 1) }",
10888      ".foo{transition-timing-function:ease-in-out,ease-in}",
10889    );
10890    minify_test(
10891      ".foo { transition-timing-function: cubic-bezier(0.42, 0, 1, 1), cubic-bezier(0.58, 0.2, 0.11, 1.2) }",
10892      ".foo{transition-timing-function:ease-in,cubic-bezier(.58,.2,.11,1.2)}",
10893    );
10894    minify_test(
10895      ".foo { transition-timing-function: step-start, steps(5, jump-start) }",
10896      ".foo{transition-timing-function:step-start,steps(5,start)}",
10897    );
10898    minify_test(".foo { transition: width 2s ease }", ".foo{transition:width 2s}");
10899    minify_test(
10900      ".foo { transition: width 2s ease, height 1000ms cubic-bezier(0.25, 0.1, 0.25, 1) }",
10901      ".foo{transition:width 2s,height 1s}",
10902    );
10903    minify_test(".foo { transition: width 2s 1s }", ".foo{transition:width 2s 1s}");
10904    minify_test(".foo { transition: width 2s ease 1s }", ".foo{transition:width 2s 1s}");
10905    minify_test(
10906      ".foo { transition: ease-in 1s width 4s }",
10907      ".foo{transition:width 1s ease-in 4s}",
10908    );
10909    minify_test(".foo { transition: opacity 0s .6s }", ".foo{transition:opacity 0s .6s}");
10910    test(
10911      r#"
10912      .foo {
10913        transition-property: opacity;
10914        transition-duration: 0.09s;
10915        transition-timing-function: ease-in-out;
10916        transition-delay: 500ms;
10917      }
10918    "#,
10919      indoc! {r#"
10920      .foo {
10921        transition: opacity 90ms ease-in-out .5s;
10922      }
10923    "#},
10924    );
10925    test(
10926      r#"
10927      .foo {
10928        transition: opacity 2s;
10929        transition-timing-function: ease;
10930        transition-delay: 500ms;
10931      }
10932    "#,
10933      indoc! {r#"
10934      .foo {
10935        transition: opacity 2s .5s;
10936      }
10937    "#},
10938    );
10939    test(
10940      r#"
10941      .foo {
10942        transition: opacity 500ms;
10943        transition-timing-function: var(--ease);
10944      }
10945    "#,
10946      indoc! {r#"
10947      .foo {
10948        transition: opacity .5s;
10949        transition-timing-function: var(--ease);
10950      }
10951    "#},
10952    );
10953    test(
10954      r#"
10955      .foo {
10956        transition-property: opacity;
10957        transition-duration: 0.09s;
10958        transition-timing-function: ease-in-out;
10959        transition-delay: 500ms;
10960        transition: color 2s;
10961      }
10962    "#,
10963      indoc! {r#"
10964      .foo {
10965        transition: color 2s;
10966      }
10967    "#},
10968    );
10969    test(
10970      r#"
10971      .foo {
10972        transition-property: opacity, color;
10973        transition-duration: 2s, 4s;
10974        transition-timing-function: ease-in-out, ease-in;
10975        transition-delay: 500ms, 0s;
10976      }
10977    "#,
10978      indoc! {r#"
10979      .foo {
10980        transition: opacity 2s ease-in-out .5s, color 4s ease-in;
10981      }
10982    "#},
10983    );
10984    test(
10985      r#"
10986      .foo {
10987        transition-property: opacity, color;
10988        transition-duration: 2s;
10989        transition-timing-function: ease-in-out;
10990        transition-delay: 500ms;
10991      }
10992    "#,
10993      indoc! {r#"
10994      .foo {
10995        transition: opacity 2s ease-in-out .5s, color 2s ease-in-out .5s;
10996      }
10997    "#},
10998    );
10999    test(
11000      r#"
11001      .foo {
11002        transition-property: opacity, color, width, height;
11003        transition-duration: 2s, 4s;
11004        transition-timing-function: ease;
11005        transition-delay: 0s;
11006      }
11007    "#,
11008      indoc! {r#"
11009      .foo {
11010        transition: opacity 2s, color 4s, width 2s, height 4s;
11011      }
11012    "#},
11013    );
11014
11015    test(
11016      r#"
11017      .foo {
11018        -webkit-transition-property: opacity, color;
11019        -webkit-transition-duration: 2s, 4s;
11020        -webkit-transition-timing-function: ease-in-out, ease-in;
11021        -webkit-transition-delay: 500ms, 0s;
11022      }
11023    "#,
11024      indoc! {r#"
11025      .foo {
11026        -webkit-transition: opacity 2s ease-in-out .5s, color 4s ease-in;
11027      }
11028    "#},
11029    );
11030
11031    test(
11032      r#"
11033      .foo {
11034        -webkit-transition-property: opacity, color;
11035        -webkit-transition-duration: 2s, 4s;
11036        -webkit-transition-timing-function: ease-in-out, ease-in;
11037        -webkit-transition-delay: 500ms, 0s;
11038        -moz-transition-property: opacity, color;
11039        -moz-transition-duration: 2s, 4s;
11040        -moz-transition-timing-function: ease-in-out, ease-in;
11041        -moz-transition-delay: 500ms, 0s;
11042        transition-property: opacity, color;
11043        transition-duration: 2s, 4s;
11044        transition-timing-function: ease-in-out, ease-in;
11045        transition-delay: 500ms, 0s;
11046      }
11047    "#,
11048      indoc! {r#"
11049      .foo {
11050        -webkit-transition: opacity 2s ease-in-out .5s, color 4s ease-in;
11051        -moz-transition: opacity 2s ease-in-out .5s, color 4s ease-in;
11052        transition: opacity 2s ease-in-out .5s, color 4s ease-in;
11053      }
11054    "#},
11055    );
11056
11057    test(
11058      r#"
11059      .foo {
11060        -webkit-transition-property: opacity, color;
11061        -moz-transition-property: opacity, color;
11062        transition-property: opacity, color;
11063        -webkit-transition-duration: 2s, 4s;
11064        -moz-transition-duration: 2s, 4s;
11065        transition-duration: 2s, 4s;
11066        -webkit-transition-timing-function: ease-in-out, ease-in;
11067        transition-timing-function: ease-in-out, ease-in;
11068        -moz-transition-timing-function: ease-in-out, ease-in;
11069        -webkit-transition-delay: 500ms, 0s;
11070        -moz-transition-delay: 500ms, 0s;
11071        transition-delay: 500ms, 0s;
11072      }
11073    "#,
11074      indoc! {r#"
11075      .foo {
11076        -webkit-transition: opacity 2s ease-in-out .5s, color 4s ease-in;
11077        -moz-transition: opacity 2s ease-in-out .5s, color 4s ease-in;
11078        transition: opacity 2s ease-in-out .5s, color 4s ease-in;
11079      }
11080    "#},
11081    );
11082
11083    test(
11084      r#"
11085      .foo {
11086        -webkit-transition-property: opacity;
11087        -moz-transition-property: color;
11088        transition-property: opacity, color;
11089        -webkit-transition-duration: 2s;
11090        -moz-transition-duration: 4s;
11091        transition-duration: 2s, 4s;
11092        -webkit-transition-timing-function: ease-in-out;
11093        -moz-transition-timing-function: ease-in-out;
11094        transition-timing-function: ease-in-out, ease-in;
11095        -webkit-transition-delay: 500ms;
11096        -moz-transition-delay: 0s;
11097        transition-delay: 500ms, 0s;
11098      }
11099    "#,
11100      indoc! {r#"
11101      .foo {
11102        -webkit-transition-property: opacity;
11103        -moz-transition-property: color;
11104        transition-property: opacity, color;
11105        -webkit-transition-duration: 2s;
11106        -moz-transition-duration: 4s;
11107        transition-duration: 2s, 4s;
11108        -webkit-transition-timing-function: ease-in-out;
11109        -moz-transition-timing-function: ease-in-out;
11110        -webkit-transition-delay: .5s;
11111        transition-timing-function: ease-in-out, ease-in;
11112        -moz-transition-delay: 0s;
11113        transition-delay: .5s, 0s;
11114      }
11115    "#},
11116    );
11117
11118    test(
11119      r#"
11120      .foo {
11121        -webkit-transition-property: opacity;
11122        transition-property: opacity, color;
11123        -moz-transition-property: color;
11124        -webkit-transition-duration: 2s;
11125        transition-duration: 2s, 4s;
11126        -moz-transition-duration: 4s;
11127        -webkit-transition-timing-function: ease-in-out;
11128        transition-timing-function: ease-in-out, ease-in;
11129        -moz-transition-timing-function: ease-in-out;
11130        -webkit-transition-delay: 500ms;
11131        transition-delay: 500ms, 0s;
11132        -moz-transition-delay: 0s;
11133      }
11134    "#,
11135      indoc! {r#"
11136      .foo {
11137        -webkit-transition-property: opacity;
11138        transition-property: opacity, color;
11139        -moz-transition-property: color;
11140        -webkit-transition-duration: 2s;
11141        transition-duration: 2s, 4s;
11142        -moz-transition-duration: 4s;
11143        -webkit-transition-timing-function: ease-in-out;
11144        transition-timing-function: ease-in-out, ease-in;
11145        -webkit-transition-delay: .5s;
11146        -moz-transition-timing-function: ease-in-out;
11147        transition-delay: .5s, 0s;
11148        -moz-transition-delay: 0s;
11149      }
11150    "#},
11151    );
11152
11153    test(
11154      r#"
11155      .foo {
11156        transition: opacity 2s;
11157        -webkit-transition-duration: 2s;
11158      }
11159    "#,
11160      indoc! {r#"
11161      .foo {
11162        transition: opacity 2s;
11163        -webkit-transition-duration: 2s;
11164      }
11165    "#},
11166    );
11167
11168    prefix_test(
11169      r#"
11170      .foo {
11171        transition-property: margin-inline-start;
11172      }
11173    "#,
11174      indoc! {r#"
11175      .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))) {
11176        transition-property: margin-left;
11177      }
11178
11179      .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))) {
11180        transition-property: margin-left;
11181      }
11182
11183      .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)) {
11184        transition-property: margin-right;
11185      }
11186
11187      .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)) {
11188        transition-property: margin-right;
11189      }
11190    "#
11191      },
11192      Browsers {
11193        safari: Some(8 << 16),
11194        ..Browsers::default()
11195      },
11196    );
11197
11198    prefix_test(
11199      r#"
11200      .foo {
11201        transition-property: margin-inline-start, padding-inline-start;
11202      }
11203    "#,
11204      indoc! {r#"
11205      .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))) {
11206        transition-property: margin-left, padding-left;
11207      }
11208
11209      .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))) {
11210        transition-property: margin-left, padding-left;
11211      }
11212
11213      .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)) {
11214        transition-property: margin-right, padding-right;
11215      }
11216
11217      .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)) {
11218        transition-property: margin-right, padding-right;
11219      }
11220    "#
11221      },
11222      Browsers {
11223        safari: Some(8 << 16),
11224        ..Browsers::default()
11225      },
11226    );
11227
11228    prefix_test(
11229      r#"
11230      .foo {
11231        transition-property: margin-inline-start, opacity, padding-inline-start, color;
11232      }
11233    "#,
11234      indoc! {r#"
11235      .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))) {
11236        transition-property: margin-left, opacity, padding-left, color;
11237      }
11238
11239      .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))) {
11240        transition-property: margin-left, opacity, padding-left, color;
11241      }
11242
11243      .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)) {
11244        transition-property: margin-right, opacity, padding-right, color;
11245      }
11246
11247      .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)) {
11248        transition-property: margin-right, opacity, padding-right, color;
11249      }
11250    "#
11251      },
11252      Browsers {
11253        safari: Some(8 << 16),
11254        ..Browsers::default()
11255      },
11256    );
11257
11258    prefix_test(
11259      r#"
11260      .foo {
11261        transition-property: margin-block;
11262      }
11263    "#,
11264      indoc! {r#"
11265      .foo {
11266        transition-property: margin-top, margin-bottom;
11267      }
11268    "#
11269      },
11270      Browsers {
11271        safari: Some(8 << 16),
11272        ..Browsers::default()
11273      },
11274    );
11275
11276    prefix_test(
11277      r#"
11278      .foo {
11279        transition: margin-inline-start 2s;
11280      }
11281    "#,
11282      indoc! {r#"
11283      .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))) {
11284        transition: margin-left 2s;
11285      }
11286
11287      .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))) {
11288        transition: margin-left 2s;
11289      }
11290
11291      .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)) {
11292        transition: margin-right 2s;
11293      }
11294
11295      .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)) {
11296        transition: margin-right 2s;
11297      }
11298    "#
11299      },
11300      Browsers {
11301        safari: Some(8 << 16),
11302        ..Browsers::default()
11303      },
11304    );
11305
11306    prefix_test(
11307      r#"
11308      .foo {
11309        transition: margin-inline-start 2s, padding-inline-start 2s;
11310      }
11311    "#,
11312      indoc! {r#"
11313      .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))) {
11314        transition: margin-left 2s, padding-left 2s;
11315      }
11316
11317      .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))) {
11318        transition: margin-left 2s, padding-left 2s;
11319      }
11320
11321      .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)) {
11322        transition: margin-right 2s, padding-right 2s;
11323      }
11324
11325      .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)) {
11326        transition: margin-right 2s, padding-right 2s;
11327      }
11328    "#
11329      },
11330      Browsers {
11331        safari: Some(8 << 16),
11332        ..Browsers::default()
11333      },
11334    );
11335
11336    prefix_test(
11337      r#"
11338      .foo {
11339        transition: margin-block-start 2s;
11340      }
11341    "#,
11342      indoc! {r#"
11343      .foo {
11344        transition: margin-top 2s;
11345      }
11346    "#
11347      },
11348      Browsers {
11349        safari: Some(8 << 16),
11350        ..Browsers::default()
11351      },
11352    );
11353
11354    prefix_test(
11355      r#"
11356      .foo {
11357        transition: transform;
11358      }
11359    "#,
11360      indoc! {r#"
11361      .foo {
11362        -webkit-transition: -webkit-transform, transform;
11363        transition: -webkit-transform, transform;
11364      }
11365    "#
11366      },
11367      Browsers {
11368        safari: Some(6 << 16),
11369        ..Browsers::default()
11370      },
11371    );
11372
11373    prefix_test(
11374      r#"
11375      .foo {
11376        transition: border-start-start-radius;
11377      }
11378    "#,
11379      indoc! {r#"
11380      .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))) {
11381        -webkit-transition: -webkit-border-top-left-radius, border-top-left-radius;
11382        transition: -webkit-border-top-left-radius, border-top-left-radius;
11383      }
11384
11385      .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)) {
11386        -webkit-transition: -webkit-border-top-right-radius, border-top-right-radius;
11387        transition: -webkit-border-top-right-radius, border-top-right-radius;
11388      }
11389    "#
11390      },
11391      Browsers {
11392        safari: Some(4 << 16),
11393        ..Browsers::default()
11394      },
11395    );
11396
11397    prefix_test(
11398      r#"
11399      .foo {
11400        transition: border-start-start-radius;
11401      }
11402    "#,
11403      indoc! {r#"
11404      .foo:not(:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi)) {
11405        transition: border-top-left-radius;
11406      }
11407
11408      .foo:lang(ae, ar, arc, bcc, bqi, ckb, dv, fa, glk, he, ku, mzn, nqo, pnb, ps, sd, ug, ur, yi) {
11409        transition: border-top-right-radius;
11410      }
11411    "#
11412      },
11413      Browsers {
11414        safari: Some(12 << 16),
11415        ..Browsers::default()
11416      },
11417    );
11418
11419    test(
11420      r#"
11421      .foo {
11422        -webkit-transition: background 200ms;
11423        -moz-transition: background 200ms;
11424        transition: background 230ms;
11425      }
11426    "#,
11427      indoc! {r#"
11428      .foo {
11429        -webkit-transition: background .2s;
11430        -moz-transition: background .2s;
11431        transition: background .23s;
11432      }
11433    "#},
11434    );
11435
11436    prefix_test(
11437      r#"
11438      .foo {
11439        -webkit-transition: background 200ms;
11440        -moz-transition: background 200ms;
11441        transition: background 230ms;
11442      }
11443    "#,
11444      indoc! {r#"
11445      .foo {
11446        -webkit-transition: background .2s;
11447        -moz-transition: background .2s;
11448        transition: background .23s;
11449      }
11450    "#},
11451      Browsers {
11452        chrome: Some(95 << 16),
11453        ..Browsers::default()
11454      },
11455    );
11456    prefix_test(
11457      r#"
11458       .foo {
11459         transition-property: -webkit-backdrop-filter, backdrop-filter;
11460       }
11461       .bar {
11462         transition-property: backdrop-filter;
11463       }
11464       .baz {
11465         transition-property: -webkit-backdrop-filter;
11466       }
11467     "#,
11468      indoc! {r#"
11469       .foo, .bar {
11470         transition-property: -webkit-backdrop-filter, backdrop-filter;
11471       }
11472
11473       .baz {
11474         transition-property: -webkit-backdrop-filter;
11475       }
11476     "#
11477      },
11478      Browsers {
11479        safari: Some(15 << 16),
11480        ..Browsers::default()
11481      },
11482    );
11483    prefix_test(
11484      r#"
11485       .foo {
11486         transition-property: -webkit-border-radius, -webkit-border-radius, -moz-border-radius;
11487       }
11488     "#,
11489      indoc! {r#"
11490       .foo {
11491         transition-property: -webkit-border-radius, -moz-border-radius;
11492       }
11493     "#
11494      },
11495      Browsers {
11496        safari: Some(15 << 16),
11497        ..Browsers::default()
11498      },
11499    );
11500    prefix_test(
11501      r#"
11502       .foo {
11503         transition: -webkit-backdrop-filter, backdrop-filter;
11504       }
11505       .bar {
11506         transition: backdrop-filter;
11507       }
11508       .baz {
11509         transition: -webkit-backdrop-filter;
11510       }
11511     "#,
11512      indoc! {r#"
11513       .foo, .bar {
11514         transition: -webkit-backdrop-filter, backdrop-filter;
11515       }
11516
11517       .baz {
11518         transition: -webkit-backdrop-filter;
11519       }
11520     "#
11521      },
11522      Browsers {
11523        safari: Some(15 << 16),
11524        ..Browsers::default()
11525      },
11526    );
11527  }
11528
11529  #[test]
11530  fn test_animation() {
11531    minify_test(".foo { animation-name: test }", ".foo{animation-name:test}");
11532    minify_test(".foo { animation-name: \"test\" }", ".foo{animation-name:test}");
11533    minify_test(".foo { animation-name: foo, bar }", ".foo{animation-name:foo,bar}");
11534    minify_test(".foo { animation-name: \"none\" }", ".foo{animation-name:\"none\"}");
11535    minify_test(
11536      ".foo { animation-name: \"none\", foo }",
11537      ".foo{animation-name:\"none\",foo}",
11538    );
11539    let name = crate::properties::animation::AnimationName::parse_string("default");
11540    assert!(matches!(name, Err(..)));
11541
11542    minify_test(".foo { animation-name: none }", ".foo{animation-name:none}");
11543    minify_test(".foo { animation-name: none, none }", ".foo{animation-name:none,none}");
11544
11545    // Test CSS-wide keywords
11546    minify_test(".foo { animation-name: unset }", ".foo{animation-name:unset}");
11547    minify_test(".foo { animation-name: \"unset\" }", ".foo{animation-name:\"unset\"}");
11548    minify_test(".foo { animation-name: \"revert\" }", ".foo{animation-name:\"revert\"}");
11549    minify_test(
11550      ".foo { animation-name: \"unset\", \"revert\"}",
11551      ".foo{animation-name:\"unset\",\"revert\"}",
11552    );
11553    minify_test(
11554      ".foo { animation-name: foo, \"revert\"}",
11555      ".foo{animation-name:foo,\"revert\"}",
11556    );
11557    minify_test(
11558      ".foo { animation-name: \"string\", \"revert\"}",
11559      ".foo{animation-name:string,\"revert\"}",
11560    );
11561    minify_test(
11562      ".foo { animation-name: \"string\", foo, \"revert\"}",
11563      ".foo{animation-name:string,foo,\"revert\"}",
11564    );
11565    minify_test(
11566      ".foo { animation-name: \"default\" }",
11567      ".foo{animation-name:\"default\"}",
11568    );
11569    minify_test(".foo { animation-duration: 100ms }", ".foo{animation-duration:.1s}");
11570    minify_test(
11571      ".foo { animation-duration: 100ms, 2000ms }",
11572      ".foo{animation-duration:.1s,2s}",
11573    );
11574    minify_test(
11575      ".foo { animation-timing-function: ease }",
11576      ".foo{animation-timing-function:ease}",
11577    );
11578    minify_test(
11579      ".foo { animation-timing-function: cubic-bezier(0.42, 0, 1, 1) }",
11580      ".foo{animation-timing-function:ease-in}",
11581    );
11582    minify_test(
11583      ".foo { animation-timing-function: ease, cubic-bezier(0.42, 0, 1, 1) }",
11584      ".foo{animation-timing-function:ease,ease-in}",
11585    );
11586    minify_test(
11587      ".foo { animation-iteration-count: 5 }",
11588      ".foo{animation-iteration-count:5}",
11589    );
11590    minify_test(
11591      ".foo { animation-iteration-count: 2.5 }",
11592      ".foo{animation-iteration-count:2.5}",
11593    );
11594    minify_test(
11595      ".foo { animation-iteration-count: 2.0 }",
11596      ".foo{animation-iteration-count:2}",
11597    );
11598    minify_test(
11599      ".foo { animation-iteration-count: infinite }",
11600      ".foo{animation-iteration-count:infinite}",
11601    );
11602    minify_test(
11603      ".foo { animation-iteration-count: 1, infinite }",
11604      ".foo{animation-iteration-count:1,infinite}",
11605    );
11606    minify_test(
11607      ".foo { animation-direction: reverse }",
11608      ".foo{animation-direction:reverse}",
11609    );
11610    minify_test(
11611      ".foo { animation-direction: alternate, reverse }",
11612      ".foo{animation-direction:alternate,reverse}",
11613    );
11614    minify_test(
11615      ".foo { animation-play-state: paused }",
11616      ".foo{animation-play-state:paused}",
11617    );
11618    minify_test(
11619      ".foo { animation-play-state: running, paused }",
11620      ".foo{animation-play-state:running,paused}",
11621    );
11622    minify_test(".foo { animation-delay: 100ms }", ".foo{animation-delay:.1s}");
11623    minify_test(
11624      ".foo { animation-delay: 100ms, 2000ms }",
11625      ".foo{animation-delay:.1s,2s}",
11626    );
11627    minify_test(
11628      ".foo { animation-fill-mode: forwards }",
11629      ".foo{animation-fill-mode:forwards}",
11630    );
11631    minify_test(
11632      ".foo { animation-fill-mode: Backwards,forwards }",
11633      ".foo{animation-fill-mode:backwards,forwards}",
11634    );
11635    minify_test(".foo { animation: none }", ".foo{animation:none}");
11636    minify_test(".foo { animation: \"none\" }", ".foo{animation:\"none\"}");
11637    minify_test(".foo { animation: \"None\" }", ".foo{animation:\"None\"}");
11638    minify_test(".foo { animation: \"none\", none }", ".foo{animation:\"none\",none}");
11639    minify_test(".foo { animation: none, none }", ".foo{animation:none,none}");
11640    minify_test(".foo { animation: \"none\" none }", ".foo{animation:\"none\"}");
11641    minify_test(".foo { animation: none none }", ".foo{animation:none}");
11642
11643    // Test animation-name + animation-fill-mode
11644    minify_test(
11645      ".foo { animation: 2s both \"none\"}",
11646      ".foo{animation:2s both \"none\"}",
11647    );
11648    minify_test(
11649      ".foo { animation: both \"none\" 2s}",
11650      ".foo{animation:2s both \"none\"}",
11651    );
11652    minify_test(".foo { animation: \"none\" 2s none}", ".foo{animation:2s \"none\"}");
11653    minify_test(".foo { animation: none \"none\" 2s}", ".foo{animation:2s \"none\"}");
11654    minify_test(
11655      ".foo { animation: none, \"none\" 2s forwards}",
11656      ".foo{animation:none,2s forwards \"none\"}",
11657    );
11658
11659    minify_test(".foo { animation: \"unset\" }", ".foo{animation:\"unset\"}");
11660    minify_test(".foo { animation: \"string\" .5s }", ".foo{animation:.5s string}");
11661    minify_test(".foo { animation: \"unset\" .5s }", ".foo{animation:.5s \"unset\"}");
11662    minify_test(
11663      ".foo { animation: none, \"unset\" .5s}",
11664      ".foo{animation:none,.5s \"unset\"}",
11665    );
11666    minify_test(
11667      ".foo { animation: \"unset\" 0s 3s infinite, none }",
11668      ".foo{animation:0s 3s infinite \"unset\",none}",
11669    );
11670
11671    minify_test(".foo { animation: \"infinite\" 2s 1 }", ".foo{animation:2s 1 infinite}");
11672    minify_test(".foo { animation: \"paused\" 2s }", ".foo{animation:2s running paused}");
11673    minify_test(
11674      ".foo { animation: \"forwards\" 2s }",
11675      ".foo{animation:2s none forwards}",
11676    );
11677    minify_test(
11678      ".foo { animation: \"reverse\" 2s }",
11679      ".foo{animation:2s normal reverse}",
11680    );
11681    minify_test(
11682      ".foo { animation: \"reverse\" 2s alternate }",
11683      ".foo{animation:2s alternate reverse}",
11684    );
11685
11686    minify_test(
11687      ".foo { animation: 3s ease-in 1s infinite reverse both running slidein }",
11688      ".foo{animation:3s ease-in 1s infinite reverse both slidein}",
11689    );
11690    minify_test(
11691      ".foo { animation: 3s slidein paused ease 1s 1 reverse both }",
11692      ".foo{animation:3s 1s reverse both paused slidein}",
11693    );
11694    minify_test(".foo { animation: 3s ease ease }", ".foo{animation:3s ease ease}");
11695    minify_test(
11696      ".foo { animation: 3s cubic-bezier(0.25, 0.1, 0.25, 1) foo }",
11697      ".foo{animation:3s foo}",
11698    );
11699    minify_test(
11700      ".foo { animation: foo 0s 3s infinite }",
11701      ".foo{animation:0s 3s infinite foo}",
11702    );
11703    minify_test(".foo { animation: foo 3s --test }", ".foo{animation:3s foo --test}");
11704    minify_test(".foo { animation: foo 3s scroll() }", ".foo{animation:3s foo scroll()}");
11705    minify_test(
11706      ".foo { animation: foo 3s scroll(block) }",
11707      ".foo{animation:3s foo scroll()}",
11708    );
11709    minify_test(
11710      ".foo { animation: foo 3s scroll(root inline) }",
11711      ".foo{animation:3s foo scroll(root inline)}",
11712    );
11713    minify_test(
11714      ".foo { animation: foo 3s scroll(inline root) }",
11715      ".foo{animation:3s foo scroll(root inline)}",
11716    );
11717    minify_test(
11718      ".foo { animation: foo 3s scroll(inline nearest) }",
11719      ".foo{animation:3s foo scroll(inline)}",
11720    );
11721    minify_test(
11722      ".foo { animation: foo 3s view(block) }",
11723      ".foo{animation:3s foo view()}",
11724    );
11725    minify_test(
11726      ".foo { animation: foo 3s view(inline) }",
11727      ".foo{animation:3s foo view(inline)}",
11728    );
11729    minify_test(
11730      ".foo { animation: foo 3s view(inline 10px 10px) }",
11731      ".foo{animation:3s foo view(inline 10px)}",
11732    );
11733    minify_test(
11734      ".foo { animation: foo 3s view(inline 10px 12px) }",
11735      ".foo{animation:3s foo view(inline 10px 12px)}",
11736    );
11737    minify_test(
11738      ".foo { animation: foo 3s view(inline auto auto) }",
11739      ".foo{animation:3s foo view(inline)}",
11740    );
11741    minify_test(".foo { animation: foo 3s auto }", ".foo{animation:3s foo}");
11742    minify_test(".foo { animation-composition: add }", ".foo{animation-composition:add}");
11743    test(
11744      r#"
11745      .foo {
11746        animation-name: foo;
11747        animation-duration: 0.09s;
11748        animation-timing-function: ease-in-out;
11749        animation-iteration-count: 2;
11750        animation-direction: alternate;
11751        animation-play-state: running;
11752        animation-delay: 100ms;
11753        animation-fill-mode: forwards;
11754        animation-timeline: auto;
11755      }
11756    "#,
11757      indoc! {r#"
11758      .foo {
11759        animation: 90ms ease-in-out .1s 2 alternate forwards foo;
11760      }
11761    "#},
11762    );
11763    test(
11764      r#"
11765      .foo {
11766        animation-name: foo, bar;
11767        animation-duration: 0.09s, 200ms;
11768        animation-timing-function: ease-in-out, ease;
11769        animation-iteration-count: 2, 1;
11770        animation-direction: alternate, normal;
11771        animation-play-state: running, paused;
11772        animation-delay: 100ms, 0s;
11773        animation-fill-mode: forwards, none;
11774        animation-timeline: auto, auto;
11775      }
11776    "#,
11777      indoc! {r#"
11778      .foo {
11779        animation: 90ms ease-in-out .1s 2 alternate forwards foo, .2s paused bar;
11780      }
11781    "#},
11782    );
11783    test(
11784      r#"
11785      .foo {
11786        animation: bar 200ms;
11787        animation-timing-function: ease-in-out;
11788      }
11789    "#,
11790      indoc! {r#"
11791      .foo {
11792        animation: .2s ease-in-out bar;
11793      }
11794    "#},
11795    );
11796    test(
11797      r#"
11798      .foo {
11799        animation: bar 200ms;
11800        animation-timing-function: var(--ease);
11801      }
11802    "#,
11803      indoc! {r#"
11804      .foo {
11805        animation: .2s bar;
11806        animation-timing-function: var(--ease);
11807      }
11808    "#},
11809    );
11810    test(
11811      r#"
11812      .foo {
11813        animation-name: foo, bar;
11814        animation-duration: 0.09s;
11815        animation-timing-function: ease-in-out;
11816        animation-iteration-count: 2;
11817        animation-direction: alternate;
11818        animation-play-state: running;
11819        animation-delay: 100ms;
11820        animation-fill-mode: forwards;
11821        animation-timeline: auto;
11822      }
11823    "#,
11824      indoc! {r#"
11825      .foo {
11826        animation-name: foo, bar;
11827        animation-duration: 90ms;
11828        animation-timing-function: ease-in-out;
11829        animation-iteration-count: 2;
11830        animation-direction: alternate;
11831        animation-play-state: running;
11832        animation-delay: .1s;
11833        animation-fill-mode: forwards;
11834        animation-timeline: auto;
11835      }
11836    "#},
11837    );
11838    test(
11839      r#"
11840      .foo {
11841        animation-name: foo;
11842        animation-duration: 0.09s;
11843        animation-timing-function: ease-in-out;
11844        animation-iteration-count: 2;
11845        animation-direction: alternate;
11846        animation-play-state: running;
11847        animation-delay: 100ms;
11848        animation-fill-mode: forwards;
11849        animation-timeline: scroll();
11850      }
11851    "#,
11852      indoc! {r#"
11853      .foo {
11854        animation: 90ms ease-in-out .1s 2 alternate forwards foo scroll();
11855      }
11856    "#},
11857    );
11858    test(
11859      r#"
11860      .foo {
11861        animation-name: foo;
11862        animation-duration: 0.09s;
11863        animation-timing-function: ease-in-out;
11864        animation-iteration-count: 2;
11865        animation-direction: alternate;
11866        animation-play-state: running;
11867        animation-delay: 100ms;
11868        animation-fill-mode: forwards;
11869        animation-timeline: scroll(), view();
11870      }
11871    "#,
11872      indoc! {r#"
11873      .foo {
11874        animation-name: foo;
11875        animation-duration: 90ms;
11876        animation-timing-function: ease-in-out;
11877        animation-iteration-count: 2;
11878        animation-direction: alternate;
11879        animation-play-state: running;
11880        animation-delay: .1s;
11881        animation-fill-mode: forwards;
11882        animation-timeline: scroll(), view();
11883      }
11884    "#},
11885    );
11886    test(
11887      r#"
11888      .foo {
11889        -webkit-animation-name: foo;
11890        -webkit-animation-duration: 0.09s;
11891        -webkit-animation-timing-function: ease-in-out;
11892        -webkit-animation-iteration-count: 2;
11893        -webkit-animation-direction: alternate;
11894        -webkit-animation-play-state: running;
11895        -webkit-animation-delay: 100ms;
11896        -webkit-animation-fill-mode: forwards;
11897      }
11898    "#,
11899      indoc! {r#"
11900      .foo {
11901        -webkit-animation: 90ms ease-in-out .1s 2 alternate forwards foo;
11902      }
11903    "#},
11904    );
11905    test(
11906      r#"
11907      .foo {
11908        -moz-animation: bar 200ms;
11909        -moz-animation-timing-function: ease-in-out;
11910      }
11911    "#,
11912      indoc! {r#"
11913      .foo {
11914        -moz-animation: .2s ease-in-out bar;
11915      }
11916    "#},
11917    );
11918    test(
11919      r#"
11920      .foo {
11921        -webkit-animation: bar 200ms;
11922        -webkit-animation-timing-function: ease-in-out;
11923        -moz-animation: bar 200ms;
11924        -moz-animation-timing-function: ease-in-out;
11925      }
11926    "#,
11927      indoc! {r#"
11928      .foo {
11929        -webkit-animation: .2s ease-in-out bar;
11930        -moz-animation: .2s ease-in-out bar;
11931      }
11932    "#},
11933    );
11934
11935    prefix_test(
11936      r#"
11937      .foo {
11938        animation: .2s ease-in-out bar;
11939      }
11940    "#,
11941      indoc! {r#"
11942      .foo {
11943        -webkit-animation: .2s ease-in-out bar;
11944        -moz-animation: .2s ease-in-out bar;
11945        animation: .2s ease-in-out bar;
11946      }
11947    "#},
11948      Browsers {
11949        firefox: Some(6 << 16),
11950        safari: Some(6 << 16),
11951        ..Browsers::default()
11952      },
11953    );
11954
11955    prefix_test(
11956      r#"
11957      .foo {
11958        -webkit-animation: .2s ease-in-out bar;
11959        -moz-animation: .2s ease-in-out bar;
11960        animation: .2s ease-in-out bar;
11961      }
11962    "#,
11963      indoc! {r#"
11964      .foo {
11965        animation: .2s ease-in-out bar;
11966      }
11967    "#},
11968      Browsers {
11969        firefox: Some(20 << 16),
11970        safari: Some(14 << 16),
11971        ..Browsers::default()
11972      },
11973    );
11974    prefix_test(
11975      r#"
11976      .foo {
11977        animation: 200ms var(--ease) bar;
11978      }
11979    "#,
11980      indoc! {r#"
11981      .foo {
11982        -webkit-animation: .2s var(--ease) bar;
11983        -moz-animation: .2s var(--ease) bar;
11984        animation: .2s var(--ease) bar;
11985      }
11986    "#},
11987      Browsers {
11988        firefox: Some(6 << 16),
11989        safari: Some(6 << 16),
11990        ..Browsers::default()
11991      },
11992    );
11993
11994    prefix_test(
11995      r#"
11996      .foo {
11997        animation: .2s ease-in-out bar scroll();
11998      }
11999    "#,
12000      indoc! {r#"
12001      .foo {
12002        animation: .2s ease-in-out bar;
12003        animation-timeline: scroll();
12004      }
12005    "#},
12006      Browsers {
12007        safari: Some(16 << 16),
12008        ..Browsers::default()
12009      },
12010    );
12011    prefix_test(
12012      r#"
12013      .foo {
12014        animation: .2s ease-in-out bar scroll();
12015      }
12016    "#,
12017      indoc! {r#"
12018      .foo {
12019        animation: .2s ease-in-out bar scroll();
12020      }
12021    "#},
12022      Browsers {
12023        chrome: Some(120 << 16),
12024        ..Browsers::default()
12025      },
12026    );
12027    prefix_test(
12028      r#"
12029      .foo {
12030        animation: .2s ease-in-out bar scroll();
12031      }
12032    "#,
12033      indoc! {r#"
12034      .foo {
12035        -webkit-animation: .2s ease-in-out bar;
12036        animation: .2s ease-in-out bar;
12037        animation-timeline: scroll();
12038      }
12039    "#},
12040      Browsers {
12041        safari: Some(6 << 16),
12042        ..Browsers::default()
12043      },
12044    );
12045
12046    minify_test(
12047      ".foo { animation-range-start: entry 10% }",
12048      ".foo{animation-range-start:entry 10%}",
12049    );
12050    minify_test(
12051      ".foo { animation-range-start: entry 0% }",
12052      ".foo{animation-range-start:entry}",
12053    );
12054    minify_test(
12055      ".foo { animation-range-start: entry }",
12056      ".foo{animation-range-start:entry}",
12057    );
12058    minify_test(".foo { animation-range-start: 50% }", ".foo{animation-range-start:50%}");
12059    minify_test(
12060      ".foo { animation-range-end: exit 10% }",
12061      ".foo{animation-range-end:exit 10%}",
12062    );
12063    minify_test(
12064      ".foo { animation-range-end: exit 100% }",
12065      ".foo{animation-range-end:exit}",
12066    );
12067    minify_test(".foo { animation-range-end: exit }", ".foo{animation-range-end:exit}");
12068    minify_test(".foo { animation-range-end: 50% }", ".foo{animation-range-end:50%}");
12069    minify_test(
12070      ".foo { animation-range: entry 10% exit 90% }",
12071      ".foo{animation-range:entry 10% exit 90%}",
12072    );
12073    minify_test(
12074      ".foo { animation-range: entry 0% exit 100% }",
12075      ".foo{animation-range:entry exit}",
12076    );
12077    minify_test(".foo { animation-range: entry }", ".foo{animation-range:entry}");
12078    minify_test(
12079      ".foo { animation-range: entry 0% entry 100% }",
12080      ".foo{animation-range:entry}",
12081    );
12082    minify_test(".foo { animation-range: 50% normal }", ".foo{animation-range:50%}");
12083    minify_test(
12084      ".foo { animation-range: normal normal }",
12085      ".foo{animation-range:normal}",
12086    );
12087    test(
12088      r#"
12089      .foo {
12090        animation-range-start: entry 10%;
12091        animation-range-end: exit 90%;
12092      }
12093      "#,
12094      indoc! {r#"
12095      .foo {
12096        animation-range: entry 10% exit 90%;
12097      }
12098      "#},
12099    );
12100    test(
12101      r#"
12102      .foo {
12103        animation-range-start: entry 0%;
12104        animation-range-end: entry 100%;
12105      }
12106      "#,
12107      indoc! {r#"
12108      .foo {
12109        animation-range: entry;
12110      }
12111      "#},
12112    );
12113    test(
12114      r#"
12115      .foo {
12116        animation-range-start: entry 0%;
12117        animation-range-end: exit 100%;
12118      }
12119      "#,
12120      indoc! {r#"
12121      .foo {
12122        animation-range: entry exit;
12123      }
12124      "#},
12125    );
12126    test(
12127      r#"
12128      .foo {
12129        animation-range-start: 10%;
12130        animation-range-end: normal;
12131      }
12132      "#,
12133      indoc! {r#"
12134      .foo {
12135        animation-range: 10%;
12136      }
12137      "#},
12138    );
12139    test(
12140      r#"
12141      .foo {
12142        animation-range-start: 10%;
12143        animation-range-end: 90%;
12144      }
12145      "#,
12146      indoc! {r#"
12147      .foo {
12148        animation-range: 10% 90%;
12149      }
12150      "#},
12151    );
12152    test(
12153      r#"
12154      .foo {
12155        animation-range-start: entry 10%;
12156        animation-range-end: exit 100%;
12157      }
12158      "#,
12159      indoc! {r#"
12160      .foo {
12161        animation-range: entry 10% exit;
12162      }
12163      "#},
12164    );
12165    test(
12166      r#"
12167      .foo {
12168        animation-range-start: 10%;
12169        animation-range-end: exit 90%;
12170      }
12171      "#,
12172      indoc! {r#"
12173      .foo {
12174        animation-range: 10% exit 90%;
12175      }
12176      "#},
12177    );
12178    test(
12179      r#"
12180      .foo {
12181        animation-range-start: entry 10%;
12182        animation-range-end: 90%;
12183      }
12184      "#,
12185      indoc! {r#"
12186      .foo {
12187        animation-range: entry 10% 90%;
12188      }
12189      "#},
12190    );
12191    test(
12192      r#"
12193      .foo {
12194        animation-range: entry;
12195        animation-range-end: 90%;
12196      }
12197      "#,
12198      indoc! {r#"
12199      .foo {
12200        animation-range: entry 90%;
12201      }
12202      "#},
12203    );
12204    test(
12205      r#"
12206      .foo {
12207        animation-range: entry;
12208        animation-range-end: var(--end);
12209      }
12210      "#,
12211      indoc! {r#"
12212      .foo {
12213        animation-range: entry;
12214        animation-range-end: var(--end);
12215      }
12216      "#},
12217    );
12218    test(
12219      r#"
12220      .foo {
12221        animation-range-start: entry 10%, entry 50%;
12222        animation-range-end: exit 90%;
12223      }
12224      "#,
12225      indoc! {r#"
12226      .foo {
12227        animation-range-start: entry 10%, entry 50%;
12228        animation-range-end: exit 90%;
12229      }
12230      "#},
12231    );
12232    test(
12233      r#"
12234      .foo {
12235        animation-range-start: entry 10%, entry 50%;
12236        animation-range-end: exit 90%, exit 100%;
12237      }
12238      "#,
12239      indoc! {r#"
12240      .foo {
12241        animation-range: entry 10% exit 90%, entry 50% exit;
12242      }
12243      "#},
12244    );
12245    test(
12246      r#"
12247      .foo {
12248        animation-range: entry;
12249        animation-range-end: 90%;
12250        animation: spin 100ms;
12251      }
12252      "#,
12253      indoc! {r#"
12254      .foo {
12255        animation: .1s spin;
12256      }
12257      "#},
12258    );
12259    test(
12260      r#"
12261      .foo {
12262        animation: spin 100ms;
12263        animation-range: entry;
12264        animation-range-end: 90%;
12265      }
12266      "#,
12267      indoc! {r#"
12268      .foo {
12269        animation: .1s spin;
12270        animation-range: entry 90%;
12271      }
12272      "#},
12273    );
12274    test(
12275      r#"
12276      .foo {
12277        animation-range: entry;
12278        animation-range-end: 90%;
12279        animation: var(--animation) 100ms;
12280      }
12281      "#,
12282      indoc! {r#"
12283      .foo {
12284        animation: var(--animation) .1s;
12285      }
12286      "#},
12287    );
12288  }
12289
12290  #[test]
12291  fn test_transform() {
12292    minify_test(
12293      ".foo { transform: translate(2px, 3px)",
12294      ".foo{transform:translate(2px,3px)}",
12295    );
12296    minify_test(
12297      ".foo { transform: translate(2px, 0px)",
12298      ".foo{transform:translate(2px)}",
12299    );
12300    minify_test(
12301      ".foo { transform: translate(0px, 2px)",
12302      ".foo{transform:translateY(2px)}",
12303    );
12304    minify_test(".foo { transform: translateX(2px)", ".foo{transform:translate(2px)}");
12305    minify_test(".foo { transform: translateY(2px)", ".foo{transform:translateY(2px)}");
12306    minify_test(".foo { transform: translateZ(2px)", ".foo{transform:translateZ(2px)}");
12307    minify_test(
12308      ".foo { transform: translate3d(2px, 3px, 4px)",
12309      ".foo{transform:translate3d(2px,3px,4px)}",
12310    );
12311    minify_test(
12312      ".foo { transform: translate3d(10%, 20%, 4px)",
12313      ".foo{transform:translate3d(10%,20%,4px)}",
12314    );
12315    minify_test(
12316      ".foo { transform: translate3d(2px, 0px, 0px)",
12317      ".foo{transform:translate(2px)}",
12318    );
12319    minify_test(
12320      ".foo { transform: translate3d(0px, 2px, 0px)",
12321      ".foo{transform:translateY(2px)}",
12322    );
12323    minify_test(
12324      ".foo { transform: translate3d(0px, 0px, 2px)",
12325      ".foo{transform:translateZ(2px)}",
12326    );
12327    minify_test(
12328      ".foo { transform: translate3d(2px, 3px, 0px)",
12329      ".foo{transform:translate(2px,3px)}",
12330    );
12331    minify_test(".foo { transform: scale(2, 3)", ".foo{transform:scale(2,3)}");
12332    minify_test(".foo { transform: scale(10%, 20%)", ".foo{transform:scale(.1,.2)}");
12333    minify_test(".foo { transform: scale(2, 2)", ".foo{transform:scale(2)}");
12334    minify_test(".foo { transform: scale(2, 1)", ".foo{transform:scaleX(2)}");
12335    minify_test(".foo { transform: scale(1, 2)", ".foo{transform:scaleY(2)}");
12336    minify_test(".foo { transform: scaleX(2)", ".foo{transform:scaleX(2)}");
12337    minify_test(".foo { transform: scaleY(2)", ".foo{transform:scaleY(2)}");
12338    minify_test(".foo { transform: scaleZ(2)", ".foo{transform:scaleZ(2)}");
12339    minify_test(".foo { transform: scale3d(2, 3, 4)", ".foo{transform:scale3d(2,3,4)}");
12340    minify_test(".foo { transform: scale3d(2, 1, 1)", ".foo{transform:scaleX(2)}");
12341    minify_test(".foo { transform: scale3d(1, 2, 1)", ".foo{transform:scaleY(2)}");
12342    minify_test(".foo { transform: scale3d(1, 1, 2)", ".foo{transform:scaleZ(2)}");
12343    minify_test(".foo { transform: scale3d(2, 2, 1)", ".foo{transform:scale(2)}");
12344    minify_test(".foo { transform: rotate(20deg)", ".foo{transform:rotate(20deg)}");
12345    minify_test(".foo { transform: rotateX(20deg)", ".foo{transform:rotateX(20deg)}");
12346    minify_test(".foo { transform: rotateY(20deg)", ".foo{transform:rotateY(20deg)}");
12347    minify_test(".foo { transform: rotateZ(20deg)", ".foo{transform:rotate(20deg)}");
12348    minify_test(".foo { transform: rotate(360deg)", ".foo{transform:rotate(360deg)}");
12349    minify_test(
12350      ".foo { transform: rotate3d(2, 3, 4, 20deg)",
12351      ".foo{transform:rotate3d(2,3,4,20deg)}",
12352    );
12353    minify_test(
12354      ".foo { transform: rotate3d(1, 0, 0, 20deg)",
12355      ".foo{transform:rotateX(20deg)}",
12356    );
12357    minify_test(
12358      ".foo { transform: rotate3d(0, 1, 0, 20deg)",
12359      ".foo{transform:rotateY(20deg)}",
12360    );
12361    minify_test(
12362      ".foo { transform: rotate3d(0, 0, 1, 20deg)",
12363      ".foo{transform:rotate(20deg)}",
12364    );
12365    minify_test(".foo { transform: rotate(405deg)}", ".foo{transform:rotate(405deg)}");
12366    minify_test(".foo { transform: rotateX(405deg)}", ".foo{transform:rotateX(405deg)}");
12367    minify_test(".foo { transform: rotateY(405deg)}", ".foo{transform:rotateY(405deg)}");
12368    minify_test(".foo { transform: rotate(-200deg)}", ".foo{transform:rotate(-200deg)}");
12369    minify_test(".foo { transform: rotate(0)", ".foo{transform:rotate(0)}");
12370    minify_test(".foo { transform: rotate(0deg)", ".foo{transform:rotate(0)}");
12371    minify_test(
12372      ".foo { transform: rotateX(-200deg)}",
12373      ".foo{transform:rotateX(-200deg)}",
12374    );
12375    minify_test(
12376      ".foo { transform: rotateY(-200deg)}",
12377      ".foo{transform:rotateY(-200deg)}",
12378    );
12379    minify_test(
12380      ".foo { transform: rotate3d(1, 1, 0, -200deg)",
12381      ".foo{transform:rotate3d(1,1,0,-200deg)}",
12382    );
12383    minify_test(".foo { transform: skew(20deg)", ".foo{transform:skew(20deg)}");
12384    minify_test(".foo { transform: skew(20deg, 0deg)", ".foo{transform:skew(20deg)}");
12385    minify_test(".foo { transform: skew(0deg, 20deg)", ".foo{transform:skewY(20deg)}");
12386    minify_test(".foo { transform: skewX(20deg)", ".foo{transform:skew(20deg)}");
12387    minify_test(".foo { transform: skewY(20deg)", ".foo{transform:skewY(20deg)}");
12388    minify_test(
12389      ".foo { transform: perspective(10px)",
12390      ".foo{transform:perspective(10px)}",
12391    );
12392    minify_test(
12393      ".foo { transform: matrix(1, 2, -1, 1, 80, 80)",
12394      ".foo{transform:matrix(1,2,-1,1,80,80)}",
12395    );
12396    minify_test(
12397      ".foo { transform: matrix3d(1, 0, 0, 0, 0, 1, 6, 0, 0, 0, 1, 0, 50, 100, 0, 1.1)",
12398      ".foo{transform:matrix3d(1,0,0,0,0,1,6,0,0,0,1,0,50,100,0,1.1)}",
12399    );
12400    // TODO: Re-enable with a better solution
12401    //       See: https://github.com/parcel-bundler/lightningcss/issues/288
12402    // minify_test(
12403    //   ".foo{transform:translate(100px,200px) rotate(45deg) skew(10deg) scale(2)}",
12404    //   ".foo{transform:matrix(1.41421,1.41421,-1.16485,1.66358,100,200)}",
12405    // );
12406    // minify_test(
12407    //   ".foo{transform:translate(200px,300px) translate(100px,200px) scale(2)}",
12408    //   ".foo{transform:matrix(2,0,0,2,300,500)}",
12409    // );
12410    minify_test(
12411      ".foo{transform:translate(100px,200px) rotate(45deg)}",
12412      ".foo{transform:translate(100px,200px)rotate(45deg)}",
12413    );
12414    minify_test(
12415      ".foo{transform:rotate3d(1, 1, 1, 45deg) translate3d(100px, 100px, 10px)}",
12416      ".foo{transform:rotate3d(1,1,1,45deg)translate3d(100px,100px,10px)}",
12417    );
12418    // TODO: Re-enable with a better solution
12419    //       See: https://github.com/parcel-bundler/lightningcss/issues/288
12420    // minify_test(
12421    //   ".foo{transform:translate3d(100px, 100px, 10px) skew(10deg) scale3d(2, 3, 4)}",
12422    //   ".foo{transform:matrix3d(2,0,0,0,.528981,3,0,0,0,0,4,0,100,100,10,1)}",
12423    // );
12424    // minify_test(
12425    //   ".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)}",
12426    //   ".foo{transform:translate3d(100px,100px,10px)rotate3d(1,1,1,45deg)}"
12427    // );
12428    // minify_test(
12429    //   ".foo{transform:matrix3d(1, 0, 0, 0, 0, 0.7071067811865476, 0.7071067811865475, 0, 0, -0.7071067811865475, 0.7071067811865476, 0, 100, 100, 10, 1)}",
12430    //   ".foo{transform:translate3d(100px,100px,10px)rotateX(45deg)}"
12431    // );
12432    // minify_test(
12433    //   ".foo{transform:translate3d(100px, 200px, 10px) translate(100px, 100px)}",
12434    //   ".foo{transform:translate3d(200px,300px,10px)}",
12435    // );
12436    // minify_test(
12437    //   ".foo{transform:rotate(45deg) rotate(45deg)}",
12438    //   ".foo{transform:rotate(90deg)}",
12439    // );
12440    // minify_test(
12441    //   ".foo{transform:matrix(0.7071067811865476, 0.7071067811865475, -0.7071067811865475, 0.7071067811865476, 100, 100)}",
12442    //   ".foo{transform:translate(100px,100px)rotate(45deg)}"
12443    // );
12444    // minify_test(
12445    //   ".foo{transform:translateX(2in) translateX(50px)}",
12446    //   ".foo{transform:translate(242px)}",
12447    // );
12448    minify_test(
12449      ".foo{transform:translateX(calc(2in + 50px))}",
12450      ".foo{transform:translate(242px)}",
12451    );
12452    minify_test(".foo{transform:translateX(50%)}", ".foo{transform:translate(50%)}");
12453    minify_test(
12454      ".foo{transform:translateX(calc(50% - 100px + 20px))}",
12455      ".foo{transform:translate(calc(50% - 80px))}",
12456    );
12457    minify_test(
12458      ".foo{transform:rotate(calc(10deg + 20deg))}",
12459      ".foo{transform:rotate(30deg)}",
12460    );
12461    minify_test(
12462      ".foo{transform:rotate(calc(10deg + 0.349066rad))}",
12463      ".foo{transform:rotate(30deg)}",
12464    );
12465    minify_test(
12466      ".foo{transform:rotate(calc(10deg + 1.5turn))}",
12467      ".foo{transform:rotate(550deg)}",
12468    );
12469    minify_test(
12470      ".foo{transform:rotate(calc(10deg * 2))}",
12471      ".foo{transform:rotate(20deg)}",
12472    );
12473    minify_test(
12474      ".foo{transform:rotate(calc(-10deg * 2))}",
12475      ".foo{transform:rotate(-20deg)}",
12476    );
12477    minify_test(
12478      ".foo{transform:rotate(calc(10deg + var(--test)))}",
12479      ".foo{transform:rotate(calc(10deg + var(--test)))}",
12480    );
12481    minify_test(".foo { transform: scale(calc(10% + 20%))", ".foo{transform:scale(.3)}");
12482    minify_test(".foo { transform: scale(calc(.1 + .2))", ".foo{transform:scale(.3)}");
12483
12484    minify_test(
12485      ".foo { -webkit-transform: scale(calc(10% + 20%))",
12486      ".foo{-webkit-transform:scale(.3)}",
12487    );
12488
12489    minify_test(".foo { translate: 1px 2px 3px }", ".foo{translate:1px 2px 3px}");
12490    minify_test(".foo { translate: 1px 0px 0px }", ".foo{translate:1px}");
12491    minify_test(".foo { translate: 1px 2px 0px }", ".foo{translate:1px 2px}");
12492    minify_test(".foo { translate: 1px 0px 2px }", ".foo{translate:1px 0 2px}");
12493    minify_test(".foo { translate: none }", ".foo{translate:none}");
12494    minify_test(".foo { rotate: 10deg }", ".foo{rotate:10deg}");
12495    minify_test(".foo { rotate: z 10deg }", ".foo{rotate:10deg}");
12496    minify_test(".foo { rotate: 0 0 1 10deg }", ".foo{rotate:10deg}");
12497    minify_test(".foo { rotate: x 10deg }", ".foo{rotate:x 10deg}");
12498    minify_test(".foo { rotate: 1 0 0 10deg }", ".foo{rotate:x 10deg}");
12499    minify_test(".foo { rotate: y 10deg }", ".foo{rotate:y 10deg}");
12500    minify_test(".foo { rotate: 0 1 0 10deg }", ".foo{rotate:y 10deg}");
12501    minify_test(".foo { rotate: 1 1 1 10deg }", ".foo{rotate:1 1 1 10deg}");
12502    minify_test(".foo { rotate: 0 0 1 0deg }", ".foo{rotate:none}");
12503    minify_test(".foo { rotate: none }", ".foo{rotate:none}");
12504    minify_test(".foo { scale: 1 }", ".foo{scale:1}");
12505    minify_test(".foo { scale: 1 1 }", ".foo{scale:1}");
12506    minify_test(".foo { scale: 1 1 1 }", ".foo{scale:1}");
12507    minify_test(".foo { scale: none }", ".foo{scale:none}");
12508    minify_test(".foo { scale: 1 0 }", ".foo{scale:1 0}");
12509    minify_test(".foo { scale: 1 0 1 }", ".foo{scale:1 0}");
12510    minify_test(".foo { scale: 1 0 0 }", ".foo{scale:1 0 0}");
12511
12512    // TODO: Re-enable with a better solution
12513    //       See: https://github.com/parcel-bundler/lightningcss/issues/288
12514    // minify_test(".foo { transform: scale(3); scale: 0.5 }", ".foo{transform:scale(1.5)}");
12515    minify_test(".foo { scale: 0.5; transform: scale(3); }", ".foo{transform:scale(3)}");
12516
12517    prefix_test(
12518      r#"
12519      .foo {
12520        transform: scale(0.5);
12521      }
12522    "#,
12523      indoc! {r#"
12524      .foo {
12525        -webkit-transform: scale(.5);
12526        -moz-transform: scale(.5);
12527        transform: scale(.5);
12528      }
12529    "#},
12530      Browsers {
12531        firefox: Some(6 << 16),
12532        safari: Some(6 << 16),
12533        ..Browsers::default()
12534      },
12535    );
12536
12537    prefix_test(
12538      r#"
12539      .foo {
12540        transform: var(--transform);
12541      }
12542    "#,
12543      indoc! {r#"
12544      .foo {
12545        -webkit-transform: var(--transform);
12546        -moz-transform: var(--transform);
12547        transform: var(--transform);
12548      }
12549    "#},
12550      Browsers {
12551        firefox: Some(6 << 16),
12552        safari: Some(6 << 16),
12553        ..Browsers::default()
12554      },
12555    );
12556
12557    test(
12558      r#"
12559      .foo {
12560        transform: translateX(-50%);
12561        transform: translateX(20px);
12562      }
12563      "#,
12564      indoc! {r#"
12565      .foo {
12566        transform: translateX(20px);
12567      }
12568      "#},
12569    );
12570  }
12571
12572  #[test]
12573  pub fn test_gradients() {
12574    minify_test(
12575      ".foo { background: linear-gradient(yellow, blue) }",
12576      ".foo{background:linear-gradient(#ff0,#00f)}",
12577    );
12578    minify_test(
12579      ".foo { background: linear-gradient(to bottom, yellow, blue); }",
12580      ".foo{background:linear-gradient(#ff0,#00f)}",
12581    );
12582    minify_test(
12583      ".foo { background: linear-gradient(180deg, yellow, blue); }",
12584      ".foo{background:linear-gradient(#ff0,#00f)}",
12585    );
12586    minify_test(
12587      ".foo { background: linear-gradient(0.5turn, yellow, blue); }",
12588      ".foo{background:linear-gradient(#ff0,#00f)}",
12589    );
12590    minify_test(
12591      ".foo { background: linear-gradient(yellow 10%, blue 20%) }",
12592      ".foo{background:linear-gradient(#ff0 10%,#00f 20%)}",
12593    );
12594    minify_test(
12595      ".foo { background: linear-gradient(to top, blue, yellow); }",
12596      ".foo{background:linear-gradient(#ff0,#00f)}",
12597    );
12598    minify_test(
12599      ".foo { background: linear-gradient(to top, blue 10%, yellow 20%); }",
12600      ".foo{background:linear-gradient(#ff0 80%,#00f 90%)}",
12601    );
12602    minify_test(
12603      ".foo { background: linear-gradient(to top, blue 10px, yellow 20px); }",
12604      ".foo{background:linear-gradient(0deg,#00f 10px,#ff0 20px)}",
12605    );
12606    minify_test(
12607      ".foo { background: linear-gradient(135deg, yellow, blue); }",
12608      ".foo{background:linear-gradient(135deg,#ff0,#00f)}",
12609    );
12610    minify_test(
12611      ".foo { background: linear-gradient(yellow, blue 20%, #0f0); }",
12612      ".foo{background:linear-gradient(#ff0,#00f 20%,#0f0)}",
12613    );
12614    minify_test(
12615      ".foo { background: linear-gradient(to top right, red, white, blue) }",
12616      ".foo{background:linear-gradient(to top right,red,#fff,#00f)}",
12617    );
12618    minify_test(
12619      ".foo { background: linear-gradient(yellow, blue calc(10% * 2), #0f0); }",
12620      ".foo{background:linear-gradient(#ff0,#00f 20%,#0f0)}",
12621    );
12622    minify_test(
12623      ".foo { background: linear-gradient(yellow, 20%, blue); }",
12624      ".foo{background:linear-gradient(#ff0,20%,#00f)}",
12625    );
12626    minify_test(
12627      ".foo { background: linear-gradient(yellow, 50%, blue); }",
12628      ".foo{background:linear-gradient(#ff0,#00f)}",
12629    );
12630    minify_test(
12631      ".foo { background: linear-gradient(yellow, 20px, blue); }",
12632      ".foo{background:linear-gradient(#ff0,20px,#00f)}",
12633    );
12634    minify_test(
12635      ".foo { background: linear-gradient(yellow, 50px, blue); }",
12636      ".foo{background:linear-gradient(#ff0,50px,#00f)}",
12637    );
12638    minify_test(
12639      ".foo { background: linear-gradient(yellow, 50px, blue); }",
12640      ".foo{background:linear-gradient(#ff0,50px,#00f)}",
12641    );
12642    minify_test(
12643      ".foo { background: linear-gradient(yellow, red 30% 40%, blue); }",
12644      ".foo{background:linear-gradient(#ff0,red 30% 40%,#00f)}",
12645    );
12646    minify_test(
12647      ".foo { background: linear-gradient(yellow, red 30%, red 40%, blue); }",
12648      ".foo{background:linear-gradient(#ff0,red 30% 40%,#00f)}",
12649    );
12650    minify_test(
12651      ".foo { background: linear-gradient(0, yellow, blue); }",
12652      ".foo{background:linear-gradient(#00f,#ff0)}",
12653    );
12654    minify_test(
12655      ".foo { background: -webkit-linear-gradient(yellow, blue) }",
12656      ".foo{background:-webkit-linear-gradient(#ff0,#00f)}",
12657    );
12658    minify_test(
12659      ".foo { background: -webkit-linear-gradient(bottom, yellow, blue); }",
12660      ".foo{background:-webkit-linear-gradient(#ff0,#00f)}",
12661    );
12662    minify_test(
12663      ".foo { background: -webkit-linear-gradient(top right, red, white, blue) }",
12664      ".foo{background:-webkit-linear-gradient(top right,red,#fff,#00f)}",
12665    );
12666    minify_test(
12667      ".foo { background: -moz-linear-gradient(yellow, blue) }",
12668      ".foo{background:-moz-linear-gradient(#ff0,#00f)}",
12669    );
12670    minify_test(
12671      ".foo { background: -moz-linear-gradient(bottom, yellow, blue); }",
12672      ".foo{background:-moz-linear-gradient(#ff0,#00f)}",
12673    );
12674    minify_test(
12675      ".foo { background: -moz-linear-gradient(top right, red, white, blue) }",
12676      ".foo{background:-moz-linear-gradient(top right,red,#fff,#00f)}",
12677    );
12678    minify_test(
12679      ".foo { background: -o-linear-gradient(yellow, blue) }",
12680      ".foo{background:-o-linear-gradient(#ff0,#00f)}",
12681    );
12682    minify_test(
12683      ".foo { background: -o-linear-gradient(bottom, yellow, blue); }",
12684      ".foo{background:-o-linear-gradient(#ff0,#00f)}",
12685    );
12686    minify_test(
12687      ".foo { background: -o-linear-gradient(top right, red, white, blue) }",
12688      ".foo{background:-o-linear-gradient(top right,red,#fff,#00f)}",
12689    );
12690    minify_test(
12691      ".foo { background: -webkit-gradient(linear, left top, left bottom, from(blue), to(yellow)) }",
12692      ".foo{background:-webkit-gradient(linear,0 0,0 100%,from(#00f),to(#ff0))}",
12693    );
12694    minify_test(
12695      ".foo { background: -webkit-gradient(linear, left top, left bottom, from(blue), color-stop(50%, red), to(yellow)) }",
12696      ".foo{background:-webkit-gradient(linear,0 0,0 100%,from(#00f),color-stop(.5,red),to(#ff0))}"
12697    );
12698    minify_test(
12699      ".foo { background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, blue), color-stop(50%, red), color-stop(100%, yellow)) }",
12700      ".foo{background:-webkit-gradient(linear,0 0,0 100%,from(#00f),color-stop(.5,red),to(#ff0))}"
12701    );
12702    minify_test(
12703      ".foo { background: repeating-linear-gradient(yellow 10px, blue 50px) }",
12704      ".foo{background:repeating-linear-gradient(#ff0 10px,#00f 50px)}",
12705    );
12706    minify_test(
12707      ".foo { background: -webkit-repeating-linear-gradient(yellow 10px, blue 50px) }",
12708      ".foo{background:-webkit-repeating-linear-gradient(#ff0 10px,#00f 50px)}",
12709    );
12710    minify_test(
12711      ".foo { background: -moz-repeating-linear-gradient(yellow 10px, blue 50px) }",
12712      ".foo{background:-moz-repeating-linear-gradient(#ff0 10px,#00f 50px)}",
12713    );
12714    minify_test(
12715      ".foo { background: -o-repeating-linear-gradient(yellow 10px, blue 50px) }",
12716      ".foo{background:-o-repeating-linear-gradient(#ff0 10px,#00f 50px)}",
12717    );
12718    minify_test(
12719      ".foo { background: radial-gradient(yellow, blue) }",
12720      ".foo{background:radial-gradient(#ff0,#00f)}",
12721    );
12722    minify_test(
12723      ".foo { background: radial-gradient(at top left, yellow, blue) }",
12724      ".foo{background:radial-gradient(at 0 0,#ff0,#00f)}",
12725    );
12726    minify_test(
12727      ".foo { background: radial-gradient(5em circle at top left, yellow, blue) }",
12728      ".foo{background:radial-gradient(5em at 0 0,#ff0,#00f)}",
12729    );
12730    minify_test(
12731      ".foo { background: radial-gradient(circle at 100%, #333, #333 50%, #eee 75%, #333 75%) }",
12732      ".foo{background:radial-gradient(circle at 100%,#333,#333 50%,#eee 75%,#333 75%)}",
12733    );
12734    minify_test(
12735      ".foo { background: radial-gradient(farthest-corner circle at 100% 50%, #333, #333 50%, #eee 75%, #333 75%) }",
12736      ".foo{background:radial-gradient(circle at 100%,#333,#333 50%,#eee 75%,#333 75%)}"
12737    );
12738    minify_test(
12739      ".foo { background: radial-gradient(farthest-corner circle at 50% 50%, #333, #333 50%, #eee 75%, #333 75%) }",
12740      ".foo{background:radial-gradient(circle,#333,#333 50%,#eee 75%,#333 75%)}"
12741    );
12742    minify_test(
12743      ".foo { background: radial-gradient(ellipse at top, #e66465, transparent) }",
12744      ".foo{background:radial-gradient(at top,#e66465,#0000)}",
12745    );
12746    minify_test(
12747      ".foo { background: radial-gradient(20px, yellow, blue) }",
12748      ".foo{background:radial-gradient(20px,#ff0,#00f)}",
12749    );
12750    minify_test(
12751      ".foo { background: radial-gradient(circle 20px, yellow, blue) }",
12752      ".foo{background:radial-gradient(20px,#ff0,#00f)}",
12753    );
12754    minify_test(
12755      ".foo { background: radial-gradient(20px 40px, yellow, blue) }",
12756      ".foo{background:radial-gradient(20px 40px,#ff0,#00f)}",
12757    );
12758    minify_test(
12759      ".foo { background: radial-gradient(ellipse 20px 40px, yellow, blue) }",
12760      ".foo{background:radial-gradient(20px 40px,#ff0,#00f)}",
12761    );
12762    minify_test(
12763      ".foo { background: radial-gradient(ellipse calc(20px + 10px) 40px, yellow, blue) }",
12764      ".foo{background:radial-gradient(30px 40px,#ff0,#00f)}",
12765    );
12766    minify_test(
12767      ".foo { background: radial-gradient(circle farthest-side, yellow, blue) }",
12768      ".foo{background:radial-gradient(circle farthest-side,#ff0,#00f)}",
12769    );
12770    minify_test(
12771      ".foo { background: radial-gradient(farthest-side circle, yellow, blue) }",
12772      ".foo{background:radial-gradient(circle farthest-side,#ff0,#00f)}",
12773    );
12774    minify_test(
12775      ".foo { background: radial-gradient(ellipse farthest-side, yellow, blue) }",
12776      ".foo{background:radial-gradient(farthest-side,#ff0,#00f)}",
12777    );
12778    minify_test(
12779      ".foo { background: radial-gradient(farthest-side ellipse, yellow, blue) }",
12780      ".foo{background:radial-gradient(farthest-side,#ff0,#00f)}",
12781    );
12782    minify_test(
12783      ".foo { background: -webkit-radial-gradient(yellow, blue) }",
12784      ".foo{background:-webkit-radial-gradient(#ff0,#00f)}",
12785    );
12786    minify_test(
12787      ".foo { background: -moz-radial-gradient(yellow, blue) }",
12788      ".foo{background:-moz-radial-gradient(#ff0,#00f)}",
12789    );
12790    minify_test(
12791      ".foo { background: -o-radial-gradient(yellow, blue) }",
12792      ".foo{background:-o-radial-gradient(#ff0,#00f)}",
12793    );
12794    minify_test(
12795      ".foo { background: repeating-radial-gradient(circle 20px, yellow, blue) }",
12796      ".foo{background:repeating-radial-gradient(20px,#ff0,#00f)}",
12797    );
12798    minify_test(
12799      ".foo { background: -webkit-repeating-radial-gradient(circle 20px, yellow, blue) }",
12800      ".foo{background:-webkit-repeating-radial-gradient(20px,#ff0,#00f)}",
12801    );
12802    minify_test(
12803      ".foo { background: -moz-repeating-radial-gradient(circle 20px, yellow, blue) }",
12804      ".foo{background:-moz-repeating-radial-gradient(20px,#ff0,#00f)}",
12805    );
12806    minify_test(
12807      ".foo { background: -o-repeating-radial-gradient(circle 20px, yellow, blue) }",
12808      ".foo{background:-o-repeating-radial-gradient(20px,#ff0,#00f)}",
12809    );
12810    minify_test(
12811      ".foo { background: -webkit-gradient(radial, center center, 0, center center, 100, from(blue), to(yellow)) }",
12812      ".foo{background:-webkit-gradient(radial,50% 50%,0,50% 50%,100,from(#00f),to(#ff0))}"
12813    );
12814    minify_test(
12815      ".foo { background: conic-gradient(#f06, gold) }",
12816      ".foo{background:conic-gradient(#f06,gold)}",
12817    );
12818    minify_test(
12819      ".foo { background: conic-gradient(at 50% 50%, #f06, gold) }",
12820      ".foo{background:conic-gradient(#f06,gold)}",
12821    );
12822    minify_test(
12823      ".foo { background: conic-gradient(from 0deg, #f06, gold) }",
12824      ".foo{background:conic-gradient(#f06,gold)}",
12825    );
12826    minify_test(
12827      ".foo { background: conic-gradient(from 0, #f06, gold) }",
12828      ".foo{background:conic-gradient(#f06,gold)}",
12829    );
12830    minify_test(
12831      ".foo { background: conic-gradient(from 0deg at center, #f06, gold) }",
12832      ".foo{background:conic-gradient(#f06,gold)}",
12833    );
12834    minify_test(
12835      ".foo { background: conic-gradient(white -50%, black 150%) }",
12836      ".foo{background:conic-gradient(#fff -50%,#000 150%)}",
12837    );
12838    minify_test(
12839      ".foo { background: conic-gradient(white -180deg, black 540deg) }",
12840      ".foo{background:conic-gradient(#fff -180deg,#000 540deg)}",
12841    );
12842    minify_test(
12843      ".foo { background: conic-gradient(from 45deg, white, black, white) }",
12844      ".foo{background:conic-gradient(from 45deg,#fff,#000,#fff)}",
12845    );
12846    minify_test(
12847      ".foo { background: repeating-conic-gradient(from 45deg, white, black, white) }",
12848      ".foo{background:repeating-conic-gradient(from 45deg,#fff,#000,#fff)}",
12849    );
12850    minify_test(
12851      ".foo { background: repeating-conic-gradient(black 0deg 25%, white 0deg 50%) }",
12852      ".foo{background:repeating-conic-gradient(#000 0deg 25%,#fff 0deg 50%)}",
12853    );
12854
12855    test(
12856      r#"
12857        .foo {
12858          background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue));
12859          background: -webkit-linear-gradient(red, blue);
12860          background: -moz-linear-gradient(red, blue);
12861          background: -o-linear-gradient(red, blue);
12862          background: linear-gradient(red, blue);
12863        }
12864      "#,
12865      indoc! {r#"
12866        .foo {
12867          background: -webkit-gradient(linear, left top, left bottom, from(red), to(#00f));
12868          background: -webkit-linear-gradient(red, #00f);
12869          background: -moz-linear-gradient(red, #00f);
12870          background: -o-linear-gradient(red, #00f);
12871          background: linear-gradient(red, #00f);
12872        }
12873      "#},
12874    );
12875
12876    prefix_test(
12877      r#"
12878      .foo {
12879        background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue));
12880        background: -webkit-linear-gradient(red, blue);
12881        background: -moz-linear-gradient(red, blue);
12882        background: -o-linear-gradient(red, blue);
12883        background: linear-gradient(red, blue);
12884      }
12885      "#,
12886      indoc! {r#"
12887      .foo {
12888        background: linear-gradient(red, #00f);
12889      }
12890      "#},
12891      Browsers {
12892        chrome: Some(95 << 16),
12893        ..Browsers::default()
12894      },
12895    );
12896    prefix_test(
12897      r#"
12898      .foo {
12899        background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue));
12900        background: -webkit-linear-gradient(red, blue);
12901        background: -moz-linear-gradient(red, blue);
12902        background: -o-linear-gradient(red, blue);
12903      }
12904      "#,
12905      indoc! {r#"
12906      .foo {
12907        background: -webkit-gradient(linear, left top, left bottom, from(red), to(#00f));
12908        background: -webkit-linear-gradient(red, #00f);
12909        background: -moz-linear-gradient(red, #00f);
12910        background: -o-linear-gradient(red, #00f);
12911      }
12912      "#},
12913      Browsers {
12914        chrome: Some(95 << 16),
12915        ..Browsers::default()
12916      },
12917    );
12918    prefix_test(
12919      r#"
12920      .foo {
12921        background-image: linear-gradient(red, blue);
12922      }
12923      "#,
12924      indoc! {r#"
12925      .foo {
12926        background-image: -webkit-gradient(linear, 0 0, 0 100%, from(red), to(#00f));
12927        background-image: -webkit-linear-gradient(red, #00f);
12928        background-image: linear-gradient(red, #00f);
12929      }
12930      "#},
12931      Browsers {
12932        chrome: Some(8 << 16),
12933        ..Browsers::default()
12934      },
12935    );
12936    prefix_test(
12937      r#"
12938      .foo {
12939        background-image: linear-gradient(to right, red, blue);
12940      }
12941      "#,
12942      indoc! {r#"
12943      .foo {
12944        background-image: -webkit-gradient(linear, 0 0, 100% 0, from(red), to(#00f));
12945        background-image: -webkit-linear-gradient(right, red, #00f);
12946        background-image: linear-gradient(to right, red, #00f);
12947      }
12948      "#},
12949      Browsers {
12950        chrome: Some(8 << 16),
12951        ..Browsers::default()
12952      },
12953    );
12954    prefix_test(
12955      r#"
12956      .foo {
12957        background-image: linear-gradient(to top, red, blue);
12958      }
12959      "#,
12960      indoc! {r#"
12961      .foo {
12962        background-image: -webkit-gradient(linear, 0 100%, 0 0, from(red), to(#00f));
12963        background-image: -webkit-linear-gradient(top, red, #00f);
12964        background-image: linear-gradient(to top, red, #00f);
12965      }
12966      "#},
12967      Browsers {
12968        chrome: Some(8 << 16),
12969        ..Browsers::default()
12970      },
12971    );
12972    prefix_test(
12973      r#"
12974      .foo {
12975        background-image: linear-gradient(to left, red, blue);
12976      }
12977      "#,
12978      indoc! {r#"
12979      .foo {
12980        background-image: -webkit-gradient(linear, 100% 0, 0 0, from(red), to(#00f));
12981        background-image: -webkit-linear-gradient(left, red, #00f);
12982        background-image: linear-gradient(to left, red, #00f);
12983      }
12984      "#},
12985      Browsers {
12986        chrome: Some(8 << 16),
12987        ..Browsers::default()
12988      },
12989    );
12990    prefix_test(
12991      r#"
12992      .foo {
12993        background-image: linear-gradient(to left bottom, red, blue);
12994      }
12995      "#,
12996      indoc! {r#"
12997      .foo {
12998        background-image: -webkit-gradient(linear, 100% 0, 0 100%, from(red), to(#00f));
12999        background-image: -webkit-linear-gradient(bottom left, red, #00f);
13000        background-image: linear-gradient(to bottom left, red, #00f);
13001      }
13002      "#},
13003      Browsers {
13004        chrome: Some(8 << 16),
13005        ..Browsers::default()
13006      },
13007    );
13008    prefix_test(
13009      r#"
13010      .foo {
13011        background-image: linear-gradient(to top right, red, blue);
13012      }
13013      "#,
13014      indoc! {r#"
13015      .foo {
13016        background-image: -webkit-gradient(linear, 0 100%, 100% 0, from(red), to(#00f));
13017        background-image: -webkit-linear-gradient(top right, red, #00f);
13018        background-image: linear-gradient(to top right, red, #00f);
13019      }
13020      "#},
13021      Browsers {
13022        chrome: Some(8 << 16),
13023        ..Browsers::default()
13024      },
13025    );
13026    prefix_test(
13027      r#"
13028      .foo {
13029        background-image: linear-gradient(90deg, red, blue);
13030      }
13031      "#,
13032      indoc! {r#"
13033      .foo {
13034        background-image: -webkit-gradient(linear, 0 0, 100% 0, from(red), to(#00f));
13035        background-image: -webkit-linear-gradient(90deg, red, #00f);
13036        background-image: linear-gradient(90deg, red, #00f);
13037      }
13038      "#},
13039      Browsers {
13040        chrome: Some(8 << 16),
13041        ..Browsers::default()
13042      },
13043    );
13044    prefix_test(
13045      r#"
13046      .foo {
13047        background-image: linear-gradient(45deg, red, blue);
13048      }
13049      "#,
13050      indoc! {r#"
13051      .foo {
13052        background-image: -webkit-linear-gradient(45deg, red, #00f);
13053        background-image: linear-gradient(45deg, red, #00f);
13054      }
13055      "#},
13056      Browsers {
13057        chrome: Some(8 << 16),
13058        ..Browsers::default()
13059      },
13060    );
13061    prefix_test(
13062      r#"
13063      .foo {
13064        background-image: linear-gradient(red, blue);
13065      }
13066      "#,
13067      indoc! {r#"
13068      .foo {
13069        background-image: -webkit-linear-gradient(red, #00f);
13070        background-image: linear-gradient(red, #00f);
13071      }
13072      "#},
13073      Browsers {
13074        chrome: Some(10 << 16),
13075        ..Browsers::default()
13076      },
13077    );
13078    prefix_test(
13079      r#"
13080      .foo {
13081        background-image: radial-gradient(20px, red, blue);
13082      }
13083      "#,
13084      indoc! {r#"
13085      .foo {
13086        background-image: -webkit-gradient(radial, center center, 0, center center, 20, from(red), to(#00f));
13087        background-image: -webkit-radial-gradient(20px, red, #00f);
13088        background-image: radial-gradient(20px, red, #00f);
13089      }
13090      "#},
13091      Browsers {
13092        chrome: Some(8 << 16),
13093        ..Browsers::default()
13094      },
13095    );
13096    prefix_test(
13097      r#"
13098      .foo {
13099        background-image: radial-gradient(20px at top left, red, blue);
13100      }
13101      "#,
13102      indoc! {r#"
13103      .foo {
13104        background-image: -webkit-gradient(radial, left top, 0, left top, 20, from(red), to(#00f));
13105        background-image: -webkit-radial-gradient(20px at 0 0, red, #00f);
13106        background-image: radial-gradient(20px at 0 0, red, #00f);
13107      }
13108      "#},
13109      Browsers {
13110        chrome: Some(8 << 16),
13111        ..Browsers::default()
13112      },
13113    );
13114    prefix_test(
13115      r#"
13116      .foo {
13117        background-image: radial-gradient(red, blue);
13118      }
13119      "#,
13120      indoc! {r#"
13121      .foo {
13122        background-image: -webkit-radial-gradient(red, #00f);
13123        background-image: radial-gradient(red, #00f);
13124      }
13125      "#},
13126      Browsers {
13127        chrome: Some(8 << 16),
13128        ..Browsers::default()
13129      },
13130    );
13131    prefix_test(
13132      r#"
13133      .foo {
13134        background-image: -webkit-gradient(radial, left top, 0, left top, 20, from(red), to(#00f));
13135        background-image: -webkit-radial-gradient(20px at 0% 0%, red, #00f);
13136        background-image: radial-gradient(20px at 0% 0%, red, #00f);
13137      }
13138      "#,
13139      indoc! {r#"
13140      .foo {
13141        background-image: radial-gradient(20px at 0 0, red, #00f);
13142      }
13143      "#},
13144      Browsers {
13145        chrome: Some(30 << 16),
13146        ..Browsers::default()
13147      },
13148    );
13149    prefix_test(
13150      r#"
13151      .foo {
13152        background: -webkit-gradient(radial, left top, 0, left top, 20, from(red), to(#00f));
13153        background: -webkit-radial-gradient(20px at 0% 0%, red, #00f);
13154        background: radial-gradient(20px at 0% 0%, red, #00f);
13155      }
13156      "#,
13157      indoc! {r#"
13158      .foo {
13159        background: radial-gradient(20px at 0 0, red, #00f);
13160      }
13161      "#},
13162      Browsers {
13163        chrome: Some(30 << 16),
13164        ..Browsers::default()
13165      },
13166    );
13167    prefix_test(
13168      r#"
13169      .foo {
13170        background: radial-gradient(red, blue);
13171      }
13172      "#,
13173      indoc! {r#"
13174      .foo {
13175        background: -webkit-radial-gradient(red, #00f);
13176        background: radial-gradient(red, #00f);
13177      }
13178      "#},
13179      Browsers {
13180        chrome: Some(8 << 16),
13181        ..Browsers::default()
13182      },
13183    );
13184    prefix_test(
13185      r#"
13186      .foo {
13187        background: radial-gradient(red, blue), linear-gradient(yellow, red), url(bg.jpg);
13188      }
13189      "#,
13190      indoc! {r#"
13191      .foo {
13192        background: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0), to(red)), url("bg.jpg");
13193        background: -webkit-radial-gradient(red, #00f), -webkit-linear-gradient(#ff0, red), url("bg.jpg");
13194        background: -moz-radial-gradient(red, #00f), -moz-linear-gradient(#ff0, red), url("bg.jpg");
13195        background: -o-radial-gradient(red, #00f), -o-linear-gradient(#ff0, red), url("bg.jpg");
13196        background: radial-gradient(red, #00f), linear-gradient(#ff0, red), url("bg.jpg");
13197      }
13198      "#},
13199      Browsers {
13200        chrome: Some(8 << 16),
13201        firefox: Some(4 << 16),
13202        opera: Some(11 << 16 | 5 << 8),
13203        ..Browsers::default()
13204      },
13205    );
13206
13207    prefix_test(
13208      r#"
13209      .foo {
13210        background: linear-gradient(yellow, red 30% 40%, blue);
13211      }
13212      "#,
13213      indoc! {r#"
13214      .foo {
13215        background: linear-gradient(#ff0, red 30%, red 40%, #00f);
13216      }
13217      "#},
13218      Browsers {
13219        chrome: Some(70 << 16),
13220        ..Browsers::default()
13221      },
13222    );
13223
13224    prefix_test(
13225      r#"
13226      .foo {
13227        background: linear-gradient(yellow, red 30% 40%, blue);
13228      }
13229      "#,
13230      indoc! {r#"
13231      .foo {
13232        background: linear-gradient(#ff0, red 30% 40%, #00f);
13233      }
13234      "#},
13235      Browsers {
13236        chrome: Some(71 << 16),
13237        ..Browsers::default()
13238      },
13239    );
13240
13241    prefix_test(
13242      ".foo { background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13243      indoc! { r#"
13244        .foo {
13245          background: linear-gradient(#ff0f0e, #7773ff);
13246          background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13247        }
13248      "#},
13249      Browsers {
13250        chrome: Some(90 << 16),
13251        ..Browsers::default()
13252      },
13253    );
13254
13255    prefix_test(
13256      ".foo { background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13257      indoc! { r#"
13258        .foo {
13259          background: linear-gradient(#ff0f0e, #7773ff);
13260          background: linear-gradient(color(display-p3 1 .0000153435 -.00000303562), color(display-p3 .440289 .28452 1.23485));
13261          background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13262        }
13263      "#},
13264      Browsers {
13265        chrome: Some(90 << 16),
13266        safari: Some(14 << 16),
13267        ..Browsers::default()
13268      },
13269    );
13270
13271    prefix_test(
13272      ".foo { background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13273      indoc! { r#"
13274        .foo {
13275          background: -webkit-linear-gradient(#ff0f0e, #7773ff);
13276          background: linear-gradient(#ff0f0e, #7773ff);
13277          background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13278        }
13279      "#},
13280      Browsers {
13281        chrome: Some(20 << 16),
13282        ..Browsers::default()
13283      },
13284    );
13285
13286    prefix_test(
13287      ".foo { background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13288      indoc! { r#"
13289        .foo {
13290          background: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0f0e), to(#7773ff));
13291          background: -webkit-linear-gradient(#ff0f0e, #7773ff);
13292          background: linear-gradient(#ff0f0e, #7773ff);
13293          background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13294        }
13295      "#},
13296      Browsers {
13297        chrome: Some(8 << 16),
13298        ..Browsers::default()
13299      },
13300    );
13301
13302    prefix_test(
13303      ".foo { background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13304      indoc! { r#"
13305        .foo {
13306          background: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13307        }
13308      "#},
13309      Browsers {
13310        safari: Some(15 << 16),
13311        ..Browsers::default()
13312      },
13313    );
13314
13315    prefix_test(
13316      ".foo { background-image: linear-gradient(oklab(59.686% 0.1009 0.1192), oklab(54.0% -0.10 -0.02)); }",
13317      indoc! { r#"
13318        .foo {
13319          background-image: linear-gradient(lab(52.2319% 40.1449 59.9171), lab(47.7776% -34.2947 -7.65904));
13320        }
13321      "#},
13322      Browsers {
13323        safari: Some(15 << 16),
13324        ..Browsers::default()
13325      },
13326    );
13327
13328    prefix_test(
13329      ".foo { background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13330      indoc! { r#"
13331        .foo {
13332          background-image: linear-gradient(#ff0f0e, #7773ff);
13333          background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13334        }
13335      "#},
13336      Browsers {
13337        chrome: Some(90 << 16),
13338        ..Browsers::default()
13339      },
13340    );
13341
13342    prefix_test(
13343      ".foo { background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13344      indoc! { r#"
13345        .foo {
13346          background-image: linear-gradient(#ff0f0e, #7773ff);
13347          background-image: linear-gradient(color(display-p3 1 .0000153435 -.00000303562), color(display-p3 .440289 .28452 1.23485));
13348          background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13349        }
13350      "#},
13351      Browsers {
13352        chrome: Some(90 << 16),
13353        safari: Some(14 << 16),
13354        ..Browsers::default()
13355      },
13356    );
13357
13358    prefix_test(
13359      ".foo { background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13360      indoc! { r#"
13361        .foo {
13362          background-image: -webkit-linear-gradient(#ff0f0e, #7773ff);
13363          background-image: linear-gradient(#ff0f0e, #7773ff);
13364          background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13365        }
13366      "#},
13367      Browsers {
13368        chrome: Some(20 << 16),
13369        ..Browsers::default()
13370      },
13371    );
13372
13373    prefix_test(
13374      ".foo { background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13375      indoc! { r#"
13376        .foo {
13377          background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0f0e), to(#7773ff));
13378          background-image: -webkit-linear-gradient(#ff0f0e, #7773ff);
13379          background-image: linear-gradient(#ff0f0e, #7773ff);
13380          background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13381        }
13382      "#},
13383      Browsers {
13384        chrome: Some(8 << 16),
13385        ..Browsers::default()
13386      },
13387    );
13388
13389    prefix_test(
13390      ".foo { background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
13391      indoc! { r#"
13392        .foo {
13393          background-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
13394        }
13395      "#},
13396      Browsers {
13397        safari: Some(15 << 16),
13398        ..Browsers::default()
13399      },
13400    );
13401
13402    prefix_test(
13403      ".foo { background-image: linear-gradient(oklab(59.686% 0.1009 0.1192), oklab(54.0% -0.10 -0.02)); }",
13404      indoc! { r#"
13405        .foo {
13406          background-image: linear-gradient(lab(52.2319% 40.1449 59.9171), lab(47.7776% -34.2947 -7.65904));
13407        }
13408      "#},
13409      Browsers {
13410        safari: Some(15 << 16),
13411        ..Browsers::default()
13412      },
13413    );
13414  }
13415
13416  #[test]
13417  fn test_font_face() {
13418    minify_test(
13419      r#"@font-face {
13420      src: url("test.woff");
13421      font-family: "Helvetica";
13422      font-weight: bold;
13423      font-style: italic;
13424    }"#,
13425      "@font-face{src:url(test.woff);font-family:Helvetica;font-weight:700;font-style:italic}",
13426    );
13427    minify_test("@font-face {src: url(test.woff);}", "@font-face{src:url(test.woff)}");
13428    minify_test("@font-face {src: local(\"Test\");}", "@font-face{src:local(Test)}");
13429    minify_test(
13430      "@font-face {src: local(\"Foo Bar\");}",
13431      "@font-face{src:local(Foo Bar)}",
13432    );
13433    minify_test("@font-face {src: local(Test);}", "@font-face{src:local(Test)}");
13434    minify_test("@font-face {src: local(Foo Bar);}", "@font-face{src:local(Foo Bar)}");
13435
13436    minify_test(
13437      "@font-face {src: url(\"test.woff\") format(woff);}",
13438      "@font-face{src:url(test.woff)format(\"woff\")}",
13439    );
13440    minify_test(
13441      "@font-face {src: url(\"test.ttc\") format(collection), url(test.ttf) format(truetype);}",
13442      "@font-face{src:url(test.ttc)format(\"collection\"),url(test.ttf)format(\"truetype\")}",
13443    );
13444    minify_test(
13445      "@font-face {src: url(\"test.otf\") format(opentype) tech(features-aat);}",
13446      "@font-face{src:url(test.otf)format(\"opentype\")tech(features-aat)}",
13447    );
13448    minify_test(
13449      "@font-face {src: url(\"test.woff\") format(woff) tech(color-colrv1);}",
13450      "@font-face{src:url(test.woff)format(\"woff\")tech(color-colrv1)}",
13451    );
13452    minify_test(
13453      "@font-face {src: url(\"test.woff2\") format(woff2) tech(variations);}",
13454      "@font-face{src:url(test.woff2)format(\"woff2\")tech(variations)}",
13455    );
13456    minify_test(
13457      "@font-face {src: url(\"test.woff\") format(woff) tech(palettes);}",
13458      "@font-face{src:url(test.woff)format(\"woff\")tech(palettes)}",
13459    );
13460    // multiple tech
13461    minify_test(
13462      "@font-face {src: url(\"test.woff\") format(woff) tech(features-opentype, color-sbix);}",
13463      "@font-face{src:url(test.woff)format(\"woff\")tech(features-opentype,color-sbix)}",
13464    );
13465    minify_test(
13466      "@font-face {src: url(\"test.woff\")   format(woff)    tech(incremental, color-svg, features-graphite, features-aat);}",
13467      "@font-face{src:url(test.woff)format(\"woff\")tech(incremental,color-svg,features-graphite,features-aat)}",
13468    );
13469    // format() function must precede tech() if both are present
13470    minify_test(
13471      "@font-face {src: url(\"foo.ttf\") format(opentype) tech(color-colrv1);}",
13472      "@font-face{src:url(foo.ttf)format(\"opentype\")tech(color-colrv1)}",
13473    );
13474    // only have tech is valid
13475    minify_test(
13476      "@font-face {src: url(\"foo.ttf\") tech(color-SVG);}",
13477      "@font-face{src:url(foo.ttf)tech(color-svg)}",
13478    );
13479    // CGQAQ: if tech and format both presence, order is matter, tech before format is invalid
13480    // but now just return raw token, we don't have strict mode yet.
13481    // ref: https://github.com/parcel-bundler/lightningcss/pull/255#issuecomment-1219049998
13482    minify_test(
13483      "@font-face {src: url(\"foo.ttf\") tech(palettes  color-colrv0  variations) format(opentype);}",
13484      "@font-face{src:url(foo.ttf) tech(palettes color-colrv0 variations)format(opentype)}",
13485    );
13486    // TODO(CGQAQ): make this test pass when we have strict mode
13487    // ref: https://github.com/web-platform-tests/wpt/blob/9f8a6ccc41aa725e8f51f4f096f686313bb88d8d/css/css-fonts/parsing/font-face-src-tech.html#L45
13488    // error_test(
13489    //   "@font-face {src: url(\"foo.ttf\") tech(features-opentype) format(opentype);}",
13490    //   ParserError::AtRuleBodyInvalid,
13491    // );
13492    // error_test(
13493    //   "@font-face {src: url(\"foo.ttf\") tech();}",
13494    //   ParserError::AtRuleBodyInvalid,
13495    // );
13496    // error_test(
13497    //   "@font-face {src: url(\"foo.ttf\") tech(\"features-opentype\");}",
13498    //   ParserError::AtRuleBodyInvalid,
13499    // );
13500    // error_test(
13501    //   "@font-face {src: url(\"foo.ttf\") tech(\"color-colrv0\");}",
13502    //   ParserError::AtRuleBodyInvalid,
13503    // );
13504    minify_test(
13505      "@font-face {src: local(\"\") url(\"test.woff\");}",
13506      "@font-face{src:local(\"\")url(test.woff)}",
13507    );
13508    minify_test("@font-face {font-weight: 200 400}", "@font-face{font-weight:200 400}");
13509    minify_test("@font-face {font-weight: 400 400}", "@font-face{font-weight:400}");
13510    minify_test(
13511      "@font-face {font-stretch: 50% 200%}",
13512      "@font-face{font-stretch:50% 200%}",
13513    );
13514    minify_test("@font-face {font-stretch: 50% 50%}", "@font-face{font-stretch:50%}");
13515    minify_test("@font-face {unicode-range: U+26;}", "@font-face{unicode-range:U+26}");
13516    minify_test("@font-face {unicode-range: u+26;}", "@font-face{unicode-range:U+26}");
13517    minify_test(
13518      "@font-face {unicode-range: U+0-7F;}",
13519      "@font-face{unicode-range:U+0-7F}",
13520    );
13521    minify_test(
13522      "@font-face {unicode-range: U+0025-00FF;}",
13523      "@font-face{unicode-range:U+25-FF}",
13524    );
13525    minify_test("@font-face {unicode-range: U+4??;}", "@font-face{unicode-range:U+4??}");
13526    minify_test(
13527      "@font-face {unicode-range: U+400-4FF;}",
13528      "@font-face{unicode-range:U+4??}",
13529    );
13530    minify_test(
13531      "@font-face {unicode-range: U+0025-00FF, U+4??;}",
13532      "@font-face{unicode-range:U+25-FF,U+4??}",
13533    );
13534    minify_test(
13535      "@font-face {unicode-range: U+A5, U+4E00-9FFF, U+30??, U+FF00-FF9F;}",
13536      "@font-face{unicode-range:U+A5,U+4E00-9FFF,U+30??,U+FF00-FF9F}",
13537    );
13538    minify_test(
13539      "@font-face {unicode-range: U+????;}",
13540      "@font-face{unicode-range:U+????}",
13541    );
13542    minify_test(
13543      "@font-face {unicode-range: U+0000-FFFF;}",
13544      "@font-face{unicode-range:U+????}",
13545    );
13546    minify_test(
13547      "@font-face {unicode-range: U+10????;}",
13548      "@font-face{unicode-range:U+10????}",
13549    );
13550    minify_test(
13551      "@font-face {unicode-range: U+100000-10FFFF;}",
13552      "@font-face{unicode-range:U+10????}",
13553    );
13554    minify_test(
13555      "@font-face {unicode-range: U+1e1e?;}",
13556      "@font-face{unicode-range:U+1E1E?}",
13557    );
13558    minify_test(
13559      "@font-face {unicode-range: u+????, U+1????, U+10????;}",
13560      "@font-face{unicode-range:U+????,U+1????,U+10????}",
13561    );
13562    minify_test(r#"
13563      @font-face {
13564        font-family: Inter;
13565        font-style: oblique 0deg 10deg;
13566        font-weight: 100 900;
13567        src: url("../fonts/Inter.var.woff2?v=3.19") format("woff2");
13568        font-display: swap;
13569      }
13570    "#, "@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}");
13571    minify_test(r#"
13572    @font-face {
13573      font-family: Inter;
13574      font-style: oblique 14deg 14deg;
13575      font-weight: 100 900;
13576      src: url("../fonts/Inter.var.woff2?v=3.19") format("woff2");
13577      font-display: swap;
13578    }
13579  "#, "@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}");
13580  }
13581
13582  #[test]
13583  fn test_font_palette_values() {
13584    minify_test(
13585      r#"@font-palette-values --Cooler {
13586      font-family: Bixa;
13587      base-palette: 1;
13588      override-colors: 1 #7EB7E4;
13589    }"#,
13590      "@font-palette-values --Cooler{font-family:Bixa;base-palette:1;override-colors:1 #7eb7e4}",
13591    );
13592    minify_test(
13593      r#"@font-palette-values --Cooler {
13594      font-family: Handover Sans;
13595      base-palette: 3;
13596      override-colors: 1 rgb(43, 12, 9), 3 lime;
13597    }"#,
13598      "@font-palette-values --Cooler{font-family:Handover Sans;base-palette:3;override-colors:1 #2b0c09,3 #0f0}",
13599    );
13600    minify_test(r#"@font-palette-values --Cooler {
13601      font-family: Handover Sans;
13602      base-palette: 3;
13603      override-colors: 1 rgb(43, 12, 9), 3 var(--highlight);
13604    }"#, "@font-palette-values --Cooler{font-family:Handover Sans;base-palette:3;override-colors:1 #2b0c09,3 var(--highlight)}");
13605    prefix_test(
13606      r#"@font-palette-values --Cooler {
13607      font-family: Handover Sans;
13608      base-palette: 3;
13609      override-colors: 1 rgb(43, 12, 9), 3 lch(50.998% 135.363 338);
13610    }"#,
13611      indoc! {r#"@font-palette-values --Cooler {
13612      font-family: Handover Sans;
13613      base-palette: 3;
13614      override-colors: 1 #2b0c09, 3 #ee00be;
13615      override-colors: 1 #2b0c09, 3 lch(50.998% 135.363 338);
13616    }
13617    "#},
13618      Browsers {
13619        chrome: Some(90 << 16),
13620        ..Browsers::default()
13621      },
13622    );
13623    prefix_test(
13624      r#"@font-palette-values --Cooler {
13625      font-family: Handover Sans;
13626      base-palette: 3;
13627      override-colors: 1 var(--foo), 3 lch(50.998% 135.363 338);
13628    }"#,
13629      indoc! {r#"@font-palette-values --Cooler {
13630      font-family: Handover Sans;
13631      base-palette: 3;
13632      override-colors: 1 var(--foo), 3 #ee00be;
13633    }
13634
13635    @supports (color: lab(0% 0 0)) {
13636      @font-palette-values --Cooler {
13637        font-family: Handover Sans;
13638        base-palette: 3;
13639        override-colors: 1 var(--foo), 3 lab(50.998% 125.506 -50.7078);
13640      }
13641    }
13642    "#},
13643      Browsers {
13644        chrome: Some(90 << 16),
13645        ..Browsers::default()
13646      },
13647    );
13648    minify_test(".foo { font-palette: --Custom; }", ".foo{font-palette:--Custom}");
13649  }
13650
13651  #[test]
13652  fn test_font_feature_values() {
13653    // https://github.com/clagnut/TODS/blob/e693d52ad411507b960cf01a9734265e3efab102/tods.css#L116-L142
13654    minify_test(
13655      r#"
13656@font-feature-values "Fancy Font Name" {
13657  @styleset { cursive: 1; swoopy: 7 16; }
13658  @character-variant { ampersand: 1; capital-q: 2; }
13659  @stylistic { two-story-g: 1; straight-y: 2; }
13660  @swash { swishy: 1; flowing: 2; }
13661  @ornaments { clover: 1; fleuron: 2; }
13662  @annotation { circled: 1; boxed: 2; }
13663}
13664    "#,
13665      r#"@font-feature-values Fancy Font Name{@styleset{cursive:1;swoopy:7 16}@character-variant{ampersand:1;capital-q:2}@stylistic{two-story-g:1;straight-y:2}@swash{swishy:1;flowing:2}@ornaments{clover:1;fleuron:2}@annotation{circled:1;boxed:2}}"#,
13666    );
13667
13668    // https://github.com/Sorixelle/srxl.me/blob/4eb4f4a15cb2d21356df24c096d6a819cfdc1a99/public/fonts/inter/inter.css#L201-L222
13669    minify_test(
13670      r#"
13671@font-feature-values "Inter", "Inter var", "Inter var experimental" {
13672  @styleset {
13673    open-digits: 1;
13674    disambiguation: 2;
13675    curved-r: 3;
13676    disambiguation-without-zero: 4;
13677  }
13678
13679  @character-variant {
13680    alt-one: 1;
13681    open-four: 2;
13682    open-six: 3;
13683    open-nine: 4;
13684    lower-l-with-tail: 5;
13685    curved-lower-r: 6;
13686    german-double-s: 7;
13687    upper-i-with-serif: 8;
13688    flat-top-three: 9;
13689    upper-g-with-spur: 10;
13690    single-storey-a: 11;
13691  }
13692}
13693      "#,
13694      r#"@font-feature-values Inter,Inter var,Inter var experimental{@styleset{open-digits:1;disambiguation:2;curved-r:3;disambiguation-without-zero:4}@character-variant{alt-one:1;open-four:2;open-six:3;open-nine:4;lower-l-with-tail:5;curved-lower-r:6;german-double-s:7;upper-i-with-serif:8;flat-top-three:9;upper-g-with-spur:10;single-storey-a:11}}"#,
13695    );
13696
13697    // https://github.com/MihailJP/Inconsolata-LGC/blob/7c53cf455787096c93d82d9a51018f12ec39a6e9/Inconsolata-LGC.css#L65-L91
13698    minify_test(
13699      r#"
13700@font-feature-values "Inconsolata LGC" {
13701	@styleset {
13702		alternative-umlaut: 1;
13703	}
13704	@character-variant {
13705		zero-plain: 1 1;
13706		zero-dotted: 1 2;
13707		zero-longslash: 1 3;
13708		r-with-serif: 2 1;
13709		eng-descender: 3 1;
13710		eng-uppercase: 3 2;
13711		dollar-open: 4 1;
13712		dollar-oldstyle: 4 2;
13713		dollar-cifrao: 4 2;
13714		ezh-no-descender: 5 1;
13715		ezh-reversed-sigma: 5 2;
13716		triangle-text-form: 6 1;
13717		el-with-hook-old: 7 1;
13718		qa-enlarged-lowercase: 8 1;
13719		qa-reversed-p: 8 2;
13720		che-with-hook: 9 1;
13721		che-with-hook-alt: 9 2;
13722		ge-with-hook: 10 1;
13723		ge-with-hook-alt: 10 2;
13724		ge-with-stroke-and-descender: 11 1;
13725	}
13726}
13727    "#,
13728      r#"@font-feature-values Inconsolata LGC{@styleset{alternative-umlaut:1}@character-variant{zero-plain:1 1;zero-dotted:1 2;zero-longslash:1 3;r-with-serif:2 1;eng-descender:3 1;eng-uppercase:3 2;dollar-open:4 1;dollar-oldstyle:4 2;dollar-cifrao:4 2;ezh-no-descender:5 1;ezh-reversed-sigma:5 2;triangle-text-form:6 1;el-with-hook-old:7 1;qa-enlarged-lowercase:8 1;qa-reversed-p:8 2;che-with-hook:9 1;che-with-hook-alt:9 2;ge-with-hook:10 1;ge-with-hook-alt:10 2;ge-with-stroke-and-descender:11 1}}"#,
13729    );
13730
13731    minify_test(
13732      r#"
13733      @font-feature-values "Fancy Font Name" {
13734        @styleset { cursive: 1; swoopy: 7 16; }
13735        @character-variant { ampersand: 1; capital-q: 2; }
13736      }
13737      "#,
13738      r#"@font-feature-values Fancy Font Name{@styleset{cursive:1;swoopy:7 16}@character-variant{ampersand:1;capital-q:2}}"#,
13739    );
13740    minify_test(
13741      r#"
13742      @font-feature-values foo {
13743          @swash { pretty: 0; pretty: 1; cool: 2; }
13744      }
13745      "#,
13746      "@font-feature-values foo{@swash{pretty:1;cool:2}}",
13747    );
13748    minify_test(
13749      r#"
13750      @font-feature-values foo {
13751          @swash { pretty: 1; }
13752          @swash { cool: 2; }
13753      }
13754      "#,
13755      "@font-feature-values foo{@swash{pretty:1;cool:2}}",
13756    );
13757    minify_test(
13758      r#"
13759      @font-feature-values foo {
13760          @swash { pretty: 1; }
13761      }
13762      @font-feature-values foo {
13763          @swash { cool: 2; }
13764      }
13765      "#,
13766      "@font-feature-values foo{@swash{pretty:1;cool:2}}",
13767    );
13768  }
13769
13770  #[test]
13771  fn test_page_rule() {
13772    minify_test("@page {margin: 0.5cm}", "@page{margin:.5cm}");
13773    minify_test("@page :left {margin: 0.5cm}", "@page:left{margin:.5cm}");
13774    minify_test("@page :right {margin: 0.5cm}", "@page:right{margin:.5cm}");
13775    minify_test(
13776      "@page LandscapeTable {margin: 0.5cm}",
13777      "@page LandscapeTable{margin:.5cm}",
13778    );
13779    minify_test(
13780      "@page CompanyLetterHead:first {margin: 0.5cm}",
13781      "@page CompanyLetterHead:first{margin:.5cm}",
13782    );
13783    minify_test("@page:first {margin: 0.5cm}", "@page:first{margin:.5cm}");
13784    minify_test("@page :blank:first {margin: 0.5cm}", "@page:blank:first{margin:.5cm}");
13785    minify_test("@page toc, index {margin: 0.5cm}", "@page toc,index{margin:.5cm}");
13786    minify_test(
13787      r#"
13788    @page :right {
13789      @bottom-left {
13790        margin: 10pt;
13791      }
13792    }
13793    "#,
13794      "@page:right{@bottom-left{margin:10pt}}",
13795    );
13796    minify_test(
13797      r#"
13798    @page :right {
13799      margin: 1in;
13800
13801      @bottom-left {
13802        margin: 10pt;
13803      }
13804    }
13805    "#,
13806      "@page:right{margin:1in;@bottom-left{margin:10pt}}",
13807    );
13808
13809    test(
13810      r#"
13811    @page :right {
13812      @bottom-left {
13813        margin: 10pt;
13814      }
13815    }
13816    "#,
13817      indoc! {r#"
13818      @page :right {
13819        @bottom-left {
13820          margin: 10pt;
13821        }
13822      }
13823      "#},
13824    );
13825
13826    test(
13827      r#"
13828    @page :right {
13829      margin: 1in;
13830
13831      @bottom-left-corner { content: "Foo"; }
13832      @bottom-right-corner { content: "Bar"; }
13833    }
13834    "#,
13835      indoc! {r#"
13836      @page :right {
13837        margin: 1in;
13838
13839        @bottom-left-corner {
13840          content: "Foo";
13841        }
13842
13843        @bottom-right-corner {
13844          content: "Bar";
13845        }
13846      }
13847      "#},
13848    );
13849
13850    error_test(
13851      r#"
13852      @page {
13853        @foo {
13854          margin: 1in;
13855        }
13856      }
13857      "#,
13858      ParserError::AtRuleInvalid("foo".into()),
13859    );
13860
13861    error_test(
13862      r#"
13863      @page {
13864        @top-left-corner {
13865          @bottom-left {
13866            margin: 1in;
13867          }
13868        }
13869      }
13870      "#,
13871      ParserError::AtRuleInvalid("bottom-left".into()),
13872    );
13873  }
13874
13875  #[test]
13876  fn test_supports_rule() {
13877    test(
13878      r#"
13879      @supports (foo: bar) {
13880        .test {
13881          foo: bar;
13882        }
13883      }
13884    "#,
13885      indoc! { r#"
13886      @supports (foo: bar) {
13887        .test {
13888          foo: bar;
13889        }
13890      }
13891    "#},
13892    );
13893    test(
13894      r#"
13895      @supports not (foo: bar) {
13896        .test {
13897          foo: bar;
13898        }
13899      }
13900    "#,
13901      indoc! { r#"
13902      @supports not (foo: bar) {
13903        .test {
13904          foo: bar;
13905        }
13906      }
13907    "#},
13908    );
13909    test(
13910      r#"
13911      @supports (foo: bar) or (bar: baz) {
13912        .test {
13913          foo: bar;
13914        }
13915      }
13916    "#,
13917      indoc! { r#"
13918      @supports (foo: bar) or (bar: baz) {
13919        .test {
13920          foo: bar;
13921        }
13922      }
13923    "#},
13924    );
13925    test(
13926      r#"
13927      @supports (((foo: bar) or (bar: baz))) {
13928        .test {
13929          foo: bar;
13930        }
13931      }
13932    "#,
13933      indoc! { r#"
13934      @supports (foo: bar) or (bar: baz) {
13935        .test {
13936          foo: bar;
13937        }
13938      }
13939    "#},
13940    );
13941    test(
13942      r#"
13943      @supports (foo: bar) and (bar: baz) {
13944        .test {
13945          foo: bar;
13946        }
13947      }
13948    "#,
13949      indoc! { r#"
13950      @supports (foo: bar) and (bar: baz) {
13951        .test {
13952          foo: bar;
13953        }
13954      }
13955    "#},
13956    );
13957    test(
13958      r#"
13959      @supports (((foo: bar) and (bar: baz))) {
13960        .test {
13961          foo: bar;
13962        }
13963      }
13964    "#,
13965      indoc! { r#"
13966      @supports (foo: bar) and (bar: baz) {
13967        .test {
13968          foo: bar;
13969        }
13970      }
13971    "#},
13972    );
13973    test(
13974      r#"
13975      @supports (foo: bar) and (((bar: baz) or (test: foo))) {
13976        .test {
13977          foo: bar;
13978        }
13979      }
13980    "#,
13981      indoc! { r#"
13982      @supports (foo: bar) and ((bar: baz) or (test: foo)) {
13983        .test {
13984          foo: bar;
13985        }
13986      }
13987    "#},
13988    );
13989    test(
13990      r#"
13991      @supports not (((foo: bar) and (bar: baz))) {
13992        .test {
13993          foo: bar;
13994        }
13995      }
13996    "#,
13997      indoc! { r#"
13998      @supports not ((foo: bar) and (bar: baz)) {
13999        .test {
14000          foo: bar;
14001        }
14002      }
14003    "#},
14004    );
14005    test(
14006      r#"
14007      @supports selector(a > b) {
14008        .test {
14009          foo: bar;
14010        }
14011      }
14012    "#,
14013      indoc! { r#"
14014      @supports selector(a > b) {
14015        .test {
14016          foo: bar;
14017        }
14018      }
14019    "#},
14020    );
14021    test(
14022      r#"
14023      @supports unknown(test) {
14024        .test {
14025          foo: bar;
14026        }
14027      }
14028    "#,
14029      indoc! { r#"
14030      @supports unknown(test) {
14031        .test {
14032          foo: bar;
14033        }
14034      }
14035    "#},
14036    );
14037    test(
14038      r#"
14039      @supports (unknown) {
14040        .test {
14041          foo: bar;
14042        }
14043      }
14044    "#,
14045      indoc! { r#"
14046      @supports (unknown) {
14047        .test {
14048          foo: bar;
14049        }
14050      }
14051    "#},
14052    );
14053    test(
14054      r#"
14055      @supports (display: grid) and (not (display: inline-grid)) {
14056        .test {
14057          foo: bar;
14058        }
14059      }
14060    "#,
14061      indoc! { r#"
14062      @supports (display: grid) and (not (display: inline-grid)) {
14063        .test {
14064          foo: bar;
14065        }
14066      }
14067    "#},
14068    );
14069    prefix_test(
14070      r#"
14071      @supports (backdrop-filter: blur(10px)) {
14072        div {
14073          backdrop-filter: blur(10px);
14074        }
14075      }
14076    "#,
14077      indoc! { r#"
14078      @supports ((-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px))) {
14079        div {
14080          -webkit-backdrop-filter: blur(10px);
14081          backdrop-filter: blur(10px);
14082        }
14083      }
14084    "#},
14085      Browsers {
14086        safari: Some(14 << 16),
14087        ..Default::default()
14088      },
14089    );
14090    prefix_test(
14091      r#"
14092      @supports ((-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px))) {
14093        div {
14094          backdrop-filter: blur(10px);
14095        }
14096      }
14097    "#,
14098      indoc! { r#"
14099      @supports ((-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px))) {
14100        div {
14101          -webkit-backdrop-filter: blur(10px);
14102          backdrop-filter: blur(10px);
14103        }
14104      }
14105    "#},
14106      Browsers {
14107        safari: Some(14 << 16),
14108        ..Default::default()
14109      },
14110    );
14111    prefix_test(
14112      r#"
14113      @supports ((-webkit-backdrop-filter: blur(20px)) or (backdrop-filter: blur(10px))) {
14114        div {
14115          backdrop-filter: blur(10px);
14116        }
14117      }
14118    "#,
14119      indoc! { r#"
14120      @supports ((-webkit-backdrop-filter: blur(20px))) or ((-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px))) {
14121        div {
14122          -webkit-backdrop-filter: blur(10px);
14123          backdrop-filter: blur(10px);
14124        }
14125      }
14126    "#},
14127      Browsers {
14128        safari: Some(14 << 16),
14129        ..Default::default()
14130      },
14131    );
14132    prefix_test(
14133      r#"
14134      @supports ((-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px))) {
14135        div {
14136          backdrop-filter: blur(10px);
14137        }
14138      }
14139    "#,
14140      indoc! { r#"
14141      @supports (backdrop-filter: blur(10px)) {
14142        div {
14143          backdrop-filter: blur(10px);
14144        }
14145      }
14146    "#},
14147      Browsers {
14148        chrome: Some(80 << 16),
14149        ..Default::default()
14150      },
14151    );
14152    minify_test(
14153      r#"
14154      @supports (width: calc(10px * 2)) {
14155        .test {
14156          width: calc(10px * 2);
14157        }
14158      }
14159    "#,
14160      "@supports (width:calc(10px * 2)){.test{width:20px}}",
14161    );
14162    minify_test(
14163      r#"
14164      @supports (color: hsl(0deg, 0%, 0%)) {
14165        .test {
14166          color: hsl(0deg, 0%, 0%);
14167        }
14168      }
14169    "#,
14170      "@supports (color:hsl(0deg, 0%, 0%)){.test{color:#000}}",
14171    );
14172  }
14173
14174  #[test]
14175  fn test_counter_style() {
14176    test(
14177      r#"
14178      @counter-style circled-alpha {
14179        system: fixed;
14180        symbols: Ⓐ Ⓑ Ⓒ;
14181        suffix: " ";
14182      }
14183    "#,
14184      indoc! { r#"
14185      @counter-style circled-alpha {
14186        system: fixed;
14187        symbols: Ⓐ Ⓑ Ⓒ;
14188        suffix: " ";
14189      }
14190    "#},
14191    );
14192  }
14193
14194  #[test]
14195  fn test_namespace() {
14196    minify_test(
14197      "@namespace url(http://toto.example.org);",
14198      "@namespace \"http://toto.example.org\";",
14199    );
14200    minify_test(
14201      "@namespace \"http://toto.example.org\";",
14202      "@namespace \"http://toto.example.org\";",
14203    );
14204    minify_test(
14205      "@namespace toto \"http://toto.example.org\";",
14206      "@namespace toto \"http://toto.example.org\";",
14207    );
14208    minify_test(
14209      "@namespace toto url(http://toto.example.org);",
14210      "@namespace toto \"http://toto.example.org\";",
14211    );
14212
14213    test(
14214      r#"
14215      @namespace "http://example.com/foo";
14216
14217      x {
14218        color: red;
14219      }
14220    "#,
14221      indoc! {r#"
14222      @namespace "http://example.com/foo";
14223
14224      x {
14225        color: red;
14226      }
14227    "#},
14228    );
14229
14230    test(
14231      r#"
14232      @namespace toto "http://toto.example.org";
14233
14234      toto|x {
14235        color: red;
14236      }
14237
14238      [toto|att=val] {
14239        color: blue
14240      }
14241    "#,
14242      indoc! {r#"
14243      @namespace toto "http://toto.example.org";
14244
14245      toto|x {
14246        color: red;
14247      }
14248
14249      [toto|att="val"] {
14250        color: #00f;
14251      }
14252    "#},
14253    );
14254
14255    test(
14256      r#"
14257      @namespace "http://example.com/foo";
14258
14259      |x {
14260        color: red;
14261      }
14262
14263      [|att=val] {
14264        color: blue
14265      }
14266    "#,
14267      indoc! {r#"
14268      @namespace "http://example.com/foo";
14269
14270      |x {
14271        color: red;
14272      }
14273
14274      [att="val"] {
14275        color: #00f;
14276      }
14277    "#},
14278    );
14279
14280    test(
14281      r#"
14282      @namespace "http://example.com/foo";
14283
14284      *|x {
14285        color: red;
14286      }
14287
14288      [*|att=val] {
14289        color: blue
14290      }
14291    "#,
14292      indoc! {r#"
14293      @namespace "http://example.com/foo";
14294
14295      *|x {
14296        color: red;
14297      }
14298
14299      [*|att="val"] {
14300        color: #00f;
14301      }
14302    "#},
14303    );
14304
14305    error_test(
14306      ".foo { color: red } @namespace \"http://example.com/foo\";",
14307      ParserError::UnexpectedNamespaceRule,
14308    );
14309  }
14310
14311  #[test]
14312  fn test_import() {
14313    minify_test("@import url(foo.css);", "@import \"foo.css\";");
14314    minify_test("@import \"foo.css\";", "@import \"foo.css\";");
14315    minify_test("@import url(foo.css) print;", "@import \"foo.css\" print;");
14316    minify_test("@import \"foo.css\" print;", "@import \"foo.css\" print;");
14317    minify_test(
14318      "@import \"foo.css\" screen and (orientation: landscape);",
14319      "@import \"foo.css\" screen and (orientation:landscape);",
14320    );
14321    minify_test(
14322      "@import url(foo.css) supports(display: flex);",
14323      "@import \"foo.css\" supports(display:flex);",
14324    );
14325    minify_test(
14326      "@import url(foo.css) supports(display: flex) print;",
14327      "@import \"foo.css\" supports(display:flex) print;",
14328    );
14329    minify_test(
14330      "@import url(foo.css) supports(not (display: flex));",
14331      "@import \"foo.css\" supports(not (display:flex));",
14332    );
14333    minify_test(
14334      "@import url(foo.css) supports((display: flex));",
14335      "@import \"foo.css\" supports(display:flex);",
14336    );
14337    minify_test("@charset \"UTF-8\"; @import url(foo.css);", "@import \"foo.css\";");
14338    minify_test("@layer foo; @import url(foo.css);", "@layer foo;@import \"foo.css\";");
14339    error_test(
14340      ".foo { color: red } @import url(bar.css);",
14341      ParserError::UnexpectedImportRule,
14342    );
14343    error_test(
14344      "@namespace \"http://example.com/foo\"; @import url(bar.css);",
14345      ParserError::UnexpectedImportRule,
14346    );
14347    error_test(
14348      "@media print { .foo { color: red }} @import url(bar.css);",
14349      ParserError::UnexpectedImportRule,
14350    );
14351    error_test(
14352      "@layer foo; @import url(foo.css); @layer bar; @import url(bar.css)",
14353      ParserError::UnexpectedImportRule,
14354    );
14355  }
14356
14357  #[test]
14358  fn test_prefixes() {
14359    prefix_test(
14360      r#"
14361      .foo {
14362        -webkit-transition: opacity 200ms;
14363        -moz-transition: opacity 200ms;
14364        transition: opacity 200ms;
14365      }
14366      "#,
14367      indoc! {r#"
14368      .foo {
14369        transition: opacity .2s;
14370      }
14371      "#},
14372      Browsers {
14373        chrome: Some(95 << 16),
14374        ..Browsers::default()
14375      },
14376    );
14377
14378    prefix_test(
14379      ".foo{transition:opacity 200ms}",
14380      indoc! {r#"
14381      .foo {
14382        -webkit-transition: opacity .2s;
14383        -moz-transition: opacity .2s;
14384        transition: opacity .2s;
14385      }
14386      "#},
14387      Browsers {
14388        safari: Some(5 << 16),
14389        firefox: Some(14 << 16),
14390        ..Browsers::default()
14391      },
14392    );
14393  }
14394
14395  #[test]
14396  fn test_display() {
14397    minify_test(".foo { display: block }", ".foo{display:block}");
14398    minify_test(".foo { display: block flow }", ".foo{display:block}");
14399    minify_test(".foo { display: flow-root }", ".foo{display:flow-root}");
14400    minify_test(".foo { display: block flow-root }", ".foo{display:flow-root}");
14401    minify_test(".foo { display: inline }", ".foo{display:inline}");
14402    minify_test(".foo { display: inline flow }", ".foo{display:inline}");
14403    minify_test(".foo { display: inline-block }", ".foo{display:inline-block}");
14404    minify_test(".foo { display: inline flow-root }", ".foo{display:inline-block}");
14405    minify_test(".foo { display: run-in }", ".foo{display:run-in}");
14406    minify_test(".foo { display: run-in flow }", ".foo{display:run-in}");
14407    minify_test(".foo { display: list-item }", ".foo{display:list-item}");
14408    minify_test(".foo { display: block flow list-item }", ".foo{display:list-item}");
14409    minify_test(".foo { display: inline list-item }", ".foo{display:inline list-item}");
14410    minify_test(
14411      ".foo { display: inline flow list-item }",
14412      ".foo{display:inline list-item}",
14413    );
14414    minify_test(".foo { display: flex }", ".foo{display:flex}");
14415    minify_test(".foo { display: block flex }", ".foo{display:flex}");
14416    minify_test(".foo { display: inline-flex }", ".foo{display:inline-flex}");
14417    minify_test(".foo { display: inline flex }", ".foo{display:inline-flex}");
14418    minify_test(".foo { display: grid }", ".foo{display:grid}");
14419    minify_test(".foo { display: block grid }", ".foo{display:grid}");
14420    minify_test(".foo { display: inline-grid }", ".foo{display:inline-grid}");
14421    minify_test(".foo { display: inline grid }", ".foo{display:inline-grid}");
14422    minify_test(".foo { display: ruby }", ".foo{display:ruby}");
14423    minify_test(".foo { display: inline ruby }", ".foo{display:ruby}");
14424    minify_test(".foo { display: block ruby }", ".foo{display:block ruby}");
14425    minify_test(".foo { display: table }", ".foo{display:table}");
14426    minify_test(".foo { display: block table }", ".foo{display:table}");
14427    minify_test(".foo { display: inline-table }", ".foo{display:inline-table}");
14428    minify_test(".foo { display: inline table }", ".foo{display:inline-table}");
14429    minify_test(".foo { display: table-row-group }", ".foo{display:table-row-group}");
14430    minify_test(".foo { display: contents }", ".foo{display:contents}");
14431    minify_test(".foo { display: none }", ".foo{display:none}");
14432    minify_test(".foo { display: -webkit-flex }", ".foo{display:-webkit-flex}");
14433    minify_test(".foo { display: -ms-flexbox }", ".foo{display:-ms-flexbox}");
14434    minify_test(".foo { display: -webkit-box }", ".foo{display:-webkit-box}");
14435    minify_test(".foo { display: -moz-box }", ".foo{display:-moz-box}");
14436    minify_test(
14437      ".foo { display: -webkit-flex; display: -moz-box; display: flex }",
14438      ".foo{display:-webkit-flex;display:-moz-box;display:flex}",
14439    );
14440    minify_test(
14441      ".foo { display: -webkit-flex; display: flex; display: -moz-box }",
14442      ".foo{display:-webkit-flex;display:flex;display:-moz-box}",
14443    );
14444    minify_test(".foo { display: flex; display: grid }", ".foo{display:grid}");
14445    minify_test(
14446      ".foo { display: -webkit-inline-flex; display: -moz-inline-box; display: inline-flex }",
14447      ".foo{display:-webkit-inline-flex;display:-moz-inline-box;display:inline-flex}",
14448    );
14449    minify_test(
14450      ".foo { display: flex; display: var(--grid); }",
14451      ".foo{display:flex;display:var(--grid)}",
14452    );
14453    prefix_test(
14454      ".foo{ display: flex }",
14455      indoc! {r#"
14456      .foo {
14457        display: -webkit-box;
14458        display: -moz-box;
14459        display: -webkit-flex;
14460        display: -ms-flexbox;
14461        display: flex;
14462      }
14463      "#},
14464      Browsers {
14465        safari: Some(4 << 16),
14466        firefox: Some(14 << 16),
14467        ie: Some(10 << 16),
14468        ..Browsers::default()
14469      },
14470    );
14471    prefix_test(
14472      ".foo{ display: flex; display: -webkit-box; }",
14473      indoc! {r#"
14474      .foo {
14475        display: -webkit-box;
14476      }
14477      "#},
14478      Browsers {
14479        safari: Some(4 << 16),
14480        firefox: Some(14 << 16),
14481        ie: Some(10 << 16),
14482        ..Browsers::default()
14483      },
14484    );
14485    prefix_test(
14486      ".foo{ display: -webkit-box; display: flex; }",
14487      indoc! {r#"
14488      .foo {
14489        display: -webkit-box;
14490        display: -moz-box;
14491        display: -webkit-flex;
14492        display: -ms-flexbox;
14493        display: flex;
14494      }
14495      "#},
14496      Browsers {
14497        safari: Some(4 << 16),
14498        firefox: Some(14 << 16),
14499        ie: Some(10 << 16),
14500        ..Browsers::default()
14501      },
14502    );
14503    prefix_test(
14504      r#"
14505      .foo {
14506        display: -webkit-box;
14507        display: -moz-box;
14508        display: -webkit-flex;
14509        display: -ms-flexbox;
14510        display: flex;
14511      }
14512      "#,
14513      indoc! {r#"
14514      .foo {
14515        display: flex;
14516      }
14517      "#},
14518      Browsers {
14519        safari: Some(14 << 16),
14520        ..Browsers::default()
14521      },
14522    );
14523    prefix_test(
14524      r#"
14525      .foo {
14526        display: -webkit-box;
14527        display: flex;
14528        display: -moz-box;
14529        display: -webkit-flex;
14530        display: -ms-flexbox;
14531      }
14532      "#,
14533      indoc! {r#"
14534      .foo {
14535        display: -moz-box;
14536        display: -webkit-flex;
14537        display: -ms-flexbox;
14538      }
14539      "#},
14540      Browsers {
14541        safari: Some(14 << 16),
14542        ..Browsers::default()
14543      },
14544    );
14545    prefix_test(
14546      ".foo{ display: inline-flex }",
14547      indoc! {r#"
14548      .foo {
14549        display: -webkit-inline-box;
14550        display: -moz-inline-box;
14551        display: -webkit-inline-flex;
14552        display: -ms-inline-flexbox;
14553        display: inline-flex;
14554      }
14555      "#},
14556      Browsers {
14557        safari: Some(4 << 16),
14558        firefox: Some(14 << 16),
14559        ie: Some(10 << 16),
14560        ..Browsers::default()
14561      },
14562    );
14563    prefix_test(
14564      r#"
14565      .foo {
14566        display: -webkit-inline-box;
14567        display: -moz-inline-box;
14568        display: -webkit-inline-flex;
14569        display: -ms-inline-flexbox;
14570        display: inline-flex;
14571      }
14572      "#,
14573      indoc! {r#"
14574      .foo {
14575        display: inline-flex;
14576      }
14577      "#},
14578      Browsers {
14579        safari: Some(14 << 16),
14580        ..Browsers::default()
14581      },
14582    );
14583  }
14584
14585  #[test]
14586  fn test_visibility() {
14587    minify_test(".foo { visibility: visible }", ".foo{visibility:visible}");
14588    minify_test(".foo { visibility: hidden }", ".foo{visibility:hidden}");
14589    minify_test(".foo { visibility: collapse }", ".foo{visibility:collapse}");
14590    minify_test(".foo { visibility: Visible }", ".foo{visibility:visible}");
14591  }
14592
14593  #[test]
14594  fn test_text_transform() {
14595    minify_test(".foo { text-transform: uppercase }", ".foo{text-transform:uppercase}");
14596    minify_test(".foo { text-transform: lowercase }", ".foo{text-transform:lowercase}");
14597    minify_test(".foo { text-transform: capitalize }", ".foo{text-transform:capitalize}");
14598    minify_test(".foo { text-transform: none }", ".foo{text-transform:none}");
14599    minify_test(".foo { text-transform: full-width }", ".foo{text-transform:full-width}");
14600    minify_test(
14601      ".foo { text-transform: full-size-kana }",
14602      ".foo{text-transform:full-size-kana}",
14603    );
14604    minify_test(
14605      ".foo { text-transform: uppercase full-width }",
14606      ".foo{text-transform:uppercase full-width}",
14607    );
14608    minify_test(
14609      ".foo { text-transform: full-width uppercase }",
14610      ".foo{text-transform:uppercase full-width}",
14611    );
14612    minify_test(
14613      ".foo { text-transform: uppercase full-width full-size-kana }",
14614      ".foo{text-transform:uppercase full-width full-size-kana}",
14615    );
14616    minify_test(
14617      ".foo { text-transform: full-width uppercase full-size-kana }",
14618      ".foo{text-transform:uppercase full-width full-size-kana}",
14619    );
14620  }
14621
14622  #[test]
14623  fn test_whitespace() {
14624    minify_test(".foo { white-space: normal }", ".foo{white-space:normal}");
14625    minify_test(".foo { white-space: pre }", ".foo{white-space:pre}");
14626    minify_test(".foo { white-space: nowrap }", ".foo{white-space:nowrap}");
14627    minify_test(".foo { white-space: pre-wrap }", ".foo{white-space:pre-wrap}");
14628    minify_test(".foo { white-space: break-spaces }", ".foo{white-space:break-spaces}");
14629    minify_test(".foo { white-space: pre-line }", ".foo{white-space:pre-line}");
14630    minify_test(".foo { white-space: NoWrAp }", ".foo{white-space:nowrap}");
14631  }
14632
14633  #[test]
14634  fn test_tab_size() {
14635    minify_test(".foo { tab-size: 8 }", ".foo{tab-size:8}");
14636    minify_test(".foo { tab-size: 4px }", ".foo{tab-size:4px}");
14637    minify_test(".foo { -moz-tab-size: 4px }", ".foo{-moz-tab-size:4px}");
14638    minify_test(".foo { -o-tab-size: 4px }", ".foo{-o-tab-size:4px}");
14639    prefix_test(
14640      ".foo{ tab-size: 4 }",
14641      indoc! {r#"
14642      .foo {
14643        -moz-tab-size: 4;
14644        -o-tab-size: 4;
14645        tab-size: 4;
14646      }
14647      "#},
14648      Browsers {
14649        safari: Some(8 << 16),
14650        firefox: Some(50 << 16),
14651        opera: Some(12 << 16),
14652        ..Browsers::default()
14653      },
14654    );
14655    prefix_test(
14656      r#"
14657      .foo {
14658        -moz-tab-size: 4;
14659        -o-tab-size: 4;
14660        tab-size: 4;
14661      }
14662      "#,
14663      indoc! {r#"
14664      .foo {
14665        tab-size: 4;
14666      }
14667      "#},
14668      Browsers {
14669        safari: Some(8 << 16),
14670        firefox: Some(94 << 16),
14671        opera: Some(30 << 16),
14672        ..Browsers::default()
14673      },
14674    );
14675  }
14676
14677  #[test]
14678  fn test_word_break() {
14679    minify_test(".foo { word-break: normal }", ".foo{word-break:normal}");
14680    minify_test(".foo { word-break: keep-all }", ".foo{word-break:keep-all}");
14681    minify_test(".foo { word-break: break-all }", ".foo{word-break:break-all}");
14682    minify_test(".foo { word-break: break-word }", ".foo{word-break:break-word}");
14683  }
14684
14685  #[test]
14686  fn test_line_break() {
14687    minify_test(".foo { line-break: auto }", ".foo{line-break:auto}");
14688    minify_test(".foo { line-break: Loose }", ".foo{line-break:loose}");
14689    minify_test(".foo { line-break: anywhere }", ".foo{line-break:anywhere}");
14690  }
14691
14692  #[test]
14693  fn test_wrap() {
14694    minify_test(".foo { overflow-wrap: nOrmal }", ".foo{overflow-wrap:normal}");
14695    minify_test(".foo { overflow-wrap: break-Word }", ".foo{overflow-wrap:break-word}");
14696    minify_test(".foo { overflow-wrap: Anywhere }", ".foo{overflow-wrap:anywhere}");
14697    minify_test(".foo { word-wrap: Normal }", ".foo{word-wrap:normal}");
14698    minify_test(".foo { word-wrap: Break-wOrd }", ".foo{word-wrap:break-word}");
14699    minify_test(".foo { word-wrap: Anywhere }", ".foo{word-wrap:anywhere}");
14700  }
14701
14702  #[test]
14703  fn test_hyphens() {
14704    minify_test(".foo { hyphens: manual }", ".foo{hyphens:manual}");
14705    minify_test(".foo { hyphens: auto }", ".foo{hyphens:auto}");
14706    minify_test(".foo { hyphens: none }", ".foo{hyphens:none}");
14707    minify_test(".foo { -webkit-hyphens: manual }", ".foo{-webkit-hyphens:manual}");
14708    minify_test(".foo { -moz-hyphens: manual }", ".foo{-moz-hyphens:manual}");
14709    minify_test(".foo { -ms-hyphens: manual }", ".foo{-ms-hyphens:manual}");
14710    prefix_test(
14711      ".foo{ hyphens: manual }",
14712      indoc! {r#"
14713      .foo {
14714        -webkit-hyphens: manual;
14715        -moz-hyphens: manual;
14716        -ms-hyphens: manual;
14717        hyphens: manual;
14718      }
14719      "#},
14720      Browsers {
14721        safari: Some(14 << 16),
14722        firefox: Some(40 << 16),
14723        ie: Some(10 << 16),
14724        ..Browsers::default()
14725      },
14726    );
14727    prefix_test(
14728      r#"
14729      .foo {
14730        -webkit-hyphens: manual;
14731        -moz-hyphens: manual;
14732        -ms-hyphens: manual;
14733        hyphens: manual;
14734      }
14735      "#,
14736      indoc! {r#"
14737      .foo {
14738        -webkit-hyphens: manual;
14739        hyphens: manual;
14740      }
14741      "#},
14742      Browsers {
14743        safari: Some(14 << 16),
14744        chrome: Some(88 << 16),
14745        firefox: Some(88 << 16),
14746        edge: Some(79 << 16),
14747        ..Browsers::default()
14748      },
14749    );
14750    prefix_test(
14751      r#"
14752      .foo {
14753        -webkit-hyphens: manual;
14754        -moz-hyphens: manual;
14755        -ms-hyphens: manual;
14756        hyphens: manual;
14757      }
14758      "#,
14759      indoc! {r#"
14760      .foo {
14761        hyphens: manual;
14762      }
14763      "#},
14764      Browsers {
14765        chrome: Some(88 << 16),
14766        firefox: Some(88 << 16),
14767        edge: Some(79 << 16),
14768        ..Browsers::default()
14769      },
14770    );
14771  }
14772
14773  #[test]
14774  fn test_text_align() {
14775    minify_test(".foo { text-align: left }", ".foo{text-align:left}");
14776    minify_test(".foo { text-align: Left }", ".foo{text-align:left}");
14777    minify_test(".foo { text-align: END }", ".foo{text-align:end}");
14778    minify_test(".foo { text-align: left }", ".foo{text-align:left}");
14779
14780    prefix_test(
14781      r#"
14782      .foo {
14783        text-align: start;
14784      }
14785    "#,
14786      indoc! {r#"
14787      .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))) {
14788        text-align: left;
14789      }
14790
14791      .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)) {
14792        text-align: right;
14793      }
14794    "#
14795      },
14796      Browsers {
14797        safari: Some(2 << 16),
14798        ..Browsers::default()
14799      },
14800    );
14801
14802    prefix_test(
14803      r#"
14804      .foo {
14805        text-align: end;
14806      }
14807    "#,
14808      indoc! {r#"
14809      .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))) {
14810        text-align: right;
14811      }
14812
14813      .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)) {
14814        text-align: left;
14815      }
14816    "#
14817      },
14818      Browsers {
14819        safari: Some(2 << 16),
14820        ..Browsers::default()
14821      },
14822    );
14823
14824    prefix_test(
14825      r#"
14826      .foo {
14827        text-align: start;
14828      }
14829    "#,
14830      indoc! {r#"
14831      .foo {
14832        text-align: start;
14833      }
14834    "#
14835      },
14836      Browsers {
14837        safari: Some(14 << 16),
14838        ..Browsers::default()
14839      },
14840    );
14841
14842    prefix_test(
14843      r#"
14844      .foo > .bar {
14845        text-align: start;
14846      }
14847    "#,
14848      indoc! {r#"
14849      .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))) {
14850        text-align: left;
14851      }
14852
14853      .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)) {
14854        text-align: right;
14855      }
14856    "#
14857      },
14858      Browsers {
14859        safari: Some(2 << 16),
14860        ..Browsers::default()
14861      },
14862    );
14863
14864    prefix_test(
14865      r#"
14866      .foo:after {
14867        text-align: start;
14868      }
14869    "#,
14870      indoc! {r#"
14871      .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 {
14872        text-align: left;
14873      }
14874
14875      .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 {
14876        text-align: right;
14877      }
14878    "#
14879      },
14880      Browsers {
14881        safari: Some(2 << 16),
14882        ..Browsers::default()
14883      },
14884    );
14885
14886    prefix_test(
14887      r#"
14888      .foo:hover {
14889        text-align: start;
14890      }
14891    "#,
14892      indoc! {r#"
14893      .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))) {
14894        text-align: left;
14895      }
14896
14897      .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)) {
14898        text-align: right;
14899      }
14900    "#
14901      },
14902      Browsers {
14903        safari: Some(2 << 16),
14904        ..Browsers::default()
14905      },
14906    );
14907  }
14908
14909  #[test]
14910  fn test_text_align_last() {
14911    minify_test(".foo { text-align-last: left }", ".foo{text-align-last:left}");
14912    minify_test(".foo { text-align-last: justify }", ".foo{text-align-last:justify}");
14913    prefix_test(
14914      ".foo{ text-align-last: left }",
14915      indoc! {r#"
14916      .foo {
14917        -moz-text-align-last: left;
14918        text-align-last: left;
14919      }
14920      "#},
14921      Browsers {
14922        firefox: Some(40 << 16),
14923        ..Browsers::default()
14924      },
14925    );
14926    prefix_test(
14927      r#"
14928      .foo {
14929        -moz-text-align-last: left;
14930        text-align-last: left;
14931      }
14932      "#,
14933      indoc! {r#"
14934      .foo {
14935        text-align-last: left;
14936      }
14937      "#},
14938      Browsers {
14939        firefox: Some(88 << 16),
14940        ..Browsers::default()
14941      },
14942    );
14943  }
14944
14945  #[test]
14946  fn test_text_justify() {
14947    minify_test(".foo { text-justify: auto }", ".foo{text-justify:auto}");
14948    minify_test(".foo { text-justify: inter-word }", ".foo{text-justify:inter-word}");
14949  }
14950
14951  #[test]
14952  fn test_word_spacing() {
14953    minify_test(".foo { word-spacing: normal }", ".foo{word-spacing:normal}");
14954    minify_test(".foo { word-spacing: 3px }", ".foo{word-spacing:3px}");
14955  }
14956
14957  #[test]
14958  fn test_letter_spacing() {
14959    minify_test(".foo { letter-spacing: normal }", ".foo{letter-spacing:normal}");
14960    minify_test(".foo { letter-spacing: 3px }", ".foo{letter-spacing:3px}");
14961  }
14962
14963  #[test]
14964  fn test_text_indent() {
14965    minify_test(".foo { text-indent: 20px }", ".foo{text-indent:20px}");
14966    minify_test(".foo { text-indent: 10% }", ".foo{text-indent:10%}");
14967    minify_test(".foo { text-indent: 3em hanging }", ".foo{text-indent:3em hanging}");
14968    minify_test(".foo { text-indent: 3em each-line }", ".foo{text-indent:3em each-line}");
14969    minify_test(
14970      ".foo { text-indent: 3em hanging each-line }",
14971      ".foo{text-indent:3em hanging each-line}",
14972    );
14973    minify_test(
14974      ".foo { text-indent: 3em each-line hanging }",
14975      ".foo{text-indent:3em hanging each-line}",
14976    );
14977    minify_test(
14978      ".foo { text-indent: each-line 3em hanging }",
14979      ".foo{text-indent:3em hanging each-line}",
14980    );
14981    minify_test(
14982      ".foo { text-indent: each-line hanging 3em }",
14983      ".foo{text-indent:3em hanging each-line}",
14984    );
14985  }
14986
14987  #[test]
14988  fn test_text_size_adjust() {
14989    minify_test(".foo { text-size-adjust: none }", ".foo{text-size-adjust:none}");
14990    minify_test(".foo { text-size-adjust: auto }", ".foo{text-size-adjust:auto}");
14991    minify_test(".foo { text-size-adjust: 80% }", ".foo{text-size-adjust:80%}");
14992    prefix_test(
14993      r#"
14994      .foo {
14995        text-size-adjust: none;
14996      }
14997    "#,
14998      indoc! {r#"
14999      .foo {
15000        -webkit-text-size-adjust: none;
15001        -moz-text-size-adjust: none;
15002        -ms-text-size-adjust: none;
15003        text-size-adjust: none;
15004      }
15005    "#},
15006      Browsers {
15007        ios_saf: Some(16 << 16),
15008        edge: Some(15 << 16),
15009        firefox: Some(20 << 16),
15010        ..Browsers::default()
15011      },
15012    );
15013    prefix_test(
15014      r#"
15015      .foo {
15016        -webkit-text-size-adjust: none;
15017        -moz-text-size-adjust: none;
15018        -ms-text-size-adjust: none;
15019        text-size-adjust: none;
15020      }
15021    "#,
15022      indoc! {r#"
15023      .foo {
15024        text-size-adjust: none;
15025      }
15026    "#},
15027      Browsers {
15028        chrome: Some(110 << 16),
15029        ..Browsers::default()
15030      },
15031    );
15032  }
15033
15034  #[test]
15035  fn test_text_decoration() {
15036    minify_test(".foo { text-decoration-line: none }", ".foo{text-decoration-line:none}");
15037    minify_test(
15038      ".foo { text-decoration-line: underline }",
15039      ".foo{text-decoration-line:underline}",
15040    );
15041    minify_test(
15042      ".foo { text-decoration-line: overline }",
15043      ".foo{text-decoration-line:overline}",
15044    );
15045    minify_test(
15046      ".foo { text-decoration-line: line-through }",
15047      ".foo{text-decoration-line:line-through}",
15048    );
15049    minify_test(
15050      ".foo { text-decoration-line: blink }",
15051      ".foo{text-decoration-line:blink}",
15052    );
15053    minify_test(
15054      ".foo { text-decoration-line: underline overline }",
15055      ".foo{text-decoration-line:underline overline}",
15056    );
15057    minify_test(
15058      ".foo { text-decoration-line: overline underline }",
15059      ".foo{text-decoration-line:underline overline}",
15060    );
15061    minify_test(
15062      ".foo { text-decoration-line: overline line-through underline }",
15063      ".foo{text-decoration-line:underline overline line-through}",
15064    );
15065    minify_test(
15066      ".foo { text-decoration-line: spelling-error }",
15067      ".foo{text-decoration-line:spelling-error}",
15068    );
15069    minify_test(
15070      ".foo { text-decoration-line: grammar-error }",
15071      ".foo{text-decoration-line:grammar-error}",
15072    );
15073    minify_test(
15074      ".foo { -webkit-text-decoration-line: overline underline }",
15075      ".foo{-webkit-text-decoration-line:underline overline}",
15076    );
15077    minify_test(
15078      ".foo { -moz-text-decoration-line: overline underline }",
15079      ".foo{-moz-text-decoration-line:underline overline}",
15080    );
15081
15082    minify_test(
15083      ".foo { text-decoration-style: solid }",
15084      ".foo{text-decoration-style:solid}",
15085    );
15086    minify_test(
15087      ".foo { text-decoration-style: dotted }",
15088      ".foo{text-decoration-style:dotted}",
15089    );
15090    minify_test(
15091      ".foo { -webkit-text-decoration-style: solid }",
15092      ".foo{-webkit-text-decoration-style:solid}",
15093    );
15094
15095    minify_test(
15096      ".foo { text-decoration-color: yellow }",
15097      ".foo{text-decoration-color:#ff0}",
15098    );
15099    minify_test(
15100      ".foo { -webkit-text-decoration-color: yellow }",
15101      ".foo{-webkit-text-decoration-color:#ff0}",
15102    );
15103
15104    minify_test(".foo { text-decoration: none }", ".foo{text-decoration:none}");
15105    minify_test(
15106      ".foo { text-decoration: underline dotted }",
15107      ".foo{text-decoration:underline dotted}",
15108    );
15109    minify_test(
15110      ".foo { text-decoration: underline dotted yellow }",
15111      ".foo{text-decoration:underline dotted #ff0}",
15112    );
15113    minify_test(
15114      ".foo { text-decoration: yellow dotted underline }",
15115      ".foo{text-decoration:underline dotted #ff0}",
15116    );
15117    minify_test(
15118      ".foo { text-decoration: underline overline dotted yellow }",
15119      ".foo{text-decoration:underline overline dotted #ff0}",
15120    );
15121    minify_test(
15122      ".foo { -webkit-text-decoration: yellow dotted underline }",
15123      ".foo{-webkit-text-decoration:underline dotted #ff0}",
15124    );
15125    minify_test(
15126      ".foo { -moz-text-decoration: yellow dotted underline }",
15127      ".foo{-moz-text-decoration:underline dotted #ff0}",
15128    );
15129
15130    test(
15131      r#"
15132      .foo {
15133        text-decoration-line: underline;
15134        text-decoration-style: dotted;
15135        text-decoration-color: yellow;
15136        text-decoration-thickness: 2px;
15137      }
15138    "#,
15139      indoc! {r#"
15140      .foo {
15141        text-decoration: underline 2px dotted #ff0;
15142      }
15143    "#},
15144    );
15145
15146    test(
15147      r#"
15148      .foo {
15149        text-decoration: underline;
15150        text-decoration-style: dotted;
15151      }
15152    "#,
15153      indoc! {r#"
15154      .foo {
15155        text-decoration: underline dotted;
15156      }
15157    "#},
15158    );
15159
15160    test(
15161      r#"
15162      .foo {
15163        text-decoration: underline;
15164        text-decoration-style: var(--style);
15165      }
15166    "#,
15167      indoc! {r#"
15168      .foo {
15169        text-decoration: underline;
15170        text-decoration-style: var(--style);
15171      }
15172    "#},
15173    );
15174
15175    test(
15176      r#"
15177      .foo {
15178        -webkit-text-decoration: underline;
15179        -webkit-text-decoration-style: dotted;
15180      }
15181    "#,
15182      indoc! {r#"
15183      .foo {
15184        -webkit-text-decoration: underline dotted;
15185      }
15186    "#},
15187    );
15188
15189    prefix_test(
15190      r#"
15191      .foo {
15192        text-decoration: underline dotted;
15193      }
15194    "#,
15195      indoc! {r#"
15196      .foo {
15197        -webkit-text-decoration: underline dotted;
15198        text-decoration: underline dotted;
15199      }
15200    "#},
15201      Browsers {
15202        safari: Some(8 << 16),
15203        firefox: Some(30 << 16),
15204        ..Browsers::default()
15205      },
15206    );
15207
15208    prefix_test(
15209      r#"
15210      .foo {
15211        text-decoration-line: underline;
15212      }
15213    "#,
15214      indoc! {r#"
15215      .foo {
15216        -webkit-text-decoration-line: underline;
15217        -moz-text-decoration-line: underline;
15218        text-decoration-line: underline;
15219      }
15220    "#},
15221      Browsers {
15222        safari: Some(8 << 16),
15223        firefox: Some(30 << 16),
15224        ..Browsers::default()
15225      },
15226    );
15227
15228    prefix_test(
15229      r#"
15230      .foo {
15231        text-decoration-style: dotted;
15232      }
15233    "#,
15234      indoc! {r#"
15235      .foo {
15236        -webkit-text-decoration-style: dotted;
15237        -moz-text-decoration-style: dotted;
15238        text-decoration-style: dotted;
15239      }
15240    "#},
15241      Browsers {
15242        safari: Some(8 << 16),
15243        firefox: Some(30 << 16),
15244        ..Browsers::default()
15245      },
15246    );
15247
15248    prefix_test(
15249      r#"
15250      .foo {
15251        text-decoration-color: yellow;
15252      }
15253    "#,
15254      indoc! {r#"
15255      .foo {
15256        -webkit-text-decoration-color: #ff0;
15257        -moz-text-decoration-color: #ff0;
15258        text-decoration-color: #ff0;
15259      }
15260    "#},
15261      Browsers {
15262        safari: Some(8 << 16),
15263        firefox: Some(30 << 16),
15264        ..Browsers::default()
15265      },
15266    );
15267
15268    prefix_test(
15269      r#"
15270      .foo {
15271        text-decoration: underline;
15272      }
15273    "#,
15274      indoc! {r#"
15275      .foo {
15276        text-decoration: underline;
15277      }
15278    "#},
15279      Browsers {
15280        safari: Some(8 << 16),
15281        firefox: Some(30 << 16),
15282        ..Browsers::default()
15283      },
15284    );
15285
15286    prefix_test(
15287      r#"
15288      .foo {
15289        -webkit-text-decoration: underline dotted;
15290        text-decoration: underline dotted;
15291      }
15292    "#,
15293      indoc! {r#"
15294      .foo {
15295        -webkit-text-decoration: underline dotted;
15296        text-decoration: underline dotted;
15297      }
15298    "#},
15299      Browsers {
15300        safari: Some(14 << 16),
15301        firefox: Some(45 << 16),
15302        ..Browsers::default()
15303      },
15304    );
15305
15306    prefix_test(
15307      r#"
15308      .foo {
15309        text-decoration: double underline;
15310      }
15311    "#,
15312      indoc! {r#"
15313      .foo {
15314        -webkit-text-decoration: underline double;
15315        text-decoration: underline double;
15316      }
15317    "#},
15318      Browsers {
15319        safari: Some(16 << 16),
15320        ..Browsers::default()
15321      },
15322    );
15323
15324    prefix_test(
15325      r#"
15326      .foo {
15327        text-decoration: underline;
15328        text-decoration-style: double;
15329      }
15330    "#,
15331      indoc! {r#"
15332      .foo {
15333        -webkit-text-decoration: underline double;
15334        text-decoration: underline double;
15335      }
15336    "#},
15337      Browsers {
15338        safari: Some(16 << 16),
15339        ..Browsers::default()
15340      },
15341    );
15342
15343    prefix_test(
15344      r#"
15345      .foo {
15346        text-decoration: underline;
15347        text-decoration-color: red;
15348      }
15349    "#,
15350      indoc! {r#"
15351      .foo {
15352        -webkit-text-decoration: underline red;
15353        text-decoration: underline red;
15354      }
15355    "#},
15356      Browsers {
15357        safari: Some(16 << 16),
15358        ..Browsers::default()
15359      },
15360    );
15361
15362    prefix_test(
15363      r#"
15364      .foo {
15365        text-decoration: var(--test);
15366      }
15367    "#,
15368      indoc! {r#"
15369      .foo {
15370        -webkit-text-decoration: var(--test);
15371        text-decoration: var(--test);
15372      }
15373    "#},
15374      Browsers {
15375        safari: Some(8 << 16),
15376        firefox: Some(30 << 16),
15377        ..Browsers::default()
15378      },
15379    );
15380
15381    minify_test(
15382      ".foo { text-decoration-skip-ink: all }",
15383      ".foo{text-decoration-skip-ink:all}",
15384    );
15385    minify_test(
15386      ".foo { -webkit-text-decoration-skip-ink: all }",
15387      ".foo{-webkit-text-decoration-skip-ink:all}",
15388    );
15389
15390    prefix_test(
15391      r#"
15392      .foo {
15393        text-decoration: lch(50.998% 135.363 338) underline;
15394      }
15395    "#,
15396      indoc! {r#"
15397      .foo {
15398        -webkit-text-decoration: underline #ee00be;
15399        text-decoration: underline #ee00be;
15400        -webkit-text-decoration: underline lch(50.998% 135.363 338);
15401        text-decoration: underline lch(50.998% 135.363 338);
15402      }
15403    "#},
15404      Browsers {
15405        safari: Some(8 << 16),
15406        firefox: Some(30 << 16),
15407        ..Browsers::default()
15408      },
15409    );
15410
15411    prefix_test(
15412      r#"
15413      .foo {
15414        text-decoration-color: lch(50.998% 135.363 338);
15415      }
15416    "#,
15417      indoc! {r#"
15418      .foo {
15419        -webkit-text-decoration-color: #ee00be;
15420        -moz-text-decoration-color: #ee00be;
15421        text-decoration-color: #ee00be;
15422        -webkit-text-decoration-color: lch(50.998% 135.363 338);
15423        -moz-text-decoration-color: lch(50.998% 135.363 338);
15424        text-decoration-color: lch(50.998% 135.363 338);
15425      }
15426    "#},
15427      Browsers {
15428        safari: Some(8 << 16),
15429        firefox: Some(30 << 16),
15430        ..Browsers::default()
15431      },
15432    );
15433
15434    prefix_test(
15435      r#"
15436      .foo {
15437        text-decoration: lch(50.998% 135.363 338) var(--style);
15438      }
15439    "#,
15440      indoc! {r#"
15441      .foo {
15442        text-decoration: #ee00be var(--style);
15443      }
15444
15445      @supports (color: lab(0% 0 0)) {
15446        .foo {
15447          text-decoration: lab(50.998% 125.506 -50.7078) var(--style);
15448        }
15449      }
15450    "#},
15451      Browsers {
15452        chrome: Some(90 << 16),
15453        ..Browsers::default()
15454      },
15455    );
15456
15457    prefix_test(
15458      r#"
15459      .foo {
15460        text-decoration: underline 10px;
15461      }
15462    "#,
15463      indoc! {r#"
15464      .foo {
15465        text-decoration: underline;
15466        text-decoration-thickness: 10px;
15467      }
15468    "#},
15469      Browsers {
15470        safari: Some(15 << 16),
15471        ..Browsers::default()
15472      },
15473    );
15474
15475    prefix_test(
15476      r#"
15477      .foo {
15478        text-decoration: underline 10px;
15479      }
15480    "#,
15481      indoc! {r#"
15482      .foo {
15483        text-decoration: underline 10px;
15484      }
15485    "#},
15486      Browsers {
15487        chrome: Some(90 << 16),
15488        ..Browsers::default()
15489      },
15490    );
15491
15492    prefix_test(
15493      r#"
15494      .foo {
15495        text-decoration: underline 10%;
15496      }
15497    "#,
15498      indoc! {r#"
15499      .foo {
15500        text-decoration: underline;
15501        text-decoration-thickness: calc(1em / 10);
15502      }
15503    "#},
15504      Browsers {
15505        safari: Some(12 << 16),
15506        ..Browsers::default()
15507      },
15508    );
15509
15510    prefix_test(
15511      r#"
15512      .foo {
15513        text-decoration: underline 10%;
15514      }
15515    "#,
15516      indoc! {r#"
15517      .foo {
15518        text-decoration: underline 10%;
15519      }
15520    "#},
15521      Browsers {
15522        firefox: Some(89 << 16),
15523        ..Browsers::default()
15524      },
15525    );
15526
15527    prefix_test(
15528      r#"
15529      .foo {
15530        text-decoration-thickness: 10%;
15531      }
15532    "#,
15533      indoc! {r#"
15534      .foo {
15535        text-decoration-thickness: calc(1em / 10);
15536      }
15537    "#},
15538      Browsers {
15539        safari: Some(12 << 16),
15540        ..Browsers::default()
15541      },
15542    );
15543
15544    prefix_test(
15545      r#"
15546      .foo {
15547        text-decoration-thickness: 10%;
15548      }
15549    "#,
15550      indoc! {r#"
15551      .foo {
15552        text-decoration-thickness: 10%;
15553      }
15554    "#},
15555      Browsers {
15556        firefox: Some(89 << 16),
15557        ..Browsers::default()
15558      },
15559    );
15560  }
15561
15562  #[test]
15563  fn test_text_emphasis() {
15564    minify_test(".foo { text-emphasis-style: none }", ".foo{text-emphasis-style:none}");
15565    minify_test(
15566      ".foo { text-emphasis-style: filled }",
15567      ".foo{text-emphasis-style:filled}",
15568    );
15569    minify_test(".foo { text-emphasis-style: open }", ".foo{text-emphasis-style:open}");
15570    minify_test(".foo { text-emphasis-style: dot }", ".foo{text-emphasis-style:dot}");
15571    minify_test(
15572      ".foo { text-emphasis-style: filled dot }",
15573      ".foo{text-emphasis-style:dot}",
15574    );
15575    minify_test(
15576      ".foo { text-emphasis-style: dot filled }",
15577      ".foo{text-emphasis-style:dot}",
15578    );
15579    minify_test(
15580      ".foo { text-emphasis-style: open dot }",
15581      ".foo{text-emphasis-style:open dot}",
15582    );
15583    minify_test(
15584      ".foo { text-emphasis-style: dot open }",
15585      ".foo{text-emphasis-style:open dot}",
15586    );
15587    minify_test(".foo { text-emphasis-style: \"x\" }", ".foo{text-emphasis-style:\"x\"}");
15588
15589    minify_test(".foo { text-emphasis-color: yellow }", ".foo{text-emphasis-color:#ff0}");
15590
15591    minify_test(".foo { text-emphasis: none }", ".foo{text-emphasis:none}");
15592    minify_test(".foo { text-emphasis: filled }", ".foo{text-emphasis:filled}");
15593    minify_test(
15594      ".foo { text-emphasis: filled yellow }",
15595      ".foo{text-emphasis:filled #ff0}",
15596    );
15597    minify_test(
15598      ".foo { text-emphasis: dot filled yellow }",
15599      ".foo{text-emphasis:dot #ff0}",
15600    );
15601
15602    test(
15603      r#"
15604      .foo {
15605        text-emphasis-style: filled;
15606        text-emphasis-color: yellow;
15607      }
15608    "#,
15609      indoc! {r#"
15610      .foo {
15611        text-emphasis: filled #ff0;
15612      }
15613    "#},
15614    );
15615
15616    test(
15617      r#"
15618      .foo {
15619        text-emphasis: filled red;
15620        text-emphasis-color: yellow;
15621      }
15622    "#,
15623      indoc! {r#"
15624      .foo {
15625        text-emphasis: filled #ff0;
15626      }
15627    "#},
15628    );
15629
15630    test(
15631      r#"
15632      .foo {
15633        text-emphasis: filled yellow;
15634        text-emphasis-color: var(--color);
15635      }
15636    "#,
15637      indoc! {r#"
15638      .foo {
15639        text-emphasis: filled #ff0;
15640        text-emphasis-color: var(--color);
15641      }
15642    "#},
15643    );
15644
15645    prefix_test(
15646      r#"
15647      .foo {
15648        text-emphasis-style: filled;
15649      }
15650    "#,
15651      indoc! {r#"
15652      .foo {
15653        -webkit-text-emphasis-style: filled;
15654        text-emphasis-style: filled;
15655      }
15656    "#},
15657      Browsers {
15658        safari: Some(10 << 16),
15659        chrome: Some(30 << 16),
15660        firefox: Some(45 << 16),
15661        ..Browsers::default()
15662      },
15663    );
15664
15665    prefix_test(
15666      r#"
15667      .foo {
15668        -webkit-text-emphasis-style: filled;
15669        text-emphasis-style: filled;
15670      }
15671    "#,
15672      indoc! {r#"
15673      .foo {
15674        text-emphasis-style: filled;
15675      }
15676    "#},
15677      Browsers {
15678        safari: Some(10 << 16),
15679        firefox: Some(45 << 16),
15680        ..Browsers::default()
15681      },
15682    );
15683
15684    minify_test(
15685      ".foo { text-emphasis-position: over }",
15686      ".foo{text-emphasis-position:over}",
15687    );
15688    minify_test(
15689      ".foo { text-emphasis-position: under }",
15690      ".foo{text-emphasis-position:under}",
15691    );
15692    minify_test(
15693      ".foo { text-emphasis-position: over right }",
15694      ".foo{text-emphasis-position:over}",
15695    );
15696    minify_test(
15697      ".foo { text-emphasis-position: over left }",
15698      ".foo{text-emphasis-position:over left}",
15699    );
15700
15701    prefix_test(
15702      r#"
15703      .foo {
15704        text-emphasis-position: over;
15705      }
15706    "#,
15707      indoc! {r#"
15708      .foo {
15709        -webkit-text-emphasis-position: over;
15710        text-emphasis-position: over;
15711      }
15712    "#},
15713      Browsers {
15714        safari: Some(10 << 16),
15715        chrome: Some(30 << 16),
15716        firefox: Some(45 << 16),
15717        ..Browsers::default()
15718      },
15719    );
15720
15721    prefix_test(
15722      r#"
15723      .foo {
15724        text-emphasis-position: over left;
15725      }
15726    "#,
15727      indoc! {r#"
15728      .foo {
15729        text-emphasis-position: over left;
15730      }
15731    "#},
15732      Browsers {
15733        safari: Some(10 << 16),
15734        chrome: Some(30 << 16),
15735        firefox: Some(45 << 16),
15736        ..Browsers::default()
15737      },
15738    );
15739
15740    prefix_test(
15741      r#"
15742      .foo {
15743        text-emphasis-position: var(--test);
15744      }
15745    "#,
15746      indoc! {r#"
15747      .foo {
15748        -webkit-text-emphasis-position: var(--test);
15749        text-emphasis-position: var(--test);
15750      }
15751    "#},
15752      Browsers {
15753        safari: Some(10 << 16),
15754        chrome: Some(30 << 16),
15755        firefox: Some(45 << 16),
15756        ..Browsers::default()
15757      },
15758    );
15759
15760    prefix_test(
15761      r#"
15762      .foo {
15763        text-emphasis: filled lch(50.998% 135.363 338);
15764      }
15765    "#,
15766      indoc! {r#"
15767      .foo {
15768        -webkit-text-emphasis: filled #ee00be;
15769        text-emphasis: filled #ee00be;
15770        -webkit-text-emphasis: filled lch(50.998% 135.363 338);
15771        text-emphasis: filled lch(50.998% 135.363 338);
15772      }
15773    "#},
15774      Browsers {
15775        chrome: Some(25 << 16),
15776        firefox: Some(48 << 16),
15777        ..Browsers::default()
15778      },
15779    );
15780
15781    prefix_test(
15782      r#"
15783      .foo {
15784        text-emphasis-color: lch(50.998% 135.363 338);
15785      }
15786    "#,
15787      indoc! {r#"
15788      .foo {
15789        -webkit-text-emphasis-color: #ee00be;
15790        text-emphasis-color: #ee00be;
15791        -webkit-text-emphasis-color: lch(50.998% 135.363 338);
15792        text-emphasis-color: lch(50.998% 135.363 338);
15793      }
15794    "#},
15795      Browsers {
15796        chrome: Some(25 << 16),
15797        firefox: Some(48 << 16),
15798        ..Browsers::default()
15799      },
15800    );
15801
15802    prefix_test(
15803      r#"
15804      .foo {
15805        text-emphasis: lch(50.998% 135.363 338) var(--style);
15806      }
15807    "#,
15808      indoc! {r#"
15809      .foo {
15810        text-emphasis: #ee00be var(--style);
15811      }
15812
15813      @supports (color: lab(0% 0 0)) {
15814        .foo {
15815          text-emphasis: lab(50.998% 125.506 -50.7078) var(--style);
15816        }
15817      }
15818    "#},
15819      Browsers {
15820        safari: Some(8 << 16),
15821        ..Browsers::default()
15822      },
15823    );
15824  }
15825
15826  #[test]
15827  fn test_text_shadow() {
15828    minify_test(
15829      ".foo { text-shadow: 1px 1px 2px yellow; }",
15830      ".foo{text-shadow:1px 1px 2px #ff0}",
15831    );
15832    minify_test(
15833      ".foo { text-shadow: 1px 1px 2px 3px yellow; }",
15834      ".foo{text-shadow:1px 1px 2px 3px #ff0}",
15835    );
15836    minify_test(
15837      ".foo { text-shadow: 1px 1px 0 yellow; }",
15838      ".foo{text-shadow:1px 1px #ff0}",
15839    );
15840    minify_test(
15841      ".foo { text-shadow: 1px 1px yellow; }",
15842      ".foo{text-shadow:1px 1px #ff0}",
15843    );
15844    minify_test(
15845      ".foo { text-shadow: 1px 1px yellow, 2px 3px red; }",
15846      ".foo{text-shadow:1px 1px #ff0,2px 3px red}",
15847    );
15848
15849    prefix_test(
15850      ".foo { text-shadow: 12px 12px lab(40% 56.6 39) }",
15851      indoc! { r#"
15852        .foo {
15853          text-shadow: 12px 12px #b32323;
15854          text-shadow: 12px 12px lab(40% 56.6 39);
15855        }
15856      "#},
15857      Browsers {
15858        chrome: Some(4 << 16),
15859        ..Browsers::default()
15860      },
15861    );
15862
15863    prefix_test(
15864      ".foo { text-shadow: 12px 12px lab(40% 56.6 39) }",
15865      indoc! { r#"
15866        .foo {
15867          text-shadow: 12px 12px #b32323;
15868          text-shadow: 12px 12px color(display-p3 .643308 .192455 .167712);
15869          text-shadow: 12px 12px lab(40% 56.6 39);
15870        }
15871      "#},
15872      Browsers {
15873        chrome: Some(90 << 16),
15874        safari: Some(14 << 16),
15875        ..Browsers::default()
15876      },
15877    );
15878
15879    prefix_test(
15880      ".foo { text-shadow: 12px 12px lab(40% 56.6 39), 12px 12px yellow }",
15881      indoc! { r#"
15882        .foo {
15883          text-shadow: 12px 12px #b32323, 12px 12px #ff0;
15884          text-shadow: 12px 12px lab(40% 56.6 39), 12px 12px #ff0;
15885        }
15886      "#},
15887      Browsers {
15888        chrome: Some(4 << 16),
15889        ..Browsers::default()
15890      },
15891    );
15892
15893    prefix_test(
15894      ".foo { text-shadow: var(--foo) 12px lab(40% 56.6 39) }",
15895      indoc! { r#"
15896        .foo {
15897          text-shadow: var(--foo) 12px #b32323;
15898        }
15899
15900        @supports (color: lab(0% 0 0)) {
15901          .foo {
15902            text-shadow: var(--foo) 12px lab(40% 56.6 39);
15903          }
15904        }
15905      "#},
15906      Browsers {
15907        chrome: Some(4 << 16),
15908        ..Browsers::default()
15909      },
15910    );
15911  }
15912
15913  #[test]
15914  fn test_break() {
15915    prefix_test(
15916      r#"
15917      .foo {
15918        box-decoration-break: clone;
15919      }
15920    "#,
15921      indoc! {r#"
15922      .foo {
15923        -webkit-box-decoration-break: clone;
15924        box-decoration-break: clone;
15925      }
15926    "#},
15927      Browsers {
15928        safari: Some(15 << 16),
15929        ..Browsers::default()
15930      },
15931    );
15932
15933    prefix_test(
15934      r#"
15935      .foo {
15936        box-decoration-break: clone;
15937      }
15938    "#,
15939      indoc! {r#"
15940      .foo {
15941        box-decoration-break: clone;
15942      }
15943    "#},
15944      Browsers {
15945        firefox: Some(95 << 16),
15946        ..Browsers::default()
15947      },
15948    );
15949  }
15950
15951  #[test]
15952  fn test_position() {
15953    test(
15954      r#"
15955      .foo {
15956        position: relative;
15957        position: absolute;
15958      }
15959    "#,
15960      indoc! {r#"
15961      .foo {
15962        position: absolute;
15963      }
15964    "#},
15965    );
15966
15967    test(
15968      r#"
15969      .foo {
15970        position: -webkit-sticky;
15971        position: sticky;
15972      }
15973    "#,
15974      indoc! {r#"
15975      .foo {
15976        position: -webkit-sticky;
15977        position: sticky;
15978      }
15979    "#},
15980    );
15981
15982    prefix_test(
15983      r#"
15984      .foo {
15985        position: sticky;
15986      }
15987    "#,
15988      indoc! {r#"
15989      .foo {
15990        position: -webkit-sticky;
15991        position: sticky;
15992      }
15993    "#},
15994      Browsers {
15995        safari: Some(8 << 16),
15996        ..Browsers::default()
15997      },
15998    );
15999
16000    prefix_test(
16001      r#"
16002      .foo {
16003        position: -webkit-sticky;
16004        position: sticky;
16005      }
16006    "#,
16007      indoc! {r#"
16008      .foo {
16009        position: sticky;
16010      }
16011    "#},
16012      Browsers {
16013        safari: Some(13 << 16),
16014        ..Browsers::default()
16015      },
16016    );
16017
16018    test(
16019      r#"
16020      .foo {
16021        top: 0;
16022        left: 0;
16023        bottom: 0;
16024        right: 0;
16025      }
16026    "#,
16027      indoc! {r#"
16028      .foo {
16029        inset: 0;
16030      }
16031    "#},
16032    );
16033
16034    test(
16035      r#"
16036      .foo {
16037        top: 2px;
16038        left: 4px;
16039        bottom: 2px;
16040        right: 4px;
16041      }
16042    "#,
16043      indoc! {r#"
16044      .foo {
16045        inset: 2px 4px;
16046      }
16047    "#},
16048    );
16049
16050    test(
16051      r#"
16052      .foo {
16053        top: 1px;
16054        left: 2px;
16055        bottom: 3px;
16056        right: 4px;
16057      }
16058    "#,
16059      indoc! {r#"
16060      .foo {
16061        inset: 1px 4px 3px 2px;
16062      }
16063    "#},
16064    );
16065
16066    test(
16067      r#"
16068      .foo {
16069        inset-block-start: 2px;
16070        inset-block-end: 2px;
16071        inset-inline-start: 4px;
16072        inset-inline-end: 4px;
16073      }
16074    "#,
16075      indoc! {r#"
16076      .foo {
16077        inset-block: 2px;
16078        inset-inline: 4px;
16079      }
16080    "#},
16081    );
16082
16083    test(
16084      r#"
16085      .foo {
16086        inset-block-start: 2px;
16087        inset-block-end: 3px;
16088        inset-inline-start: 4px;
16089        inset-inline-end: 5px;
16090      }
16091    "#,
16092      indoc! {r#"
16093      .foo {
16094        inset-block: 2px 3px;
16095        inset-inline: 4px 5px;
16096      }
16097    "#},
16098    );
16099
16100    test(
16101      r#"
16102      .foo {
16103        inset-block-start: 2px;
16104        inset-block-end: 3px;
16105        inset: 4px;
16106        inset-inline-start: 4px;
16107        inset-inline-end: 5px;
16108      }
16109    "#,
16110      indoc! {r#"
16111      .foo {
16112        inset: 4px;
16113        inset-inline: 4px 5px;
16114      }
16115    "#},
16116    );
16117
16118    prefix_test(
16119      r#"
16120      .foo {
16121        inset-inline-start: 2px;
16122      }
16123    "#,
16124      indoc! {r#"
16125      .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))) {
16126        left: 2px;
16127      }
16128
16129      .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))) {
16130        left: 2px;
16131      }
16132
16133      .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)) {
16134        right: 2px;
16135      }
16136
16137      .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)) {
16138        right: 2px;
16139      }
16140    "#
16141      },
16142      Browsers {
16143        safari: Some(8 << 16),
16144        ..Browsers::default()
16145      },
16146    );
16147
16148    prefix_test(
16149      r#"
16150      .foo {
16151        inset-inline-start: 2px;
16152        inset-inline-end: 4px;
16153      }
16154    "#,
16155      indoc! {r#"
16156      .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))) {
16157        left: 2px;
16158        right: 4px;
16159      }
16160
16161      .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))) {
16162        left: 2px;
16163        right: 4px;
16164      }
16165
16166      .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)) {
16167        left: 4px;
16168        right: 2px;
16169      }
16170
16171      .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)) {
16172        left: 4px;
16173        right: 2px;
16174      }
16175    "#
16176      },
16177      Browsers {
16178        safari: Some(8 << 16),
16179        ..Browsers::default()
16180      },
16181    );
16182
16183    prefix_test(
16184      r#"
16185      .foo {
16186        inset-inline: 2px;
16187      }
16188    "#,
16189      indoc! {r#"
16190      .foo {
16191        left: 2px;
16192        right: 2px;
16193      }
16194    "#
16195      },
16196      Browsers {
16197        safari: Some(8 << 16),
16198        ..Browsers::default()
16199      },
16200    );
16201
16202    prefix_test(
16203      r#"
16204      .foo {
16205        inset-block-start: 2px;
16206      }
16207    "#,
16208      indoc! {r#"
16209      .foo {
16210        top: 2px;
16211      }
16212    "#
16213      },
16214      Browsers {
16215        safari: Some(8 << 16),
16216        ..Browsers::default()
16217      },
16218    );
16219
16220    prefix_test(
16221      r#"
16222      .foo {
16223        inset-block-end: 2px;
16224      }
16225    "#,
16226      indoc! {r#"
16227      .foo {
16228        bottom: 2px;
16229      }
16230    "#
16231      },
16232      Browsers {
16233        safari: Some(8 << 16),
16234        ..Browsers::default()
16235      },
16236    );
16237
16238    prefix_test(
16239      r#"
16240      .foo {
16241        top: 1px;
16242        left: 2px;
16243        bottom: 3px;
16244        right: 4px;
16245      }
16246    "#,
16247      indoc! {r#"
16248      .foo {
16249        top: 1px;
16250        bottom: 3px;
16251        left: 2px;
16252        right: 4px;
16253      }
16254    "#},
16255      Browsers {
16256        safari: Some(8 << 16),
16257        ..Browsers::default()
16258      },
16259    );
16260  }
16261
16262  #[test]
16263  fn test_overflow() {
16264    minify_test(".foo { overflow: hidden }", ".foo{overflow:hidden}");
16265    minify_test(".foo { overflow: hidden hidden }", ".foo{overflow:hidden}");
16266    minify_test(".foo { overflow: hidden auto }", ".foo{overflow:hidden auto}");
16267
16268    test(
16269      r#"
16270      .foo {
16271        overflow-x: hidden;
16272        overflow-y: auto;
16273      }
16274    "#,
16275      indoc! {r#"
16276      .foo {
16277        overflow: hidden auto;
16278      }
16279    "#},
16280    );
16281
16282    test(
16283      r#"
16284      .foo {
16285        overflow: hidden;
16286        overflow-y: auto;
16287      }
16288    "#,
16289      indoc! {r#"
16290      .foo {
16291        overflow: hidden auto;
16292      }
16293    "#},
16294    );
16295    test(
16296      r#"
16297      .foo {
16298        overflow: hidden;
16299        overflow-y: var(--y);
16300      }
16301    "#,
16302      indoc! {r#"
16303      .foo {
16304        overflow: hidden;
16305        overflow-y: var(--y);
16306      }
16307    "#},
16308    );
16309    prefix_test(
16310      r#"
16311      .foo {
16312        overflow: hidden auto;
16313      }
16314    "#,
16315      indoc! {r#"
16316      .foo {
16317        overflow-x: hidden;
16318        overflow-y: auto;
16319      }
16320    "#},
16321      Browsers {
16322        chrome: Some(67 << 16),
16323        ..Browsers::default()
16324      },
16325    );
16326    prefix_test(
16327      r#"
16328      .foo {
16329        overflow: hidden hidden;
16330      }
16331    "#,
16332      indoc! {r#"
16333      .foo {
16334        overflow: hidden;
16335      }
16336    "#},
16337      Browsers {
16338        chrome: Some(67 << 16),
16339        ..Browsers::default()
16340      },
16341    );
16342    prefix_test(
16343      r#"
16344      .foo {
16345        overflow: hidden auto;
16346      }
16347    "#,
16348      indoc! {r#"
16349      .foo {
16350        overflow: hidden auto;
16351      }
16352    "#},
16353      Browsers {
16354        chrome: Some(68 << 16),
16355        ..Browsers::default()
16356      },
16357    );
16358
16359    minify_test(".foo { text-overflow: ellipsis }", ".foo{text-overflow:ellipsis}");
16360    prefix_test(
16361      r#"
16362      .foo {
16363        text-overflow: ellipsis;
16364      }
16365    "#,
16366      indoc! {r#"
16367      .foo {
16368        -o-text-overflow: ellipsis;
16369        text-overflow: ellipsis;
16370      }
16371    "#},
16372      Browsers {
16373        safari: Some(4 << 16),
16374        opera: Some(10 << 16),
16375        ..Browsers::default()
16376      },
16377    );
16378
16379    prefix_test(
16380      r#"
16381      .foo {
16382        -o-text-overflow: ellipsis;
16383        text-overflow: ellipsis;
16384      }
16385    "#,
16386      indoc! {r#"
16387      .foo {
16388        text-overflow: ellipsis;
16389      }
16390    "#},
16391      Browsers {
16392        safari: Some(4 << 16),
16393        opera: Some(14 << 16),
16394        ..Browsers::default()
16395      },
16396    );
16397  }
16398
16399  #[test]
16400  fn test_ui() {
16401    minify_test(".foo { resize: both }", ".foo{resize:both}");
16402    minify_test(".foo { resize: Horizontal }", ".foo{resize:horizontal}");
16403    minify_test(".foo { cursor: ew-resize }", ".foo{cursor:ew-resize}");
16404    minify_test(
16405      ".foo { cursor: url(\"test.cur\"), ew-resize }",
16406      ".foo{cursor:url(test.cur),ew-resize}",
16407    );
16408    minify_test(
16409      ".foo { cursor: url(\"test.cur\"), url(\"foo.cur\"), ew-resize }",
16410      ".foo{cursor:url(test.cur),url(foo.cur),ew-resize}",
16411    );
16412    minify_test(".foo { caret-color: auto }", ".foo{caret-color:auto}");
16413    minify_test(".foo { caret-color: yellow }", ".foo{caret-color:#ff0}");
16414    minify_test(".foo { caret-shape: block }", ".foo{caret-shape:block}");
16415    minify_test(".foo { caret: yellow block }", ".foo{caret:#ff0 block}");
16416    minify_test(".foo { caret: block yellow }", ".foo{caret:#ff0 block}");
16417    minify_test(".foo { caret: block }", ".foo{caret:block}");
16418    minify_test(".foo { caret: yellow }", ".foo{caret:#ff0}");
16419    minify_test(".foo { caret: auto auto }", ".foo{caret:auto}");
16420    minify_test(".foo { caret: auto }", ".foo{caret:auto}");
16421    minify_test(".foo { caret: yellow auto }", ".foo{caret:#ff0}");
16422    minify_test(".foo { caret: auto block }", ".foo{caret:block}");
16423    minify_test(".foo { user-select: none }", ".foo{user-select:none}");
16424    minify_test(".foo { -webkit-user-select: none }", ".foo{-webkit-user-select:none}");
16425    minify_test(".foo { accent-color: auto }", ".foo{accent-color:auto}");
16426    minify_test(".foo { accent-color: yellow }", ".foo{accent-color:#ff0}");
16427    minify_test(".foo { appearance: None }", ".foo{appearance:none}");
16428    minify_test(
16429      ".foo { -webkit-appearance: textfield }",
16430      ".foo{-webkit-appearance:textfield}",
16431    );
16432
16433    prefix_test(
16434      r#"
16435      .foo {
16436        user-select: none;
16437      }
16438    "#,
16439      indoc! {r#"
16440      .foo {
16441        -webkit-user-select: none;
16442        -moz-user-select: none;
16443        -ms-user-select: none;
16444        user-select: none;
16445      }
16446    "#},
16447      Browsers {
16448        safari: Some(8 << 16),
16449        opera: Some(5 << 16),
16450        firefox: Some(10 << 16),
16451        ie: Some(10 << 16),
16452        ..Browsers::default()
16453      },
16454    );
16455
16456    prefix_test(
16457      r#"
16458      .foo {
16459        -webkit-user-select: none;
16460        -moz-user-select: none;
16461        -ms-user-select: none;
16462        user-select: none;
16463      }
16464    "#,
16465      indoc! {r#"
16466      .foo {
16467        -webkit-user-select: none;
16468        user-select: none;
16469      }
16470    "#},
16471      Browsers {
16472        safari: Some(8 << 16),
16473        opera: Some(80 << 16),
16474        firefox: Some(80 << 16),
16475        edge: Some(80 << 16),
16476        ..Browsers::default()
16477      },
16478    );
16479
16480    prefix_test(
16481      r#"
16482      .foo {
16483        -webkit-user-select: none;
16484        -moz-user-select: none;
16485        -ms-user-select: none;
16486        user-select: none;
16487      }
16488    "#,
16489      indoc! {r#"
16490      .foo {
16491        user-select: none;
16492      }
16493    "#},
16494      Browsers {
16495        opera: Some(80 << 16),
16496        firefox: Some(80 << 16),
16497        edge: Some(80 << 16),
16498        ..Browsers::default()
16499      },
16500    );
16501
16502    prefix_test(
16503      r#"
16504      .foo {
16505        appearance: none;
16506      }
16507    "#,
16508      indoc! {r#"
16509      .foo {
16510        -webkit-appearance: none;
16511        -moz-appearance: none;
16512        -ms-appearance: none;
16513        appearance: none;
16514      }
16515    "#},
16516      Browsers {
16517        safari: Some(8 << 16),
16518        chrome: Some(80 << 16),
16519        firefox: Some(10 << 16),
16520        ie: Some(11 << 16),
16521        ..Browsers::default()
16522      },
16523    );
16524
16525    prefix_test(
16526      r#"
16527      .foo {
16528        -webkit-appearance: none;
16529        -moz-appearance: none;
16530        -ms-appearance: none;
16531        appearance: none;
16532      }
16533    "#,
16534      indoc! {r#"
16535      .foo {
16536        -webkit-appearance: none;
16537        appearance: none;
16538      }
16539    "#},
16540      Browsers {
16541        safari: Some(15 << 16),
16542        chrome: Some(85 << 16),
16543        firefox: Some(80 << 16),
16544        edge: Some(85 << 16),
16545        ..Browsers::default()
16546      },
16547    );
16548
16549    prefix_test(
16550      r#"
16551      .foo {
16552        -webkit-appearance: none;
16553        -moz-appearance: none;
16554        -ms-appearance: none;
16555        appearance: none;
16556      }
16557    "#,
16558      indoc! {r#"
16559      .foo {
16560        appearance: none;
16561      }
16562    "#},
16563      Browsers {
16564        chrome: Some(85 << 16),
16565        firefox: Some(80 << 16),
16566        edge: Some(85 << 16),
16567        ..Browsers::default()
16568      },
16569    );
16570
16571    prefix_test(
16572      ".foo { caret-color: lch(50.998% 135.363 338) }",
16573      indoc! { r#"
16574        .foo {
16575          caret-color: #ee00be;
16576          caret-color: color(display-p3 .972962 -.362078 .804206);
16577          caret-color: lch(50.998% 135.363 338);
16578        }
16579      "#},
16580      Browsers {
16581        chrome: Some(90 << 16),
16582        safari: Some(14 << 16),
16583        ..Browsers::default()
16584      },
16585    );
16586
16587    prefix_test(
16588      ".foo { caret: lch(50.998% 135.363 338) block }",
16589      indoc! { r#"
16590        .foo {
16591          caret: #ee00be block;
16592          caret: color(display-p3 .972962 -.362078 .804206) block;
16593          caret: lch(50.998% 135.363 338) block;
16594        }
16595      "#},
16596      Browsers {
16597        chrome: Some(90 << 16),
16598        safari: Some(14 << 16),
16599        ..Browsers::default()
16600      },
16601    );
16602
16603    prefix_test(
16604      ".foo { caret: lch(50.998% 135.363 338) var(--foo) }",
16605      indoc! { r#"
16606        .foo {
16607          caret: #ee00be var(--foo);
16608        }
16609
16610        @supports (color: lab(0% 0 0)) {
16611          .foo {
16612            caret: lab(50.998% 125.506 -50.7078) var(--foo);
16613          }
16614        }
16615      "#},
16616      Browsers {
16617        chrome: Some(90 << 16),
16618        ..Browsers::default()
16619      },
16620    );
16621  }
16622
16623  #[test]
16624  fn test_list() {
16625    minify_test(".foo { list-style-type: disc; }", ".foo{list-style-type:disc}");
16626    minify_test(".foo { list-style-type: \"★\"; }", ".foo{list-style-type:\"★\"}");
16627    minify_test(
16628      ".foo { list-style-type: symbols(cyclic '○' '●'); }",
16629      ".foo{list-style-type:symbols(cyclic \"○\" \"●\")}",
16630    );
16631    minify_test(
16632      ".foo { list-style-type: symbols('○' '●'); }",
16633      ".foo{list-style-type:symbols(\"○\" \"●\")}",
16634    );
16635    minify_test(
16636      ".foo { list-style-type: symbols(symbolic '○' '●'); }",
16637      ".foo{list-style-type:symbols(\"○\" \"●\")}",
16638    );
16639    minify_test(
16640      ".foo { list-style-type: symbols(symbolic url('ellipse.png')); }",
16641      ".foo{list-style-type:symbols(url(ellipse.png))}",
16642    );
16643    minify_test(
16644      ".foo { list-style-image: url('ellipse.png'); }",
16645      ".foo{list-style-image:url(ellipse.png)}",
16646    );
16647    minify_test(
16648      ".foo { list-style-position: outside; }",
16649      ".foo{list-style-position:outside}",
16650    );
16651    minify_test(
16652      ".foo { list-style: \"★\" url(ellipse.png) outside; }",
16653      ".foo{list-style:url(ellipse.png) \"★\"}",
16654    );
16655    minify_test(".foo { list-style: none; }", ".foo{list-style:none}");
16656    minify_test(".foo { list-style: none none outside; }", ".foo{list-style:none}");
16657    minify_test(".foo { list-style: none none inside; }", ".foo{list-style:inside none}");
16658    minify_test(".foo { list-style: none inside; }", ".foo{list-style:inside none}");
16659    minify_test(".foo { list-style: none disc; }", ".foo{list-style:outside}");
16660    minify_test(".foo { list-style: none inside disc; }", ".foo{list-style:inside}");
16661    minify_test(".foo { list-style: none \"★\"; }", ".foo{list-style:\"★\"}");
16662    minify_test(
16663      ".foo { list-style: none url(foo.png); }",
16664      ".foo{list-style:url(foo.png) none}",
16665    );
16666
16667    test(
16668      r#"
16669      .foo {
16670        list-style-type: disc;
16671        list-style-image: url(ellipse.png);
16672        list-style-position: outside;
16673      }
16674    "#,
16675      indoc! {r#"
16676      .foo {
16677        list-style: url("ellipse.png");
16678      }
16679    "#},
16680    );
16681
16682    test(
16683      r#"
16684      .foo {
16685        list-style: \"★\" url(ellipse.png) outside;
16686        list-style-image: none;
16687      }
16688    "#,
16689      indoc! {r#"
16690      .foo {
16691        list-style: \"★\";
16692      }
16693    "#},
16694    );
16695
16696    test(
16697      r#"
16698      .foo {
16699        list-style: \"★\" url(ellipse.png) outside;
16700        list-style-image: var(--img);
16701      }
16702    "#,
16703      indoc! {r#"
16704      .foo {
16705        list-style: url("ellipse.png") \"★\";
16706        list-style-image: var(--img);
16707      }
16708    "#},
16709    );
16710
16711    prefix_test(
16712      ".foo { list-style-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
16713      indoc! { r#"
16714        .foo {
16715          list-style-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0f0e), to(#7773ff));
16716          list-style-image: -webkit-linear-gradient(#ff0f0e, #7773ff);
16717          list-style-image: linear-gradient(#ff0f0e, #7773ff);
16718          list-style-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
16719        }
16720      "#},
16721      Browsers {
16722        chrome: Some(8 << 16),
16723        ..Browsers::default()
16724      },
16725    );
16726
16727    prefix_test(
16728      ".foo { list-style: \"★\" linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
16729      indoc! { r#"
16730        .foo {
16731          list-style: linear-gradient(#ff0f0e, #7773ff) "★";
16732          list-style: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) "★";
16733        }
16734      "#},
16735      Browsers {
16736        chrome: Some(90 << 16),
16737        ..Browsers::default()
16738      },
16739    );
16740
16741    prefix_test(
16742      ".foo { list-style: var(--foo) linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
16743      indoc! { r#"
16744        .foo {
16745          list-style: var(--foo) linear-gradient(#ff0f0e, #7773ff);
16746        }
16747
16748        @supports (color: lab(0% 0 0)) {
16749          .foo {
16750            list-style: var(--foo) linear-gradient(lab(56.208% 94.4644 98.8928), lab(51% 70.4544 -115.586));
16751          }
16752        }
16753      "#},
16754      Browsers {
16755        chrome: Some(90 << 16),
16756        ..Browsers::default()
16757      },
16758    );
16759
16760    test(
16761      r#"
16762      .foo {
16763        list-style: inside;
16764        list-style-type: disc;
16765      }
16766    "#,
16767      indoc! {r#"
16768      .foo {
16769        list-style: inside;
16770      }
16771    "#},
16772    );
16773    test(
16774      r#"
16775      .foo {
16776        list-style: inside;
16777        list-style-type: decimal;
16778      }
16779    "#,
16780      indoc! {r#"
16781      .foo {
16782        list-style: inside decimal;
16783      }
16784    "#},
16785    );
16786  }
16787
16788  #[test]
16789  fn test_image_set() {
16790    // Spec: https://drafts.csswg.org/css-images-4/#image-set-notation
16791    // WPT: https://github.com/web-platform-tests/wpt/blob/master/css/css-images/image-set/image-set-parsing.html
16792    // test image-set(<string>)
16793    minify_test(
16794      ".foo { background: image-set(\"foo.png\" 2x, url(bar.png) 1x) }",
16795      ".foo{background:image-set(\"foo.png\" 2x,\"bar.png\" 1x)}",
16796    );
16797
16798    // test image-set(type(<string>))
16799    minify_test(
16800      ".foo { background: image-set('foo.webp' type('webp'), url(foo.jpg)) }",
16801      ".foo{background:image-set(\"foo.webp\" 1x type(\"webp\"),\"foo.jpg\" 1x)}",
16802    );
16803    minify_test(
16804      ".foo { background: image-set('foo.avif' 2x type('image/avif'), url(foo.png)) }",
16805      ".foo{background:image-set(\"foo.avif\" 2x type(\"image/avif\"),\"foo.png\" 1x)}",
16806    );
16807    minify_test(
16808      ".foo { background: image-set(url('example.png') 3x type('image/png')) }",
16809      ".foo{background:image-set(\"example.png\" 3x type(\"image/png\"))}",
16810    );
16811
16812    minify_test(
16813      ".foo { background: image-set(url(example.png) type('image/png') 1x) }",
16814      ".foo{background:image-set(\"example.png\" 1x type(\"image/png\"))}",
16815    );
16816
16817    minify_test(
16818      ".foo { background: -webkit-image-set(url(\"foo.png\") 2x, url(bar.png) 1x) }",
16819      ".foo{background:-webkit-image-set(url(foo.png) 2x,url(bar.png) 1x)}",
16820    );
16821
16822    test(
16823      r#"
16824      .foo {
16825        background: -webkit-image-set(url("foo.png") 2x, url(bar.png) 1x);
16826        background: image-set(url("foo.png") 2x, url(bar.png) 1x);
16827      }
16828    "#,
16829      indoc! {r#"
16830      .foo {
16831        background: -webkit-image-set(url("foo.png") 2x, url("bar.png") 1x);
16832        background: image-set("foo.png" 2x, "bar.png" 1x);
16833      }
16834    "#},
16835    );
16836
16837    // test image-set(<gradient>)
16838    test(
16839      r#"
16840      .foo {
16841        background: image-set(linear-gradient(cornflowerblue, white) 1x, url("detailed-gradient.png") 3x);
16842      }
16843    "#,
16844      indoc! {r#"
16845      .foo {
16846        background: image-set(linear-gradient(#6495ed, #fff) 1x, "detailed-gradient.png" 3x);
16847      }
16848    "#},
16849    );
16850
16851    prefix_test(
16852      r#"
16853      .foo {
16854        background: image-set(url("foo.png") 2x, url(bar.png) 1x);
16855      }
16856    "#,
16857      indoc! {r#"
16858      .foo {
16859        background: -webkit-image-set(url("foo.png") 2x, url("bar.png") 1x);
16860        background: image-set("foo.png" 2x, "bar.png" 1x);
16861      }
16862    "#},
16863      Browsers {
16864        chrome: Some(85 << 16),
16865        firefox: Some(80 << 16),
16866        ..Browsers::default()
16867      },
16868    );
16869
16870    prefix_test(
16871      r#"
16872      .foo {
16873        background: -webkit-image-set(url("foo.png") 2x, url(bar.png) 1x);
16874        background: image-set(url("foo.png") 2x, url(bar.png) 1x);
16875      }
16876    "#,
16877      indoc! {r#"
16878      .foo {
16879        background: -webkit-image-set(url("foo.png") 2x, url("bar.png") 1x);
16880        background: image-set("foo.png" 2x, "bar.png" 1x);
16881      }
16882    "#},
16883      Browsers {
16884        firefox: Some(80 << 16),
16885        ..Browsers::default()
16886      },
16887    );
16888
16889    prefix_test(
16890      r#"
16891      .foo {
16892        background: -webkit-image-set(url("foo.png") 2x, url(bar.png) 1x);
16893      }
16894    "#,
16895      indoc! {r#"
16896      .foo {
16897        background: -webkit-image-set(url("foo.png") 2x, url("bar.png") 1x);
16898      }
16899    "#},
16900      Browsers {
16901        chrome: Some(95 << 16),
16902        ..Browsers::default()
16903      },
16904    );
16905
16906    for property in &[
16907      "background",
16908      "background-image",
16909      "border-image-source",
16910      "border-image",
16911      "border-image-source",
16912      "-webkit-mask-image",
16913      "-webkit-mask",
16914      "list-style-image",
16915      "list-style",
16916    ] {
16917      prefix_test(
16918        &format!(
16919          r#"
16920        .foo {{
16921          {}: url(foo.png);
16922          {}: image-set(url("foo.png") 2x, url(bar.png) 1x);
16923        }}
16924      "#,
16925          property, property
16926        ),
16927        &format!(
16928          indoc! {r#"
16929        .foo {{
16930          {}: url("foo.png");
16931          {}: image-set("foo.png" 2x, "bar.png" 1x);
16932        }}
16933      "#},
16934          property, property
16935        ),
16936        Browsers {
16937          ie: Some(11 << 16),
16938          chrome: Some(95 << 16),
16939          ..Browsers::default()
16940        },
16941      );
16942
16943      prefix_test(
16944        &format!(
16945          r#"
16946        .foo {{
16947          {}: url(foo.png);
16948          {}: image-set(url("foo.png") 2x, url(bar.png) 1x);
16949        }}
16950      "#,
16951          property, property
16952        ),
16953        &format!(
16954          indoc! {r#"
16955        .foo {{
16956          {}: -webkit-image-set(url("foo.png") 2x, url("bar.png") 1x);
16957          {}: image-set("foo.png" 2x, "bar.png" 1x);
16958        }}
16959      "#},
16960          property, property
16961        ),
16962        Browsers {
16963          chrome: Some(95 << 16),
16964          ..Browsers::default()
16965        },
16966      );
16967    }
16968  }
16969
16970  #[test]
16971  fn test_color() {
16972    minify_test(".foo { color: yellow }", ".foo{color:#ff0}");
16973    minify_test(".foo { color: rgb(255, 255, 0) }", ".foo{color:#ff0}");
16974    minify_test(".foo { color: rgba(255, 255, 0, 1) }", ".foo{color:#ff0}");
16975    minify_test(".foo { color: rgba(255, 255, 0, 0.8) }", ".foo{color:#ff0c}");
16976    minify_test(".foo { color: rgb(128, 128, 128) }", ".foo{color:gray}");
16977    minify_test(".foo { color: rgb(123, 255, 255) }", ".foo{color:#7bffff}");
16978    minify_test(".foo { color: rgba(123, 255, 255, 0.5) }", ".foo{color:#7bffff80}");
16979    minify_test(".foo { color: rgb(123 255 255) }", ".foo{color:#7bffff}");
16980    minify_test(".foo { color: rgb(123 255 255 / .5) }", ".foo{color:#7bffff80}");
16981    minify_test(".foo { color: rgb(123 255 255 / 50%) }", ".foo{color:#7bffff80}");
16982    minify_test(".foo { color: rgb(48% 100% 100% / 50%) }", ".foo{color:#7affff80}");
16983    minify_test(".foo { color: hsl(100deg, 100%, 50%) }", ".foo{color:#5f0}");
16984    minify_test(".foo { color: hsl(100, 100%, 50%) }", ".foo{color:#5f0}");
16985    minify_test(".foo { color: hsl(100 100% 50%) }", ".foo{color:#5f0}");
16986    minify_test(".foo { color: hsl(100, 100%, 50%, .8) }", ".foo{color:#5f0c}");
16987    minify_test(".foo { color: hsl(100 100% 50% / .8) }", ".foo{color:#5f0c}");
16988    minify_test(".foo { color: hsla(100, 100%, 50%, .8) }", ".foo{color:#5f0c}");
16989    minify_test(".foo { color: hsla(100 100% 50% / .8) }", ".foo{color:#5f0c}");
16990    minify_test(".foo { color: transparent }", ".foo{color:#0000}");
16991    minify_test(".foo { color: currentColor }", ".foo{color:currentColor}");
16992    minify_test(".foo { color: ButtonBorder }", ".foo{color:buttonborder}");
16993    minify_test(".foo { color: hwb(194 0% 0%) }", ".foo{color:#00c4ff}");
16994    minify_test(".foo { color: hwb(194 0% 0% / 50%) }", ".foo{color:#00c4ff80}");
16995    minify_test(".foo { color: hwb(194 0% 50%) }", ".foo{color:#006280}");
16996    minify_test(".foo { color: hwb(194 50% 0%) }", ".foo{color:#80e1ff}");
16997    minify_test(".foo { color: hwb(194 50% 50%) }", ".foo{color:gray}");
16998    // minify_test(".foo { color: ActiveText }", ".foo{color:ActiveTet}");
16999    minify_test(
17000      ".foo { color: lab(29.2345% 39.3825 20.0664); }",
17001      ".foo{color:lab(29.2345% 39.3825 20.0664)}",
17002    );
17003    minify_test(
17004      ".foo { color: lab(29.2345% 39.3825 20.0664 / 100%); }",
17005      ".foo{color:lab(29.2345% 39.3825 20.0664)}",
17006    );
17007    minify_test(
17008      ".foo { color: lab(29.2345% 39.3825 20.0664 / 50%); }",
17009      ".foo{color:lab(29.2345% 39.3825 20.0664/.5)}",
17010    );
17011    minify_test(
17012      ".foo { color: lch(29.2345% 44.2 27); }",
17013      ".foo{color:lch(29.2345% 44.2 27)}",
17014    );
17015    minify_test(
17016      ".foo { color: lch(29.2345% 44.2 45deg); }",
17017      ".foo{color:lch(29.2345% 44.2 45)}",
17018    );
17019    minify_test(
17020      ".foo { color: lch(29.2345% 44.2 .5turn); }",
17021      ".foo{color:lch(29.2345% 44.2 180)}",
17022    );
17023    minify_test(
17024      ".foo { color: lch(29.2345% 44.2 27 / 100%); }",
17025      ".foo{color:lch(29.2345% 44.2 27)}",
17026    );
17027    minify_test(
17028      ".foo { color: lch(29.2345% 44.2 27 / 50%); }",
17029      ".foo{color:lch(29.2345% 44.2 27/.5)}",
17030    );
17031    minify_test(
17032      ".foo { color: oklab(40.101% 0.1147 0.0453); }",
17033      ".foo{color:oklab(40.101% .1147 .0453)}",
17034    );
17035    minify_test(
17036      ".foo { color: oklch(40.101% 0.12332 21.555); }",
17037      ".foo{color:oklch(40.101% .12332 21.555)}",
17038    );
17039    minify_test(
17040      ".foo { color: oklch(40.101% 0.12332 .5turn); }",
17041      ".foo{color:oklch(40.101% .12332 180)}",
17042    );
17043    minify_test(
17044      ".foo { color: color(display-p3 1 0.5 0); }",
17045      ".foo{color:color(display-p3 1 .5 0)}",
17046    );
17047    minify_test(
17048      ".foo { color: color(display-p3 100% 50% 0%); }",
17049      ".foo{color:color(display-p3 1 .5 0)}",
17050    );
17051    minify_test(
17052      ".foo { color: color(xyz-d50 0.2005 0.14089 0.4472); }",
17053      ".foo{color:color(xyz-d50 .2005 .14089 .4472)}",
17054    );
17055    minify_test(
17056      ".foo { color: color(xyz-d50 20.05% 14.089% 44.72%); }",
17057      ".foo{color:color(xyz-d50 .2005 .14089 .4472)}",
17058    );
17059    minify_test(
17060      ".foo { color: color(xyz-d65 0.2005 0.14089 0.4472); }",
17061      ".foo{color:color(xyz .2005 .14089 .4472)}",
17062    );
17063    minify_test(
17064      ".foo { color: color(xyz-d65 20.05% 14.089% 44.72%); }",
17065      ".foo{color:color(xyz .2005 .14089 .4472)}",
17066    );
17067    minify_test(
17068      ".foo { color: color(xyz 0.2005 0.14089 0.4472); }",
17069      ".foo{color:color(xyz .2005 .14089 .4472)}",
17070    );
17071    minify_test(
17072      ".foo { color: color(xyz 20.05% 14.089% 44.72%); }",
17073      ".foo{color:color(xyz .2005 .14089 .4472)}",
17074    );
17075    minify_test(
17076      ".foo { color: color(xyz 0.2005 0 0); }",
17077      ".foo{color:color(xyz .2005 0 0)}",
17078    );
17079    minify_test(".foo { color: color(xyz 0 0 0); }", ".foo{color:color(xyz 0 0 0)}");
17080    minify_test(".foo { color: color(xyz 0 1 0); }", ".foo{color:color(xyz 0 1 0)}");
17081    minify_test(
17082      ".foo { color: color(xyz 0 1 0 / 20%); }",
17083      ".foo{color:color(xyz 0 1 0/.2)}",
17084    );
17085    minify_test(
17086      ".foo { color: color(xyz 0 0 0 / 20%); }",
17087      ".foo{color:color(xyz 0 0 0/.2)}",
17088    );
17089    minify_test(
17090      ".foo { color: color(display-p3 100% 50% 0 / 20%); }",
17091      ".foo{color:color(display-p3 1 .5 0/.2)}",
17092    );
17093    minify_test(
17094      ".foo { color: color(display-p3 100% 0 0 / 20%); }",
17095      ".foo{color:color(display-p3 1 0 0/.2)}",
17096    );
17097    minify_test(".foo { color: hsl(none none none) }", ".foo{color:#000}");
17098    minify_test(".foo { color: hwb(none none none) }", ".foo{color:red}");
17099    minify_test(".foo { color: rgb(none none none) }", ".foo{color:#000}");
17100
17101    // If the browser doesn't support `#rrggbbaa` color syntax, it is converted to `transparent`.
17102    attr_test(
17103      "color: rgba(0, 0, 0, 0)",
17104      "color:transparent",
17105      true,
17106      Some(Browsers {
17107        chrome: Some(61 << 16), // Chrome >= 62 supports `#rrggbbaa` color.
17108        ..Browsers::default()
17109      }),
17110    );
17111
17112    attr_test(
17113      "color: #0000",
17114      "color:transparent",
17115      true,
17116      Some(Browsers {
17117        chrome: Some(61 << 16), // Chrome >= 62 supports `#rrggbbaa` color.
17118        ..Browsers::default()
17119      }),
17120    );
17121
17122    attr_test(
17123      "color: transparent",
17124      "color:transparent",
17125      true,
17126      Some(Browsers {
17127        chrome: Some(61 << 16),
17128        ..Browsers::default()
17129      }),
17130    );
17131
17132    attr_test(
17133      "color: rgba(0, 0, 0, 0)",
17134      "color: rgba(0, 0, 0, 0)",
17135      false,
17136      Some(Browsers {
17137        chrome: Some(61 << 16),
17138        ..Browsers::default()
17139      }),
17140    );
17141
17142    attr_test(
17143      "color: rgba(255, 0, 0, 0)",
17144      "color:rgba(255,0,0,0)",
17145      true,
17146      Some(Browsers {
17147        chrome: Some(61 << 16),
17148        ..Browsers::default()
17149      }),
17150    );
17151
17152    attr_test(
17153      "color: rgba(255, 0, 0, 0)",
17154      "color:#f000",
17155      true,
17156      Some(Browsers {
17157        chrome: Some(62 << 16),
17158        ..Browsers::default()
17159      }),
17160    );
17161
17162    prefix_test(
17163      ".foo { color: rgba(123, 456, 789, 0.5) }",
17164      indoc! { r#"
17165        .foo {
17166          color: #7bffff80;
17167        }
17168      "#},
17169      Browsers {
17170        chrome: Some(95 << 16),
17171        ..Browsers::default()
17172      },
17173    );
17174
17175    prefix_test(
17176      ".foo { color: rgba(123, 255, 255, 0.5) }",
17177      indoc! { r#"
17178        .foo {
17179          color: rgba(123, 255, 255, .5);
17180        }
17181      "#},
17182      Browsers {
17183        ie: Some(11 << 16),
17184        ..Browsers::default()
17185      },
17186    );
17187
17188    prefix_test(
17189      ".foo { color: #7bffff80 }",
17190      indoc! { r#"
17191        .foo {
17192          color: rgba(123, 255, 255, .5);
17193        }
17194      "#},
17195      Browsers {
17196        ie: Some(11 << 16),
17197        ..Browsers::default()
17198      },
17199    );
17200
17201    prefix_test(
17202      ".foo { color: rgba(123, 456, 789, 0.5) }",
17203      indoc! { r#"
17204        .foo {
17205          color: rgba(123, 255, 255, .5);
17206        }
17207      "#},
17208      Browsers {
17209        firefox: Some(48 << 16),
17210        safari: Some(10 << 16),
17211        ios_saf: Some(9 << 16),
17212        ..Browsers::default()
17213      },
17214    );
17215
17216    prefix_test(
17217      ".foo { color: rgba(123, 456, 789, 0.5) }",
17218      indoc! { r#"
17219        .foo {
17220          color: #7bffff80;
17221        }
17222      "#},
17223      Browsers {
17224        firefox: Some(49 << 16),
17225        safari: Some(10 << 16),
17226        ios_saf: Some(10 << 16),
17227        ..Browsers::default()
17228      },
17229    );
17230
17231    prefix_test(
17232      ".foo { background-color: lab(40% 56.6 39) }",
17233      indoc! { r#"
17234        .foo {
17235          background-color: #b32323;
17236          background-color: lab(40% 56.6 39);
17237        }
17238      "#},
17239      Browsers {
17240        chrome: Some(90 << 16),
17241        ..Browsers::default()
17242      },
17243    );
17244
17245    prefix_test(
17246      ".foo { background-color: lch(40% 68.735435 34.568626) }",
17247      indoc! { r#"
17248        .foo {
17249          background-color: #b32323;
17250          background-color: lch(40% 68.7354 34.5686);
17251        }
17252      "#},
17253      Browsers {
17254        chrome: Some(90 << 16),
17255        ..Browsers::default()
17256      },
17257    );
17258
17259    prefix_test(
17260      ".foo { background-color: oklab(59.686% 0.1009 0.1192); }",
17261      indoc! { r#"
17262        .foo {
17263          background-color: #c65d07;
17264          background-color: lab(52.2319% 40.1449 59.9171);
17265        }
17266      "#},
17267      Browsers {
17268        chrome: Some(90 << 16),
17269        ..Browsers::default()
17270      },
17271    );
17272
17273    prefix_test(
17274      ".foo { background-color: oklch(40% 0.1268735435 34.568626) }",
17275      indoc! { r#"
17276        .foo {
17277          background-color: #7e250f;
17278          background-color: lab(29.2661% 38.2437 35.3889);
17279        }
17280      "#},
17281      Browsers {
17282        chrome: Some(90 << 16),
17283        ..Browsers::default()
17284      },
17285    );
17286
17287    prefix_test(
17288      ".foo { background-color: lab(40% 56.6 39) }",
17289      indoc! { r#"
17290        .foo {
17291          background-color: lab(40% 56.6 39);
17292        }
17293      "#},
17294      Browsers {
17295        safari: Some(15 << 16),
17296        ..Browsers::default()
17297      },
17298    );
17299
17300    prefix_test(
17301      ".foo { background-color: oklab(59.686% 0.1009 0.1192); }",
17302      indoc! { r#"
17303        .foo {
17304          background-color: #c65d07;
17305          background-color: lab(52.2319% 40.1449 59.9171);
17306        }
17307      "#},
17308      Browsers {
17309        chrome: Some(90 << 16),
17310        safari: Some(15 << 16),
17311        ..Browsers::default()
17312      },
17313    );
17314
17315    prefix_test(
17316      ".foo { background-color: oklab(59.686% 0.1009 0.1192); }",
17317      indoc! { r#"
17318        .foo {
17319          background-color: #c65d07;
17320          background-color: color(display-p3 .724144 .386777 .148795);
17321          background-color: lab(52.2319% 40.1449 59.9171);
17322        }
17323      "#},
17324      Browsers {
17325        chrome: Some(90 << 16),
17326        safari: Some(14 << 16),
17327        ..Browsers::default()
17328      },
17329    );
17330
17331    prefix_test(
17332      ".foo { background-color: lab(40% 56.6 39) }",
17333      indoc! { r#"
17334        .foo {
17335          background-color: #b32323;
17336          background-color: color(display-p3 .643308 .192455 .167712);
17337          background-color: lab(40% 56.6 39);
17338        }
17339      "#},
17340      Browsers {
17341        chrome: Some(90 << 16),
17342        safari: Some(14 << 16),
17343        ..Browsers::default()
17344      },
17345    );
17346
17347    prefix_test(
17348      ".foo { background-color: oklch(59.686% 0.15619 49.7694); }",
17349      indoc! { r#"
17350        .foo {
17351          background-color: #c65d06;
17352          background-color: lab(52.2321% 40.1417 59.9527);
17353        }
17354      "#},
17355      Browsers {
17356        chrome: Some(90 << 16),
17357        safari: Some(15 << 16),
17358        ..Browsers::default()
17359      },
17360    );
17361
17362    prefix_test(
17363      ".foo { background-color: color(sRGB 0.41587 0.503670 0.36664); }",
17364      indoc! { r#"
17365        .foo {
17366          background-color: #6a805d;
17367          background-color: color(srgb .41587 .50367 .36664);
17368        }
17369      "#},
17370      Browsers {
17371        chrome: Some(90 << 16),
17372        ..Browsers::default()
17373      },
17374    );
17375
17376    prefix_test(
17377      ".foo { background-color: color(display-p3 0.43313 0.50108 0.37950); }",
17378      indoc! { r#"
17379        .foo {
17380          background-color: #6a805d;
17381          background-color: color(display-p3 .43313 .50108 .3795);
17382        }
17383      "#},
17384      Browsers {
17385        chrome: Some(90 << 16),
17386        ..Browsers::default()
17387      },
17388    );
17389
17390    prefix_test(
17391      ".foo { background-color: color(display-p3 0.43313 0.50108 0.37950); }",
17392      indoc! { r#"
17393        .foo {
17394          background-color: #6a805d;
17395          background-color: color(display-p3 .43313 .50108 .3795);
17396        }
17397      "#},
17398      Browsers {
17399        chrome: Some(90 << 16),
17400        safari: Some(14 << 16),
17401        ..Browsers::default()
17402      },
17403    );
17404
17405    prefix_test(
17406      ".foo { background-color: color(display-p3 0.43313 0.50108 0.37950); }",
17407      indoc! { r#"
17408        .foo {
17409          background-color: color(display-p3 .43313 .50108 .3795);
17410        }
17411      "#},
17412      Browsers {
17413        safari: Some(14 << 16),
17414        ..Browsers::default()
17415      },
17416    );
17417
17418    prefix_test(
17419      ".foo { background-color: color(display-p3 0.43313 0.50108 0.37950); }",
17420      indoc! { r#"
17421        .foo {
17422          background-color: #6a805d;
17423          background-color: color(display-p3 .43313 .50108 .3795);
17424        }
17425      "#},
17426      Browsers {
17427        chrome: Some(90 << 16),
17428        safari: Some(15 << 16),
17429        ..Browsers::default()
17430      },
17431    );
17432
17433    prefix_test(
17434      ".foo { background-color: color(display-p3 0.43313 0.50108 0.37950); }",
17435      indoc! { r#"
17436        .foo {
17437          background-color: #6a805d;
17438          background-color: color(display-p3 .43313 .50108 .3795);
17439        }
17440      "#},
17441      Browsers {
17442        chrome: Some(90 << 16),
17443        ..Browsers::default()
17444      },
17445    );
17446
17447    prefix_test(
17448      ".foo { background-color: color(a98-rgb 0.44091 0.49971 0.37408); }",
17449      indoc! { r#"
17450        .foo {
17451          background-color: #6a805d;
17452          background-color: color(a98-rgb .44091 .49971 .37408);
17453        }
17454      "#},
17455      Browsers {
17456        chrome: Some(90 << 16),
17457        ..Browsers::default()
17458      },
17459    );
17460
17461    prefix_test(
17462      ".foo { background-color: color(a98-rgb 0.44091 0.49971 0.37408); }",
17463      indoc! { r#"
17464        .foo {
17465          background-color: color(a98-rgb .44091 .49971 .37408);
17466        }
17467      "#},
17468      Browsers {
17469        safari: Some(15 << 16),
17470        ..Browsers::default()
17471      },
17472    );
17473
17474    prefix_test(
17475      ".foo { background-color: color(prophoto-rgb 0.36589 0.41717 0.31333); }",
17476      indoc! { r#"
17477        .foo {
17478          background-color: #6a805d;
17479          background-color: color(prophoto-rgb .36589 .41717 .31333);
17480        }
17481      "#},
17482      Browsers {
17483        chrome: Some(90 << 16),
17484        ..Browsers::default()
17485      },
17486    );
17487
17488    prefix_test(
17489      ".foo { background-color: color(rec2020 0.42210 0.47580 0.35605); }",
17490      indoc! { r#"
17491        .foo {
17492          background-color: #728765;
17493          background-color: color(rec2020 .4221 .4758 .35605);
17494        }
17495      "#},
17496      Browsers {
17497        chrome: Some(90 << 16),
17498        ..Browsers::default()
17499      },
17500    );
17501
17502    prefix_test(
17503      ".foo { background-color: color(xyz-d50 0.2005 0.14089 0.4472); }",
17504      indoc! { r#"
17505        .foo {
17506          background-color: #7654cd;
17507          background-color: color(xyz-d50 .2005 .14089 .4472);
17508        }
17509      "#},
17510      Browsers {
17511        chrome: Some(90 << 16),
17512        ..Browsers::default()
17513      },
17514    );
17515
17516    prefix_test(
17517      ".foo { background-color: color(xyz-d65 0.21661 0.14602 0.59452); }",
17518      indoc! { r#"
17519        .foo {
17520          background-color: #7654cd;
17521          background-color: color(xyz .21661 .14602 .59452);
17522        }
17523      "#},
17524      Browsers {
17525        chrome: Some(90 << 16),
17526        ..Browsers::default()
17527      },
17528    );
17529
17530    prefix_test(
17531      ".foo { background-color: lch(50.998% 135.363 338) }",
17532      indoc! { r#"
17533        .foo {
17534          background-color: #ee00be;
17535          background-color: color(display-p3 .972962 -.362078 .804206);
17536          background-color: lch(50.998% 135.363 338);
17537        }
17538      "#},
17539      Browsers {
17540        chrome: Some(90 << 16),
17541        safari: Some(14 << 16),
17542        ..Browsers::default()
17543      },
17544    );
17545
17546    prefix_test(
17547      ".foo { color: lch(50.998% 135.363 338) }",
17548      indoc! { r#"
17549        .foo {
17550          color: #ee00be;
17551          color: color(display-p3 .972962 -.362078 .804206);
17552          color: lch(50.998% 135.363 338);
17553        }
17554      "#},
17555      Browsers {
17556        chrome: Some(90 << 16),
17557        safari: Some(14 << 16),
17558        ..Browsers::default()
17559      },
17560    );
17561
17562    prefix_test(
17563      ".foo { background: var(--image) lch(40% 68.735435 34.568626) }",
17564      indoc! { r#"
17565        .foo {
17566          background: var(--image) #b32323;
17567        }
17568
17569        @supports (color: lab(0% 0 0)) {
17570          .foo {
17571            background: var(--image) lab(40% 56.6 39);
17572          }
17573        }
17574      "#},
17575      Browsers {
17576        chrome: Some(90 << 16),
17577        ..Browsers::default()
17578      },
17579    );
17580
17581    prefix_test(
17582      r#"
17583      .foo {
17584        color: red;
17585        color: lab(40% 56.6 39);
17586      }
17587    "#,
17588      indoc! {r#"
17589      .foo {
17590        color: red;
17591        color: lab(40% 56.6 39);
17592      }
17593    "#
17594      },
17595      Browsers {
17596        safari: Some(14 << 16),
17597        ..Browsers::default()
17598      },
17599    );
17600    prefix_test(
17601      r#"
17602      .foo {
17603        color: red;
17604        color: lab(40% 56.6 39);
17605      }
17606    "#,
17607      indoc! {r#"
17608      .foo {
17609        color: lab(40% 56.6 39);
17610      }
17611    "#
17612      },
17613      Browsers {
17614        safari: Some(16 << 16),
17615        ..Browsers::default()
17616      },
17617    );
17618
17619    prefix_test(
17620      r#"
17621      .foo {
17622        color: var(--fallback);
17623        color: lab(40% 56.6 39);
17624      }
17625    "#,
17626      indoc! {r#"
17627      .foo {
17628        color: var(--fallback);
17629        color: lab(40% 56.6 39);
17630      }
17631    "#
17632      },
17633      Browsers {
17634        safari: Some(14 << 16),
17635        ..Browsers::default()
17636      },
17637    );
17638
17639    prefix_test(
17640      r#"
17641      .foo {
17642        color: var(--fallback);
17643        color: lab(40% 56.6 39);
17644      }
17645    "#,
17646      indoc! {r#"
17647      .foo {
17648        color: lab(40% 56.6 39);
17649      }
17650    "#
17651      },
17652      Browsers {
17653        safari: Some(16 << 16),
17654        ..Browsers::default()
17655      },
17656    );
17657
17658    prefix_test(
17659      r#"
17660      .foo {
17661        color: red;
17662        color: var(--foo, lab(40% 56.6 39));
17663      }
17664    "#,
17665      indoc! {r#"
17666      .foo {
17667        color: var(--foo, color(display-p3 .643308 .192455 .167712));
17668      }
17669
17670      @supports (color: lab(0% 0 0)) {
17671        .foo {
17672          color: var(--foo, lab(40% 56.6 39));
17673        }
17674      }
17675    "#
17676      },
17677      Browsers {
17678        safari: Some(14 << 16),
17679        ..Browsers::default()
17680      },
17681    );
17682
17683    prefix_test(
17684      r#"
17685      .foo {
17686        --a: rgb(0 0 0 / var(--alpha));
17687        --b: rgb(50% 50% 50% / var(--alpha));
17688        --c: rgb(var(--x) 0 0);
17689        --d: rgb(0 var(--x) 0);
17690        --e: rgb(0 0 var(--x));
17691        --f: rgb(var(--x) 0 0 / var(--alpha));
17692        --g: rgb(0 var(--x) 0 / var(--alpha));
17693        --h: rgb(0 0 var(--x) / var(--alpha));
17694        --i: rgb(none 0 0 / var(--alpha));
17695        --j: rgb(from yellow r g b / var(--alpha));
17696      }
17697      "#,
17698      indoc! { r#"
17699        .foo {
17700          --a: rgba(0, 0, 0, var(--alpha));
17701          --b: rgba(128, 128, 128, var(--alpha));
17702          --c: rgb(var(--x) 0 0);
17703          --d: rgb(0 var(--x) 0);
17704          --e: rgb(0 0 var(--x));
17705          --f: rgb(var(--x) 0 0 / var(--alpha));
17706          --g: rgb(0 var(--x) 0 / var(--alpha));
17707          --h: rgb(0 0 var(--x) / var(--alpha));
17708          --i: rgb(none 0 0 / var(--alpha));
17709          --j: rgba(255, 255, 0, var(--alpha));
17710        }
17711      "#},
17712      Browsers {
17713        safari: Some(11 << 16),
17714        ..Browsers::default()
17715      },
17716    );
17717
17718    prefix_test(
17719      r#"
17720      .foo {
17721        --a: rgb(0 0 0 / var(--alpha));
17722        --b: rgb(50% 50% 50% / var(--alpha));
17723        --c: rgb(var(--x) 0 0);
17724        --d: rgb(0 var(--x) 0);
17725        --e: rgb(0 0 var(--x));
17726        --f: rgb(var(--x) 0 0 / var(--alpha));
17727        --g: rgb(0 var(--x) 0 / var(--alpha));
17728        --h: rgb(0 0 var(--x) / var(--alpha));
17729        --i: rgb(none 0 0 / var(--alpha));
17730        --j: rgb(from yellow r g b / var(--alpha));
17731      }
17732      "#,
17733      indoc! { r#"
17734        .foo {
17735          --a: rgb(0 0 0 / var(--alpha));
17736          --b: rgb(128 128 128 / var(--alpha));
17737          --c: rgb(var(--x) 0 0);
17738          --d: rgb(0 var(--x) 0);
17739          --e: rgb(0 0 var(--x));
17740          --f: rgb(var(--x) 0 0 / var(--alpha));
17741          --g: rgb(0 var(--x) 0 / var(--alpha));
17742          --h: rgb(0 0 var(--x) / var(--alpha));
17743          --i: rgb(none 0 0 / var(--alpha));
17744          --j: rgb(255 255 0 / var(--alpha));
17745        }
17746      "#},
17747      Browsers {
17748        safari: Some(13 << 16),
17749        ..Browsers::default()
17750      },
17751    );
17752
17753    prefix_test(
17754      r#"
17755      .foo {
17756        --a: hsl(270 100% 50% / var(--alpha));
17757        --b: hsl(var(--x) 0 0);
17758        --c: hsl(0 var(--x) 0);
17759        --d: hsl(0 0 var(--x));
17760        --e: hsl(var(--x) 0 0 / var(--alpha));
17761        --f: hsl(0 var(--x) 0 / var(--alpha));
17762        --g: hsl(0 0 var(--x) / var(--alpha));
17763        --h: hsl(270 100% 50% / calc(var(--alpha) / 2));
17764        --i: hsl(none 100% 50% / var(--alpha));
17765        --j: hsl(from yellow h s l / var(--alpha));
17766      }
17767      "#,
17768      indoc! { r#"
17769        .foo {
17770          --a: hsla(270, 100%, 50%, var(--alpha));
17771          --b: hsl(var(--x) 0 0);
17772          --c: hsl(0 var(--x) 0);
17773          --d: hsl(0 0 var(--x));
17774          --e: hsl(var(--x) 0 0 / var(--alpha));
17775          --f: hsl(0 var(--x) 0 / var(--alpha));
17776          --g: hsl(0 0 var(--x) / var(--alpha));
17777          --h: hsla(270, 100%, 50%, calc(var(--alpha) / 2));
17778          --i: hsl(none 100% 50% / var(--alpha));
17779          --j: hsla(60, 100%, 50%, var(--alpha));
17780        }
17781      "#},
17782      Browsers {
17783        safari: Some(11 << 16),
17784        ..Browsers::default()
17785      },
17786    );
17787
17788    prefix_test(
17789      r#"
17790      .foo {
17791        --a: hsl(270 100% 50% / var(--alpha));
17792        --b: hsl(var(--x) 0 0);
17793        --c: hsl(0 var(--x) 0);
17794        --d: hsl(0 0 var(--x));
17795        --e: hsl(var(--x) 0 0 / var(--alpha));
17796        --f: hsl(0 var(--x) 0 / var(--alpha));
17797        --g: hsl(0 0 var(--x) / var(--alpha));
17798        --h: hsl(270 100% 50% / calc(var(--alpha) / 2));
17799        --i: hsl(none 100% 50% / var(--alpha));
17800      }
17801      "#,
17802      indoc! { r#"
17803        .foo {
17804          --a: hsl(270 100% 50% / var(--alpha));
17805          --b: hsl(var(--x) 0 0);
17806          --c: hsl(0 var(--x) 0);
17807          --d: hsl(0 0 var(--x));
17808          --e: hsl(var(--x) 0 0 / var(--alpha));
17809          --f: hsl(0 var(--x) 0 / var(--alpha));
17810          --g: hsl(0 0 var(--x) / var(--alpha));
17811          --h: hsl(270 100% 50% / calc(var(--alpha) / 2));
17812          --i: hsl(none 100% 50% / var(--alpha));
17813        }
17814      "#},
17815      Browsers {
17816        safari: Some(13 << 16),
17817        ..Browsers::default()
17818      },
17819    );
17820
17821    test(
17822      r#"
17823      .foo {
17824        --a: rgb(50% 50% 50% / calc(100% / 2));
17825        --b: hsl(calc(360deg / 2) 50% 50%);
17826        --c: oklab(40.101% calc(0.1 + 0.2) 0.0453);
17827        --d: color(display-p3 0.43313 0.50108 calc(0.1 + 0.2));
17828        --e: rgb(calc(255 / 2), calc(255 / 2), calc(255 / 2));
17829      }
17830      "#,
17831      indoc! { r#"
17832        .foo {
17833          --a: #80808080;
17834          --b: #40bfbf;
17835          --c: oklab(40.101% .3 .0453);
17836          --d: color(display-p3 .43313 .50108 .3);
17837          --e: gray;
17838        }
17839      "#},
17840    );
17841  }
17842
17843  #[test]
17844  fn test_relative_color() {
17845    fn test(input: &str, output: &str) {
17846      let output = CssColor::parse_string(output)
17847        .unwrap()
17848        .to_css_string(PrinterOptions {
17849          minify: true,
17850          ..PrinterOptions::default()
17851        })
17852        .unwrap();
17853      minify_test(
17854        &format!(".foo {{ color: {} }}", input),
17855        &format!(".foo{{color:{}}}", output),
17856      );
17857    }
17858
17859    test("lab(from indianred calc(l * .8) a b)", "lab(43.1402% 45.7516 23.1557)");
17860    test("lch(from indianred calc(l + 10%) c h)", "lch(63.9252% 51.2776 26.8448)");
17861    test("lch(from indianred l calc(c - 50) h)", "lch(53.9252% 1.27763 26.8448)");
17862    test(
17863      "lch(from indianred l c calc(h + 180deg))",
17864      "lch(53.9252% 51.2776 206.845)",
17865    );
17866    test("lch(from orchid l 30 h)", "lch(62.7526% 30 326.969)");
17867    test("lch(from orchid l 30 h)", "lch(62.7526% 30 326.969)");
17868    test("lch(from peru calc(l * 0.8) c h)", "lch(49.8022% 54.0117 63.6804)");
17869    test("rgb(from indianred 255 g b)", "rgb(255, 92, 92)");
17870    test("rgb(from indianred r g b / .5)", "rgba(205, 92, 92, .5)");
17871    test(
17872      "rgb(from rgba(205, 92, 92, .5) r g b / calc(alpha + .2))",
17873      "rgba(205, 92, 92, .7)",
17874    );
17875    test(
17876      "rgb(from rgba(205, 92, 92, .5) r g b / calc(alpha + 20%))",
17877      "rgba(205, 92, 92, .7)",
17878    );
17879    test("lch(from indianred l sin(c) h)", "lch(53.9252% .84797 26.8448)");
17880    test("lch(from indianred l sqrt(c) h)", "lch(53.9252% 7.16084 26.8448)");
17881    test("lch(from indianred l c sin(h))", "lch(53.9252% 51.2776 .990043)");
17882    minify_test(
17883      ".foo{color:lch(from currentColor l c sin(h))}",
17884      ".foo{color:lch(from currentColor l c sin(h))}",
17885    );
17886
17887    // The following tests were converted from WPT: https://github.com/web-platform-tests/wpt/blob/master/css/css-color/parsing/relative-color-valid.html
17888    // Find: test_valid_value\(`color`, `(.*?)`,\s*`(.*?)`\)
17889    // Replace: test("$1", "$2")
17890
17891    // Testing no modifications.
17892    test("rgb(from rebeccapurple r g b)", "#639");
17893    test("rgb(from rebeccapurple r g b / alpha)", "#639");
17894    test("rgb(from rgb(20%, 40%, 60%, 80%) r g b / alpha)", "#369c");
17895    test("rgb(from hsl(120deg 20% 50% / .5) r g b / alpha)", "#66996680");
17896
17897    // Test nesting relative colors.
17898    test("rgb(from rgb(from rebeccapurple r g b) r g b)", "#639");
17899
17900    // Testing non-sRGB origin colors to see gamut mapping.
17901    test("rgb(from color(display-p3 0 1 0) r g b / alpha)", "#00f942"); // Naive clip based mapping would give rgb(0, 255, 0).
17902    test("rgb(from lab(100% 104.3 -50.9) r g b)", "#fff"); // Naive clip based mapping would give rgb(255, 150, 255).
17903    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.
17904    test("rgb(from lch(100% 116 334) r g b)", "#fff"); // Naive clip based mapping would give rgb(255, 150, 255).
17905    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.
17906    test("rgb(from oklab(100% 0.365 -0.16) r g b)", "#fff"); // Naive clip based mapping would give rgb(255, 92, 255).
17907    test("rgb(from oklab(0% 0.365 -0.16) r g b)", "#000"); // Naive clip based mapping would give rgb(19, 0, 24).
17908    test("rgb(from oklch(100% 0.399 336.3) r g b)", "#fff"); // Naive clip based mapping would give rgb(255, 91, 255).
17909    test("rgb(from oklch(0% 0.399 336.3) r g b)", "#000"); // Naive clip based mapping would give rgb(20, 0, 24).
17910
17911    // Testing replacement with 0.
17912    test("rgb(from rebeccapurple 0 0 0)", "rgb(0, 0, 0)");
17913    test("rgb(from rebeccapurple 0 0 0 / 0)", "rgba(0, 0, 0, 0)");
17914    test("rgb(from rebeccapurple 0 g b / alpha)", "rgb(0, 51, 153)");
17915    test("rgb(from rebeccapurple r 0 b / alpha)", "rgb(102, 0, 153)");
17916    test("rgb(from rebeccapurple r g 0 / alpha)", "rgb(102, 51, 0)");
17917    test("rgb(from rebeccapurple r g b / 0)", "rgba(102, 51, 153, 0)");
17918    test(
17919      "rgb(from rgb(20%, 40%, 60%, 80%) 0 g b / alpha)",
17920      "rgba(0, 102, 153, 0.8)",
17921    );
17922    test(
17923      "rgb(from rgb(20%, 40%, 60%, 80%) r 0 b / alpha)",
17924      "rgba(51, 0, 153, 0.8)",
17925    );
17926    test(
17927      "rgb(from rgb(20%, 40%, 60%, 80%) r g 0 / alpha)",
17928      "rgba(51, 102, 0, 0.8)",
17929    );
17930    test("rgb(from rgb(20%, 40%, 60%, 80%) r g b / 0)", "rgba(51, 102, 153, 0)");
17931
17932    // Testing replacement with a number.
17933    test("rgb(from rebeccapurple 25 g b / alpha)", "rgb(25, 51, 153)");
17934    test("rgb(from rebeccapurple r 25 b / alpha)", "rgb(102, 25, 153)");
17935    test("rgb(from rebeccapurple r g 25 / alpha)", "rgb(102, 51, 25)");
17936    test("rgb(from rebeccapurple r g b / .25)", "rgba(102, 51, 153, 0.25)");
17937    test(
17938      "rgb(from rgb(20%, 40%, 60%, 80%) 25 g b / alpha)",
17939      "rgba(25, 102, 153, 0.8)",
17940    );
17941    test(
17942      "rgb(from rgb(20%, 40%, 60%, 80%) r 25 b / alpha)",
17943      "rgba(51, 25, 153, 0.8)",
17944    );
17945    test(
17946      "rgb(from rgb(20%, 40%, 60%, 80%) r g 25 / alpha)",
17947      "rgba(51, 102, 25, 0.8)",
17948    );
17949    test(
17950      "rgb(from rgb(20%, 40%, 60%, 80%) r g b / .20)",
17951      "rgba(51, 102, 153, 0.2)",
17952    );
17953
17954    // Testing replacement with a percentage.
17955    test("rgb(from rebeccapurple 20% g b / alpha)", "rgb(51, 51, 153)");
17956    test("rgb(from rebeccapurple r 20% b / alpha)", "rgb(102, 51, 153)");
17957    test("rgb(from rebeccapurple r g 20% / alpha)", "rgb(102, 51, 51)");
17958    test("rgb(from rebeccapurple r g b / 20%)", "rgba(102, 51, 153, 0.2)");
17959    test(
17960      "rgb(from rgb(20%, 40%, 60%, 80%) 20% g b / alpha)",
17961      "rgba(51, 102, 153, 0.8)",
17962    );
17963    test(
17964      "rgb(from rgb(20%, 40%, 60%, 80%) r 20% b / alpha)",
17965      "rgba(51, 51, 153, 0.8)",
17966    );
17967    test(
17968      "rgb(from rgb(20%, 40%, 60%, 80%) r g 20% / alpha)",
17969      "rgba(51, 102, 51, 0.8)",
17970    );
17971    test(
17972      "rgb(from rgb(20%, 40%, 60%, 80%) r g b / 20%)",
17973      "rgba(51, 102, 153, 0.2)",
17974    );
17975
17976    // Testing replacement with a number for r, g, b but percent for alpha.
17977    test("rgb(from rebeccapurple 25 g b / 25%)", "rgba(25, 51, 153, 0.25)");
17978    test("rgb(from rebeccapurple r 25 b / 25%)", "rgba(102, 25, 153, 0.25)");
17979    test("rgb(from rebeccapurple r g 25 / 25%)", "rgba(102, 51, 25, 0.25)");
17980    test(
17981      "rgb(from rgb(20%, 40%, 60%, 80%) 25 g b / 25%)",
17982      "rgba(25, 102, 153, 0.25)",
17983    );
17984    test(
17985      "rgb(from rgb(20%, 40%, 60%, 80%) r 25 b / 25%)",
17986      "rgba(51, 25, 153, 0.25)",
17987    );
17988    test(
17989      "rgb(from rgb(20%, 40%, 60%, 80%) r g 25 / 25%)",
17990      "rgba(51, 102, 25, 0.25)",
17991    );
17992
17993    // Testing permutation.
17994    test("rgb(from rebeccapurple g b r)", "rgb(51, 153, 102)");
17995    test("rgb(from rebeccapurple b alpha r / g)", "rgba(153, 255, 102, 0.2)");
17996    test("rgb(from rebeccapurple r r r / r)", "rgba(102, 102, 102, 0.4)");
17997    test(
17998      "rgb(from rebeccapurple alpha alpha alpha / alpha)",
17999      "rgb(255, 255, 255)",
18000    );
18001    test("rgb(from rgb(20%, 40%, 60%, 80%) g b r)", "rgb(102, 153, 51)");
18002    test(
18003      "rgb(from rgb(20%, 40%, 60%, 80%) b alpha r / g)",
18004      "rgba(153, 204, 51, 0.4)",
18005    );
18006    test("rgb(from rgb(20%, 40%, 60%, 80%) r r r / r)", "rgba(51, 51, 51, 0.2)");
18007    test(
18008      "rgb(from rgb(20%, 40%, 60%, 80%) alpha alpha alpha / alpha)",
18009      "rgba(204, 204, 204, 0.8)",
18010    );
18011
18012    // Testing mixes of number and percentage. (These would not be allowed in the non-relative syntax).
18013    test("rgb(from rebeccapurple r 20% 10)", "rgb(102, 51, 10)");
18014    test("rgb(from rebeccapurple r 10 20%)", "rgb(102, 10, 51)");
18015    test("rgb(from rebeccapurple 0% 10 10)", "rgb(0, 10, 10)");
18016    test("rgb(from rgb(20%, 40%, 60%, 80%) r 20% 10)", "rgb(51, 51, 10)");
18017    test("rgb(from rgb(20%, 40%, 60%, 80%) r 10 20%)", "rgb(51, 10, 51)");
18018    test("rgb(from rgb(20%, 40%, 60%, 80%) 0% 10 10)", "rgb(0, 10, 10)");
18019
18020    // Testing with calc().
18021    test("rgb(from rebeccapurple calc(r) calc(g) calc(b))", "rgb(102, 51, 153)");
18022    test("rgb(from rebeccapurple r calc(g * 2) 10)", "rgb(102, 102, 10)");
18023    test("rgb(from rebeccapurple b calc(r * .5) 10)", "rgb(153, 51, 10)");
18024    test("rgb(from rebeccapurple r calc(g * .5 + g * .5) 10)", "rgb(102, 51, 10)");
18025    test("rgb(from rebeccapurple r calc(b * .5 - g * .5) 10)", "rgb(102, 51, 10)");
18026    test(
18027      "rgb(from rgb(20%, 40%, 60%, 80%) calc(r) calc(g) calc(b) / calc(alpha))",
18028      "rgba(51, 102, 153, 0.8)",
18029    );
18030
18031    // Testing with 'none'.
18032    test("rgb(from rebeccapurple none none none)", "rgb(0, 0, 0)");
18033    test("rgb(from rebeccapurple none none none / none)", "rgba(0, 0, 0, 0)");
18034    test("rgb(from rebeccapurple r g none)", "rgb(102, 51, 0)");
18035    test("rgb(from rebeccapurple r g none / alpha)", "rgb(102, 51, 0)");
18036    test("rgb(from rebeccapurple r g b / none)", "rgba(102, 51, 153, 0)");
18037    test(
18038      "rgb(from rgb(20% 40% 60% / 80%) r g none / alpha)",
18039      "rgba(51, 102, 0, 0.8)",
18040    );
18041    test("rgb(from rgb(20% 40% 60% / 80%) r g b / none)", "rgba(51, 102, 153, 0)");
18042    // FIXME: Clarify with spec editors if 'none' should pass through to the constants.
18043    test("rgb(from rgb(none none none) r g b)", "rgb(0, 0, 0)");
18044    test("rgb(from rgb(none none none / none) r g b / alpha)", "rgba(0, 0, 0, 0)");
18045    test("rgb(from rgb(20% none 60%) r g b)", "rgb(51, 0, 153)");
18046    test(
18047      "rgb(from rgb(20% 40% 60% / none) r g b / alpha)",
18048      "rgba(51, 102, 153, 0)",
18049    );
18050
18051    // hsl(from ...)
18052
18053    // Testing no modifications.
18054    test("hsl(from rebeccapurple h s l)", "rgb(102, 51, 153)");
18055    test("hsl(from rebeccapurple h s l / alpha)", "rgb(102, 51, 153)");
18056    test(
18057      "hsl(from rgb(20%, 40%, 60%, 80%) h s l / alpha)",
18058      "rgba(51, 102, 153, 0.8)",
18059    );
18060    test(
18061      "hsl(from hsl(120deg 20% 50% / .5) h s l / alpha)",
18062      "rgba(102, 153, 102, 0.5)",
18063    );
18064
18065    // Test nesting relative colors.
18066    test("hsl(from hsl(from rebeccapurple h s l) h s l)", "rgb(102, 51, 153)");
18067
18068    // Testing non-sRGB origin colors to see gamut mapping.
18069    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).
18070    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).
18071    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,
18072    test("hsl(from lch(100% 116 334) h s l)", "rgb(255, 255, 255)"); // Naive clip based mapping would give rgb(255, 150, 255).
18073    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,
18074    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).
18075    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).
18076    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).
18077    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).
18078
18079    // Testing replacement with 0.
18080    test("hsl(from rebeccapurple 0 0% 0%)", "rgb(0, 0, 0)");
18081    test("hsl(from rebeccapurple 0deg 0% 0%)", "rgb(0, 0, 0)");
18082    test("hsl(from rebeccapurple 0 0% 0% / 0)", "rgba(0, 0, 0, 0)");
18083    test("hsl(from rebeccapurple 0deg 0% 0% / 0)", "rgba(0, 0, 0, 0)");
18084    test("hsl(from rebeccapurple 0 s l / alpha)", "rgb(153, 51, 51)");
18085    test("hsl(from rebeccapurple 0deg s l / alpha)", "rgb(153, 51, 51)");
18086    test("hsl(from rebeccapurple h 0% l / alpha)", "rgb(102, 102, 102)");
18087    test("hsl(from rebeccapurple h s 0% / alpha)", "rgb(0, 0, 0)");
18088    test("hsl(from rebeccapurple h s l / 0)", "rgba(102, 51, 153, 0)");
18089    test(
18090      "hsl(from rgb(20%, 40%, 60%, 80%) 0 s l / alpha)",
18091      "rgba(153, 51, 51, 0.8)",
18092    );
18093    test(
18094      "hsl(from rgb(20%, 40%, 60%, 80%) 0deg s l / alpha)",
18095      "rgba(153, 51, 51, 0.8)",
18096    );
18097    test(
18098      "hsl(from rgb(20%, 40%, 60%, 80%) h 0% l / alpha)",
18099      "rgba(102, 102, 102, 0.8)",
18100    );
18101    test("hsl(from rgb(20%, 40%, 60%, 80%) h s 0% / alpha)", "rgba(0, 0, 0, 0.8)");
18102    test("hsl(from rgb(20%, 40%, 60%, 80%) h s l / 0)", "rgba(51, 102, 153, 0)");
18103
18104    // Testing replacement with a constant.
18105    test("hsl(from rebeccapurple 25 s l / alpha)", "rgb(153, 94, 51)");
18106    test("hsl(from rebeccapurple 25deg s l / alpha)", "rgb(153, 94, 51)");
18107    test("hsl(from rebeccapurple h 20% l / alpha)", "rgb(102, 82, 122)");
18108    test("hsl(from rebeccapurple h s 20% / alpha)", "rgb(51, 25, 77)");
18109    test("hsl(from rebeccapurple h s l / .25)", "rgba(102, 51, 153, 0.25)");
18110    test(
18111      "hsl(from rgb(20%, 40%, 60%, 80%) 25 s l / alpha)",
18112      "rgba(153, 94, 51, 0.8)",
18113    );
18114    test(
18115      "hsl(from rgb(20%, 40%, 60%, 80%) 25deg s l / alpha)",
18116      "rgba(153, 94, 51, 0.8)",
18117    );
18118    test(
18119      "hsl(from rgb(20%, 40%, 60%, 80%) h 20% l / alpha)",
18120      "rgba(82, 102, 122, 0.8)",
18121    );
18122    test(
18123      "hsl(from rgb(20%, 40%, 60%, 80%) h s 20% / alpha)",
18124      "rgba(25, 51, 77, 0.8)",
18125    );
18126    test(
18127      "hsl(from rgb(20%, 40%, 60%, 80%) h s l / .2)",
18128      "rgba(51, 102, 153, 0.2)",
18129    );
18130
18131    // Testing valid permutation (types match).
18132    test("hsl(from rebeccapurple h l s)", "rgb(128, 77, 179)");
18133    test("hsl(from rebeccapurple h alpha l / s)", "rgba(102, 0, 204, 0.5)");
18134    test("hsl(from rebeccapurple h l l / l)", "rgba(102, 61, 143, 0.4)");
18135    test("hsl(from rebeccapurple h alpha alpha / alpha)", "rgb(255, 255, 255)");
18136    test("hsl(from rgb(20%, 40%, 60%, 80%) h l s)", "rgb(77, 128, 179)");
18137    test(
18138      "hsl(from rgb(20%, 40%, 60%, 80%) h alpha l / s)",
18139      "rgba(20, 102, 184, 0.5)",
18140    );
18141    test("hsl(from rgb(20%, 40%, 60%, 80%) h l l / l)", "rgba(61, 102, 143, 0.4)");
18142    test(
18143      "hsl(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)",
18144      "rgba(163, 204, 245, 0.8)",
18145    );
18146
18147    // Testing with calc().
18148    test("hsl(from rebeccapurple calc(h) calc(s) calc(l))", "rgb(102, 51, 153)");
18149    test(
18150      "hsl(from rgb(20%, 40%, 60%, 80%) calc(h) calc(s) calc(l) / calc(alpha))",
18151      "rgba(51, 102, 153, 0.8)",
18152    );
18153
18154    // Testing with 'none'.
18155    test("hsl(from rebeccapurple none none none)", "rgb(0, 0, 0)");
18156    test("hsl(from rebeccapurple none none none / none)", "rgba(0, 0, 0, 0)");
18157    test("hsl(from rebeccapurple h s none)", "rgb(0, 0, 0)");
18158    test("hsl(from rebeccapurple h s none / alpha)", "rgb(0, 0, 0)");
18159    test("hsl(from rebeccapurple h s l / none)", "rgba(102, 51, 153, 0)");
18160    test("hsl(from rebeccapurple none s l / alpha)", "rgb(153, 51, 51)");
18161    test(
18162      "hsl(from hsl(120deg 20% 50% / .5) h s none / alpha)",
18163      "rgba(0, 0, 0, 0.5)",
18164    );
18165    test(
18166      "hsl(from hsl(120deg 20% 50% / .5) h s l / none)",
18167      "rgba(102, 153, 102, 0)",
18168    );
18169    test(
18170      "hsl(from hsl(120deg 20% 50% / .5) none s l / alpha)",
18171      "rgba(153, 102, 102, 0.5)",
18172    );
18173    // FIXME: Clarify with spec editors if 'none' should pass through to the constants.
18174    test("hsl(from hsl(none none none) h s l)", "rgb(0, 0, 0)");
18175    test("hsl(from hsl(none none none / none) h s l / alpha)", "rgba(0, 0, 0, 0)");
18176    test("hsl(from hsl(120deg none 50% / .5) h s l)", "rgb(128, 128, 128)");
18177    test(
18178      "hsl(from hsl(120deg 20% 50% / none) h s l / alpha)",
18179      "rgba(102, 153, 102, 0)",
18180    );
18181    test(
18182      "hsl(from hsl(none 20% 50% / .5) h s l / alpha)",
18183      "rgba(153, 102, 102, 0.5)",
18184    );
18185
18186    // hwb(from ...)
18187
18188    // Testing no modifications.
18189    test("hwb(from rebeccapurple h w b)", "rgb(102, 51, 153)");
18190    test("hwb(from rebeccapurple h w b / alpha)", "rgb(102, 51, 153)");
18191    test(
18192      "hwb(from rgb(20%, 40%, 60%, 80%) h w b / alpha)",
18193      "rgba(51, 102, 153, 0.8)",
18194    );
18195    test(
18196      "hwb(from hsl(120deg 20% 50% / .5) h w b / alpha)",
18197      "rgba(102, 153, 102, 0.5)",
18198    );
18199
18200    // Test nesting relative colors.
18201    test("hwb(from hwb(from rebeccapurple h w b) h w b)", "rgb(102, 51, 153)");
18202
18203    // Testing non-sRGB origin colors to see gamut mapping.
18204    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).
18205    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).
18206    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,
18207    test("hwb(from lch(100% 116 334) h w b)", "rgb(255, 255, 255)"); // Naive clip based mapping would give rgb(255, 150, 255).
18208    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,
18209    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).
18210    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).
18211    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).
18212    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).
18213
18214    // Testing replacement with 0.
18215    test("hwb(from rebeccapurple 0 0% 0%)", "rgb(255, 0, 0)");
18216    test("hwb(from rebeccapurple 0deg 0% 0%)", "rgb(255, 0, 0)");
18217    test("hwb(from rebeccapurple 0 0% 0% / 0)", "rgba(255, 0, 0, 0)");
18218    test("hwb(from rebeccapurple 0deg 0% 0% / 0)", "rgba(255, 0, 0, 0)");
18219    test("hwb(from rebeccapurple 0 w b / alpha)", "rgb(153, 51, 51)");
18220    test("hwb(from rebeccapurple 0deg w b / alpha)", "rgb(153, 51, 51)");
18221    test("hwb(from rebeccapurple h 0% b / alpha)", "rgb(77, 0, 153)");
18222    test("hwb(from rebeccapurple h w 0% / alpha)", "rgb(153, 51, 255)");
18223    test("hwb(from rebeccapurple h w b / 0)", "rgba(102, 51, 153, 0)");
18224    test(
18225      "hwb(from rgb(20%, 40%, 60%, 80%) 0 w b / alpha)",
18226      "rgba(153, 51, 51, 0.8)",
18227    );
18228    test(
18229      "hwb(from rgb(20%, 40%, 60%, 80%) 0deg w b / alpha)",
18230      "rgba(153, 51, 51, 0.8)",
18231    );
18232    test(
18233      "hwb(from rgb(20%, 40%, 60%, 80%) h 0% b / alpha)",
18234      "rgba(0, 77, 153, 0.8)",
18235    );
18236    test(
18237      "hwb(from rgb(20%, 40%, 60%, 80%) h w 0% / alpha)",
18238      "rgba(51, 153, 255, 0.8)",
18239    );
18240    test("hwb(from rgb(20%, 40%, 60%, 80%) h w b / 0)", "rgba(51, 102, 153, 0)");
18241
18242    // Testing replacement with a constant.
18243    test("hwb(from rebeccapurple 25 w b / alpha)", "rgb(153, 94, 51)");
18244    test("hwb(from rebeccapurple 25deg w b / alpha)", "rgb(153, 94, 51)");
18245    test("hwb(from rebeccapurple h 20% b / alpha)", "rgb(102, 51, 153)");
18246    test("hwb(from rebeccapurple h w 20% / alpha)", "rgb(128, 51, 204)");
18247    test("hwb(from rebeccapurple h w b / .2)", "rgba(102, 51, 153, 0.2)");
18248    test(
18249      "hwb(from rgb(20%, 40%, 60%, 80%) 25 w b / alpha)",
18250      "rgba(153, 94, 51, 0.8)",
18251    );
18252    test(
18253      "hwb(from rgb(20%, 40%, 60%, 80%) 25deg w b / alpha)",
18254      "rgba(153, 94, 51, 0.8)",
18255    );
18256    test(
18257      "hwb(from rgb(20%, 40%, 60%, 80%) h 20% b / alpha)",
18258      "rgba(51, 102, 153, 0.8)",
18259    );
18260    test(
18261      "hwb(from rgb(20%, 40%, 60%, 80%) h w 20% / alpha)",
18262      "rgba(51, 128, 204, 0.8)",
18263    );
18264    test(
18265      "hwb(from rgb(20%, 40%, 60%, 80%) h w b / .2)",
18266      "rgba(51, 102, 153, 0.2)",
18267    );
18268
18269    // Testing valid permutation (types match).
18270    test("hwb(from rebeccapurple h b w)", "rgb(153, 102, 204)");
18271    test("hwb(from rebeccapurple h alpha w / b)", "rgba(213, 213, 213, 0.4)");
18272    test("hwb(from rebeccapurple h w w / w)", "rgba(128, 51, 204, 0.2)");
18273    test("hwb(from rebeccapurple h alpha alpha / alpha)", "rgb(128, 128, 128)");
18274    test("hwb(from rgb(20%, 40%, 60%, 80%) h b w)", "rgb(102, 153, 204)");
18275    test(
18276      "hwb(from rgb(20%, 40%, 60%, 80%) h alpha w / b)",
18277      "rgba(204, 204, 204, 0.4)",
18278    );
18279    test("hwb(from rgb(20%, 40%, 60%, 80%) h w w / w)", "rgba(51, 128, 204, 0.2)");
18280    test(
18281      "hwb(from rgb(20%, 40%, 60%, 80%) h alpha alpha / alpha)",
18282      "rgba(128, 128, 128, 0.8)",
18283    );
18284
18285    // Testing with calc().
18286    test("hwb(from rebeccapurple calc(h) calc(w) calc(b))", "rgb(102, 51, 153)");
18287    test(
18288      "hwb(from rgb(20%, 40%, 60%, 80%) calc(h) calc(w) calc(b) / calc(alpha))",
18289      "rgba(51, 102, 153, 0.8)",
18290    );
18291
18292    // Testing with 'none'.
18293    test("hwb(from rebeccapurple none none none)", "rgb(255, 0, 0)");
18294    test("hwb(from rebeccapurple none none none / none)", "rgba(255, 0, 0, 0)");
18295    test("hwb(from rebeccapurple h w none)", "rgb(153, 51, 255)");
18296    test("hwb(from rebeccapurple h w none / alpha)", "rgb(153, 51, 255)");
18297    test("hwb(from rebeccapurple h w b / none)", "rgba(102, 51, 153, 0)");
18298    test("hwb(from rebeccapurple none w b / alpha)", "rgb(153, 51, 51)");
18299    test(
18300      "hwb(from hwb(120deg 20% 50% / .5) h w none / alpha)",
18301      "rgba(51, 255, 51, 0.5)",
18302    );
18303    test(
18304      "hwb(from hwb(120deg 20% 50% / .5) h w b / none)",
18305      "rgba(51, 128, 51, 0)",
18306    );
18307    test(
18308      "hwb(from hwb(120deg 20% 50% / .5) none w b / alpha)",
18309      "rgba(128, 51, 51, 0.5)",
18310    );
18311    // FIXME: Clarify with spec editors if 'none' should pass through to the constants.
18312    test("hwb(from hwb(none none none) h w b)", "rgb(255, 0, 0)");
18313    test(
18314      "hwb(from hwb(none none none / none) h w b / alpha)",
18315      "rgba(255, 0, 0, 0)",
18316    );
18317    test("hwb(from hwb(120deg none 50% / .5) h w b)", "rgb(0, 128, 0)");
18318    test(
18319      "hwb(from hwb(120deg 20% 50% / none) h w b / alpha)",
18320      "rgba(51, 128, 51, 0)",
18321    );
18322    test(
18323      "hwb(from hwb(none 20% 50% / .5) h w b / alpha)",
18324      "rgba(128, 51, 51, 0.5)",
18325    );
18326
18327    for color_space in &["lab", "oklab"] {
18328      // Testing no modifications.
18329      test(
18330        &format!("{}(from {}(25% 20 50) l a b)", color_space, color_space),
18331        &format!("{}(25% 20 50)", color_space),
18332      );
18333      test(
18334        &format!("{}(from {}(25% 20 50) l a b / alpha)", color_space, color_space),
18335        &format!("{}(25% 20 50)", color_space),
18336      );
18337      test(
18338        &format!("{}(from {}(25% 20 50 / 40%) l a b / alpha)", color_space, color_space),
18339        &format!("{}(25% 20 50 / 0.4)", color_space),
18340      );
18341      test(
18342        &format!(
18343          "{}(from {}(200% 300 400 / 500%) l a b / alpha)",
18344          color_space, color_space
18345        ),
18346        &format!("{}(200% 300 400)", color_space),
18347      );
18348      test(
18349        &format!(
18350          "{}(from {}(-200% -300 -400 / -500%) l a b / alpha)",
18351          color_space, color_space
18352        ),
18353        &format!("{}(0% -300 -400 / 0)", color_space),
18354      );
18355
18356      // Test nesting relative colors.
18357      test(
18358        &format!(
18359          "{}(from {}(from {}(25% 20 50) l a b) l a b)",
18360          color_space, color_space, color_space
18361        ),
18362        &format!("{}(25% 20 50)", color_space),
18363      );
18364
18365      // Testing non-${colorSpace} origin to see conversion.
18366      test(
18367        &format!("{}(from color(display-p3 0 0 0) l a b / alpha)", color_space),
18368        &format!("{}(0% 0 0)", color_space),
18369      );
18370
18371      // Testing replacement with 0.
18372      test(
18373        &format!("{}(from {}(25% 20 50) 0% 0 0)", color_space, color_space),
18374        &format!("{}(0% 0 0)", color_space),
18375      );
18376      test(
18377        &format!("{}(from {}(25% 20 50) 0% 0 0 / 0)", color_space, color_space),
18378        &format!("{}(0% 0 0 / 0)", color_space),
18379      );
18380      test(
18381        &format!("{}(from {}(25% 20 50) 0% a b / alpha)", color_space, color_space),
18382        &format!("{}(0% 20 50)", color_space),
18383      );
18384      test(
18385        &format!("{}(from {}(25% 20 50) l 0 b / alpha)", color_space, color_space),
18386        &format!("{}(25% 0 50)", color_space),
18387      );
18388      test(
18389        &format!("{}(from {}(25% 20 50) l a 0 / alpha)", color_space, color_space),
18390        &format!("{}(25% 20 0)", color_space),
18391      );
18392      test(
18393        &format!("{}(from {}(25% 20 50) l a b / 0)", color_space, color_space),
18394        &format!("{}(25% 20 50 / 0)", color_space),
18395      );
18396      test(
18397        &format!("{}(from {}(25% 20 50 / 40%) 0% a b / alpha)", color_space, color_space),
18398        &format!("{}(0% 20 50 / 0.4)", color_space),
18399      );
18400      test(
18401        &format!("{}(from {}(25% 20 50 / 40%) l 0 b / alpha)", color_space, color_space),
18402        &format!("{}(25% 0 50 / 0.4)", color_space),
18403      );
18404      test(
18405        &format!("{}(from {}(25% 20 50 / 40%) l a 0 / alpha)", color_space, color_space),
18406        &format!("{}(25% 20 0 / 0.4)", color_space),
18407      );
18408      test(
18409        &format!("{}(from {}(25% 20 50 / 40%) l a b / 0)", color_space, color_space),
18410        &format!("{}(25% 20 50 / 0)", color_space),
18411      );
18412
18413      // Testing replacement with a constant.
18414      test(
18415        &format!("{}(from {}(25% 20 50) 35% a b / alpha)", color_space, color_space),
18416        &format!("{}(35% 20 50)", color_space),
18417      );
18418      test(
18419        &format!("{}(from {}(25% 20 50) l 35 b / alpha)", color_space, color_space),
18420        &format!("{}(25% 35 50)", color_space),
18421      );
18422      test(
18423        &format!("{}(from {}(25% 20 50) l a 35 / alpha)", color_space, color_space),
18424        &format!("{}(25% 20 35)", color_space),
18425      );
18426      test(
18427        &format!("{}(from {}(25% 20 50) l a b / .35)", color_space, color_space),
18428        &format!("{}(25% 20 50 / 0.35)", color_space),
18429      );
18430      test(
18431        &format!("{}(from {}(25% 20 50 / 40%) 35% a b / alpha)", color_space, color_space),
18432        &format!("{}(35% 20 50 / 0.4)", color_space),
18433      );
18434      test(
18435        &format!("{}(from {}(25% 20 50 / 40%) l 35 b / alpha)", color_space, color_space),
18436        &format!("{}(25% 35 50 / 0.4)", color_space),
18437      );
18438      test(
18439        &format!("{}(from {}(25% 20 50 / 40%) l a 35 / alpha)", color_space, color_space),
18440        &format!("{}(25% 20 35 / 0.4)", color_space),
18441      );
18442      test(
18443        &format!("{}(from {}(25% 20 50 / 40%) l a b / .35)", color_space, color_space),
18444        &format!("{}(25% 20 50 / 0.35)", color_space),
18445      );
18446      test(
18447        &format!(
18448          "{}(from {}(70% 45 30 / 40%) 200% 300 400 / 500)",
18449          color_space, color_space
18450        ),
18451        &format!("{}(200% 300 400)", color_space),
18452      );
18453      test(
18454        &format!(
18455          "{}(from {}(70% 45 30 / 40%) -200% -300 -400 / -500)",
18456          color_space, color_space
18457        ),
18458        &format!("{}(0% -300 -400 / 0)", color_space),
18459      );
18460
18461      // Testing valid permutation (types match).
18462      test(
18463        &format!("{}(from {}(25% 20 50) l b a)", color_space, color_space),
18464        &format!("{}(25% 50 20)", color_space),
18465      );
18466      test(
18467        &format!("{}(from {}(25% 20 50) l a a / a)", color_space, color_space),
18468        &format!("{}(25% 20 20)", color_space),
18469      );
18470      test(
18471        &format!("{}(from {}(25% 20 50 / 40%) l b a)", color_space, color_space),
18472        &format!("{}(25% 50 20)", color_space),
18473      );
18474      test(
18475        &format!("{}(from {}(25% 20 50 / 40%) l a a / a)", color_space, color_space),
18476        &format!("{}(25% 20 20)", color_space),
18477      );
18478
18479      // Testing with calc().
18480      test(
18481        &format!(
18482          "{}(from {}(25% 20 50) calc(l) calc(a) calc(b))",
18483          color_space, color_space
18484        ),
18485        &format!("{}(25% 20 50)", color_space),
18486      );
18487      test(
18488        &format!(
18489          "{}(from {}(25% 20 50 / 40%) calc(l) calc(a) calc(b) / calc(alpha))",
18490          color_space, color_space
18491        ),
18492        &format!("{}(25% 20 50 / 0.4)", color_space),
18493      );
18494
18495      // Testing with 'none'.
18496      test(
18497        &format!("{}(from {}(25% 20 50) none none none)", color_space, color_space),
18498        &format!("{}(none none none)", color_space),
18499      );
18500      test(
18501        &format!("{}(from {}(25% 20 50) none none none / none)", color_space, color_space),
18502        &format!("{}(none none none / none)", color_space),
18503      );
18504      test(
18505        &format!("{}(from {}(25% 20 50) l a none)", color_space, color_space),
18506        &format!("{}(25% 20 none)", color_space),
18507      );
18508      test(
18509        &format!("{}(from {}(25% 20 50) l a none / alpha)", color_space, color_space),
18510        &format!("{}(25% 20 none)", color_space),
18511      );
18512      test(
18513        &format!("{}(from {}(25% 20 50) l a b / none)", color_space, color_space),
18514        &format!("{}(25% 20 50 / none)", color_space),
18515      );
18516      test(
18517        &format!(
18518          "{}(from {}(25% 20 50 / 40%) l a none / alpha)",
18519          color_space, color_space
18520        ),
18521        &format!("{}(25% 20 none / 0.4)", color_space),
18522      );
18523      test(
18524        &format!("{}(from {}(25% 20 50 / 40%) l a b / none)", color_space, color_space),
18525        &format!("{}(25% 20 50 / none)", color_space),
18526      );
18527      // FIXME: Clarify with spec editors if 'none' should pass through to the constants.
18528      test(
18529        &format!("{}(from {}(none none none) l a b)", color_space, color_space),
18530        &format!("{}(0% 0 0)", color_space),
18531      );
18532      test(
18533        &format!(
18534          "{}(from {}(none none none / none) l a b / alpha)",
18535          color_space, color_space
18536        ),
18537        &format!("{}(0% 0 0 / 0)", color_space),
18538      );
18539      test(
18540        &format!("{}(from {}(25% none 50) l a b)", color_space, color_space),
18541        &format!("{}(25% 0 50)", color_space),
18542      );
18543      test(
18544        &format!("{}(from {}(25% 20 50 / none) l a b / alpha)", color_space, color_space),
18545        &format!("{}(25% 20 50 / 0)", color_space),
18546      );
18547    }
18548
18549    // test_valid_value\(`color`, `\$\{colorSpace\}\(from \$\{colorSpace\}\((.*?)`,\s*`\$\{colorSpace\}(.*?)`\)
18550    // test(&format!("{}(from {}($1", color_space, color_space), &format!("{}$2", color_space))
18551
18552    for color_space in &["lch", "oklch"] {
18553      // Testing no modifications.
18554      test(
18555        &format!("{}(from {}(70% 45 30) l c h)", color_space, color_space),
18556        &format!("{}(70% 45 30)", color_space),
18557      );
18558      test(
18559        &format!("{}(from {}(70% 45 30) l c h / alpha)", color_space, color_space),
18560        &format!("{}(70% 45 30)", color_space),
18561      );
18562      test(
18563        &format!("{}(from {}(70% 45 30 / 40%) l c h / alpha)", color_space, color_space),
18564        &format!("{}(70% 45 30 / 0.4)", color_space),
18565      );
18566      test(
18567        &format!(
18568          "{}(from {}(200% 300 400 / 500%) l c h / alpha)",
18569          color_space, color_space
18570        ),
18571        &format!("{}(200% 300 40)", color_space),
18572      );
18573      test(
18574        &format!(
18575          "{}(from {}(-200% -300 -400 / -500%) l c h / alpha)",
18576          color_space, color_space
18577        ),
18578        &format!("{}(0% 0 320 / 0)", color_space),
18579      );
18580
18581      // Test nesting relative colors.
18582      test(
18583        &format!(
18584          "{}(from {}(from {}(70% 45 30) l c h) l c h)",
18585          color_space, color_space, color_space
18586        ),
18587        &format!("{}(70% 45 30)", color_space),
18588      );
18589
18590      // Testing non-sRGB origin colors (no gamut mapping will happen since the destination is not a bounded RGB color space).
18591      test(
18592        &format!("{}(from color(display-p3 0 0 0) l c h / alpha)", color_space),
18593        &format!("{}(0% 0 0)", color_space),
18594      );
18595
18596      // Testing replacement with 0.
18597      test(
18598        &format!("{}(from {}(70% 45 30) 0% 0 0)", color_space, color_space),
18599        &format!("{}(0% 0 0)", color_space),
18600      );
18601      test(
18602        &format!("{}(from {}(70% 45 30) 0% 0 0deg)", color_space, color_space),
18603        &format!("{}(0% 0 0)", color_space),
18604      );
18605      test(
18606        &format!("{}(from {}(70% 45 30) 0% 0 0 / 0)", color_space, color_space),
18607        &format!("{}(0% 0 0 / 0)", color_space),
18608      );
18609      test(
18610        &format!("{}(from {}(70% 45 30) 0% 0 0deg / 0)", color_space, color_space),
18611        &format!("{}(0% 0 0 / 0)", color_space),
18612      );
18613      test(
18614        &format!("{}(from {}(70% 45 30) 0% c h / alpha)", color_space, color_space),
18615        &format!("{}(0% 45 30)", color_space),
18616      );
18617      test(
18618        &format!("{}(from {}(70% 45 30) l 0 h / alpha)", color_space, color_space),
18619        &format!("{}(70% 0 30)", color_space),
18620      );
18621      test(
18622        &format!("{}(from {}(70% 45 30) l c 0 / alpha)", color_space, color_space),
18623        &format!("{}(70% 45 0)", color_space),
18624      );
18625      test(
18626        &format!("{}(from {}(70% 45 30) l c 0deg / alpha)", color_space, color_space),
18627        &format!("{}(70% 45 0)", color_space),
18628      );
18629      test(
18630        &format!("{}(from {}(70% 45 30) l c h / 0)", color_space, color_space),
18631        &format!("{}(70% 45 30 / 0)", color_space),
18632      );
18633      test(
18634        &format!("{}(from {}(70% 45 30 / 40%) 0% c h / alpha)", color_space, color_space),
18635        &format!("{}(0% 45 30 / 0.4)", color_space),
18636      );
18637      test(
18638        &format!("{}(from {}(70% 45 30 / 40%) l 0 h / alpha)", color_space, color_space),
18639        &format!("{}(70% 0 30 / 0.4)", color_space),
18640      );
18641      test(
18642        &format!("{}(from {}(70% 45 30 / 40%) l c 0 / alpha)", color_space, color_space),
18643        &format!("{}(70% 45 0 / 0.4)", color_space),
18644      );
18645      test(
18646        &format!(
18647          "{}(from {}(70% 45 30 / 40%) l c 0deg / alpha)",
18648          color_space, color_space
18649        ),
18650        &format!("{}(70% 45 0 / 0.4)", color_space),
18651      );
18652      test(
18653        &format!("{}(from {}(70% 45 30 / 40%) l c h / 0)", color_space, color_space),
18654        &format!("{}(70% 45 30 / 0)", color_space),
18655      );
18656
18657      // Testing replacement with a constant.
18658      test(
18659        &format!("{}(from {}(70% 45 30) 25% c h / alpha)", color_space, color_space),
18660        &format!("{}(25% 45 30)", color_space),
18661      );
18662      test(
18663        &format!("{}(from {}(70% 45 30) l 25 h / alpha)", color_space, color_space),
18664        &format!("{}(70% 25 30)", color_space),
18665      );
18666      test(
18667        &format!("{}(from {}(70% 45 30) l c 25 / alpha)", color_space, color_space),
18668        &format!("{}(70% 45 25)", color_space),
18669      );
18670      test(
18671        &format!("{}(from {}(70% 45 30) l c 25deg / alpha)", color_space, color_space),
18672        &format!("{}(70% 45 25)", color_space),
18673      );
18674      test(
18675        &format!("{}(from {}(70% 45 30) l c h / .25)", color_space, color_space),
18676        &format!("{}(70% 45 30 / 0.25)", color_space),
18677      );
18678      test(
18679        &format!("{}(from {}(70% 45 30 / 40%) 25% c h / alpha)", color_space, color_space),
18680        &format!("{}(25% 45 30 / 0.4)", color_space),
18681      );
18682      test(
18683        &format!("{}(from {}(70% 45 30 / 40%) l 25 h / alpha)", color_space, color_space),
18684        &format!("{}(70% 25 30 / 0.4)", color_space),
18685      );
18686      test(
18687        &format!("{}(from {}(70% 45 30 / 40%) l c 25 / alpha)", color_space, color_space),
18688        &format!("{}(70% 45 25 / 0.4)", color_space),
18689      );
18690      test(
18691        &format!(
18692          "{}(from {}(70% 45 30 / 40%) l c 25deg / alpha)",
18693          color_space, color_space
18694        ),
18695        &format!("{}(70% 45 25 / 0.4)", color_space),
18696      );
18697      test(
18698        &format!("{}(from {}(70% 45 30 / 40%) l c h / .25)", color_space, color_space),
18699        &format!("{}(70% 45 30 / 0.25)", color_space),
18700      );
18701      test(
18702        &format!(
18703          "{}(from {}(70% 45 30 / 40%) 200% 300 400 / 500)",
18704          color_space, color_space
18705        ),
18706        &format!("{}(200% 300 400)", color_space),
18707      );
18708      test(
18709        &format!(
18710          "{}(from {}(70% 45 30 / 40%) -200% -300 -400 / -500)",
18711          color_space, color_space
18712        ),
18713        &format!("{}(0% 0 -400 / 0)", color_space),
18714      );
18715      test(
18716        &format!(
18717          "{}(from {}(70% 45 30 / 40%) 50% 120 400deg / 500)",
18718          color_space, color_space
18719        ),
18720        &format!("{}(50% 120 400)", color_space),
18721      );
18722      test(
18723        &format!(
18724          "{}(from {}(70% 45 30 / 40%) 50% 120 -400deg / -500)",
18725          color_space, color_space
18726        ),
18727        &format!("{}(50% 120 -400 / 0)", color_space),
18728      );
18729
18730      // Testing valid permutation (types match).
18731      // NOTE: 'c' is a valid hue, as hue is <angle>|<number>.
18732      test(
18733        &format!("{}(from {}(70% 45 30) alpha c h / l)", color_space, color_space),
18734        &format!("{}(100% 45 30 / 0.7)", color_space),
18735      );
18736      test(
18737        &format!("{}(from {}(70% 45 30) l c c / alpha)", color_space, color_space),
18738        &format!("{}(70% 45 45)", color_space),
18739      );
18740      test(
18741        &format!("{}(from {}(70% 45 30) alpha c h / alpha)", color_space, color_space),
18742        &format!("{}(100% 45 30)", color_space),
18743      );
18744      test(
18745        &format!("{}(from {}(70% 45 30) alpha c c / alpha)", color_space, color_space),
18746        &format!("{}(100% 45 45)", color_space),
18747      );
18748      test(
18749        &format!("{}(from {}(70% 45 30 / 40%) alpha c h / l)", color_space, color_space),
18750        &format!("{}(40% 45 30 / 0.7)", color_space),
18751      );
18752      test(
18753        &format!("{}(from {}(70% 45 30 / 40%) l c c / alpha)", color_space, color_space),
18754        &format!("{}(70% 45 45 / 0.4)", color_space),
18755      );
18756      test(
18757        &format!(
18758          "{}(from {}(70% 45 30 / 40%) alpha c h / alpha)",
18759          color_space, color_space
18760        ),
18761        &format!("{}(40% 45 30 / 0.4)", color_space),
18762      );
18763      test(
18764        &format!(
18765          "{}(from {}(70% 45 30 / 40%) alpha c c / alpha)",
18766          color_space, color_space
18767        ),
18768        &format!("{}(40% 45 45 / 0.4)", color_space),
18769      );
18770
18771      // Testing with calc().
18772      test(
18773        &format!(
18774          "{}(from {}(70% 45 30) calc(l) calc(c) calc(h))",
18775          color_space, color_space
18776        ),
18777        &format!("{}(70% 45 30)", color_space),
18778      );
18779      test(
18780        &format!(
18781          "{}(from {}(70% 45 30 / 40%) calc(l) calc(c) calc(h) / calc(alpha))",
18782          color_space, color_space
18783        ),
18784        &format!("{}(70% 45 30 / 0.4)", color_space),
18785      );
18786
18787      // Testing with 'none'.
18788      test(
18789        &format!("{}(from {}(70% 45 30) none none none)", color_space, color_space),
18790        &format!("{}(none none none)", color_space),
18791      );
18792      test(
18793        &format!("{}(from {}(70% 45 30) none none none / none)", color_space, color_space),
18794        &format!("{}(none none none / none)", color_space),
18795      );
18796      test(
18797        &format!("{}(from {}(70% 45 30) l c none)", color_space, color_space),
18798        &format!("{}(70% 45 none)", color_space),
18799      );
18800      test(
18801        &format!("{}(from {}(70% 45 30) l c none / alpha)", color_space, color_space),
18802        &format!("{}(70% 45 none)", color_space),
18803      );
18804      test(
18805        &format!("{}(from {}(70% 45 30) l c h / none)", color_space, color_space),
18806        &format!("{}(70% 45 30 / none)", color_space),
18807      );
18808      test(
18809        &format!(
18810          "{}(from {}(70% 45 30 / 40%) l c none / alpha)",
18811          color_space, color_space
18812        ),
18813        &format!("{}(70% 45 none / 0.4)", color_space),
18814      );
18815      test(
18816        &format!("{}(from {}(70% 45 30 / 40%) l c h / none)", color_space, color_space),
18817        &format!("{}(70% 45 30 / none)", color_space),
18818      );
18819      // FIXME: Clarify with spec editors if 'none' should pass through to the constants.
18820      test(
18821        &format!("{}(from {}(none none none) l c h)", color_space, color_space),
18822        &format!("{}(0% 0 0)", color_space),
18823      );
18824      test(
18825        &format!(
18826          "{}(from {}(none none none / none) l c h / alpha)",
18827          color_space, color_space
18828        ),
18829        &format!("{}(0% 0 0 / 0)", color_space),
18830      );
18831      test(
18832        &format!("{}(from {}(70% none 30) l c h)", color_space, color_space),
18833        &format!("{}(70% 0 30)", color_space),
18834      );
18835      test(
18836        &format!("{}(from {}(70% 45 30 / none) l c h / alpha)", color_space, color_space),
18837        &format!("{}(70% 45 30 / 0)", color_space),
18838      );
18839    }
18840
18841    // test_valid_value\(`color`, `color\(from color\(\$\{colorSpace\}(.*?) \$\{colorSpace\}(.*?)`,\s*`color\(\$\{colorSpace\}(.*?)`\)
18842    // test(&format!("color(from color({}$1 {}$2", color_space, color_space), &format!("color({}$3", color_space))
18843
18844    for color_space in &["srgb", "srgb-linear", "a98-rgb", "rec2020", "prophoto-rgb"] {
18845      // Testing no modifications.
18846      test(
18847        &format!("color(from color({} 0.7 0.5 0.3) {} r g b)", color_space, color_space),
18848        &format!("color({} 0.7 0.5 0.3)", color_space),
18849      );
18850      test(
18851        &format!(
18852          "color(from color({} 0.7 0.5 0.3) {} r g b / alpha)",
18853          color_space, color_space
18854        ),
18855        &format!("color({} 0.7 0.5 0.3)", color_space),
18856      );
18857      test(
18858        &format!(
18859          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g b)",
18860          color_space, color_space
18861        ),
18862        &format!("color({} 0.7 0.5 0.3)", color_space),
18863      );
18864      test(
18865        &format!(
18866          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g b / alpha)",
18867          color_space, color_space
18868        ),
18869        &format!("color({} 0.7 0.5 0.3 / 0.4)", color_space),
18870      );
18871
18872      // Test nesting relative colors.
18873      test(
18874        &format!(
18875          "color(from color(from color({} 0.7 0.5 0.3) {} r g b) {} r g b)",
18876          color_space, color_space, color_space
18877        ),
18878        &format!("color({} 0.7 0.5 0.3)", color_space),
18879      );
18880
18881      // Testing replacement with 0.
18882      test(
18883        &format!("color(from color({} 0.7 0.5 0.3) {} 0 0 0)", color_space, color_space),
18884        &format!("color({} 0 0 0)", color_space),
18885      );
18886      test(
18887        &format!(
18888          "color(from color({} 0.7 0.5 0.3) {} 0 0 0 / 0)",
18889          color_space, color_space
18890        ),
18891        &format!("color({} 0 0 0 / 0)", color_space),
18892      );
18893      test(
18894        &format!(
18895          "color(from color({} 0.7 0.5 0.3) {} 0 g b / alpha)",
18896          color_space, color_space
18897        ),
18898        &format!("color({} 0 0.5 0.3)", color_space),
18899      );
18900      test(
18901        &format!(
18902          "color(from color({} 0.7 0.5 0.3) {} r 0 b / alpha)",
18903          color_space, color_space
18904        ),
18905        &format!("color({} 0.7 0 0.3)", color_space),
18906      );
18907      test(
18908        &format!(
18909          "color(from color({} 0.7 0.5 0.3) {} r g 0 / alpha)",
18910          color_space, color_space
18911        ),
18912        &format!("color({} 0.7 0.5 0)", color_space),
18913      );
18914      test(
18915        &format!(
18916          "color(from color({} 0.7 0.5 0.3) {} r g b / 0)",
18917          color_space, color_space
18918        ),
18919        &format!("color({} 0.7 0.5 0.3 / 0)", color_space),
18920      );
18921      test(
18922        &format!(
18923          "color(from color({} 0.7 0.5 0.3 / 40%) {} 0 g b / alpha)",
18924          color_space, color_space
18925        ),
18926        &format!("color({} 0 0.5 0.3 / 0.4)", color_space),
18927      );
18928      test(
18929        &format!(
18930          "color(from color({} 0.7 0.5 0.3 / 40%) {} r 0 b / alpha)",
18931          color_space, color_space
18932        ),
18933        &format!("color({} 0.7 0 0.3 / 0.4)", color_space),
18934      );
18935      test(
18936        &format!(
18937          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g 0 / alpha)",
18938          color_space, color_space
18939        ),
18940        &format!("color({} 0.7 0.5 0 / 0.4)", color_space),
18941      );
18942      test(
18943        &format!(
18944          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g b / 0)",
18945          color_space, color_space
18946        ),
18947        &format!("color({} 0.7 0.5 0.3 / 0)", color_space),
18948      );
18949
18950      // Testing replacement with a constant.
18951      test(
18952        &format!(
18953          "color(from color({} 0.7 0.5 0.3) {} 0.2 g b / alpha)",
18954          color_space, color_space
18955        ),
18956        &format!("color({} 0.2 0.5 0.3)", color_space),
18957      );
18958      test(
18959        &format!(
18960          "color(from color({} 0.7 0.5 0.3) {} 20% g b / alpha)",
18961          color_space, color_space
18962        ),
18963        &format!("color({} 0.2 0.5 0.3)", color_space),
18964      );
18965      test(
18966        &format!(
18967          "color(from color({} 0.7 0.5 0.3) {} r 0.2 b / alpha)",
18968          color_space, color_space
18969        ),
18970        &format!("color({} 0.7 0.2 0.3)", color_space),
18971      );
18972      test(
18973        &format!(
18974          "color(from color({} 0.7 0.5 0.3) {} r 20% b / alpha)",
18975          color_space, color_space
18976        ),
18977        &format!("color({} 0.7 0.2 0.3)", color_space),
18978      );
18979      test(
18980        &format!(
18981          "color(from color({} 0.7 0.5 0.3) {} r g 0.2 / alpha)",
18982          color_space, color_space
18983        ),
18984        &format!("color({} 0.7 0.5 0.2)", color_space),
18985      );
18986      test(
18987        &format!(
18988          "color(from color({} 0.7 0.5 0.3) {} r g 20% / alpha)",
18989          color_space, color_space
18990        ),
18991        &format!("color({} 0.7 0.5 0.2)", color_space),
18992      );
18993      test(
18994        &format!(
18995          "color(from color({} 0.7 0.5 0.3) {} r g b / 0.2)",
18996          color_space, color_space
18997        ),
18998        &format!("color({} 0.7 0.5 0.3 / 0.2)", color_space),
18999      );
19000      test(
19001        &format!(
19002          "color(from color({} 0.7 0.5 0.3) {} r g b / 20%)",
19003          color_space, color_space
19004        ),
19005        &format!("color({} 0.7 0.5 0.3 / 0.2)", color_space),
19006      );
19007      test(
19008        &format!(
19009          "color(from color({} 0.7 0.5 0.3 / 40%) {} 0.2 g b / alpha)",
19010          color_space, color_space
19011        ),
19012        &format!("color({} 0.2 0.5 0.3 / 0.4)", color_space),
19013      );
19014      test(
19015        &format!(
19016          "color(from color({} 0.7 0.5 0.3 / 40%) {} 20% g b / alpha)",
19017          color_space, color_space
19018        ),
19019        &format!("color({} 0.2 0.5 0.3 / 0.4)", color_space),
19020      );
19021      test(
19022        &format!(
19023          "color(from color({} 0.7 0.5 0.3 / 40%) {} r 0.2 b / alpha)",
19024          color_space, color_space
19025        ),
19026        &format!("color({} 0.7 0.2 0.3 / 0.4)", color_space),
19027      );
19028      test(
19029        &format!(
19030          "color(from color({} 0.7 0.5 0.3 / 40%) {} r 20% b / alpha)",
19031          color_space, color_space
19032        ),
19033        &format!("color({} 0.7 0.2 0.3 / 0.4)", color_space),
19034      );
19035      test(
19036        &format!(
19037          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g 0.2 / alpha)",
19038          color_space, color_space
19039        ),
19040        &format!("color({} 0.7 0.5 0.2 / 0.4)", color_space),
19041      );
19042      test(
19043        &format!(
19044          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g 20% / alpha)",
19045          color_space, color_space
19046        ),
19047        &format!("color({} 0.7 0.5 0.2 / 0.4)", color_space),
19048      );
19049      test(
19050        &format!(
19051          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g b / 0.2)",
19052          color_space, color_space
19053        ),
19054        &format!("color({} 0.7 0.5 0.3 / 0.2)", color_space),
19055      );
19056      test(
19057        &format!(
19058          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g b / 20%)",
19059          color_space, color_space
19060        ),
19061        &format!("color({} 0.7 0.5 0.3 / 0.2)", color_space),
19062      );
19063      test(
19064        &format!("color(from color({} 0.7 0.5 0.3) {} 2 3 4)", color_space, color_space),
19065        &format!("color({} 2 3 4)", color_space),
19066      );
19067      test(
19068        &format!(
19069          "color(from color({} 0.7 0.5 0.3) {} 2 3 4 / 5)",
19070          color_space, color_space
19071        ),
19072        &format!("color({} 2 3 4)", color_space),
19073      );
19074      test(
19075        &format!(
19076          "color(from color({} 0.7 0.5 0.3) {} -2 -3 -4)",
19077          color_space, color_space
19078        ),
19079        &format!("color({} -2 -3 -4)", color_space),
19080      );
19081      test(
19082        &format!(
19083          "color(from color({} 0.7 0.5 0.3) {} -2 -3 -4 / -5)",
19084          color_space, color_space
19085        ),
19086        &format!("color({} -2 -3 -4 / 0)", color_space),
19087      );
19088      test(
19089        &format!(
19090          "color(from color({} 0.7 0.5 0.3) {} 200% 300% 400%)",
19091          color_space, color_space
19092        ),
19093        &format!("color({} 2 3 4)", color_space),
19094      );
19095      test(
19096        &format!(
19097          "color(from color({} 0.7 0.5 0.3) {} 200% 300% 400% / 500%)",
19098          color_space, color_space
19099        ),
19100        &format!("color({} 2 3 4)", color_space),
19101      );
19102      test(
19103        &format!(
19104          "color(from color({} 0.7 0.5 0.3) {} -200% -300% -400%)",
19105          color_space, color_space
19106        ),
19107        &format!("color({} -2 -3 -4)", color_space),
19108      );
19109      test(
19110        &format!(
19111          "color(from color({} 0.7 0.5 0.3) {} -200% -300% -400% / -500%)",
19112          color_space, color_space
19113        ),
19114        &format!("color({} -2 -3 -4 / 0)", color_space),
19115      );
19116
19117      // Testing valid permutation (types match).
19118      test(
19119        &format!("color(from color({} 0.7 0.5 0.3) {} g b r)", color_space, color_space),
19120        &format!("color({} 0.5 0.3 0.7)", color_space),
19121      );
19122      test(
19123        &format!(
19124          "color(from color({} 0.7 0.5 0.3) {} b alpha r / g)",
19125          color_space, color_space
19126        ),
19127        &format!("color({} 0.3 1 0.7 / 0.5)", color_space),
19128      );
19129      test(
19130        &format!(
19131          "color(from color({} 0.7 0.5 0.3) {} r r r / r)",
19132          color_space, color_space
19133        ),
19134        &format!("color({} 0.7 0.7 0.7 / 0.7)", color_space),
19135      );
19136      test(
19137        &format!(
19138          "color(from color({} 0.7 0.5 0.3) {} alpha alpha alpha / alpha)",
19139          color_space, color_space
19140        ),
19141        &format!("color({} 1 1 1)", color_space),
19142      );
19143      test(
19144        &format!(
19145          "color(from color({} 0.7 0.5 0.3 / 40%) {} g b r)",
19146          color_space, color_space
19147        ),
19148        &format!("color({} 0.5 0.3 0.7)", color_space),
19149      );
19150      test(
19151        &format!(
19152          "color(from color({} 0.7 0.5 0.3 / 40%) {} b alpha r / g)",
19153          color_space, color_space
19154        ),
19155        &format!("color({} 0.3 0.4 0.7 / 0.5)", color_space),
19156      );
19157      test(
19158        &format!(
19159          "color(from color({} 0.7 0.5 0.3 / 40%) {} r r r / r)",
19160          color_space, color_space
19161        ),
19162        &format!("color({} 0.7 0.7 0.7 / 0.7)", color_space),
19163      );
19164      test(
19165        &format!(
19166          "color(from color({} 0.7 0.5 0.3 / 40%) {} alpha alpha alpha / alpha)",
19167          color_space, color_space
19168        ),
19169        &format!("color({} 0.4 0.4 0.4 / 0.4)", color_space),
19170      );
19171
19172      // Testing out of gamut components.
19173      test(
19174        &format!("color(from color({} 1.7 1.5 1.3) {} r g b)", color_space, color_space),
19175        &format!("color({} 1.7 1.5 1.3)", color_space),
19176      );
19177      test(
19178        &format!(
19179          "color(from color({} 1.7 1.5 1.3) {} r g b / alpha)",
19180          color_space, color_space
19181        ),
19182        &format!("color({} 1.7 1.5 1.3)", color_space),
19183      );
19184      test(
19185        &format!(
19186          "color(from color({} 1.7 1.5 1.3 / 140%) {} r g b)",
19187          color_space, color_space
19188        ),
19189        &format!("color({} 1.7 1.5 1.3)", color_space),
19190      );
19191      test(
19192        &format!(
19193          "color(from color({} 1.7 1.5 1.3 / 140%) {} r g b / alpha)",
19194          color_space, color_space
19195        ),
19196        &format!("color({} 1.7 1.5 1.3)", color_space),
19197      );
19198      test(
19199        &format!(
19200          "color(from color({} -0.7 -0.5 -0.3) {} r g b)",
19201          color_space, color_space
19202        ),
19203        &format!("color({} -0.7 -0.5 -0.3)", color_space),
19204      );
19205      test(
19206        &format!(
19207          "color(from color({} -0.7 -0.5 -0.3) {} r g b / alpha)",
19208          color_space, color_space
19209        ),
19210        &format!("color({} -0.7 -0.5 -0.3)", color_space),
19211      );
19212      test(
19213        &format!(
19214          "color(from color({} -0.7 -0.5 -0.3 / -40%) {} r g b)",
19215          color_space, color_space
19216        ),
19217        &format!("color({} -0.7 -0.5 -0.3)", color_space),
19218      );
19219      test(
19220        &format!(
19221          "color(from color({} -0.7 -0.5 -0.3 / -40%) {} r g b / alpha)",
19222          color_space, color_space
19223        ),
19224        &format!("color({} -0.7 -0.5 -0.3 / 0)", color_space),
19225      );
19226
19227      // Testing with calc().
19228      test(
19229        &format!(
19230          "color(from color({} 0.7 0.5 0.3) {} calc(r) calc(g) calc(b))",
19231          color_space, color_space
19232        ),
19233        &format!("color({} 0.7 0.5 0.3)", color_space),
19234      );
19235      test(
19236        &format!(
19237          "color(from color({} 0.7 0.5 0.3 / 40%) {} calc(r) calc(g) calc(b) / calc(alpha))",
19238          color_space, color_space
19239        ),
19240        &format!("color({} 0.7 0.5 0.3 / 0.4)", color_space),
19241      );
19242
19243      // Testing with 'none'.
19244      test(
19245        &format!(
19246          "color(from color({} 0.7 0.5 0.3) {} none none none)",
19247          color_space, color_space
19248        ),
19249        &format!("color({} none none none)", color_space),
19250      );
19251      test(
19252        &format!(
19253          "color(from color({} 0.7 0.5 0.3) {} none none none / none)",
19254          color_space, color_space
19255        ),
19256        &format!("color({} none none none / none)", color_space),
19257      );
19258      test(
19259        &format!(
19260          "color(from color({} 0.7 0.5 0.3) {} r g none)",
19261          color_space, color_space
19262        ),
19263        &format!("color({} 0.7 0.5 none)", color_space),
19264      );
19265      test(
19266        &format!(
19267          "color(from color({} 0.7 0.5 0.3) {} r g none / alpha)",
19268          color_space, color_space
19269        ),
19270        &format!("color({} 0.7 0.5 none)", color_space),
19271      );
19272      test(
19273        &format!(
19274          "color(from color({} 0.7 0.5 0.3) {} r g b / none)",
19275          color_space, color_space
19276        ),
19277        &format!("color({} 0.7 0.5 0.3 / none)", color_space),
19278      );
19279      test(
19280        &format!(
19281          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g none / alpha)",
19282          color_space, color_space
19283        ),
19284        &format!("color({} 0.7 0.5 none / 0.4)", color_space),
19285      );
19286      test(
19287        &format!(
19288          "color(from color({} 0.7 0.5 0.3 / 40%) {} r g b / none)",
19289          color_space, color_space
19290        ),
19291        &format!("color({} 0.7 0.5 0.3 / none)", color_space),
19292      );
19293      // FIXME: Clarify with spec editors if 'none' should pass through to the constants.
19294      test(
19295        &format!(
19296          "color(from color({} none none none) {} r g b)",
19297          color_space, color_space
19298        ),
19299        &format!("color({} 0 0 0)", color_space),
19300      );
19301      test(
19302        &format!(
19303          "color(from color({} none none none / none) {} r g b / alpha)",
19304          color_space, color_space
19305        ),
19306        &format!("color({} 0 0 0 / 0)", color_space),
19307      );
19308      test(
19309        &format!("color(from color({} 0.7 none 0.3) {} r g b)", color_space, color_space),
19310        &format!("color({} 0.7 0 0.3)", color_space),
19311      );
19312      test(
19313        &format!(
19314          "color(from color({} 0.7 0.5 0.3 / none) {} r g b / alpha)",
19315          color_space, color_space
19316        ),
19317        &format!("color({} 0.7 0.5 0.3 / 0)", color_space),
19318      );
19319    }
19320
19321    // test_valid_value\(`color`, `color\(from color\(\$\{colorSpace\}(.*?) \$\{colorSpace\}(.*?)`,\s*`color\(\$\{resultColorSpace\}(.*?)`\)
19322    // test(&format!("color(from color({}$1 {}$2", color_space, color_space), &format!("color({}$3", result_color_space))
19323
19324    for color_space in &["xyz", "xyz-d50", "xyz-d65"] {
19325      let result_color_space = if *color_space == "xyz" { "xyz-d65" } else { color_space };
19326
19327      // Testing no modifications.
19328      test(
19329        &format!("color(from color({} 7 -20.5 100) {} x y z)", color_space, color_space),
19330        &format!("color({} 7 -20.5 100)", result_color_space),
19331      );
19332      test(
19333        &format!(
19334          "color(from color({} 7 -20.5 100) {} x y z / alpha)",
19335          color_space, color_space
19336        ),
19337        &format!("color({} 7 -20.5 100)", result_color_space),
19338      );
19339      test(
19340        &format!(
19341          "color(from color({} 7 -20.5 100 / 40%) {} x y z)",
19342          color_space, color_space
19343        ),
19344        &format!("color({} 7 -20.5 100)", result_color_space),
19345      );
19346      test(
19347        &format!(
19348          "color(from color({} 7 -20.5 100 / 40%) {} x y z / alpha)",
19349          color_space, color_space
19350        ),
19351        &format!("color({} 7 -20.5 100 / 0.4)", result_color_space),
19352      );
19353
19354      // Test nesting relative colors.
19355      test(
19356        &format!(
19357          "color(from color(from color({} 7 -20.5 100) {} x y z) {} x y z)",
19358          color_space, color_space, color_space
19359        ),
19360        &format!("color({} 7 -20.5 100)", result_color_space),
19361      );
19362
19363      // Testing replacement with 0.
19364      test(
19365        &format!("color(from color({} 7 -20.5 100) {} 0 0 0)", color_space, color_space),
19366        &format!("color({} 0 0 0)", result_color_space),
19367      );
19368      test(
19369        &format!(
19370          "color(from color({} 7 -20.5 100) {} 0 0 0 / 0)",
19371          color_space, color_space
19372        ),
19373        &format!("color({} 0 0 0 / 0)", result_color_space),
19374      );
19375      test(
19376        &format!(
19377          "color(from color({} 7 -20.5 100) {} 0 y z / alpha)",
19378          color_space, color_space
19379        ),
19380        &format!("color({} 0 -20.5 100)", result_color_space),
19381      );
19382      test(
19383        &format!(
19384          "color(from color({} 7 -20.5 100) {} x 0 z / alpha)",
19385          color_space, color_space
19386        ),
19387        &format!("color({} 7 0 100)", result_color_space),
19388      );
19389      test(
19390        &format!(
19391          "color(from color({} 7 -20.5 100) {} x y 0 / alpha)",
19392          color_space, color_space
19393        ),
19394        &format!("color({} 7 -20.5 0)", result_color_space),
19395      );
19396      test(
19397        &format!(
19398          "color(from color({} 7 -20.5 100) {} x y z / 0)",
19399          color_space, color_space
19400        ),
19401        &format!("color({} 7 -20.5 100 / 0)", result_color_space),
19402      );
19403      test(
19404        &format!(
19405          "color(from color({} 7 -20.5 100 / 40%) {} 0 y z / alpha)",
19406          color_space, color_space
19407        ),
19408        &format!("color({} 0 -20.5 100 / 0.4)", result_color_space),
19409      );
19410      test(
19411        &format!(
19412          "color(from color({} 7 -20.5 100 / 40%) {} x 0 z / alpha)",
19413          color_space, color_space
19414        ),
19415        &format!("color({} 7 0 100 / 0.4)", result_color_space),
19416      );
19417      test(
19418        &format!(
19419          "color(from color({} 7 -20.5 100 / 40%) {} x y 0 / alpha)",
19420          color_space, color_space
19421        ),
19422        &format!("color({} 7 -20.5 0 / 0.4)", result_color_space),
19423      );
19424      test(
19425        &format!(
19426          "color(from color({} 7 -20.5 100 / 40%) {} x y z / 0)",
19427          color_space, color_space
19428        ),
19429        &format!("color({} 7 -20.5 100 / 0)", result_color_space),
19430      );
19431
19432      // Testing replacement with a constant.
19433      test(
19434        &format!(
19435          "color(from color({} 7 -20.5 100) {} 0.2 y z / alpha)",
19436          color_space, color_space
19437        ),
19438        &format!("color({} 0.2 -20.5 100)", result_color_space),
19439      );
19440      test(
19441        &format!(
19442          "color(from color({} 7 -20.5 100) {} x 0.2 z / alpha)",
19443          color_space, color_space
19444        ),
19445        &format!("color({} 7 0.2 100)", result_color_space),
19446      );
19447      test(
19448        &format!(
19449          "color(from color({} 7 -20.5 100) {} x y 0.2 / alpha)",
19450          color_space, color_space
19451        ),
19452        &format!("color({} 7 -20.5 0.2)", result_color_space),
19453      );
19454      test(
19455        &format!(
19456          "color(from color({} 7 -20.5 100) {} x y z / 0.2)",
19457          color_space, color_space
19458        ),
19459        &format!("color({} 7 -20.5 100 / 0.2)", result_color_space),
19460      );
19461      test(
19462        &format!(
19463          "color(from color({} 7 -20.5 100) {} x y z / 20%)",
19464          color_space, color_space
19465        ),
19466        &format!("color({} 7 -20.5 100 / 0.2)", result_color_space),
19467      );
19468      test(
19469        &format!(
19470          "color(from color({} 7 -20.5 100 / 40%) {} 0.2 y z / alpha)",
19471          color_space, color_space
19472        ),
19473        &format!("color({} 0.2 -20.5 100 / 0.4)", result_color_space),
19474      );
19475      test(
19476        &format!(
19477          "color(from color({} 7 -20.5 100 / 40%) {} x 0.2 z / alpha)",
19478          color_space, color_space
19479        ),
19480        &format!("color({} 7 0.2 100 / 0.4)", result_color_space),
19481      );
19482      test(
19483        &format!(
19484          "color(from color({} 7 -20.5 100 / 40%) {} x y 0.2 / alpha)",
19485          color_space, color_space
19486        ),
19487        &format!("color({} 7 -20.5 0.2 / 0.4)", result_color_space),
19488      );
19489      test(
19490        &format!(
19491          "color(from color({} 7 -20.5 100 / 40%) {} x y z / 0.2)",
19492          color_space, color_space
19493        ),
19494        &format!("color({} 7 -20.5 100 / 0.2)", result_color_space),
19495      );
19496
19497      // Testing valid permutation (types match).
19498      test(
19499        &format!("color(from color({} 7 -20.5 100) {} y z x)", color_space, color_space),
19500        &format!("color({} -20.5 100 7)", result_color_space),
19501      );
19502      test(
19503        &format!(
19504          "color(from color({} 7 -20.5 100) {} x x x / x)",
19505          color_space, color_space
19506        ),
19507        &format!("color({} 7 7 7)", result_color_space),
19508      );
19509      test(
19510        &format!(
19511          "color(from color({} 7 -20.5 100 / 40%) {} y z x)",
19512          color_space, color_space
19513        ),
19514        &format!("color({} -20.5 100 7)", result_color_space),
19515      );
19516      test(
19517        &format!(
19518          "color(from color({} 7 -20.5 100 / 40%) {} x x x / x)",
19519          color_space, color_space
19520        ),
19521        &format!("color({} 7 7 7)", result_color_space),
19522      );
19523
19524      // Testing with calc().
19525      test(
19526        &format!(
19527          "color(from color({} 7 -20.5 100) {} calc(x) calc(y) calc(z))",
19528          color_space, color_space
19529        ),
19530        &format!("color({} 7 -20.5 100)", result_color_space),
19531      );
19532      test(
19533        &format!(
19534          "color(from color({} 7 -20.5 100 / 40%) {} calc(x) calc(y) calc(z) / calc(alpha))",
19535          color_space, color_space
19536        ),
19537        &format!("color({} 7 -20.5 100 / 0.4)", result_color_space),
19538      );
19539
19540      // Testing with 'none'.
19541      test(
19542        &format!(
19543          "color(from color({} 7 -20.5 100) {} none none none)",
19544          color_space, color_space
19545        ),
19546        &format!("color({} none none none)", result_color_space),
19547      );
19548      test(
19549        &format!(
19550          "color(from color({} 7 -20.5 100) {} none none none / none)",
19551          color_space, color_space
19552        ),
19553        &format!("color({} none none none / none)", result_color_space),
19554      );
19555      test(
19556        &format!(
19557          "color(from color({} 7 -20.5 100) {} x y none)",
19558          color_space, color_space
19559        ),
19560        &format!("color({} 7 -20.5 none)", result_color_space),
19561      );
19562      test(
19563        &format!(
19564          "color(from color({} 7 -20.5 100) {} x y none / alpha)",
19565          color_space, color_space
19566        ),
19567        &format!("color({} 7 -20.5 none)", result_color_space),
19568      );
19569      test(
19570        &format!(
19571          "color(from color({} 7 -20.5 100) {} x y z / none)",
19572          color_space, color_space
19573        ),
19574        &format!("color({} 7 -20.5 100 / none)", result_color_space),
19575      );
19576      test(
19577        &format!(
19578          "color(from color({} 7 -20.5 100 / 40%) {} x y none / alpha)",
19579          color_space, color_space
19580        ),
19581        &format!("color({} 7 -20.5 none / 0.4)", result_color_space),
19582      );
19583      test(
19584        &format!(
19585          "color(from color({} 7 -20.5 100 / 40%) {} x y z / none)",
19586          color_space, color_space
19587        ),
19588        &format!("color({} 7 -20.5 100 / none)", result_color_space),
19589      );
19590      // FIXME: Clarify with spec editors if 'none' should pass through to the constants.
19591      test(
19592        &format!(
19593          "color(from color({} none none none) {} x y z)",
19594          color_space, color_space
19595        ),
19596        &format!("color({} 0 0 0)", result_color_space),
19597      );
19598      test(
19599        &format!(
19600          "color(from color({} none none none / none) {} x y z / alpha)",
19601          color_space, color_space
19602        ),
19603        &format!("color({} 0 0 0 / 0)", result_color_space),
19604      );
19605      test(
19606        &format!("color(from color({} 7 none 100) {} x y z)", color_space, color_space),
19607        &format!("color({} 7 0 100)", result_color_space),
19608      );
19609      test(
19610        &format!(
19611          "color(from color({} 7 -20.5 100 / none) {} x y z / alpha)",
19612          color_space, color_space
19613        ),
19614        &format!("color({} 7 -20.5 100 / 0)", result_color_space),
19615      );
19616
19617      // https://github.com/web-platform-tests/wpt/blob/master/css/css-color/parsing/relative-color-invalid.html
19618      minify_test(
19619        ".foo{color:rgb(from rebeccapurple r 10deg 10)}",
19620        ".foo{color:rgb(from rebeccapurple r 10deg 10)}",
19621      );
19622      minify_test(
19623        ".foo{color:rgb(from rebeccapurple l g b)}",
19624        ".foo{color:rgb(from rebeccapurple l g b)}",
19625      );
19626      minify_test(
19627        ".foo{color:hsl(from rebeccapurple s h l)}",
19628        ".foo{color:hsl(from rebeccapurple s h l)}",
19629      );
19630      minify_test(
19631        ".foo{color:hsl(from rebeccapurple s s s / s)}",
19632        ".foo{color:hsl(from rebeccapurple s s s/s)}",
19633      );
19634      minify_test(
19635        ".foo{color:hsl(from rebeccapurple alpha alpha alpha / alpha)}",
19636        ".foo{color:hsl(from rebeccapurple alpha alpha alpha/alpha)}",
19637      );
19638    }
19639  }
19640
19641  #[test]
19642  fn test_color_mix() {
19643    minify_test(
19644      ".foo { color: color-mix(in lab, purple 50%, plum 50%); }",
19645      ".foo{color:lab(51.5117% 43.3777 -29.0443)}",
19646    );
19647    minify_test(
19648      ".foo { color: color-mix(in lch, peru 40%, palegoldenrod); }",
19649      ".foo{color:lch(79.7255% 40.4542 84.7634)}",
19650    );
19651    minify_test(
19652      ".foo { color: color-mix(in lch, teal 65%, olive); }",
19653      ".foo{color:lch(49.4431% 40.4806 162.546)}",
19654    );
19655    minify_test(
19656      ".foo { color: color-mix(in lch, white, black); }",
19657      ".foo{color:lch(50% 0 none)}",
19658    );
19659    minify_test(
19660      ".foo { color: color-mix(in xyz, rgb(82.02% 30.21% 35.02%) 75.23%, rgb(5.64% 55.94% 85.31%)); }",
19661      ".foo{color:color(xyz .287458 .208776 .260566)}",
19662    );
19663    minify_test(
19664      ".foo { color: color-mix(in lch, white, blue); }",
19665      ".foo{color:lch(64.7842% 65.6007 301.364)}",
19666    );
19667    minify_test(
19668      ".foo { color: color-mix(in oklch, white, blue); }",
19669      ".foo{color:oklch(72.6007% .156607 264.052)}",
19670    );
19671    minify_test(
19672      ".foo { color: color-mix(in srgb, white, blue); }",
19673      ".foo{color:#8080ff}",
19674    );
19675    minify_test(
19676      ".foo { color: color-mix(in lch, blue, white); }",
19677      ".foo{color:lch(64.7842% 65.6007 301.364)}",
19678    );
19679    minify_test(
19680      ".foo { color: color-mix(in oklch, blue, white); }",
19681      ".foo{color:oklch(72.6007% .156607 264.052)}",
19682    );
19683    minify_test(
19684      ".foo { color: color-mix(in srgb, blue, white); }",
19685      ".foo{color:#8080ff}",
19686    );
19687    // minify_test(".foo { color: color-mix(in hsl, color(display-p3 0 1 0) 80%, yellow); }", ".foo{color:hsl(108 100% 49.9184%) }");
19688    minify_test(
19689      ".foo { color: color-mix(in hsl, hsl(120 100% 49.898%) 80%, yellow); }",
19690      ".foo{color:#33fe00}",
19691    );
19692    minify_test(
19693      ".foo { color: color-mix(in srgb, rgb(100% 0% 0% / 0.7) 25%, rgb(0% 100% 0% / 0.2)); }",
19694      ".foo{color:#89760053}",
19695    );
19696    minify_test(
19697      ".foo { color: color-mix(in srgb, rgb(100% 0% 0% / 0.7) 20%, rgb(0% 100% 0% / 0.2) 60%); }",
19698      ".foo{color:#89760042}",
19699    );
19700    minify_test(
19701      ".foo { color: color-mix(in lch, color(display-p3 0 1 none), color(display-p3 0 0 1)); }",
19702      ".foo{color:lch(58.8143% 141.732 218.684)}",
19703    );
19704    minify_test(
19705      ".foo { color: color-mix(in srgb, rgb(128 128 none), rgb(none none 128)); }",
19706      ".foo{color:gray}",
19707    );
19708    minify_test(
19709      ".foo { color: color-mix(in srgb, rgb(50% 50% none), rgb(none none 50%)); }",
19710      ".foo{color:gray}",
19711    );
19712    minify_test(
19713      ".foo { color: color-mix(in srgb, rgb(none 50% none), rgb(50% none 50%)); }",
19714      ".foo{color:gray}",
19715    );
19716    minify_test(
19717      ".foo { --color: color-mix(in lch, teal 65%, olive); }",
19718      ".foo{--color:lch(49.4431% 40.4806 162.546)}",
19719    );
19720    minify_test(
19721      ".foo { color: color-mix(in xyz, transparent, green 65%); }",
19722      ".foo{color:color(xyz .0771883 .154377 .0257295/.65)}",
19723    );
19724    prefix_test(
19725      ".foo { color: color-mix(in xyz, transparent, green 65%); }",
19726      indoc! { r#"
19727      .foo {
19728        color: #008000a6;
19729        color: color(xyz .0771883 .154377 .0257295 / .65);
19730      }
19731      "# },
19732      Browsers {
19733        chrome: Some(95 << 16),
19734        ..Default::default()
19735      },
19736    );
19737    minify_test(
19738      ".foo { color: color-mix(in srgb, currentColor, blue); }",
19739      ".foo{color:color-mix(in srgb,currentColor,blue)}",
19740    );
19741    minify_test(
19742      ".foo { color: color-mix(in srgb, blue, currentColor); }",
19743      ".foo{color:color-mix(in srgb,blue,currentColor)}",
19744    );
19745    minify_test(
19746      ".foo { color: color-mix(in srgb, accentcolor, blue); }",
19747      ".foo{color:color-mix(in srgb,accentcolor,blue)}",
19748    );
19749    minify_test(
19750      ".foo { color: color-mix(in srgb, blue, accentcolor); }",
19751      ".foo{color:color-mix(in srgb,blue,accentcolor)}",
19752    );
19753
19754    // regex for converting web platform tests:
19755    // test_computed_value\(.*?, `(.*?)`, `(.*?)`\);
19756    // minify_test(".foo { color: $1 }", ".foo{color:$2}");
19757
19758    // https://github.com/web-platform-tests/wpt/blob/f8c76b11cff66a7adc87264a18e39353cb5a60c9/css/css-color/parsing/color-mix-computed.html
19759    minify_test(
19760      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%)) }",
19761      ".foo{color:#545c3d}",
19762    );
19763    minify_test(
19764      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40%)) }",
19765      ".foo{color:#706a43}",
19766    );
19767    minify_test(
19768      ".foo { color: color-mix(in hsl, 25% hsl(120deg 10% 20%), hsl(30deg 30% 40%)) }",
19769      ".foo{color:#706a43}",
19770    );
19771    minify_test(
19772      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%), 25% hsl(30deg 30% 40%)) }",
19773      ".foo{color:#3d4936}",
19774    );
19775    minify_test(
19776      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%), hsl(30deg 30% 40%) 25%) }",
19777      ".foo{color:#3d4936}",
19778    );
19779    minify_test(
19780      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40%) 75%) }",
19781      ".foo{color:#706a43}",
19782    );
19783    minify_test(
19784      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%) 30%, hsl(30deg 30% 40%) 90%) }",
19785      ".foo{color:#706a43}",
19786    ); // Scale down > 100% sum.
19787    minify_test(
19788      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%) 12.5%, hsl(30deg 30% 40%) 37.5%) }",
19789      ".foo{color:#706a4380}",
19790    ); // Scale up < 100% sum, causes alpha multiplication.
19791    minify_test(
19792      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%) 0%, hsl(30deg 30% 40%)) }",
19793      ".foo{color:#856647}",
19794    );
19795
19796    minify_test(
19797      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20% / .4), hsl(30deg 30% 40% / .8)) }",
19798      ".foo{color:#5f694199}",
19799    );
19800    minify_test(
19801      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20%) 25%, hsl(30deg 30% 40% / .8)) }",
19802      ".foo{color:#6c6742d9}",
19803    );
19804    minify_test(
19805      ".foo { color: color-mix(in hsl, 25% hsl(120deg 10% 20% / .4), hsl(30deg 30% 40% / .8)) }",
19806      ".foo{color:#797245b3}",
19807    );
19808    minify_test(
19809      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20% / .4), 25% hsl(30deg 30% 40% / .8)) }",
19810      ".foo{color:#44543b80}",
19811    );
19812    minify_test(
19813      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20% / .4), hsl(30deg 30% 40% / .8) 25%) }",
19814      ".foo{color:#44543b80}",
19815    );
19816    minify_test(
19817      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20% / .4) 25%, hsl(30deg 30% 40% / .8) 75%) }",
19818      ".foo{color:#797245b3}",
19819    );
19820    minify_test(
19821      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20% / .4) 30%, hsl(30deg 30% 40% / .8) 90%) }",
19822      ".foo{color:#797245b3}",
19823    ); // Scale down > 100% sum.
19824    minify_test(
19825      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20% / .4) 12.5%, hsl(30deg 30% 40% / .8) 37.5%) }",
19826      ".foo{color:#79724559}",
19827    ); // Scale up < 100% sum, causes alpha multiplication.
19828    minify_test(
19829      ".foo { color: color-mix(in hsl, hsl(120deg 10% 20% / .4) 0%, hsl(30deg 30% 40% / .8)) }",
19830      ".foo{color:#856647cc}",
19831    );
19832
19833    fn canonicalize(s: &str) -> String {
19834      use crate::traits::{Parse, ToCss};
19835      use crate::values::color::CssColor;
19836      use cssparser::{Parser, ParserInput};
19837
19838      let mut input = ParserInput::new(s);
19839      let mut parser = Parser::new(&mut input);
19840      let v = CssColor::parse(&mut parser).unwrap().to_rgb().unwrap();
19841      format!(".foo{{color:{}}}", v.to_css_string(PrinterOptions::default()).unwrap())
19842    }
19843
19844    // regex for converting web platform tests:
19845    // test_computed_value\(.*?, `(.*?)`, canonicalize\(`(.*?)`\)\);
19846    // minify_test(".foo { color: $1 }", &canonicalize("$2"));
19847
19848    minify_test(
19849      ".foo { color: color-mix(in hsl, hsl(40deg 50% 50%), hsl(60deg 50% 50%)) }",
19850      &canonicalize("hsl(50deg 50% 50%)"),
19851    );
19852    minify_test(
19853      ".foo { color: color-mix(in hsl, hsl(60deg 50% 50%), hsl(40deg 50% 50%)) }",
19854      &canonicalize("hsl(50deg 50% 50%)"),
19855    );
19856    minify_test(
19857      ".foo { color: color-mix(in hsl, hsl(50deg 50% 50%), hsl(330deg 50% 50%)) }",
19858      &canonicalize("hsl(10deg 50% 50%)"),
19859    );
19860    minify_test(
19861      ".foo { color: color-mix(in hsl, hsl(330deg 50% 50%), hsl(50deg 50% 50%)) }",
19862      &canonicalize("hsl(10deg 50% 50%)"),
19863    );
19864    minify_test(
19865      ".foo { color: color-mix(in hsl, hsl(20deg 50% 50%), hsl(320deg 50% 50%)) }",
19866      &canonicalize("hsl(350deg 50% 50%)"),
19867    );
19868    minify_test(
19869      ".foo { color: color-mix(in hsl, hsl(320deg 50% 50%), hsl(20deg 50% 50%)) }",
19870      &canonicalize("hsl(350deg 50% 50%)"),
19871    );
19872
19873    minify_test(
19874      ".foo { color: color-mix(in hsl shorter hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%)) }",
19875      &canonicalize("hsl(50deg 50% 50%)"),
19876    );
19877    minify_test(
19878      ".foo { color: color-mix(in hsl shorter hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%)) }",
19879      &canonicalize("hsl(50deg 50% 50%)"),
19880    );
19881    minify_test(
19882      ".foo { color: color-mix(in hsl shorter hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%)) }",
19883      &canonicalize("hsl(10deg 50% 50%)"),
19884    );
19885    minify_test(
19886      ".foo { color: color-mix(in hsl shorter hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%)) }",
19887      &canonicalize("hsl(10deg 50% 50%)"),
19888    );
19889    minify_test(
19890      ".foo { color: color-mix(in hsl shorter hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%)) }",
19891      &canonicalize("hsl(350deg 50% 50%)"),
19892    );
19893    minify_test(
19894      ".foo { color: color-mix(in hsl shorter hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%)) }",
19895      &canonicalize("hsl(350deg 50% 50%)"),
19896    );
19897
19898    minify_test(
19899      ".foo { color: color-mix(in hsl longer hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%)) }",
19900      &canonicalize("hsl(230deg 50% 50%)"),
19901    );
19902    minify_test(
19903      ".foo { color: color-mix(in hsl longer hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%)) }",
19904      &canonicalize("hsl(230deg 50% 50%)"),
19905    );
19906    minify_test(
19907      ".foo { color: color-mix(in hsl longer hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%)) }",
19908      &canonicalize("hsl(190deg 50% 50%)"),
19909    );
19910    minify_test(
19911      ".foo { color: color-mix(in hsl longer hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%)) }",
19912      &canonicalize("hsl(190deg 50% 50%)"),
19913    );
19914    // minify_test(".foo { color: color-mix(in hsl longer hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%)) }", &canonicalize("hsl(170deg 50% 50%)"));
19915    // minify_test(".foo { color: color-mix(in hsl longer hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%)) }", &canonicalize("hsl(170deg 50% 50%)"));
19916
19917    minify_test(
19918      ".foo { color: color-mix(in hsl increasing hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%)) }",
19919      &canonicalize("hsl(50deg 50% 50%)"),
19920    );
19921    minify_test(
19922      ".foo { color: color-mix(in hsl increasing hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%)) }",
19923      &canonicalize("hsl(230deg 50% 50%)"),
19924    );
19925    minify_test(
19926      ".foo { color: color-mix(in hsl increasing hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%)) }",
19927      &canonicalize("hsl(190deg 50% 50%)"),
19928    );
19929    minify_test(
19930      ".foo { color: color-mix(in hsl increasing hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%)) }",
19931      &canonicalize("hsl(10deg 50% 50%)"),
19932    );
19933    // minify_test(".foo { color: color-mix(in hsl increasing hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%)) }", &canonicalize("hsl(170deg 50% 50%)"));
19934    // minify_test(".foo { color: color-mix(in hsl increasing hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%)) }", &canonicalize("hsl(350deg 50% 50%)"));
19935
19936    minify_test(
19937      ".foo { color: color-mix(in hsl decreasing hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%)) }",
19938      &canonicalize("hsl(230deg 50% 50%)"),
19939    );
19940    minify_test(
19941      ".foo { color: color-mix(in hsl decreasing hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%)) }",
19942      &canonicalize("hsl(50deg 50% 50%)"),
19943    );
19944    minify_test(
19945      ".foo { color: color-mix(in hsl decreasing hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%)) }",
19946      &canonicalize("hsl(10deg 50% 50%)"),
19947    );
19948    minify_test(
19949      ".foo { color: color-mix(in hsl decreasing hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%)) }",
19950      &canonicalize("hsl(190deg 50% 50%)"),
19951    );
19952    minify_test(
19953      ".foo { color: color-mix(in hsl decreasing hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%)) }",
19954      &canonicalize("hsl(350deg 50% 50%)"),
19955    );
19956    // minify_test(".foo { color: color-mix(in hsl decreasing hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%)) }", &canonicalize("hsl(170deg 50% 50%)"));
19957
19958    minify_test(
19959      ".foo { color: color-mix(in hsl specified hue, hsl(40deg 50% 50%), hsl(60deg 50% 50%)) }",
19960      &canonicalize("hsl(50deg 50% 50%)"),
19961    );
19962    minify_test(
19963      ".foo { color: color-mix(in hsl specified hue, hsl(60deg 50% 50%), hsl(40deg 50% 50%)) }",
19964      &canonicalize("hsl(50deg 50% 50%)"),
19965    );
19966    minify_test(
19967      ".foo { color: color-mix(in hsl specified hue, hsl(50deg 50% 50%), hsl(330deg 50% 50%)) }",
19968      &canonicalize("hsl(190deg 50% 50%)"),
19969    );
19970    minify_test(
19971      ".foo { color: color-mix(in hsl specified hue, hsl(330deg 50% 50%), hsl(50deg 50% 50%)) }",
19972      &canonicalize("hsl(190deg 50% 50%)"),
19973    );
19974    // minify_test(".foo { color: color-mix(in hsl specified hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%)) }", &canonicalize("hsl(170deg 50% 50%)"));
19975    // minify_test(".foo { color: color-mix(in hsl specified hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%)) }", &canonicalize("hsl(170deg 50% 50%)"));
19976
19977    minify_test(
19978      ".foo { color: color-mix(in hsl, hsl(none none none), hsl(none none none)) }",
19979      &canonicalize("hsl(none none none)"),
19980    );
19981    minify_test(
19982      ".foo { color: color-mix(in hsl, hsl(none none none), hsl(30deg 40% 80%)) }",
19983      &canonicalize("hsl(30deg 40% 80%)"),
19984    );
19985    minify_test(
19986      ".foo { color: color-mix(in hsl, hsl(120deg 20% 40%), hsl(none none none)) }",
19987      &canonicalize("hsl(120deg 20% 40%)"),
19988    );
19989    minify_test(
19990      ".foo { color: color-mix(in hsl, hsl(120deg 20% none), hsl(30deg 40% 60%)) }",
19991      &canonicalize("hsl(75deg 30% 60%)"),
19992    );
19993    minify_test(
19994      ".foo { color: color-mix(in hsl, hsl(120deg 20% 40%), hsl(30deg 20% none)) }",
19995      &canonicalize("hsl(75deg 20% 40%)"),
19996    );
19997    minify_test(
19998      ".foo { color: color-mix(in hsl, hsl(none 20% 40%), hsl(30deg none 80%)) }",
19999      &canonicalize("hsl(30deg 20% 60%)"),
20000    );
20001
20002    minify_test(
20003      ".foo { color: color-mix(in hsl, color(display-p3 0 1 0) 100%, rgb(0, 0, 0) 0%) }",
20004      &canonicalize("rgb(0, 249, 66)"),
20005    ); // Naive clip based mapping would give rgb(0, 255, 0).
20006    minify_test(
20007      ".foo { color: color-mix(in hsl, lab(100% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%) }",
20008      &canonicalize("rgb(255, 255, 255)"),
20009    ); // Naive clip based mapping would give rgb(255, 150, 255).
20010    minify_test(
20011      ".foo { color: color-mix(in hsl, lab(0% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%) }",
20012      &canonicalize("rgb(42, 0, 34)"),
20013    ); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black,
20014    minify_test(
20015      ".foo { color: color-mix(in hsl, lch(100% 116 334) 100%, rgb(0, 0, 0) 0%) }",
20016      &canonicalize("rgb(255, 255, 255)"),
20017    ); // Naive clip based mapping would give rgb(255, 150, 255).
20018    minify_test(
20019      ".foo { color: color-mix(in hsl, lch(0% 116 334) 100%, rgb(0, 0, 0) 0%) }",
20020      &canonicalize("rgb(42, 0, 34)"),
20021    ); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black,
20022    minify_test(
20023      ".foo { color: color-mix(in hsl, oklab(100% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%) }",
20024      &canonicalize("rgb(255, 255, 255)"),
20025    ); // Naive clip based mapping would give rgb(255, 92, 255).
20026    minify_test(
20027      ".foo { color: color-mix(in hsl, oklab(0% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%) }",
20028      &canonicalize("rgb(0, 0, 0)"),
20029    ); // Naive clip based mapping would give rgb(19, 0, 24).
20030    minify_test(
20031      ".foo { color: color-mix(in hsl, oklch(100% 0.399 336.3) 100%, rgb(0, 0, 0) 0%) }",
20032      &canonicalize("rgb(255, 255, 255)"),
20033    ); // Naive clip based mapping would give rgb(255, 91, 255).
20034    minify_test(
20035      ".foo { color: color-mix(in hsl, oklch(0% 0.399 336.3) 100%, rgb(0, 0, 0) 0%) }",
20036      &canonicalize("rgb(0, 0, 0)"),
20037    ); // Naive clip based mapping would give rgb(20, 0, 24).
20038
20039    minify_test(
20040      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%)) }",
20041      &canonicalize("rgb(147, 179, 52)"),
20042    );
20043    minify_test(
20044      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%)) }",
20045      &canonicalize("rgb(166, 153, 64)"),
20046    );
20047    minify_test(
20048      ".foo { color: color-mix(in hwb, 25% hwb(120deg 10% 20%), hwb(30deg 30% 40%)) }",
20049      &canonicalize("rgb(166, 153, 64)"),
20050    );
20051    minify_test(
20052      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%), 25% hwb(30deg 30% 40%)) }",
20053      &canonicalize("rgb(96, 191, 39)"),
20054    );
20055    minify_test(
20056      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%), hwb(30deg 30% 40%) 25%) }",
20057      &canonicalize("rgb(96, 191, 39)"),
20058    );
20059    minify_test(
20060      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%) 25%, hwb(30deg 30% 40%) 75%) }",
20061      &canonicalize("rgb(166, 153, 64)"),
20062    );
20063    minify_test(
20064      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%) 30%, hwb(30deg 30% 40%) 90%) }",
20065      &canonicalize("rgb(166, 153, 64)"),
20066    ); // Scale down > 100% sum.
20067    minify_test(
20068      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%) 12.5%, hwb(30deg 30% 40%) 37.5%) }",
20069      &canonicalize("rgba(166, 153, 64, 0.5)"),
20070    ); // Scale up < 100% sum, causes alpha multiplication.
20071    minify_test(
20072      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%) 0%, hwb(30deg 30% 40%)) }",
20073      &canonicalize("rgb(153, 115, 77)"),
20074    );
20075
20076    minify_test(
20077      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20% / .4), hwb(30deg 30% 40% / .8)) }",
20078      &canonicalize("rgba(143, 170, 60, 0.6)"),
20079    );
20080    minify_test(
20081      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20% / .4) 25%, hwb(30deg 30% 40% / .8)) }",
20082      &canonicalize("rgba(160, 149, 70, 0.7)"),
20083    );
20084    minify_test(
20085      ".foo { color: color-mix(in hwb, 25% hwb(120deg 10% 20% / .4), hwb(30deg 30% 40% / .8)) }",
20086      &canonicalize("rgba(160, 149, 70, 0.7)"),
20087    );
20088    minify_test(
20089      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20%), 25% hwb(30deg 30% 40% / .8)) }",
20090      &canonicalize("rgba(95, 193, 37, 0.95)"),
20091    );
20092    minify_test(
20093      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20% / .4), hwb(30deg 30% 40% / .8) 25%) }",
20094      &canonicalize("rgba(98, 184, 46, 0.5)"),
20095    );
20096    minify_test(
20097      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20% / .4) 25%, hwb(30deg 30% 40% / .8) 75%) }",
20098      &canonicalize("rgba(160, 149, 70, 0.7)"),
20099    );
20100    minify_test(
20101      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20% / .4) 30%, hwb(30deg 30% 40% / .8) 90%) }",
20102      &canonicalize("rgba(160, 149, 70, 0.7)"),
20103    ); // Scale down > 100% sum.
20104    minify_test(
20105      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20% / .4) 12.5%, hwb(30deg 30% 40% / .8) 37.5%) }",
20106      &canonicalize("rgba(160, 149, 70, 0.35)"),
20107    ); // Scale up < 100% sum, causes alpha multiplication.
20108    minify_test(
20109      ".foo { color: color-mix(in hwb, hwb(120deg 10% 20% / .4) 0%, hwb(30deg 30% 40% / .8)) }",
20110      &canonicalize("rgba(153, 115, 77, 0.8)"),
20111    );
20112
20113    //  minify_test(".foo { color: color-mix(in hwb, hwb(40deg 30% 40%), hwb(60deg 30% 40%)) }", &canonicalize("hwb(50deg 30% 40%)"));
20114    //  minify_test(".foo { color: color-mix(in hwb, hwb(60deg 30% 40%), hwb(40deg 30% 40%)) }", &canonicalize("hwb(50deg 30% 40%)"));
20115    minify_test(
20116      ".foo { color: color-mix(in hwb, hwb(50deg 30% 40%), hwb(330deg 30% 40%)) }",
20117      &canonicalize("hwb(10deg 30% 40%)"),
20118    );
20119    minify_test(
20120      ".foo { color: color-mix(in hwb, hwb(330deg 30% 40%), hwb(50deg 30% 40%)) }",
20121      &canonicalize("hwb(10deg 30% 40%)"),
20122    );
20123    minify_test(
20124      ".foo { color: color-mix(in hwb, hwb(20deg 30% 40%), hwb(320deg 30% 40%)) }",
20125      &canonicalize("hwb(350deg 30% 40%)"),
20126    );
20127    minify_test(
20128      ".foo { color: color-mix(in hwb, hwb(320deg 30% 40%), hwb(20deg 30% 40%)) }",
20129      &canonicalize("hwb(350deg 30% 40%)"),
20130    );
20131
20132    //  minify_test(".foo { color: color-mix(in hwb shorter hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%)) }", &canonicalize("hwb(50deg 30% 40%)"));
20133    //  minify_test(".foo { color: color-mix(in hwb shorter hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%)) }", &canonicalize("hwb(50deg 30% 40%)"));
20134    minify_test(
20135      ".foo { color: color-mix(in hwb shorter hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%)) }",
20136      &canonicalize("hwb(10deg 30% 40%)"),
20137    );
20138    minify_test(
20139      ".foo { color: color-mix(in hwb shorter hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%)) }",
20140      &canonicalize("hwb(10deg 30% 40%)"),
20141    );
20142    minify_test(
20143      ".foo { color: color-mix(in hwb shorter hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%)) }",
20144      &canonicalize("hwb(350deg 30% 40%)"),
20145    );
20146    minify_test(
20147      ".foo { color: color-mix(in hwb shorter hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%)) }",
20148      &canonicalize("hwb(350deg 30% 40%)"),
20149    );
20150
20151    minify_test(
20152      ".foo { color: color-mix(in hwb longer hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%)) }",
20153      &canonicalize("hwb(230deg 30% 40%)"),
20154    );
20155    minify_test(
20156      ".foo { color: color-mix(in hwb longer hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%)) }",
20157      &canonicalize("hwb(230deg 30% 40%)"),
20158    );
20159    //  minify_test(".foo { color: color-mix(in hwb longer hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%)) }", &canonicalize("hwb(190deg 30% 40%)"));
20160    //  minify_test(".foo { color: color-mix(in hwb longer hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%)) }", &canonicalize("hwb(190deg 30% 40%)"));
20161    //  minify_test(".foo { color: color-mix(in hwb longer hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%)) }", &canonicalize("hwb(170deg 30% 40%)"));
20162    //  minify_test(".foo { color: color-mix(in hwb longer hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%)) }", &canonicalize("hwb(170deg 30% 40%)"));
20163
20164    // minify_test(".foo { color: color-mix(in hwb increasing hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%)) }", &canonicalize("hwb(50deg 30% 40%)"));
20165    minify_test(
20166      ".foo { color: color-mix(in hwb increasing hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%)) }",
20167      &canonicalize("hwb(230deg 30% 40%)"),
20168    );
20169    // minify_test(".foo { color: color-mix(in hwb increasing hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%)) }", &canonicalize("hwb(190deg 30% 40%)"));
20170    minify_test(
20171      ".foo { color: color-mix(in hwb increasing hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%)) }",
20172      &canonicalize("hwb(10deg 30% 40%)"),
20173    );
20174    // minify_test(".foo { color: color-mix(in hwb increasing hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%)) }", &canonicalize("hwb(170deg 30% 40%)"));
20175    minify_test(
20176      ".foo { color: color-mix(in hwb increasing hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%)) }",
20177      &canonicalize("hwb(350deg 30% 40%)"),
20178    );
20179
20180    minify_test(
20181      ".foo { color: color-mix(in hwb decreasing hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%)) }",
20182      &canonicalize("hwb(230deg 30% 40%)"),
20183    );
20184    // minify_test(".foo { color: color-mix(in hwb decreasing hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%)) }", &canonicalize("hwb(50deg 30% 40%)"));
20185    minify_test(
20186      ".foo { color: color-mix(in hwb decreasing hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%)) }",
20187      &canonicalize("hwb(10deg 30% 40%)"),
20188    );
20189    // minify_test(".foo { color: color-mix(in hwb decreasing hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%)) }", &canonicalize("hwb(190deg 30% 40%)"));
20190    minify_test(
20191      ".foo { color: color-mix(in hwb decreasing hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%)) }",
20192      &canonicalize("hwb(350deg 30% 40%)"),
20193    );
20194    // minify_test(".foo { color: color-mix(in hwb decreasing hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%)) }", &canonicalize("hwb(170deg 30% 40%)"));
20195
20196    // minify_test(".foo { color: color-mix(in hwb specified hue, hwb(40deg 30% 40%), hwb(60deg 30% 40%)) }", &canonicalize("hwb(50deg 30% 40%)"));
20197    // minify_test(".foo { color: color-mix(in hwb specified hue, hwb(60deg 30% 40%), hwb(40deg 30% 40%)) }", &canonicalize("hwb(50deg 30% 40%)"));
20198    // minify_test(".foo { color: color-mix(in hwb specified hue, hwb(50deg 30% 40%), hwb(330deg 30% 40%)) }", &canonicalize("hwb(190deg 30% 40%)"));
20199    // minify_test(".foo { color: color-mix(in hwb specified hue, hwb(330deg 30% 40%), hwb(50deg 30% 40%)) }", &canonicalize("hwb(190deg 30% 40%)"));
20200    // minify_test(".foo { color: color-mix(in hwb specified hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%)) }", &canonicalize("hwb(170deg 30% 40%)"));
20201    // minify_test(".foo { color: color-mix(in hwb specified hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%)) }", &canonicalize("hwb(170deg 30% 40%)"));
20202
20203    minify_test(
20204      ".foo { color: color-mix(in hwb, color(display-p3 0 1 0) 100%, rgb(0, 0, 0) 0%) }",
20205      &canonicalize("rgb(0, 249, 66)"),
20206    ); // Naive clip based mapping would give rgb(0, 255, 0).
20207    minify_test(
20208      ".foo { color: color-mix(in hwb, lab(100% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%) }",
20209      &canonicalize("rgb(255, 255, 255)"),
20210    ); // Naive clip based mapping would give rgb(255, 150, 255).
20211    minify_test(
20212      ".foo { color: color-mix(in hwb, lab(0% 104.3 -50.9) 100%, rgb(0, 0, 0) 0%) }",
20213      &canonicalize("rgb(42, 0, 34)"),
20214    ); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black,
20215    minify_test(
20216      ".foo { color: color-mix(in hwb, lch(100% 116 334) 100%, rgb(0, 0, 0) 0%) }",
20217      &canonicalize("rgb(255, 255, 255)"),
20218    ); // Naive clip based mapping would give rgb(255, 150, 255).
20219    minify_test(
20220      ".foo { color: color-mix(in hwb, lch(0% 116 334) 100%, rgb(0, 0, 0) 0%) }",
20221      &canonicalize("rgb(42, 0, 34)"),
20222    ); // Naive clip based mapping would give rgb(90, 0, 76). NOTE: 0% lightness in Lab/LCH does not automatically correspond with sRGB black,
20223    minify_test(
20224      ".foo { color: color-mix(in hwb, oklab(100% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%) }",
20225      &canonicalize("rgb(255, 255, 255)"),
20226    ); // Naive clip based mapping would give rgb(255, 92, 255).
20227    minify_test(
20228      ".foo { color: color-mix(in hwb, oklab(0% 0.365 -0.16) 100%, rgb(0, 0, 0) 0%) }",
20229      &canonicalize("rgb(0, 0, 0)"),
20230    ); // Naive clip based mapping would give rgb(19, 0, 24).
20231    minify_test(
20232      ".foo { color: color-mix(in hwb, oklch(100% 0.399 336.3) 100%, rgb(0, 0, 0) 0%) }",
20233      &canonicalize("rgb(255, 255, 255)"),
20234    ); // Naive clip based mapping would give rgb(255, 91, 255).
20235    minify_test(
20236      ".foo { color: color-mix(in hwb, oklch(0% 0.399 336.3) 100%, rgb(0, 0, 0) 0%) }",
20237      &canonicalize("rgb(0, 0, 0)"),
20238    ); // Naive clip based mapping would give rgb(20, 0, 24).
20239
20240    for color_space in &["lch", "oklch"] {
20241      // regex for converting web platform tests:
20242      // test_computed_value\(.*?, `color-mix\(in \$\{colorSpace\}(.*?), (.*?)\$\{colorSpace\}(.*?) \$\{colorSpace\}(.*?)`, `\$\{colorSpace\}(.*?)`\);
20243      // minify_test(&format!(".foo {{ color: color-mix(in {0}$1, $2{0}$3 {0}$4 }}", color_space), &format!(".foo{{color:{}$5}}", color_space));
20244
20245      minify_test(
20246        &format!(
20247          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg), {0}(50% 60 70deg)) }}",
20248          color_space
20249        ),
20250        &format!(".foo{{color:{}(30% 40 50)}}", color_space),
20251      );
20252      minify_test(
20253        &format!(
20254          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg) 25%, {0}(50% 60 70deg)) }}",
20255          color_space
20256        ),
20257        &format!(".foo{{color:{}(40% 50 60)}}", color_space),
20258      );
20259      minify_test(
20260        &format!(
20261          ".foo {{ color: color-mix(in {0}, 25% {0}(10% 20 30deg), {0}(50% 60 70deg)) }}",
20262          color_space
20263        ),
20264        &format!(".foo{{color:{}(40% 50 60)}}", color_space),
20265      );
20266      minify_test(
20267        &format!(
20268          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg), 25% {0}(50% 60 70deg)) }}",
20269          color_space
20270        ),
20271        &format!(".foo{{color:{}(20% 30 40)}}", color_space),
20272      );
20273      minify_test(
20274        &format!(
20275          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg), {0}(50% 60 70deg) 25%) }}",
20276          color_space
20277        ),
20278        &format!(".foo{{color:{}(20% 30 40)}}", color_space),
20279      );
20280      minify_test(
20281        &format!(
20282          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg) 25%, {0}(50% 60 70deg) 75%) }}",
20283          color_space
20284        ),
20285        &format!(".foo{{color:{}(40% 50 60)}}", color_space),
20286      );
20287      minify_test(
20288        &format!(
20289          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg) 30%, {0}(50% 60 70deg) 90%) }}",
20290          color_space
20291        ),
20292        &format!(".foo{{color:{}(40% 50 60)}}", color_space),
20293      ); // Scale down > 100% sum.
20294      minify_test(
20295        &format!(
20296          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg) 12.5%, {0}(50% 60 70deg) 37.5%) }}",
20297          color_space
20298        ),
20299        &format!(".foo{{color:{}(40% 50 60/.5)}}", color_space),
20300      ); // Scale up < 100% sum, causes alpha multiplication.
20301      minify_test(
20302        &format!(
20303          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg) 0%, {0}(50% 60 70deg)) }}",
20304          color_space
20305        ),
20306        &format!(".foo{{color:{}(50% 60 70)}}", color_space),
20307      );
20308
20309      minify_test(
20310        &format!(
20311          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / .4), {0}(50% 60 70deg / .8)) }}",
20312          color_space
20313        ),
20314        &format!(".foo{{color:{}(36.6667% 46.6667 50/.6)}}", color_space),
20315      );
20316      minify_test(
20317        &format!(
20318          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / .4) 25%, {0}(50% 60 70deg / .8)) }}",
20319          color_space
20320        ),
20321        &format!(".foo{{color:{}(44.2857% 54.2857 60/.7)}}", color_space),
20322      );
20323      minify_test(
20324        &format!(
20325          ".foo {{ color: color-mix(in {0}, 25% {0}(10% 20 30deg / .4), {0}(50% 60 70deg / .8)) }}",
20326          color_space
20327        ),
20328        &format!(".foo{{color:{}(44.2857% 54.2857 60/.7)}}", color_space),
20329      );
20330      minify_test(
20331        &format!(
20332          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / .4), 25% {0}(50% 60 70deg / .8)) }}",
20333          color_space
20334        ),
20335        &format!(".foo{{color:{}(26% 36 40/.5)}}", color_space),
20336      );
20337      minify_test(
20338        &format!(
20339          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / .4), {0}(50% 60 70deg / .8) 25%) }}",
20340          color_space
20341        ),
20342        &format!(".foo{{color:{}(26% 36 40/.5)}}", color_space),
20343      );
20344      minify_test(
20345        &format!(
20346          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / .4) 25%, {0}(50% 60 70deg / .8) 75%) }}",
20347          color_space
20348        ),
20349        &format!(".foo{{color:{}(44.2857% 54.2857 60/.7)}}", color_space),
20350      );
20351      minify_test(
20352        &format!(
20353          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / .4) 30%, {0}(50% 60 70deg / .8) 90%) }}",
20354          color_space
20355        ),
20356        &format!(".foo{{color:{}(44.2857% 54.2857 60/.7)}}", color_space),
20357      ); // Scale down > 100% sum.
20358      minify_test(
20359        &format!(
20360          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / .4) 12.5%, {0}(50% 60 70deg / .8) 37.5%) }}",
20361          color_space
20362        ),
20363        &format!(".foo{{color:{}(44.2857% 54.2857 60/.35)}}", color_space),
20364      ); // Scale up < 100% sum, causes alpha multiplication.
20365      minify_test(
20366        &format!(
20367          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / .4) 0%, {0}(50% 60 70deg / .8)) }}",
20368          color_space
20369        ),
20370        &format!(".foo{{color:{}(50% 60 70/.8)}}", color_space),
20371      );
20372
20373      minify_test(
20374        &format!(
20375          ".foo {{ color: color-mix(in {0}, {0}(100% 0 40deg), {0}(100% 0 60deg)) }}",
20376          color_space
20377        ),
20378        &format!(".foo{{color:{}(100% 0 50)}}", color_space),
20379      );
20380      minify_test(
20381        &format!(
20382          ".foo {{ color: color-mix(in {0}, {0}(100% 0 60deg), {0}(100% 0 40deg)) }}",
20383          color_space
20384        ),
20385        &format!(".foo{{color:{}(100% 0 50)}}", color_space),
20386      );
20387      minify_test(
20388        &format!(
20389          ".foo {{ color: color-mix(in {0}, {0}(100% 0 50deg), {0}(100% 0 330deg)) }}",
20390          color_space
20391        ),
20392        &format!(".foo{{color:{}(100% 0 10)}}", color_space),
20393      );
20394      minify_test(
20395        &format!(
20396          ".foo {{ color: color-mix(in {0}, {0}(100% 0 330deg), {0}(100% 0 50deg)) }}",
20397          color_space
20398        ),
20399        &format!(".foo{{color:{}(100% 0 10)}}", color_space),
20400      );
20401      minify_test(
20402        &format!(
20403          ".foo {{ color: color-mix(in {0}, {0}(100% 0 20deg), {0}(100% 0 320deg)) }}",
20404          color_space
20405        ),
20406        &format!(".foo{{color:{}(100% 0 350)}}", color_space),
20407      );
20408      minify_test(
20409        &format!(
20410          ".foo {{ color: color-mix(in {0}, {0}(100% 0 320deg), {0}(100% 0 20deg)) }}",
20411          color_space
20412        ),
20413        &format!(".foo{{color:{}(100% 0 350)}}", color_space),
20414      );
20415
20416      minify_test(
20417        &format!(
20418          ".foo {{ color: color-mix(in {0} shorter hue, {0}(100% 0 40deg), {0}(100% 0 60deg)) }}",
20419          color_space
20420        ),
20421        &format!(".foo{{color:{}(100% 0 50)}}", color_space),
20422      );
20423      minify_test(
20424        &format!(
20425          ".foo {{ color: color-mix(in {0} shorter hue, {0}(100% 0 60deg), {0}(100% 0 40deg)) }}",
20426          color_space
20427        ),
20428        &format!(".foo{{color:{}(100% 0 50)}}", color_space),
20429      );
20430      minify_test(
20431        &format!(
20432          ".foo {{ color: color-mix(in {0} shorter hue, {0}(100% 0 50deg), {0}(100% 0 330deg)) }}",
20433          color_space
20434        ),
20435        &format!(".foo{{color:{}(100% 0 10)}}", color_space),
20436      );
20437      minify_test(
20438        &format!(
20439          ".foo {{ color: color-mix(in {0} shorter hue, {0}(100% 0 330deg), {0}(100% 0 50deg)) }}",
20440          color_space
20441        ),
20442        &format!(".foo{{color:{}(100% 0 10)}}", color_space),
20443      );
20444      minify_test(
20445        &format!(
20446          ".foo {{ color: color-mix(in {0} shorter hue, {0}(100% 0 20deg), {0}(100% 0 320deg)) }}",
20447          color_space
20448        ),
20449        &format!(".foo{{color:{}(100% 0 350)}}", color_space),
20450      );
20451      minify_test(
20452        &format!(
20453          ".foo {{ color: color-mix(in {0} shorter hue, {0}(100% 0 320deg), {0}(100% 0 20deg)) }}",
20454          color_space
20455        ),
20456        &format!(".foo{{color:{}(100% 0 350)}}", color_space),
20457      );
20458
20459      minify_test(
20460        &format!(
20461          ".foo {{ color: color-mix(in {0} longer hue, {0}(100% 0 40deg), {0}(100% 0 60deg)) }}",
20462          color_space
20463        ),
20464        &format!(".foo{{color:{}(100% 0 230)}}", color_space),
20465      );
20466      minify_test(
20467        &format!(
20468          ".foo {{ color: color-mix(in {0} longer hue, {0}(100% 0 60deg), {0}(100% 0 40deg)) }}",
20469          color_space
20470        ),
20471        &format!(".foo{{color:{}(100% 0 230)}}", color_space),
20472      );
20473      minify_test(
20474        &format!(
20475          ".foo {{ color: color-mix(in {0} longer hue, {0}(100% 0 50deg), {0}(100% 0 330deg)) }}",
20476          color_space
20477        ),
20478        &format!(".foo{{color:{}(100% 0 190)}}", color_space),
20479      );
20480      minify_test(
20481        &format!(
20482          ".foo {{ color: color-mix(in {0} longer hue, {0}(100% 0 330deg), {0}(100% 0 50deg)) }}",
20483          color_space
20484        ),
20485        &format!(".foo{{color:{}(100% 0 190)}}", color_space),
20486      );
20487      minify_test(
20488        &format!(
20489          ".foo {{ color: color-mix(in {0} longer hue, {0}(100% 0 20deg), {0}(100% 0 320deg)) }}",
20490          color_space
20491        ),
20492        &format!(".foo{{color:{}(100% 0 170)}}", color_space),
20493      );
20494      minify_test(
20495        &format!(
20496          ".foo {{ color: color-mix(in {0} longer hue, {0}(100% 0 320deg), {0}(100% 0 20deg)) }}",
20497          color_space
20498        ),
20499        &format!(".foo{{color:{}(100% 0 170)}}", color_space),
20500      );
20501
20502      minify_test(
20503        &format!(
20504          ".foo {{ color: color-mix(in {0} increasing hue, {0}(100% 0 40deg), {0}(100% 0 60deg)) }}",
20505          color_space
20506        ),
20507        &format!(".foo{{color:{}(100% 0 50)}}", color_space),
20508      );
20509      minify_test(
20510        &format!(
20511          ".foo {{ color: color-mix(in {0} increasing hue, {0}(100% 0 60deg), {0}(100% 0 40deg)) }}",
20512          color_space
20513        ),
20514        &format!(".foo{{color:{}(100% 0 230)}}", color_space),
20515      );
20516      minify_test(
20517        &format!(
20518          ".foo {{ color: color-mix(in {0} increasing hue, {0}(100% 0 50deg), {0}(100% 0 330deg)) }}",
20519          color_space
20520        ),
20521        &format!(".foo{{color:{}(100% 0 190)}}", color_space),
20522      );
20523      minify_test(
20524        &format!(
20525          ".foo {{ color: color-mix(in {0} increasing hue, {0}(100% 0 330deg), {0}(100% 0 50deg)) }}",
20526          color_space
20527        ),
20528        &format!(".foo{{color:{}(100% 0 10)}}", color_space),
20529      );
20530      minify_test(
20531        &format!(
20532          ".foo {{ color: color-mix(in {0} increasing hue, {0}(100% 0 20deg), {0}(100% 0 320deg)) }}",
20533          color_space
20534        ),
20535        &format!(".foo{{color:{}(100% 0 170)}}", color_space),
20536      );
20537      minify_test(
20538        &format!(
20539          ".foo {{ color: color-mix(in {0} increasing hue, {0}(100% 0 320deg), {0}(100% 0 20deg)) }}",
20540          color_space
20541        ),
20542        &format!(".foo{{color:{}(100% 0 350)}}", color_space),
20543      );
20544
20545      minify_test(
20546        &format!(
20547          ".foo {{ color: color-mix(in {0} decreasing hue, {0}(100% 0 40deg), {0}(100% 0 60deg)) }}",
20548          color_space
20549        ),
20550        &format!(".foo{{color:{}(100% 0 230)}}", color_space),
20551      );
20552      minify_test(
20553        &format!(
20554          ".foo {{ color: color-mix(in {0} decreasing hue, {0}(100% 0 60deg), {0}(100% 0 40deg)) }}",
20555          color_space
20556        ),
20557        &format!(".foo{{color:{}(100% 0 50)}}", color_space),
20558      );
20559      minify_test(
20560        &format!(
20561          ".foo {{ color: color-mix(in {0} decreasing hue, {0}(100% 0 50deg), {0}(100% 0 330deg)) }}",
20562          color_space
20563        ),
20564        &format!(".foo{{color:{}(100% 0 10)}}", color_space),
20565      );
20566      minify_test(
20567        &format!(
20568          ".foo {{ color: color-mix(in {0} decreasing hue, {0}(100% 0 330deg), {0}(100% 0 50deg)) }}",
20569          color_space
20570        ),
20571        &format!(".foo{{color:{}(100% 0 190)}}", color_space),
20572      );
20573      minify_test(
20574        &format!(
20575          ".foo {{ color: color-mix(in {0} decreasing hue, {0}(100% 0 20deg), {0}(100% 0 320deg)) }}",
20576          color_space
20577        ),
20578        &format!(".foo{{color:{}(100% 0 350)}}", color_space),
20579      );
20580      minify_test(
20581        &format!(
20582          ".foo {{ color: color-mix(in {0} decreasing hue, {0}(100% 0 320deg), {0}(100% 0 20deg)) }}",
20583          color_space
20584        ),
20585        &format!(".foo{{color:{}(100% 0 170)}}", color_space),
20586      );
20587
20588      minify_test(
20589        &format!(
20590          ".foo {{ color: color-mix(in {0} specified hue, {0}(100% 0 40deg), {0}(100% 0 60deg)) }}",
20591          color_space
20592        ),
20593        &format!(".foo{{color:{}(100% 0 50)}}", color_space),
20594      );
20595      minify_test(
20596        &format!(
20597          ".foo {{ color: color-mix(in {0} specified hue, {0}(100% 0 60deg), {0}(100% 0 40deg)) }}",
20598          color_space
20599        ),
20600        &format!(".foo{{color:{}(100% 0 50)}}", color_space),
20601      );
20602      minify_test(
20603        &format!(
20604          ".foo {{ color: color-mix(in {0} specified hue, {0}(100% 0 50deg), {0}(100% 0 330deg)) }}",
20605          color_space
20606        ),
20607        &format!(".foo{{color:{}(100% 0 190)}}", color_space),
20608      );
20609      minify_test(
20610        &format!(
20611          ".foo {{ color: color-mix(in {0} specified hue, {0}(100% 0 330deg), {0}(100% 0 50deg)) }}",
20612          color_space
20613        ),
20614        &format!(".foo{{color:{}(100% 0 190)}}", color_space),
20615      );
20616      minify_test(
20617        &format!(
20618          ".foo {{ color: color-mix(in {0} specified hue, {0}(100% 0 20deg), {0}(100% 0 320deg)) }}",
20619          color_space
20620        ),
20621        &format!(".foo{{color:{}(100% 0 170)}}", color_space),
20622      );
20623      minify_test(
20624        &format!(
20625          ".foo {{ color: color-mix(in {0} specified hue, {0}(100% 0 320deg), {0}(100% 0 20deg)) }}",
20626          color_space
20627        ),
20628        &format!(".foo{{color:{}(100% 0 170)}}", color_space),
20629      );
20630
20631      minify_test(
20632        &format!(
20633          ".foo {{ color: color-mix(in {0}, {0}(none none none), {0}(none none none)) }}",
20634          color_space
20635        ),
20636        &format!(".foo{{color:{}(none none none)}}", color_space),
20637      );
20638      minify_test(
20639        &format!(
20640          ".foo {{ color: color-mix(in {0}, {0}(none none none), {0}(50% 60 70deg)) }}",
20641          color_space
20642        ),
20643        &format!(".foo{{color:{}(50% 60 70)}}", color_space),
20644      );
20645      minify_test(
20646        &format!(
20647          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg), {0}(none none none)) }}",
20648          color_space
20649        ),
20650        &format!(".foo{{color:{}(10% 20 30)}}", color_space),
20651      );
20652      minify_test(
20653        &format!(
20654          ".foo {{ color: color-mix(in {0}, {0}(10% 20 none), {0}(50% 60 70deg)) }}",
20655          color_space
20656        ),
20657        &format!(".foo{{color:{}(30% 40 70)}}", color_space),
20658      );
20659      minify_test(
20660        &format!(
20661          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg), {0}(50% 60 none)) }}",
20662          color_space
20663        ),
20664        &format!(".foo{{color:{}(30% 40 30)}}", color_space),
20665      );
20666      minify_test(
20667        &format!(
20668          ".foo {{ color: color-mix(in {0}, {0}(none 20 30deg), {0}(50% none 70deg)) }}",
20669          color_space
20670        ),
20671        &format!(".foo{{color:{}(50% 20 50)}}", color_space),
20672      );
20673      minify_test(
20674        &format!(
20675          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / none), {0}(50% 60 70deg)) }}",
20676          color_space
20677        ),
20678        &format!(".foo{{color:{}(30% 40 50)}}", color_space),
20679      );
20680      minify_test(
20681        &format!(
20682          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / none), {0}(50% 60 70deg / 0.5)) }}",
20683          color_space
20684        ),
20685        &format!(".foo{{color:{}(30% 40 50/.5)}}", color_space),
20686      );
20687      minify_test(
20688        &format!(
20689          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30deg / none), {0}(50% 60 70deg / none)) }}",
20690          color_space
20691        ),
20692        &format!(".foo{{color:{}(30% 40 50/none)}}", color_space),
20693      );
20694    }
20695
20696    for color_space in ["lab", "oklab"] {
20697      minify_test(
20698        &format!(
20699          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30), {0}(50% 60 70)) }}",
20700          color_space
20701        ),
20702        &format!(".foo{{color:{}(30% 40 50)}}", color_space),
20703      );
20704      minify_test(
20705        &format!(
20706          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30) 25%, {0}(50% 60 70)) }}",
20707          color_space
20708        ),
20709        &format!(".foo{{color:{}(40% 50 60)}}", color_space),
20710      );
20711      minify_test(
20712        &format!(
20713          ".foo {{ color: color-mix(in {0}, 25% {0}(10% 20 30), {0}(50% 60 70)) }}",
20714          color_space
20715        ),
20716        &format!(".foo{{color:{}(40% 50 60)}}", color_space),
20717      );
20718      minify_test(
20719        &format!(
20720          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30), 25% {0}(50% 60 70)) }}",
20721          color_space
20722        ),
20723        &format!(".foo{{color:{}(20% 30 40)}}", color_space),
20724      );
20725      minify_test(
20726        &format!(
20727          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30), {0}(50% 60 70) 25%) }}",
20728          color_space
20729        ),
20730        &format!(".foo{{color:{}(20% 30 40)}}", color_space),
20731      );
20732      minify_test(
20733        &format!(
20734          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30) 25%, {0}(50% 60 70) 75%) }}",
20735          color_space
20736        ),
20737        &format!(".foo{{color:{}(40% 50 60)}}", color_space),
20738      );
20739      minify_test(
20740        &format!(
20741          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30) 30%, {0}(50% 60 70) 90%) }}",
20742          color_space
20743        ),
20744        &format!(".foo{{color:{}(40% 50 60)}}", color_space),
20745      ); // Scale down > 100% sum.
20746      minify_test(
20747        &format!(
20748          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30) 12.5%, {0}(50% 60 70) 37.5%) }}",
20749          color_space
20750        ),
20751        &format!(".foo{{color:{}(40% 50 60/.5)}}", color_space),
20752      ); // Scale up < 100% sum, causes alpha multiplication.
20753      minify_test(
20754        &format!(
20755          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30) 0%, {0}(50% 60 70)) }}",
20756          color_space
20757        ),
20758        &format!(".foo{{color:{}(50% 60 70)}}", color_space),
20759      );
20760
20761      minify_test(
20762        &format!(
20763          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / .4), {0}(50% 60 70 / .8)) }}",
20764          color_space
20765        ),
20766        &format!(".foo{{color:{}(36.6667% 46.6667 56.6667/.6)}}", color_space),
20767      );
20768      minify_test(
20769        &format!(
20770          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / .4) 25%, {0}(50% 60 70 / .8)) }}",
20771          color_space
20772        ),
20773        &format!(".foo{{color:{}(44.2857% 54.2857 64.2857/.7)}}", color_space),
20774      );
20775      minify_test(
20776        &format!(
20777          ".foo {{ color: color-mix(in {0}, 25% {0}(10% 20 30 / .4), {0}(50% 60 70 / .8)) }}",
20778          color_space
20779        ),
20780        &format!(".foo{{color:{}(44.2857% 54.2857 64.2857/.7)}}", color_space),
20781      );
20782      minify_test(
20783        &format!(
20784          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / .4), 25% {0}(50% 60 70 / .8)) }}",
20785          color_space
20786        ),
20787        &format!(".foo{{color:{}(26% 36 46/.5)}}", color_space),
20788      );
20789      minify_test(
20790        &format!(
20791          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / .4), {0}(50% 60 70 / .8) 25%) }}",
20792          color_space
20793        ),
20794        &format!(".foo{{color:{}(26% 36 46/.5)}}", color_space),
20795      );
20796      minify_test(
20797        &format!(
20798          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / .4) 25%, {0}(50% 60 70 / .8) 75%) }}",
20799          color_space
20800        ),
20801        &format!(".foo{{color:{}(44.2857% 54.2857 64.2857/.7)}}", color_space),
20802      );
20803      minify_test(
20804        &format!(
20805          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / .4) 30%, {0}(50% 60 70 / .8) 90%) }}",
20806          color_space
20807        ),
20808        &format!(".foo{{color:{}(44.2857% 54.2857 64.2857/.7)}}", color_space),
20809      ); // Scale down > 100% sum.
20810      minify_test(
20811        &format!(
20812          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / .4) 12.5%, {0}(50% 60 70 / .8) 37.5%) }}",
20813          color_space
20814        ),
20815        &format!(".foo{{color:{}(44.2857% 54.2857 64.2857/.35)}}", color_space),
20816      ); // Scale up < 100% sum, causes alpha multiplication.
20817      minify_test(
20818        &format!(
20819          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / .4) 0%, {0}(50% 60 70 / .8)) }}",
20820          color_space
20821        ),
20822        &format!(".foo{{color:{}(50% 60 70/.8)}}", color_space),
20823      );
20824
20825      minify_test(
20826        &format!(
20827          ".foo {{ color: color-mix(in {0}, {0}(none none none), {0}(none none none)) }}",
20828          color_space
20829        ),
20830        &format!(".foo{{color:{}(none none none)}}", color_space),
20831      );
20832      minify_test(
20833        &format!(
20834          ".foo {{ color: color-mix(in {0}, {0}(none none none), {0}(50% 60 70)) }}",
20835          color_space
20836        ),
20837        &format!(".foo{{color:{}(50% 60 70)}}", color_space),
20838      );
20839      minify_test(
20840        &format!(
20841          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30), {0}(none none none)) }}",
20842          color_space
20843        ),
20844        &format!(".foo{{color:{}(10% 20 30)}}", color_space),
20845      );
20846      minify_test(
20847        &format!(
20848          ".foo {{ color: color-mix(in {0}, {0}(10% 20 none), {0}(50% 60 70)) }}",
20849          color_space
20850        ),
20851        &format!(".foo{{color:{}(30% 40 70)}}", color_space),
20852      );
20853      minify_test(
20854        &format!(
20855          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30), {0}(50% 60 none)) }}",
20856          color_space
20857        ),
20858        &format!(".foo{{color:{}(30% 40 30)}}", color_space),
20859      );
20860      minify_test(
20861        &format!(
20862          ".foo {{ color: color-mix(in {0}, {0}(none 20 30), {0}(50% none 70)) }}",
20863          color_space
20864        ),
20865        &format!(".foo{{color:{}(50% 20 50)}}", color_space),
20866      );
20867      minify_test(
20868        &format!(
20869          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / none), {0}(50% 60 70)) }}",
20870          color_space
20871        ),
20872        &format!(".foo{{color:{}(30% 40 50)}}", color_space),
20873      );
20874      minify_test(
20875        &format!(
20876          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / none), {0}(50% 60 70 / 0.5)) }}",
20877          color_space
20878        ),
20879        &format!(".foo{{color:{}(30% 40 50/.5)}}", color_space),
20880      );
20881      minify_test(
20882        &format!(
20883          ".foo {{ color: color-mix(in {0}, {0}(10% 20 30 / none), {0}(50% 60 70 / none)) }}",
20884          color_space
20885        ),
20886        &format!(".foo{{color:{}(30% 40 50/none)}}", color_space),
20887      );
20888    }
20889
20890    for color_space in [/*"srgb", */ "srgb-linear", "xyz", "xyz-d50", "xyz-d65"] {
20891      // regex for converting web platform tests:
20892      // test_computed_value\(.*?, `color-mix\(in \$\{colorSpace\}(.*?), (.*?)color\(\$\{colorSpace\}(.*?) color\(\$\{colorSpace\}(.*?)`, `color\(\$\{resultColorSpace\}(.*?)`\);
20893      // 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));
20894
20895      let result_color_space = if color_space == "xyz-d65" { "xyz" } else { color_space };
20896
20897      minify_test(
20898        &format!(
20899          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3), color({0} .5 .6 .7)) }}",
20900          color_space
20901        ),
20902        &format!(".foo{{color:color({} .3 .4 .5)}}", result_color_space),
20903      );
20904      minify_test(
20905        &format!(
20906          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3) 25%, color({0} .5 .6 .7)) }}",
20907          color_space
20908        ),
20909        &format!(".foo{{color:color({} .4 .5 .6)}}", result_color_space),
20910      );
20911      minify_test(
20912        &format!(
20913          ".foo {{ color: color-mix(in {0}, 25% color({0} .1 .2 .3), color({0} .5 .6 .7)) }}",
20914          color_space
20915        ),
20916        &format!(".foo{{color:color({} .4 .5 .6)}}", result_color_space),
20917      );
20918      minify_test(
20919        &format!(
20920          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3), color({0} .5 .6 .7) 25%) }}",
20921          color_space
20922        ),
20923        &format!(".foo{{color:color({} .2 .3 .4)}}", result_color_space),
20924      );
20925      minify_test(
20926        &format!(
20927          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3), 25% color({0} .5 .6 .7)) }}",
20928          color_space
20929        ),
20930        &format!(".foo{{color:color({} .2 .3 .4)}}", result_color_space),
20931      );
20932      minify_test(
20933        &format!(
20934          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3) 25%, color({0} .5 .6 .7) 75%) }}",
20935          color_space
20936        ),
20937        &format!(".foo{{color:color({} .4 .5 .6)}}", result_color_space),
20938      );
20939      minify_test(
20940        &format!(
20941          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3) 30%, color({0} .5 .6 .7) 90%) }}",
20942          color_space
20943        ),
20944        &format!(".foo{{color:color({} .4 .5 .6)}}", result_color_space),
20945      ); // Scale down > 100% sum.
20946      minify_test(
20947        &format!(
20948          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3) 12.5%, color({0} .5 .6 .7) 37.5%) }}",
20949          color_space
20950        ),
20951        &format!(".foo{{color:color({} .4 .5 .6/.5)}}", result_color_space),
20952      ); // Scale up < 100% sum, causes alpha multiplication.
20953      minify_test(
20954        &format!(
20955          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3) 0%, color({0} .5 .6 .7)) }}",
20956          color_space
20957        ),
20958        &format!(".foo{{color:color({} .5 .6 .7)}}", result_color_space),
20959      );
20960
20961      minify_test(
20962        &format!(
20963          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / .5), color({0} .5 .6 .7 / .8)) }}",
20964          color_space
20965        ),
20966        &format!(
20967          ".foo{{color:color({} .346154 .446154 .546154/.65)}}",
20968          result_color_space
20969        ),
20970      );
20971      minify_test(
20972        &format!(
20973          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / .4) 25%, color({0} .5 .6 .7 / .8)) }}",
20974          color_space
20975        ),
20976        &format!(".foo{{color:color({} .442857 .542857 .642857/.7)}}", result_color_space),
20977      );
20978      minify_test(
20979        &format!(
20980          ".foo {{ color: color-mix(in {0}, 25% color({0} .1 .2 .3 / .4), color({0} .5 .6 .7 / .8)) }}",
20981          color_space
20982        ),
20983        &format!(".foo{{color:color({} .442857 .542857 .642857/.7)}}", result_color_space),
20984      );
20985      minify_test(
20986        &format!(
20987          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / .4), color({0} .5 .6 .7 / .8) 25%) }}",
20988          color_space
20989        ),
20990        &format!(".foo{{color:color({} .26 .36 .46/.5)}}", result_color_space),
20991      );
20992      minify_test(
20993        &format!(
20994          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / .4), 25% color({0} .5 .6 .7 / .8)) }}",
20995          color_space
20996        ),
20997        &format!(".foo{{color:color({} .26 .36 .46/.5)}}", result_color_space),
20998      );
20999      minify_test(
21000        &format!(
21001          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / .4) 25%, color({0} .5 .6 .7 / .8) 75%) }}",
21002          color_space
21003        ),
21004        &format!(".foo{{color:color({} .442857 .542857 .642857/.7)}}", result_color_space),
21005      );
21006      minify_test(
21007        &format!(
21008          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / .4) 30%, color({0} .5 .6 .7 / .8) 90%) }}",
21009          color_space
21010        ),
21011        &format!(".foo{{color:color({} .442857 .542857 .642857/.7)}}", result_color_space),
21012      ); // Scale down > 100% sum.
21013      minify_test(
21014        &format!(
21015          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / .4) 12.5%, color({0} .5 .6 .7 / .8) 37.5%) }}",
21016          color_space
21017        ),
21018        &format!(
21019          ".foo{{color:color({} .442857 .542857 .642857/.35)}}",
21020          result_color_space
21021        ),
21022      ); // Scale up < 100% sum, causes alpha multiplication.
21023      minify_test(
21024        &format!(
21025          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / .4) 0%, color({0} .5 .6 .7 / .8)) }}",
21026          color_space
21027        ),
21028        &format!(".foo{{color:color({} .5 .6 .7/.8)}}", result_color_space),
21029      );
21030
21031      minify_test(
21032        &format!(
21033          ".foo {{ color: color-mix(in {0}, color({0} 2 3 4 / 5), color({0} 4 6 8 / 10)) }}",
21034          color_space
21035        ),
21036        &format!(".foo{{color:color({} 3 4.5 6)}}", result_color_space),
21037      );
21038      minify_test(
21039        &format!(
21040          ".foo {{ color: color-mix(in {0}, color({0} -2 -3 -4), color({0} -4 -6 -8)) }}",
21041          color_space
21042        ),
21043        &format!(".foo{{color:color({} -3 -4.5 -6)}}", result_color_space),
21044      );
21045      minify_test(
21046        &format!(
21047          ".foo {{ color: color-mix(in {0}, color({0} -2 -3 -4 / -5), color({0} -4 -6 -8 / -10)) }}",
21048          color_space
21049        ),
21050        &format!(".foo{{color:color({} 0 0 0/0)}}", result_color_space),
21051      );
21052
21053      minify_test(
21054        &format!(
21055          ".foo {{ color: color-mix(in {0}, color({0} none none none), color({0} none none none)) }}",
21056          color_space
21057        ),
21058        &format!(".foo{{color:color({} none none none)}}", result_color_space),
21059      );
21060      minify_test(
21061        &format!(
21062          ".foo {{ color: color-mix(in {0}, color({0} none none none), color({0} .5 .6 .7)) }}",
21063          color_space
21064        ),
21065        &format!(".foo{{color:color({} .5 .6 .7)}}", result_color_space),
21066      );
21067      minify_test(
21068        &format!(
21069          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3), color({0} none none none)) }}",
21070          color_space
21071        ),
21072        &format!(".foo{{color:color({} .1 .2 .3)}}", result_color_space),
21073      );
21074      minify_test(
21075        &format!(
21076          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 none), color({0} .5 .6 .7)) }}",
21077          color_space
21078        ),
21079        &format!(".foo{{color:color({} .3 .4 .7)}}", result_color_space),
21080      );
21081      minify_test(
21082        &format!(
21083          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3), color({0} .5 .6 none)) }}",
21084          color_space
21085        ),
21086        &format!(".foo{{color:color({} .3 .4 .3)}}", result_color_space),
21087      );
21088      minify_test(
21089        &format!(
21090          ".foo {{ color: color-mix(in {0}, color({0} none .2 .3), color({0} .5 none .7)) }}",
21091          color_space
21092        ),
21093        &format!(".foo{{color:color({} .5 .2 .5)}}", result_color_space),
21094      );
21095      minify_test(
21096        &format!(
21097          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / none), color({0} .5 .6 .7)) }}",
21098          color_space
21099        ),
21100        &format!(".foo{{color:color({} .3 .4 .5)}}", result_color_space),
21101      );
21102      minify_test(
21103        &format!(
21104          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / none), color({0} .5 .6 .7 / 0.5)) }}",
21105          color_space
21106        ),
21107        &format!(".foo{{color:color({} .3 .4 .5/.5)}}", result_color_space),
21108      );
21109      minify_test(
21110        &format!(
21111          ".foo {{ color: color-mix(in {0}, color({0} .1 .2 .3 / none), color({0} .5 .6 .7 / none)) }}",
21112          color_space
21113        ),
21114        &format!(".foo{{color:color({} .3 .4 .5/none)}}", result_color_space),
21115      );
21116    }
21117  }
21118
21119  #[cfg(feature = "grid")]
21120  #[test]
21121  fn test_grid() {
21122    minify_test(
21123      ".foo { grid-template-columns: [first nav-start]  150px [main-start] 1fr [last]; }",
21124      ".foo{grid-template-columns:[first nav-start]150px[main-start]1fr[last]}",
21125    );
21126    minify_test(
21127      ".foo { grid-template-columns: 150px 1fr; }",
21128      ".foo{grid-template-columns:150px 1fr}",
21129    );
21130    minify_test(
21131      ".foo { grid-template-columns: repeat(4, 1fr); }",
21132      ".foo{grid-template-columns:repeat(4,1fr)}",
21133    );
21134    minify_test(
21135      ".foo { grid-template-columns: repeat(2, [e] 40px); }",
21136      ".foo{grid-template-columns:repeat(2,[e]40px)}",
21137    );
21138    minify_test(
21139      ".foo { grid-template-columns: repeat(4, [col-start] 250px [col-end]); }",
21140      ".foo{grid-template-columns:repeat(4,[col-start]250px[col-end])}",
21141    );
21142    minify_test(
21143      ".foo { grid-template-columns: repeat(4, [col-start] 60% [col-end]); }",
21144      ".foo{grid-template-columns:repeat(4,[col-start]60%[col-end])}",
21145    );
21146    minify_test(
21147      ".foo { grid-template-columns: repeat(4, [col-start] 1fr [col-end]); }",
21148      ".foo{grid-template-columns:repeat(4,[col-start]1fr[col-end])}",
21149    );
21150    minify_test(
21151      ".foo { grid-template-columns: repeat(4, [col-start] min-content [col-end]); }",
21152      ".foo{grid-template-columns:repeat(4,[col-start]min-content[col-end])}",
21153    );
21154    minify_test(
21155      ".foo { grid-template-columns: repeat(4, [col-start] max-content [col-end]); }",
21156      ".foo{grid-template-columns:repeat(4,[col-start]max-content[col-end])}",
21157    );
21158    minify_test(
21159      ".foo { grid-template-columns: repeat(4, [col-start] auto [col-end]); }",
21160      ".foo{grid-template-columns:repeat(4,[col-start]auto[col-end])}",
21161    );
21162    minify_test(
21163      ".foo { grid-template-columns: repeat(4, [col-start] minmax(100px, 1fr) [col-end]); }",
21164      ".foo{grid-template-columns:repeat(4,[col-start]minmax(100px,1fr)[col-end])}",
21165    );
21166    minify_test(
21167      ".foo { grid-template-columns: repeat(4, [col-start] fit-content(200px) [col-end]); }",
21168      ".foo{grid-template-columns:repeat(4,[col-start]fit-content(200px)[col-end])}",
21169    );
21170    minify_test(
21171      ".foo { grid-template-columns: repeat(4, 10px [col-start] 30% [col-middle] auto [col-end]); }",
21172      ".foo{grid-template-columns:repeat(4,10px[col-start]30%[col-middle]auto[col-end])}",
21173    );
21174    minify_test(
21175      ".foo { grid-template-columns: repeat(5, auto); }",
21176      ".foo{grid-template-columns:repeat(5,auto)}",
21177    );
21178    minify_test(
21179      ".foo { grid-template-columns: repeat(auto-fill, 250px); }",
21180      ".foo{grid-template-columns:repeat(auto-fill,250px)}",
21181    );
21182    minify_test(
21183      ".foo { grid-template-columns: repeat(auto-fit, 250px); }",
21184      ".foo{grid-template-columns:repeat(auto-fit,250px)}",
21185    );
21186    minify_test(
21187      ".foo { grid-template-columns: repeat(auto-fill, [col-start] 250px [col-end]); }",
21188      ".foo{grid-template-columns:repeat(auto-fill,[col-start]250px[col-end])}",
21189    );
21190    minify_test(
21191      ".foo { grid-template-columns: repeat(auto-fill, [col-start] minmax(100px, 1fr) [col-end]); }",
21192      ".foo{grid-template-columns:repeat(auto-fill,[col-start]minmax(100px,1fr)[col-end])}",
21193    );
21194    minify_test(
21195      ".foo { grid-template-columns: minmax(min-content, 1fr); }",
21196      ".foo{grid-template-columns:minmax(min-content,1fr)}",
21197    );
21198    minify_test(
21199      ".foo { grid-template-columns: 200px repeat(auto-fill, 100px) 300px; }",
21200      ".foo{grid-template-columns:200px repeat(auto-fill,100px) 300px}",
21201    );
21202    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]}");
21203    minify_test(
21204      ".foo { grid-template-rows: [linename1 linename2] 100px repeat(auto-fit, [linename1] 300px) [linename3]; }",
21205      ".foo{grid-template-rows:[linename1 linename2]100px repeat(auto-fit,[linename1]300px)[linename3]}",
21206    );
21207
21208    minify_test(".foo { grid-auto-rows: auto; }", ".foo{grid-auto-rows:auto}");
21209    minify_test(".foo { grid-auto-rows: 1fr; }", ".foo{grid-auto-rows:1fr}");
21210    minify_test(".foo { grid-auto-rows: 100px; }", ".foo{grid-auto-rows:100px}");
21211    minify_test(
21212      ".foo { grid-auto-rows: min-content; }",
21213      ".foo{grid-auto-rows:min-content}",
21214    );
21215    minify_test(
21216      ".foo { grid-auto-rows: max-content; }",
21217      ".foo{grid-auto-rows:max-content}",
21218    );
21219    minify_test(
21220      ".foo { grid-auto-rows: minmax(100px,auto); }",
21221      ".foo{grid-auto-rows:minmax(100px,auto)}",
21222    );
21223    minify_test(
21224      ".foo { grid-auto-rows: fit-content(20%); }",
21225      ".foo{grid-auto-rows:fit-content(20%)}",
21226    );
21227    minify_test(
21228      ".foo { grid-auto-rows: 100px minmax(100px, auto) 10% 0.5fr fit-content(400px); }",
21229      ".foo{grid-auto-rows:100px minmax(100px,auto) 10% .5fr fit-content(400px)}",
21230    );
21231    minify_test(
21232      ".foo { grid-auto-columns: 100px minmax(100px, auto) 10% 0.5fr fit-content(400px); }",
21233      ".foo{grid-auto-columns:100px minmax(100px,auto) 10% .5fr fit-content(400px)}",
21234    );
21235
21236    minify_test(
21237      r#"
21238      .foo {
21239        grid-template-areas: "head head"
21240                             "nav  main"
21241                             "foot ....";
21242      }
21243    "#,
21244      ".foo{grid-template-areas:\"head head\"\"nav main\"\"foot.\"}",
21245    );
21246    minify_test(
21247      r#"
21248      .foo {
21249        grid-template-areas: "head head"
21250                             "nav  main"
21251                             ".... foot";
21252      }
21253    "#,
21254      ".foo{grid-template-areas:\"head head\"\"nav main\"\".foot\"}",
21255    );
21256    minify_test(
21257      r#"
21258      .foo {
21259        grid-template-areas: "head head"
21260                             "nav  main"
21261                             ".... ....";
21262      }
21263    "#,
21264      ".foo{grid-template-areas:\"head head\"\"nav main\"\". .\"}",
21265    );
21266
21267    test(
21268      r#"
21269      .foo {
21270        grid-template-areas: "head head" "nav  main" "foot ....";
21271      }
21272    "#,
21273      indoc! { r#"
21274      .foo {
21275        grid-template-areas: "head head"
21276                             "nav main"
21277                             "foot .";
21278      }
21279    "#},
21280    );
21281
21282    minify_test(
21283      r#"
21284      .foo {
21285        grid-template: [header-top] "a   a   a"     [header-bottom]
21286                       [main-top] "b   b   b" 1fr [main-bottom];
21287      }
21288    "#,
21289      ".foo{grid-template:[header-top]\"a a a\"[header-bottom main-top]\"b b b\"1fr[main-bottom]}",
21290    );
21291    minify_test(
21292      r#"
21293      .foo {
21294        grid-template: "head head"
21295                       "nav  main" 1fr
21296                       "foot ....";
21297      }
21298    "#,
21299      ".foo{grid-template:\"head head\"\"nav main\"1fr\"foot.\"}",
21300    );
21301    minify_test(
21302      r#"
21303      .foo {
21304        grid-template: [header-top] "a   a   a"     [header-bottom]
21305                         [main-top] "b   b   b" 1fr [main-bottom]
21306                                  / auto 1fr auto;
21307      }
21308    "#,
21309      ".foo{grid-template:[header-top]\"a a a\"[header-bottom main-top]\"b b b\"1fr[main-bottom]/auto 1fr auto}",
21310    );
21311
21312    minify_test(
21313      ".foo { grid-template: auto 1fr / auto 1fr auto; }",
21314      ".foo{grid-template:auto 1fr/auto 1fr auto}",
21315    );
21316    minify_test(
21317      ".foo { grid-template: [linename1 linename2] 100px repeat(auto-fit, [linename1] 300px) [linename3] / [linename1 linename2] 100px repeat(auto-fit, [linename1] 300px) [linename3]; }",
21318      ".foo{grid-template:[linename1 linename2]100px repeat(auto-fit,[linename1]300px)[linename3]/[linename1 linename2]100px repeat(auto-fit,[linename1]300px)[linename3]}"
21319    );
21320
21321    test(
21322      ".foo{grid-template:[header-top]\"a a a\"[header-bottom main-top]\"b b b\"1fr[main-bottom]/auto 1fr auto}",
21323      indoc! {r#"
21324        .foo {
21325          grid-template: [header-top] "a a a" [header-bottom]
21326                         [main-top] "b b b" 1fr [main-bottom]
21327                         / auto 1fr auto;
21328        }
21329      "#},
21330    );
21331    test(
21332      ".foo{grid-template:[header-top]\"a a a\"[main-top]\"b b b\"1fr/auto 1fr auto}",
21333      indoc! {r#"
21334        .foo {
21335          grid-template: [header-top] "a a a"
21336                         [main-top] "b b b" 1fr
21337                         / auto 1fr auto;
21338        }
21339      "#},
21340    );
21341
21342    minify_test(".foo { grid-auto-flow: row }", ".foo{grid-auto-flow:row}");
21343    minify_test(".foo { grid-auto-flow: column }", ".foo{grid-auto-flow:column}");
21344    minify_test(".foo { grid-auto-flow: row dense }", ".foo{grid-auto-flow:dense}");
21345    minify_test(".foo { grid-auto-flow: dense row }", ".foo{grid-auto-flow:dense}");
21346    minify_test(
21347      ".foo { grid-auto-flow: column dense }",
21348      ".foo{grid-auto-flow:column dense}",
21349    );
21350    minify_test(
21351      ".foo { grid-auto-flow: dense column }",
21352      ".foo{grid-auto-flow:column dense}",
21353    );
21354
21355    minify_test(".foo { grid: none }", ".foo{grid:none}");
21356    minify_test(".foo { grid: \"a\" 100px \"b\" 1fr }", ".foo{grid:\"a\"100px\"b\"1fr}");
21357    minify_test(
21358      ".foo { grid: [linename1] \"a\" 100px [linename2] }",
21359      ".foo{grid:[linename1]\"a\"100px[linename2]}",
21360    );
21361    minify_test(
21362      ".foo { grid: \"a\" 200px \"b\" min-content }",
21363      ".foo{grid:\"a\"200px\"b\"min-content}",
21364    );
21365    minify_test(
21366      ".foo { grid: \"a\" minmax(100px, max-content) \"b\" 20% }",
21367      ".foo{grid:\"a\"minmax(100px,max-content)\"b\"20%}",
21368    );
21369    minify_test(".foo { grid: 100px / 200px }", ".foo{grid:100px/200px}");
21370    minify_test(
21371      ".foo { grid: minmax(400px, min-content) / repeat(auto-fill, 50px) }",
21372      ".foo{grid:minmax(400px,min-content)/repeat(auto-fill,50px)}",
21373    );
21374
21375    minify_test(".foo { grid: 200px / auto-flow }", ".foo{grid:200px/auto-flow}");
21376    minify_test(".foo { grid: 30% / auto-flow dense }", ".foo{grid:30%/auto-flow dense}");
21377    minify_test(".foo { grid: 30% / dense auto-flow }", ".foo{grid:30%/auto-flow dense}");
21378    minify_test(
21379      ".foo { grid: repeat(3, [line1 line2 line3] 200px) / auto-flow 300px }",
21380      ".foo{grid:repeat(3,[line1 line2 line3]200px)/auto-flow 300px}",
21381    );
21382    minify_test(
21383      ".foo { grid: [line1] minmax(20em, max-content) / auto-flow dense 40% }",
21384      ".foo{grid:[line1]minmax(20em,max-content)/auto-flow dense 40%}",
21385    );
21386    minify_test(".foo { grid: none / auto-flow 1fr }", ".foo{grid:none/auto-flow 1fr}");
21387
21388    minify_test(".foo { grid: auto-flow / 200px }", ".foo{grid:none/200px}");
21389    minify_test(".foo { grid: auto-flow dense / 30% }", ".foo{grid:auto-flow dense/30%}");
21390    minify_test(".foo { grid: dense auto-flow / 30% }", ".foo{grid:auto-flow dense/30%}");
21391    minify_test(
21392      ".foo { grid: auto-flow 300px / repeat(3, [line1 line2 line3] 200px) }",
21393      ".foo{grid:auto-flow 300px/repeat(3,[line1 line2 line3]200px)}",
21394    );
21395    minify_test(
21396      ".foo { grid: auto-flow dense 40% / [line1] minmax(20em, max-content) }",
21397      ".foo{grid:auto-flow dense 40%/[line1]minmax(20em,max-content)}",
21398    );
21399
21400    minify_test(".foo { grid-row-start: auto }", ".foo{grid-row-start:auto}");
21401    minify_test(".foo { grid-row-start: some-area }", ".foo{grid-row-start:some-area}");
21402    minify_test(".foo { grid-row-start: 2 }", ".foo{grid-row-start:2}");
21403    minify_test(
21404      ".foo { grid-row-start: 2 some-line }",
21405      ".foo{grid-row-start:2 some-line}",
21406    );
21407    minify_test(
21408      ".foo { grid-row-start: some-line 2 }",
21409      ".foo{grid-row-start:2 some-line}",
21410    );
21411    minify_test(".foo { grid-row-start: span 3 }", ".foo{grid-row-start:span 3}");
21412    minify_test(
21413      ".foo { grid-row-start: span some-line }",
21414      ".foo{grid-row-start:span some-line}",
21415    );
21416    minify_test(
21417      ".foo { grid-row-start: span some-line 1 }",
21418      ".foo{grid-row-start:span some-line}",
21419    );
21420    minify_test(
21421      ".foo { grid-row-start: span 1 some-line }",
21422      ".foo{grid-row-start:span some-line}",
21423    );
21424    minify_test(
21425      ".foo { grid-row-start: span 5 some-line }",
21426      ".foo{grid-row-start:span 5 some-line}",
21427    );
21428    minify_test(
21429      ".foo { grid-row-start: span some-line 5 }",
21430      ".foo{grid-row-start:span 5 some-line}",
21431    );
21432
21433    minify_test(
21434      ".foo { grid-row-end: span 1 some-line }",
21435      ".foo{grid-row-end:span some-line}",
21436    );
21437    minify_test(
21438      ".foo { grid-column-start: span 1 some-line }",
21439      ".foo{grid-column-start:span some-line}",
21440    );
21441    minify_test(
21442      ".foo { grid-column-end: span 1 some-line }",
21443      ".foo{grid-column-end:span some-line}",
21444    );
21445
21446    minify_test(".foo { grid-row: 1 }", ".foo{grid-row:1}");
21447    minify_test(".foo { grid-row: 1 / auto }", ".foo{grid-row:1}");
21448    minify_test(".foo { grid-row: 1 / 1 }", ".foo{grid-row:1/1}");
21449    minify_test(".foo { grid-row: 1 / 3 }", ".foo{grid-row:1/3}");
21450    minify_test(".foo { grid-row: 1 / span 2 }", ".foo{grid-row:1/span 2}");
21451    minify_test(".foo { grid-row: main-start }", ".foo{grid-row:main-start}");
21452    minify_test(
21453      ".foo { grid-row: main-start / main-end }",
21454      ".foo{grid-row:main-start/main-end}",
21455    );
21456    minify_test(
21457      ".foo { grid-row: main-start / main-start }",
21458      ".foo{grid-row:main-start}",
21459    );
21460    minify_test(".foo { grid-column: 1 / auto }", ".foo{grid-column:1}");
21461
21462    minify_test(".foo { grid-area: a }", ".foo{grid-area:a}");
21463    minify_test(".foo { grid-area: a / a / a / a }", ".foo{grid-area:a}");
21464    minify_test(".foo { grid-area: a / b / a / b }", ".foo{grid-area:a/b}");
21465    minify_test(".foo { grid-area: a / b / c / b }", ".foo{grid-area:a/b/c}");
21466    minify_test(".foo { grid-area: a / b / c / d }", ".foo{grid-area:a/b/c/d}");
21467
21468    minify_test(".foo { grid-area: auto / auto / auto / auto }", ".foo{grid-area:auto}");
21469    minify_test(".foo { grid-area: 1 / auto }", ".foo{grid-area:1}");
21470    minify_test(".foo { grid-area: 1 / 2 / 3 / 4 }", ".foo{grid-area:1/2/3/4}");
21471    minify_test(".foo { grid-area: 1 / 1 / 1 / 1 }", ".foo{grid-area:1/1/1/1}");
21472
21473    test(
21474      r#"
21475        .foo{
21476          grid-template-rows: auto 1fr;
21477          grid-template-columns: auto 1fr auto;
21478          grid-template-areas: none;
21479        }
21480      "#,
21481      indoc! {r#"
21482        .foo {
21483          grid-template: auto 1fr / auto 1fr auto;
21484        }
21485      "#},
21486    );
21487
21488    test(
21489      r#"
21490        .foo{
21491          grid-template-areas: "a a a"
21492                               "b b b";
21493          grid-template-rows: [header-top] auto [header-bottom main-top] 1fr [main-bottom];
21494          grid-template-columns: auto 1fr auto;
21495        }
21496      "#,
21497      indoc! {r#"
21498        .foo {
21499          grid-template: [header-top] "a a a" [header-bottom]
21500                         [main-top] "b b b" 1fr [main-bottom]
21501                         / auto 1fr auto;
21502        }
21503      "#},
21504    );
21505
21506    test(
21507      r#"
21508        .foo{
21509          grid-template-areas: "a a a"
21510                               "b b b";
21511          grid-template-columns: repeat(3, 1fr);
21512          grid-template-rows: auto 1fr;
21513        }
21514      "#,
21515      indoc! {r#"
21516        .foo {
21517          grid-template-rows: auto 1fr;
21518          grid-template-columns: repeat(3, 1fr);
21519          grid-template-areas: "a a a"
21520                               "b b b";
21521        }
21522      "#},
21523    );
21524
21525    test(
21526      r#"
21527        .foo{
21528          grid-template-areas: "a a a"
21529                               "b b b";
21530          grid-template-columns: auto 1fr auto;
21531          grid-template-rows: repeat(2, 1fr);
21532        }
21533      "#,
21534      indoc! {r#"
21535        .foo {
21536          grid-template-rows: repeat(2, 1fr);
21537          grid-template-columns: auto 1fr auto;
21538          grid-template-areas: "a a a"
21539                               "b b b";
21540        }
21541      "#},
21542    );
21543
21544    test(
21545      r#"
21546        .foo{
21547          grid-template-areas: ". a a ."
21548                               ". b b .";
21549          grid-template-rows: auto 1fr;
21550          grid-template-columns: 10px 1fr 1fr 10px;
21551        }
21552      "#,
21553      indoc! {r#"
21554        .foo {
21555          grid-template: ". a a ."
21556                         ". b b ." 1fr
21557                         / 10px 1fr 1fr 10px;
21558        }
21559      "#},
21560    );
21561
21562    test(
21563      r#"
21564        .foo{
21565          grid-template-areas: none;
21566          grid-template-columns: auto 1fr auto;
21567          grid-template-rows: repeat(2, 1fr);
21568        }
21569      "#,
21570      indoc! {r#"
21571        .foo {
21572          grid-template: repeat(2, 1fr) / auto 1fr auto;
21573        }
21574      "#},
21575    );
21576
21577    test(
21578      r#"
21579        .foo{
21580          grid-template-areas: none;
21581          grid-template-columns: none;
21582          grid-template-rows: none;
21583        }
21584      "#,
21585      indoc! {r#"
21586        .foo {
21587          grid-template: none;
21588        }
21589      "#},
21590    );
21591
21592    test(
21593      r#"
21594        .foo{
21595          grid-template-areas: "a a a"
21596                               "b b b";
21597          grid-template-rows: [header-top] auto [header-bottom main-top] 1fr [main-bottom];
21598          grid-template-columns: auto 1fr auto;
21599          grid-auto-flow: row;
21600          grid-auto-rows: auto;
21601          grid-auto-columns: auto;
21602        }
21603      "#,
21604      indoc! {r#"
21605        .foo {
21606          grid: [header-top] "a a a" [header-bottom]
21607                [main-top] "b b b" 1fr [main-bottom]
21608                / auto 1fr auto;
21609        }
21610      "#},
21611    );
21612
21613    test(
21614      r#"
21615        .foo{
21616          grid-template-areas: none;
21617          grid-template-columns: auto 1fr auto;
21618          grid-template-rows: repeat(2, 1fr);
21619          grid-auto-flow: row;
21620          grid-auto-rows: auto;
21621          grid-auto-columns: auto;
21622        }
21623      "#,
21624      indoc! {r#"
21625        .foo {
21626          grid: repeat(2, 1fr) / auto 1fr auto;
21627        }
21628      "#},
21629    );
21630
21631    test(
21632      r#"
21633        .foo{
21634          grid-template-areas: none;
21635          grid-template-columns: none;
21636          grid-template-rows: none;
21637          grid-auto-flow: row;
21638          grid-auto-rows: auto;
21639          grid-auto-columns: auto;
21640        }
21641      "#,
21642      indoc! {r#"
21643        .foo {
21644          grid: none;
21645        }
21646      "#},
21647    );
21648
21649    test(
21650      r#"
21651        .foo{
21652          grid-template-areas: "a a a"
21653                               "b b b";
21654          grid-template-rows: [header-top] auto [header-bottom main-top] 1fr [main-bottom];
21655          grid-template-columns: auto 1fr auto;
21656          grid-auto-flow: column;
21657          grid-auto-rows: 1fr;
21658          grid-auto-columns: 1fr;
21659        }
21660      "#,
21661      indoc! {r#"
21662        .foo {
21663          grid-template: [header-top] "a a a" [header-bottom]
21664                         [main-top] "b b b" 1fr [main-bottom]
21665                         / auto 1fr auto;
21666          grid-auto-rows: 1fr;
21667          grid-auto-columns: 1fr;
21668          grid-auto-flow: column;
21669        }
21670      "#},
21671    );
21672
21673    test(
21674      r#"
21675        .foo{
21676          grid-template-rows: auto 1fr;
21677          grid-template-columns: auto 1fr auto;
21678          grid-template-areas: none;
21679          grid-auto-flow: row;
21680          grid-auto-rows: auto;
21681          grid-auto-columns: auto;
21682        }
21683      "#,
21684      indoc! {r#"
21685        .foo {
21686          grid: auto 1fr / auto 1fr auto;
21687        }
21688      "#},
21689    );
21690
21691    test(
21692      r#"
21693        .foo{
21694          grid-template-rows: auto 1fr;
21695          grid-template-columns: auto 1fr auto;
21696          grid-template-areas: none;
21697          grid-auto-flow: column;
21698          grid-auto-rows: 1fr;
21699          grid-auto-columns: 1fr;
21700        }
21701      "#,
21702      indoc! {r#"
21703        .foo {
21704          grid-template: auto 1fr / auto 1fr auto;
21705          grid-auto-rows: 1fr;
21706          grid-auto-columns: 1fr;
21707          grid-auto-flow: column;
21708        }
21709      "#},
21710    );
21711
21712    test(
21713      r#"
21714        .foo{
21715          grid-template-rows: none;
21716          grid-template-columns: auto 1fr auto;
21717          grid-template-areas: none;
21718          grid-auto-flow: column;
21719          grid-auto-rows: 1fr;
21720          grid-auto-columns: 1fr;
21721        }
21722      "#,
21723      indoc! {r#"
21724        .foo {
21725          grid-template: none / auto 1fr auto;
21726          grid-auto-rows: 1fr;
21727          grid-auto-columns: 1fr;
21728          grid-auto-flow: column;
21729        }
21730      "#},
21731    );
21732
21733    test(
21734      r#"
21735        .foo{
21736          grid-template-rows: none;
21737          grid-template-columns: auto 1fr auto;
21738          grid-template-areas: none;
21739          grid-auto-flow: row;
21740          grid-auto-rows: 1fr;
21741          grid-auto-columns: auto;
21742        }
21743      "#,
21744      indoc! {r#"
21745        .foo {
21746          grid: auto-flow 1fr / auto 1fr auto;
21747        }
21748      "#},
21749    );
21750
21751    test(
21752      r#"
21753        .foo{
21754          grid-template-rows: none;
21755          grid-template-columns: auto 1fr auto;
21756          grid-template-areas: none;
21757          grid-auto-flow: row dense;
21758          grid-auto-rows: 1fr;
21759          grid-auto-columns: auto;
21760        }
21761      "#,
21762      indoc! {r#"
21763        .foo {
21764          grid: auto-flow dense 1fr / auto 1fr auto;
21765        }
21766      "#},
21767    );
21768
21769    test(
21770      r#"
21771        .foo{
21772          grid-template-rows: auto 1fr auto;
21773          grid-template-columns: none;
21774          grid-template-areas: none;
21775          grid-auto-flow: column;
21776          grid-auto-rows: auto;
21777          grid-auto-columns: 1fr;
21778        }
21779      "#,
21780      indoc! {r#"
21781        .foo {
21782          grid: auto 1fr auto / auto-flow 1fr;
21783        }
21784      "#},
21785    );
21786
21787    test(
21788      r#"
21789        .foo{
21790          grid-template-rows: auto 1fr auto;
21791          grid-template-columns: none;
21792          grid-template-areas: none;
21793          grid-auto-flow: column dense;
21794          grid-auto-rows: auto;
21795          grid-auto-columns: 1fr;
21796        }
21797      "#,
21798      indoc! {r#"
21799        .foo {
21800          grid: auto 1fr auto / auto-flow dense 1fr;
21801        }
21802      "#},
21803    );
21804
21805    test(
21806      r#"
21807        .foo{
21808          grid-template-rows: auto 1fr auto;
21809          grid-template-columns: none;
21810          grid-template-areas: none;
21811          grid-auto-flow: var(--auto-flow);
21812          grid-auto-rows: auto;
21813          grid-auto-columns: 1fr;
21814        }
21815      "#,
21816      indoc! {r#"
21817        .foo {
21818          grid-template: auto 1fr auto / none;
21819          grid-auto-flow: var(--auto-flow);
21820          grid-auto-rows: auto;
21821          grid-auto-columns: 1fr;
21822        }
21823      "#},
21824    );
21825
21826    test(
21827      r#"
21828        .foo{
21829          grid: auto 1fr auto / auto-flow dense 1fr;
21830          grid-template-rows: 1fr 1fr 1fr;
21831        }
21832      "#,
21833      indoc! {r#"
21834        .foo {
21835          grid: 1fr 1fr 1fr / auto-flow dense 1fr;
21836        }
21837      "#},
21838    );
21839
21840    test(
21841      r#"
21842        .foo{
21843          grid-row-start: a;
21844          grid-row-end: a;
21845          grid-column-start: a;
21846          grid-column-end: a;
21847        }
21848      "#,
21849      indoc! {r#"
21850        .foo {
21851          grid-area: a;
21852        }
21853      "#},
21854    );
21855
21856    test(
21857      r#"
21858        .foo{
21859          grid-row-start: 1;
21860          grid-row-end: 2;
21861          grid-column-start: 3;
21862          grid-column-end: 4;
21863        }
21864      "#,
21865      indoc! {r#"
21866        .foo {
21867          grid-area: 1 / 3 / 2 / 4;
21868        }
21869      "#},
21870    );
21871
21872    test(
21873      r#"
21874        .foo{
21875          grid-row-start: a;
21876          grid-row-end: a;
21877        }
21878      "#,
21879      indoc! {r#"
21880        .foo {
21881          grid-row: a;
21882        }
21883      "#},
21884    );
21885
21886    test(
21887      r#"
21888        .foo{
21889          grid-column-start: a;
21890          grid-column-end: a;
21891        }
21892      "#,
21893      indoc! {r#"
21894        .foo {
21895          grid-column: a;
21896        }
21897      "#},
21898    );
21899  }
21900
21901  #[test]
21902  fn test_moz_document() {
21903    minify_test(
21904      r#"
21905      @-moz-document url-prefix() {
21906        h1 {
21907          color: yellow;
21908        }
21909      }
21910    "#,
21911      "@-moz-document url-prefix(){h1{color:#ff0}}",
21912    );
21913    minify_test(
21914      r#"
21915      @-moz-document url-prefix("") {
21916        h1 {
21917          color: yellow;
21918        }
21919      }
21920    "#,
21921      "@-moz-document url-prefix(){h1{color:#ff0}}",
21922    );
21923    error_test(
21924      "@-moz-document url-prefix(foo) {}",
21925      ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("foo".into())),
21926    );
21927    error_test(
21928      "@-moz-document url-prefix(\"foo\") {}",
21929      ParserError::UnexpectedToken(crate::properties::custom::Token::String("foo".into())),
21930    );
21931  }
21932
21933  #[test]
21934  fn test_custom_properties() {
21935    minify_test(".foo { --test: ; }", ".foo{--test: }");
21936    minify_test(".foo { --test:  ; }", ".foo{--test: }");
21937    minify_test(".foo { --test: foo; }", ".foo{--test:foo}");
21938    minify_test(".foo { --test:  foo; }", ".foo{--test:foo}");
21939    minify_test(".foo { --test: foo ; }", ".foo{--test:foo}");
21940    minify_test(".foo { --test: foo  ; }", ".foo{--test:foo}");
21941    minify_test(".foo { --test:foo; }", ".foo{--test:foo}");
21942    minify_test(".foo { --test:foo ; }", ".foo{--test:foo}");
21943    minify_test(".foo { --test: var(--foo, 20px); }", ".foo{--test:var(--foo,20px)}");
21944    minify_test(
21945      ".foo { transition: var(--foo, 20px),\nvar(--bar, 40px); }",
21946      ".foo{transition:var(--foo,20px),var(--bar,40px)}",
21947    );
21948    minify_test(
21949      ".foo { background: var(--color) var(--image); }",
21950      ".foo{background:var(--color)var(--image)}",
21951    );
21952    minify_test(
21953      ".foo { height: calc(var(--spectrum-global-dimension-size-300) / 2);",
21954      ".foo{height:calc(var(--spectrum-global-dimension-size-300)/2)}",
21955    );
21956    minify_test(
21957      ".foo { color: var(--color, rgb(255, 255, 0)); }",
21958      ".foo{color:var(--color,#ff0)}",
21959    );
21960    minify_test(
21961      ".foo { color: var(--color, #ffff00); }",
21962      ".foo{color:var(--color,#ff0)}",
21963    );
21964    minify_test(
21965      ".foo { color: var(--color, rgb(var(--red), var(--green), 0)); }",
21966      ".foo{color:var(--color,rgb(var(--red),var(--green),0))}",
21967    );
21968    minify_test(".foo { --test: .5s; }", ".foo{--test:.5s}");
21969    minify_test(".foo { --theme-sizes-1\\/12: 2 }", ".foo{--theme-sizes-1\\/12:2}");
21970    minify_test(".foo { --test: 0px; }", ".foo{--test:0px}");
21971
21972    prefix_test(
21973      r#"
21974      .foo {
21975        --custom: lab(40% 56.6 39);
21976      }
21977    "#,
21978      indoc! {r#"
21979      .foo {
21980        --custom: #b32323;
21981      }
21982
21983      @supports (color: lab(0% 0 0)) {
21984        .foo {
21985          --custom: lab(40% 56.6 39);
21986        }
21987      }
21988    "#},
21989      Browsers {
21990        chrome: Some(90 << 16),
21991        ..Browsers::default()
21992      },
21993    );
21994
21995    prefix_test(
21996      r#"
21997      .foo {
21998        --custom: lab(40% 56.6 39) !important;
21999      }
22000    "#,
22001      indoc! {r#"
22002      .foo {
22003        --custom: #b32323 !important;
22004      }
22005
22006      @supports (color: lab(0% 0 0)) {
22007        .foo {
22008          --custom: lab(40% 56.6 39) !important;
22009        }
22010      }
22011    "#},
22012      Browsers {
22013        chrome: Some(90 << 16),
22014        ..Browsers::default()
22015      },
22016    );
22017
22018    prefix_test(
22019      r#"
22020      .foo {
22021        --custom: lab(40% 56.6 39);
22022      }
22023    "#,
22024      indoc! {r#"
22025      .foo {
22026        --custom: #b32323;
22027      }
22028
22029      @supports (color: color(display-p3 0 0 0)) {
22030        .foo {
22031          --custom: color(display-p3 .643308 .192455 .167712);
22032        }
22033      }
22034
22035      @supports (color: lab(0% 0 0)) {
22036        .foo {
22037          --custom: lab(40% 56.6 39);
22038        }
22039      }
22040    "#},
22041      Browsers {
22042        chrome: Some(90 << 16),
22043        safari: Some(14 << 16),
22044        ..Browsers::default()
22045      },
22046    );
22047
22048    prefix_test(
22049      r#"
22050      .foo {
22051        --custom: lab(40% 56.6 39);
22052      }
22053    "#,
22054      indoc! {r#"
22055      .foo {
22056        --custom: color(display-p3 .643308 .192455 .167712);
22057      }
22058
22059      @supports (color: lab(0% 0 0)) {
22060        .foo {
22061          --custom: lab(40% 56.6 39);
22062        }
22063      }
22064    "#},
22065      Browsers {
22066        safari: Some(14 << 16),
22067        ..Browsers::default()
22068      },
22069    );
22070
22071    prefix_test(
22072      r#"
22073      .foo {
22074        --custom: lab(40% 56.6 39);
22075      }
22076    "#,
22077      indoc! {r#"
22078      .foo {
22079        --custom: lab(40% 56.6 39);
22080      }
22081    "#},
22082      Browsers {
22083        safari: Some(15 << 16),
22084        ..Browsers::default()
22085      },
22086    );
22087
22088    prefix_test(
22089      r#"
22090      .foo {
22091        --custom: oklab(59.686% 0.1009 0.1192);
22092      }
22093    "#,
22094      indoc! {r#"
22095      .foo {
22096        --custom: lab(52.2319% 40.1449 59.9171);
22097      }
22098    "#},
22099      Browsers {
22100        safari: Some(15 << 16),
22101        ..Browsers::default()
22102      },
22103    );
22104
22105    prefix_test(
22106      r#"
22107      .foo {
22108        --custom: oklab(59.686% 0.1009 0.1192);
22109      }
22110    "#,
22111      indoc! {r#"
22112      .foo {
22113        --custom: color(display-p3 .724144 .386777 .148795);
22114      }
22115
22116      @supports (color: lab(0% 0 0)) {
22117        .foo {
22118          --custom: lab(52.2319% 40.1449 59.9171);
22119        }
22120      }
22121    "#},
22122      Browsers {
22123        safari: Some(14 << 16),
22124        ..Browsers::default()
22125      },
22126    );
22127
22128    prefix_test(
22129      r#"
22130      .foo {
22131        --custom: oklab(59.686% 0.1009 0.1192);
22132      }
22133    "#,
22134      indoc! {r#"
22135      .foo {
22136        --custom: #c65d07;
22137      }
22138
22139      @supports (color: color(display-p3 0 0 0)) {
22140        .foo {
22141          --custom: color(display-p3 .724144 .386777 .148795);
22142        }
22143      }
22144
22145      @supports (color: lab(0% 0 0)) {
22146        .foo {
22147          --custom: lab(52.2319% 40.1449 59.9171);
22148        }
22149      }
22150    "#},
22151      Browsers {
22152        safari: Some(14 << 16),
22153        chrome: Some(90 << 16),
22154        ..Browsers::default()
22155      },
22156    );
22157
22158    prefix_test(
22159      r#"
22160      .foo {
22161        --foo: oklab(59.686% 0.1009 0.1192);
22162        --bar: lab(40% 56.6 39);
22163      }
22164    "#,
22165      indoc! {r#"
22166      .foo {
22167        --foo: #c65d07;
22168        --bar: #b32323;
22169      }
22170
22171      @supports (color: color(display-p3 0 0 0)) {
22172        .foo {
22173          --foo: color(display-p3 .724144 .386777 .148795);
22174          --bar: color(display-p3 .643308 .192455 .167712);
22175        }
22176      }
22177
22178      @supports (color: lab(0% 0 0)) {
22179        .foo {
22180          --foo: lab(52.2319% 40.1449 59.9171);
22181          --bar: lab(40% 56.6 39);
22182        }
22183      }
22184    "#},
22185      Browsers {
22186        safari: Some(14 << 16),
22187        chrome: Some(90 << 16),
22188        ..Browsers::default()
22189      },
22190    );
22191
22192    prefix_test(
22193      r#"
22194      .foo {
22195        --foo: color(display-p3 0 1 0);
22196      }
22197    "#,
22198      indoc! {r#"
22199      .foo {
22200        --foo: #00f942;
22201      }
22202
22203      @supports (color: color(display-p3 0 0 0)) {
22204        .foo {
22205          --foo: color(display-p3 0 1 0);
22206        }
22207      }
22208    "#},
22209      Browsers {
22210        safari: Some(14 << 16),
22211        chrome: Some(90 << 16),
22212        ..Browsers::default()
22213      },
22214    );
22215
22216    prefix_test(
22217      r#"
22218      .foo {
22219        --foo: color(display-p3 0 1 0);
22220      }
22221    "#,
22222      indoc! {r#"
22223      .foo {
22224        --foo: color(display-p3 0 1 0);
22225      }
22226    "#},
22227      Browsers {
22228        safari: Some(14 << 16),
22229        ..Browsers::default()
22230      },
22231    );
22232
22233    prefix_test(
22234      r#"
22235      .foo {
22236        --foo: color(display-p3 0 1 0);
22237      }
22238    "#,
22239      indoc! {r#"
22240      .foo {
22241        --foo: #00f942;
22242      }
22243
22244      @supports (color: color(display-p3 0 0 0)) {
22245        .foo {
22246          --foo: color(display-p3 0 1 0);
22247        }
22248      }
22249    "#},
22250      Browsers {
22251        safari: Some(15 << 16),
22252        chrome: Some(90 << 16),
22253        ..Browsers::default()
22254      },
22255    );
22256
22257    prefix_test(
22258      r#"
22259      .foo {
22260        --foo: color(display-p3 0 1 0);
22261      }
22262    "#,
22263      indoc! {r#"
22264      .foo {
22265        --foo: #00f942;
22266      }
22267
22268      @supports (color: color(display-p3 0 0 0)) {
22269        .foo {
22270          --foo: color(display-p3 0 1 0);
22271        }
22272      }
22273    "#},
22274      Browsers {
22275        chrome: Some(90 << 16),
22276        ..Browsers::default()
22277      },
22278    );
22279
22280    prefix_test(
22281      r#"
22282      .foo {
22283        text-decoration: underline;
22284      }
22285
22286      .foo {
22287        --custom: lab(40% 56.6 39);
22288      }
22289    "#,
22290      indoc! {r#"
22291      .foo {
22292        --custom: #b32323;
22293        text-decoration: underline;
22294      }
22295
22296      @supports (color: lab(0% 0 0)) {
22297        .foo {
22298          --custom: lab(40% 56.6 39);
22299        }
22300      }
22301    "#},
22302      Browsers {
22303        chrome: Some(90 << 16),
22304        ..Browsers::default()
22305      },
22306    );
22307
22308    prefix_test(
22309      r#"
22310      .foo {
22311        --custom: lab(40% 56.6 39);
22312      }
22313
22314      .foo {
22315        text-decoration: underline;
22316      }
22317    "#,
22318      indoc! {r#"
22319      .foo {
22320        --custom: #b32323;
22321      }
22322
22323      @supports (color: lab(0% 0 0)) {
22324        .foo {
22325          --custom: lab(40% 56.6 39);
22326        }
22327      }
22328
22329      .foo {
22330        text-decoration: underline;
22331      }
22332    "#},
22333      Browsers {
22334        chrome: Some(90 << 16),
22335        ..Browsers::default()
22336      },
22337    );
22338
22339    prefix_test(
22340      r#"
22341      @keyframes foo {
22342        from {
22343          --custom: lab(40% 56.6 39);
22344        }
22345
22346        to {
22347          --custom: lch(50.998% 135.363 338);
22348        }
22349      }
22350    "#,
22351      indoc! {r#"
22352      @keyframes foo {
22353        from {
22354          --custom: #b32323;
22355        }
22356
22357        to {
22358          --custom: #ee00be;
22359        }
22360      }
22361
22362      @supports (color: lab(0% 0 0)) {
22363        @keyframes foo {
22364          from {
22365            --custom: lab(40% 56.6 39);
22366          }
22367
22368          to {
22369            --custom: lab(50.998% 125.506 -50.7078);
22370          }
22371        }
22372      }
22373    "#},
22374      Browsers {
22375        chrome: Some(90 << 16),
22376        ..Browsers::default()
22377      },
22378    );
22379
22380    prefix_test(
22381      r#"
22382      @keyframes foo {
22383        from {
22384          --custom: lab(40% 56.6 39);
22385        }
22386
22387        to {
22388          --custom: lch(50.998% 135.363 338);
22389        }
22390      }
22391    "#,
22392      indoc! {r#"
22393      @keyframes foo {
22394        from {
22395          --custom: #b32323;
22396        }
22397
22398        to {
22399          --custom: #ee00be;
22400        }
22401      }
22402
22403      @supports (color: color(display-p3 0 0 0)) {
22404        @keyframes foo {
22405          from {
22406            --custom: color(display-p3 .643308 .192455 .167712);
22407          }
22408
22409          to {
22410            --custom: color(display-p3 .972962 -.362078 .804206);
22411          }
22412        }
22413      }
22414
22415      @supports (color: lab(0% 0 0)) {
22416        @keyframes foo {
22417          from {
22418            --custom: lab(40% 56.6 39);
22419          }
22420
22421          to {
22422            --custom: lab(50.998% 125.506 -50.7078);
22423          }
22424        }
22425      }
22426    "#},
22427      Browsers {
22428        chrome: Some(90 << 16),
22429        safari: Some(14 << 16),
22430        ..Browsers::default()
22431      },
22432    );
22433
22434    prefix_test(
22435      r#"
22436      @keyframes foo {
22437        from {
22438          --custom: #ff0;
22439          opacity: 0;
22440        }
22441
22442        to {
22443          --custom: lch(50.998% 135.363 338);
22444          opacity: 1;
22445        }
22446      }
22447    "#,
22448      indoc! {r#"
22449      @keyframes foo {
22450        from {
22451          --custom: #ff0;
22452          opacity: 0;
22453        }
22454
22455        to {
22456          --custom: #ee00be;
22457          opacity: 1;
22458        }
22459      }
22460
22461      @supports (color: lab(0% 0 0)) {
22462        @keyframes foo {
22463          from {
22464            --custom: #ff0;
22465            opacity: 0;
22466          }
22467
22468          to {
22469            --custom: lab(50.998% 125.506 -50.7078);
22470            opacity: 1;
22471          }
22472        }
22473      }
22474    "#},
22475      Browsers {
22476        chrome: Some(90 << 16),
22477        ..Browsers::default()
22478      },
22479    );
22480
22481    prefix_test(
22482      r#"
22483      @keyframes foo {
22484        from {
22485          text-decoration: var(--foo) lab(29.2345% 39.3825 20.0664);
22486        }
22487      }
22488    "#,
22489      indoc! {r#"
22490      @keyframes foo {
22491        from {
22492          text-decoration: var(--foo) #7d2329;
22493        }
22494      }
22495
22496      @supports (color: lab(0% 0 0)) {
22497        @keyframes foo {
22498          from {
22499            text-decoration: var(--foo) lab(29.2345% 39.3825 20.0664);
22500          }
22501        }
22502      }
22503    "#},
22504      Browsers {
22505        chrome: Some(90 << 16),
22506        ..Browsers::default()
22507      },
22508    );
22509  }
22510
22511  #[test]
22512  fn test_charset() {
22513    test(
22514      r#"
22515      @charset "UTF-8";
22516
22517      .foo {
22518        color: red;
22519      }
22520
22521      @charset "UTF-8";
22522
22523      .bar {
22524        color: yellow;
22525      }
22526    "#,
22527      indoc! { r#"
22528      .foo {
22529        color: red;
22530      }
22531
22532      .bar {
22533        color: #ff0;
22534      }
22535    "#},
22536    )
22537  }
22538
22539  #[test]
22540  fn test_style_attr() {
22541    attr_test("color: yellow; flex: 1 1 auto", "color: #ff0; flex: auto", false, None);
22542    attr_test("color: yellow; flex: 1 1 auto", "color:#ff0;flex:auto", true, None);
22543    attr_test(
22544      "border-inline-start: 2px solid red",
22545      "border-inline-start: 2px solid red",
22546      false,
22547      Some(Browsers {
22548        safari: Some(12 << 16),
22549        ..Browsers::default()
22550      }),
22551    );
22552    attr_test(
22553      "color: lab(40% 56.6 39);",
22554      "color:#b32323;color:lab(40% 56.6 39)",
22555      true,
22556      Some(Browsers {
22557        safari: Some(8 << 16),
22558        ..Browsers::default()
22559      }),
22560    );
22561    attr_test(
22562      "--foo: lab(40% 56.6 39);",
22563      "--foo:#b32323",
22564      true,
22565      Some(Browsers {
22566        safari: Some(8 << 16),
22567        ..Browsers::default()
22568      }),
22569    );
22570    attr_test(
22571      "text-decoration: var(--foo) lab(40% 56.6 39);",
22572      "text-decoration:var(--foo)#b32323",
22573      true,
22574      Some(Browsers {
22575        chrome: Some(90 << 16),
22576        ..Browsers::default()
22577      }),
22578    );
22579  }
22580
22581  #[test]
22582  fn test_nesting() {
22583    nesting_test(
22584      r#"
22585        .foo {
22586          color: blue;
22587          & > .bar { color: red; }
22588        }
22589      "#,
22590      indoc! {r#"
22591        .foo {
22592          color: #00f;
22593        }
22594
22595        .foo > .bar {
22596          color: red;
22597        }
22598      "#},
22599    );
22600
22601    nesting_test(
22602      r#"
22603        .foo {
22604          color: blue;
22605          &.bar { color: red; }
22606        }
22607      "#,
22608      indoc! {r#"
22609        .foo {
22610          color: #00f;
22611        }
22612
22613        .foo.bar {
22614          color: red;
22615        }
22616      "#},
22617    );
22618
22619    nesting_test(
22620      r#"
22621        .foo, .bar {
22622          color: blue;
22623          & + .baz, &.qux { color: red; }
22624        }
22625      "#,
22626      indoc! {r#"
22627        .foo, .bar {
22628          color: #00f;
22629        }
22630
22631        :is(.foo, .bar) + .baz, :is(.foo, .bar).qux {
22632          color: red;
22633        }
22634      "#},
22635    );
22636
22637    nesting_test(
22638      r#"
22639        .foo {
22640          color: blue;
22641          & .bar & .baz & .qux { color: red; }
22642        }
22643      "#,
22644      indoc! {r#"
22645        .foo {
22646          color: #00f;
22647        }
22648
22649        .foo .bar .foo .baz .foo .qux {
22650          color: red;
22651        }
22652      "#},
22653    );
22654
22655    nesting_test(
22656      r#"
22657        .foo {
22658          color: blue;
22659          & { padding: 2ch; }
22660        }
22661      "#,
22662      indoc! {r#"
22663        .foo {
22664          color: #00f;
22665        }
22666
22667        .foo {
22668          padding: 2ch;
22669        }
22670      "#},
22671    );
22672
22673    nesting_test(
22674      r#"
22675        .foo {
22676          color: blue;
22677          && { padding: 2ch; }
22678        }
22679      "#,
22680      indoc! {r#"
22681        .foo {
22682          color: #00f;
22683        }
22684
22685        .foo.foo {
22686          padding: 2ch;
22687        }
22688      "#},
22689    );
22690
22691    nesting_test(
22692      r#"
22693        .error, .invalid {
22694          &:hover > .baz { color: red; }
22695        }
22696      "#,
22697      indoc! {r#"
22698        :is(.error, .invalid):hover > .baz {
22699          color: red;
22700        }
22701      "#},
22702    );
22703
22704    nesting_test(
22705      r#"
22706        .foo {
22707          &:is(.bar, &.baz) { color: red; }
22708        }
22709      "#,
22710      indoc! {r#"
22711        .foo:is(.bar, .foo.baz) {
22712          color: red;
22713        }
22714      "#},
22715    );
22716
22717    nesting_test(
22718      r#"
22719        figure {
22720          margin: 0;
22721
22722          & > figcaption {
22723            background: hsl(0 0% 0% / 50%);
22724
22725            & > p {
22726              font-size: .9rem;
22727            }
22728          }
22729        }
22730      "#,
22731      indoc! {r#"
22732        figure {
22733          margin: 0;
22734        }
22735
22736        figure > figcaption {
22737          background: #00000080;
22738        }
22739
22740        figure > figcaption > p {
22741          font-size: .9rem;
22742        }
22743      "#},
22744    );
22745
22746    nesting_test(
22747      r#"
22748        .foo {
22749          display: grid;
22750
22751          @media (orientation: landscape) {
22752            grid-auto-flow: column;
22753          }
22754        }
22755      "#,
22756      indoc! {r#"
22757        .foo {
22758          display: grid;
22759        }
22760
22761        @media (orientation: landscape) {
22762          .foo {
22763            grid-auto-flow: column;
22764          }
22765        }
22766      "#},
22767    );
22768
22769    nesting_test(
22770      r#"
22771        .foo {
22772          display: grid;
22773
22774          @media (orientation: landscape) {
22775            grid-auto-flow: column;
22776
22777            @media (width > 1024px) {
22778              max-inline-size: 1024px;
22779            }
22780          }
22781        }
22782      "#,
22783      indoc! {r#"
22784        .foo {
22785          display: grid;
22786        }
22787
22788        @media (orientation: landscape) {
22789          .foo {
22790            grid-auto-flow: column;
22791          }
22792
22793          @media not (max-width: 1024px) {
22794            .foo {
22795              max-inline-size: 1024px;
22796            }
22797          }
22798        }
22799      "#},
22800    );
22801
22802    nesting_test(
22803      r#"
22804        .foo {
22805          @media (min-width: 640px) {
22806            color: red !important;
22807          }
22808        }
22809      "#,
22810      indoc! {r#"
22811        @media (min-width: 640px) {
22812          .foo {
22813            color: red !important;
22814          }
22815        }
22816      "#},
22817    );
22818
22819    nesting_test(
22820      r#"
22821        .foo {
22822          display: grid;
22823
22824          @supports (foo: bar) {
22825            grid-auto-flow: column;
22826          }
22827        }
22828      "#,
22829      indoc! {r#"
22830        .foo {
22831          display: grid;
22832        }
22833
22834        @supports (foo: bar) {
22835          .foo {
22836            grid-auto-flow: column;
22837          }
22838        }
22839      "#},
22840    );
22841
22842    nesting_test(
22843      r#"
22844        .foo {
22845          display: grid;
22846
22847          @container (min-width: 100px) {
22848            grid-auto-flow: column;
22849          }
22850        }
22851      "#,
22852      indoc! {r#"
22853        .foo {
22854          display: grid;
22855        }
22856
22857        @container (width >= 100px) {
22858          .foo {
22859            grid-auto-flow: column;
22860          }
22861        }
22862      "#},
22863    );
22864
22865    nesting_test(
22866      r#"
22867        .foo {
22868          display: grid;
22869
22870          @layer test {
22871            grid-auto-flow: column;
22872          }
22873        }
22874      "#,
22875      indoc! {r#"
22876        .foo {
22877          display: grid;
22878        }
22879
22880        @layer test {
22881          .foo {
22882            grid-auto-flow: column;
22883          }
22884        }
22885      "#},
22886    );
22887
22888    nesting_test(
22889      r#"
22890        .foo {
22891          display: grid;
22892
22893          @layer {
22894            grid-auto-flow: column;
22895          }
22896        }
22897      "#,
22898      indoc! {r#"
22899        .foo {
22900          display: grid;
22901        }
22902
22903        @layer {
22904          .foo {
22905            grid-auto-flow: column;
22906          }
22907        }
22908      "#},
22909    );
22910
22911    nesting_test(
22912      r#"
22913        @namespace "http://example.com/foo";
22914        @namespace toto "http://toto.example.org";
22915
22916        .foo {
22917          &div {
22918            color: red;
22919          }
22920
22921          &* {
22922            color: green;
22923          }
22924
22925          &|x {
22926            color: red;
22927          }
22928
22929          &*|x {
22930            color: green;
22931          }
22932
22933          &toto|x {
22934            color: red;
22935          }
22936        }
22937      "#,
22938      indoc! {r#"
22939        @namespace "http://example.com/foo";
22940        @namespace toto "http://toto.example.org";
22941
22942        div.foo {
22943          color: red;
22944        }
22945
22946        *.foo {
22947          color: green;
22948        }
22949
22950        |x.foo {
22951          color: red;
22952        }
22953
22954        *|x.foo {
22955          color: green;
22956        }
22957
22958        toto|x.foo {
22959          color: red;
22960        }
22961      "#},
22962    );
22963
22964    nesting_test(
22965      r#"
22966        .foo {
22967          &article > figure {
22968            color: red;
22969          }
22970        }
22971      "#,
22972      indoc! {r#"
22973        article.foo > figure {
22974          color: red;
22975        }
22976      "#},
22977    );
22978
22979    nesting_test(
22980      r#"
22981        div {
22982          &.bar {
22983            background: green;
22984          }
22985        }
22986      "#,
22987      indoc! {r#"
22988        div.bar {
22989          background: green;
22990        }
22991      "#},
22992    );
22993
22994    nesting_test(
22995      r#"
22996        div > .foo {
22997          &span {
22998            background: green;
22999          }
23000        }
23001      "#,
23002      indoc! {r#"
23003        span:is(div > .foo) {
23004          background: green;
23005        }
23006      "#},
23007    );
23008
23009    nesting_test(
23010      r#"
23011        .foo {
23012          & h1 {
23013            background: green;
23014          }
23015        }
23016      "#,
23017      indoc! {r#"
23018        .foo h1 {
23019          background: green;
23020        }
23021      "#},
23022    );
23023
23024    nesting_test(
23025      r#"
23026        .foo .bar {
23027          &h1 {
23028            background: green;
23029          }
23030        }
23031      "#,
23032      indoc! {r#"
23033        h1:is(.foo .bar) {
23034          background: green;
23035        }
23036      "#},
23037    );
23038
23039    nesting_test(
23040      r#"
23041        .foo.bar {
23042          &h1 {
23043            background: green;
23044          }
23045        }
23046      "#,
23047      indoc! {r#"
23048        h1.foo.bar {
23049          background: green;
23050        }
23051      "#},
23052    );
23053
23054    nesting_test(
23055      r#"
23056        .foo .bar {
23057          &h1 .baz {
23058            background: green;
23059          }
23060        }
23061      "#,
23062      indoc! {r#"
23063        h1:is(.foo .bar) .baz {
23064          background: green;
23065        }
23066      "#},
23067    );
23068
23069    nesting_test(
23070      r#"
23071        .foo .bar {
23072          &.baz {
23073            background: green;
23074          }
23075        }
23076      "#,
23077      indoc! {r#"
23078        .foo .bar.baz {
23079          background: green;
23080        }
23081      "#},
23082    );
23083
23084    nesting_test(
23085      r#"
23086        .foo {
23087          color: red;
23088          @nest .parent & {
23089            color: blue;
23090          }
23091        }
23092      "#,
23093      indoc! {r#"
23094        .foo {
23095          color: red;
23096        }
23097
23098        .parent .foo {
23099          color: #00f;
23100        }
23101      "#},
23102    );
23103
23104    nesting_test(
23105      r#"
23106        .foo {
23107          color: red;
23108          @nest :not(&) {
23109            color: blue;
23110          }
23111        }
23112      "#,
23113      indoc! {r#"
23114        .foo {
23115          color: red;
23116        }
23117
23118        :not(.foo) {
23119          color: #00f;
23120        }
23121      "#},
23122    );
23123
23124    nesting_test(
23125      r#"
23126        .foo {
23127          color: blue;
23128          @nest .bar & {
23129            color: red;
23130            &.baz {
23131              color: green;
23132            }
23133          }
23134        }
23135      "#,
23136      indoc! {r#"
23137        .foo {
23138          color: #00f;
23139        }
23140
23141        .bar .foo {
23142          color: red;
23143        }
23144
23145        .bar .foo.baz {
23146          color: green;
23147        }
23148      "#},
23149    );
23150
23151    nesting_test(
23152      r#"
23153        .foo {
23154          @nest :not(&) {
23155            color: red;
23156          }
23157
23158          & h1 {
23159            background: green;
23160          }
23161        }
23162      "#,
23163      indoc! {r#"
23164        :not(.foo) {
23165          color: red;
23166        }
23167
23168        .foo h1 {
23169          background: green;
23170        }
23171      "#},
23172    );
23173
23174    nesting_test(
23175      r#"
23176        .foo {
23177          & h1 {
23178            background: green;
23179          }
23180
23181          @nest :not(&) {
23182            color: red;
23183          }
23184        }
23185      "#,
23186      indoc! {r#"
23187        .foo h1 {
23188          background: green;
23189        }
23190
23191        :not(.foo) {
23192          color: red;
23193        }
23194      "#},
23195    );
23196
23197    nesting_test(
23198      r#"
23199        .foo .bar {
23200          @nest h1& {
23201            background: green;
23202          }
23203        }
23204      "#,
23205      indoc! {r#"
23206        h1:is(.foo .bar) {
23207          background: green;
23208        }
23209      "#},
23210    );
23211
23212    nesting_test(
23213      r#"
23214        @namespace "http://example.com/foo";
23215        @namespace toto "http://toto.example.org";
23216
23217        div {
23218          @nest .foo& {
23219            color: red;
23220          }
23221        }
23222
23223        * {
23224          @nest .foo& {
23225            color: red;
23226          }
23227        }
23228
23229        |x {
23230          @nest .foo& {
23231            color: red;
23232          }
23233        }
23234
23235        *|x {
23236          @nest .foo& {
23237            color: red;
23238          }
23239        }
23240
23241        toto|x {
23242          @nest .foo& {
23243            color: red;
23244          }
23245        }
23246      "#,
23247      indoc! {r#"
23248        @namespace "http://example.com/foo";
23249        @namespace toto "http://toto.example.org";
23250
23251        .foo:is(div) {
23252          color: red;
23253        }
23254
23255        .foo:is(*) {
23256          color: red;
23257        }
23258
23259        .foo:is(|x) {
23260          color: red;
23261        }
23262
23263        .foo:is(*|x) {
23264          color: red;
23265        }
23266
23267        .foo:is(toto|x) {
23268          color: red;
23269        }
23270      "#},
23271    );
23272
23273    nesting_test(
23274      r#"
23275        .foo .bar {
23276          @nest h1 .baz& {
23277            background: green;
23278          }
23279        }
23280      "#,
23281      indoc! {r#"
23282        h1 .baz:is(.foo .bar) {
23283          background: green;
23284        }
23285      "#},
23286    );
23287
23288    nesting_test(
23289      r#"
23290        .foo .bar {
23291          @nest .baz& {
23292            background: green;
23293          }
23294        }
23295      "#,
23296      indoc! {r#"
23297        .baz:is(.foo .bar) {
23298          background: green;
23299        }
23300      "#},
23301    );
23302
23303    nesting_test(
23304      r#"
23305        .foo .bar {
23306          @nest .baz & {
23307            background: green;
23308          }
23309        }
23310      "#,
23311      indoc! {r#"
23312        .baz :is(.foo .bar) {
23313          background: green;
23314        }
23315      "#},
23316    );
23317
23318    nesting_test(
23319      r#"
23320        .foo {
23321          color: red;
23322          @nest & > .bar {
23323            color: blue;
23324          }
23325        }
23326      "#,
23327      indoc! {r#"
23328        .foo {
23329          color: red;
23330        }
23331
23332        .foo > .bar {
23333          color: #00f;
23334        }
23335      "#},
23336    );
23337
23338    nesting_test(
23339      r#"
23340      .foo {
23341        color: red;
23342        .bar {
23343          color: blue;
23344        }
23345      }
23346      "#,
23347      indoc! {r#"
23348      .foo {
23349        color: red;
23350      }
23351
23352      .foo .bar {
23353        color: #00f;
23354      }
23355      "#},
23356    );
23357
23358    nesting_test(
23359      r#"
23360      .foo {
23361        color: red;
23362        .bar & {
23363          color: blue;
23364        }
23365      }
23366      "#,
23367      indoc! {r#"
23368      .foo {
23369        color: red;
23370      }
23371
23372      .bar .foo {
23373        color: #00f;
23374      }
23375      "#},
23376    );
23377
23378    nesting_test(
23379      r#"
23380      .foo {
23381        color: red;
23382        + .bar + & { color: blue; }
23383      }
23384      "#,
23385      indoc! {r#"
23386      .foo {
23387        color: red;
23388      }
23389
23390      .foo + .bar + .foo {
23391        color: #00f;
23392      }
23393      "#},
23394    );
23395
23396    nesting_test(
23397      r#"
23398      .foo {
23399        color: red;
23400        .bar & {
23401          color: blue;
23402        }
23403      }
23404      "#,
23405      indoc! {r#"
23406      .foo {
23407        color: red;
23408      }
23409
23410      .bar .foo {
23411        color: #00f;
23412      }
23413      "#},
23414    );
23415
23416    nesting_test(
23417      r#"
23418        .foo {
23419          color: red;
23420          .parent & {
23421            color: blue;
23422          }
23423        }
23424      "#,
23425      indoc! {r#"
23426        .foo {
23427          color: red;
23428        }
23429
23430        .parent .foo {
23431          color: #00f;
23432        }
23433      "#},
23434    );
23435
23436    nesting_test(
23437      r#"
23438        .foo {
23439          color: red;
23440          :not(&) {
23441            color: blue;
23442          }
23443        }
23444      "#,
23445      indoc! {r#"
23446        .foo {
23447          color: red;
23448        }
23449
23450        :not(.foo) {
23451          color: #00f;
23452        }
23453      "#},
23454    );
23455
23456    nesting_test(
23457      r#"
23458        .foo {
23459          color: blue;
23460          .bar & {
23461            color: red;
23462            &.baz {
23463              color: green;
23464            }
23465          }
23466        }
23467      "#,
23468      indoc! {r#"
23469        .foo {
23470          color: #00f;
23471        }
23472
23473        .bar .foo {
23474          color: red;
23475        }
23476
23477        .bar .foo.baz {
23478          color: green;
23479        }
23480      "#},
23481    );
23482
23483    nesting_test(
23484      r#"
23485        .foo {
23486          :not(&) {
23487            color: red;
23488          }
23489
23490          & h1 {
23491            background: green;
23492          }
23493        }
23494      "#,
23495      indoc! {r#"
23496        :not(.foo) {
23497          color: red;
23498        }
23499
23500        .foo h1 {
23501          background: green;
23502        }
23503      "#},
23504    );
23505
23506    nesting_test(
23507      r#"
23508        .foo {
23509          & h1 {
23510            background: green;
23511          }
23512
23513          :not(&) {
23514            color: red;
23515          }
23516        }
23517      "#,
23518      indoc! {r#"
23519        .foo h1 {
23520          background: green;
23521        }
23522
23523        :not(.foo) {
23524          color: red;
23525        }
23526      "#},
23527    );
23528
23529    nesting_test(
23530      r#"
23531        .foo .bar {
23532          :is(h1)& {
23533            background: green;
23534          }
23535        }
23536      "#,
23537      indoc! {r#"
23538        :is(h1):is(.foo .bar) {
23539          background: green;
23540        }
23541      "#},
23542    );
23543
23544    nesting_test(
23545      r#"
23546        @namespace "http://example.com/foo";
23547        @namespace toto "http://toto.example.org";
23548
23549        div {
23550          .foo& {
23551            color: red;
23552          }
23553        }
23554
23555        * {
23556          .foo& {
23557            color: red;
23558          }
23559        }
23560
23561        |x {
23562          .foo& {
23563            color: red;
23564          }
23565        }
23566
23567        *|x {
23568          .foo& {
23569            color: red;
23570          }
23571        }
23572
23573        toto|x {
23574          .foo& {
23575            color: red;
23576          }
23577        }
23578      "#,
23579      indoc! {r#"
23580        @namespace "http://example.com/foo";
23581        @namespace toto "http://toto.example.org";
23582
23583        .foo:is(div) {
23584          color: red;
23585        }
23586
23587        .foo:is(*) {
23588          color: red;
23589        }
23590
23591        .foo:is(|x) {
23592          color: red;
23593        }
23594
23595        .foo:is(*|x) {
23596          color: red;
23597        }
23598
23599        .foo:is(toto|x) {
23600          color: red;
23601        }
23602      "#},
23603    );
23604
23605    nesting_test(
23606      r#"
23607        .foo .bar {
23608          :is(h1) .baz& {
23609            background: green;
23610          }
23611        }
23612      "#,
23613      indoc! {r#"
23614        :is(h1) .baz:is(.foo .bar) {
23615          background: green;
23616        }
23617      "#},
23618    );
23619
23620    nesting_test(
23621      r#"
23622        .foo .bar {
23623          .baz& {
23624            background: green;
23625          }
23626        }
23627      "#,
23628      indoc! {r#"
23629        .baz:is(.foo .bar) {
23630          background: green;
23631        }
23632      "#},
23633    );
23634
23635    nesting_test(
23636      r#"
23637        .foo .bar {
23638          .baz & {
23639            background: green;
23640          }
23641        }
23642      "#,
23643      indoc! {r#"
23644        .baz :is(.foo .bar) {
23645          background: green;
23646        }
23647      "#},
23648    );
23649
23650    nesting_test(
23651      r#"
23652        .foo {
23653          .bar {
23654            color: blue;
23655          }
23656          color: red;
23657        }
23658      "#,
23659      indoc! {r#"
23660        .foo {
23661          color: red;
23662        }
23663
23664        .foo .bar {
23665          color: #00f;
23666        }
23667      "#},
23668    );
23669
23670    nesting_test(
23671      r#"
23672        article {
23673          color: green;
23674          & { color: blue; }
23675          color: red;
23676        }
23677      "#,
23678      indoc! {r#"
23679        article {
23680          color: red;
23681        }
23682
23683        article {
23684          color: #00f;
23685        }
23686      "#},
23687    );
23688
23689    nesting_test(
23690      r#"
23691        & .foo {
23692          color: red;
23693        }
23694      "#,
23695      indoc! {r#"
23696        :scope .foo {
23697          color: red;
23698        }
23699      "#},
23700    );
23701
23702    nesting_test(
23703      r#"
23704        &.foo {
23705          color: red;
23706        }
23707      "#,
23708      indoc! {r#"
23709        :scope.foo {
23710          color: red;
23711        }
23712      "#},
23713    );
23714
23715    nesting_test(
23716      r#"
23717        .foo& {
23718          color: red;
23719        }
23720      "#,
23721      indoc! {r#"
23722        .foo:scope {
23723          color: red;
23724        }
23725      "#},
23726    );
23727
23728    nesting_test(
23729      r#"
23730        &html {
23731          color: red;
23732        }
23733      "#,
23734      indoc! {r#"
23735        html:scope {
23736          color: red;
23737        }
23738      "#},
23739    );
23740
23741    nesting_test(
23742      r#"
23743        .foo {
23744          color: blue;
23745          div {
23746            color: red;
23747          }
23748        }
23749      "#,
23750      indoc! {r#"
23751        .foo {
23752          color: #00f;
23753        }
23754
23755        .foo div {
23756          color: red;
23757        }
23758      "#},
23759    );
23760
23761    nesting_test(
23762      r#"
23763        div {
23764          color: blue;
23765
23766          button:focus {
23767            color: red;
23768          }
23769        }
23770      "#,
23771      indoc! {r#"
23772        div {
23773          color: #00f;
23774        }
23775
23776        div button:focus {
23777          color: red;
23778        }
23779      "#},
23780    );
23781    nesting_test(
23782      r#"
23783        div {
23784          color: blue;
23785
23786          --button:focus {
23787            color: red;
23788          }
23789        }
23790      "#,
23791      indoc! {r#"
23792        div {
23793          color: #00f;
23794          --button: focus { color: red; };
23795        }
23796      "#},
23797    );
23798
23799    nesting_test_no_targets(
23800      r#"
23801        .foo {
23802          color: blue;
23803          @nest .bar & {
23804            color: red;
23805            &.baz {
23806              color: green;
23807            }
23808          }
23809        }
23810      "#,
23811      indoc! {r#"
23812        .foo {
23813          color: #00f;
23814
23815          @nest .bar & {
23816            color: red;
23817
23818            &.baz {
23819              color: green;
23820            }
23821          }
23822        }
23823      "#},
23824    );
23825
23826    nesting_test_no_targets(
23827      r#"
23828        .foo {
23829          color: blue;
23830          &div {
23831            color: red;
23832          }
23833
23834          &span {
23835            color: purple;
23836          }
23837        }
23838      "#,
23839      indoc! {r#"
23840        .foo {
23841          color: #00f;
23842
23843          &div {
23844            color: red;
23845          }
23846
23847          &span {
23848            color: purple;
23849          }
23850        }
23851      "#},
23852    );
23853
23854    nesting_test_no_targets(
23855      r#"
23856        .error, .invalid {
23857          &:hover > .baz { color: red; }
23858        }
23859      "#,
23860      indoc! {r#"
23861        .error, .invalid {
23862          &:hover > .baz {
23863            color: red;
23864          }
23865        }
23866      "#},
23867    );
23868
23869    nesting_test_with_targets(
23870      r#"
23871        .foo {
23872          color: blue;
23873          & > .bar { color: red; }
23874        }
23875      "#,
23876      indoc! {r#"
23877        .foo {
23878          color: #00f;
23879        }
23880
23881        .foo > .bar {
23882          color: red;
23883        }
23884      "#},
23885      Targets {
23886        browsers: Some(Browsers {
23887          chrome: Some(112 << 16),
23888          ..Browsers::default()
23889        }),
23890        include: Features::Nesting,
23891        exclude: Features::empty(),
23892      },
23893    );
23894    nesting_test_with_targets(
23895      r#"
23896        .foo {
23897          color: blue;
23898          & > .bar { color: red; }
23899        }
23900      "#,
23901      indoc! {r#"
23902        .foo {
23903          color: #00f;
23904
23905          & > .bar {
23906            color: red;
23907          }
23908        }
23909      "#},
23910      Targets {
23911        browsers: Some(Browsers {
23912          chrome: Some(50 << 16),
23913          ..Browsers::default()
23914        }),
23915        include: Features::empty(),
23916        exclude: Features::Nesting,
23917      },
23918    );
23919
23920    let mut stylesheet = StyleSheet::parse(
23921      r#"
23922      .foo {
23923        color: blue;
23924        .bar {
23925          color: red;
23926        }
23927      }
23928      "#,
23929      ParserOptions::default(),
23930    )
23931    .unwrap();
23932    stylesheet.minify(MinifyOptions::default()).unwrap();
23933    let res = stylesheet
23934      .to_css(PrinterOptions {
23935        minify: true,
23936        ..PrinterOptions::default()
23937      })
23938      .unwrap();
23939    assert_eq!(res.code, ".foo{color:#00f;& .bar{color:red}}");
23940
23941    nesting_test_with_targets(
23942      r#"
23943        .a {
23944          &.b,
23945          &.c {
23946            &.d {
23947              color: red;
23948            }
23949          }
23950        }
23951      "#,
23952      indoc! {r#"
23953        .a.b.d {
23954          color: red;
23955        }
23956
23957        .a.c.d {
23958          color: red;
23959        }
23960      "#},
23961      Targets {
23962        browsers: Some(Browsers {
23963          safari: Some(13 << 16),
23964          ..Browsers::default()
23965        }),
23966        include: Features::Nesting,
23967        exclude: Features::empty(),
23968      },
23969    );
23970  }
23971
23972  #[test]
23973  fn test_css_modules() {
23974    css_modules_test(
23975      r#"
23976      .foo {
23977        color: red;
23978      }
23979
23980      #id {
23981        animation: 2s test;
23982      }
23983
23984      @keyframes test {
23985        from { color: red }
23986        to { color: yellow }
23987      }
23988
23989      @counter-style circles {
23990        symbols: Ⓐ Ⓑ Ⓒ;
23991      }
23992
23993      ul {
23994        list-style: circles;
23995      }
23996
23997      ol {
23998        list-style-type: none;
23999      }
24000
24001      li {
24002        list-style-type: disc;
24003      }
24004
24005      @keyframes fade {
24006        from { opacity: 0 }
24007        to { opacity: 1 }
24008      }
24009    "#,
24010      indoc! {r#"
24011      .EgL3uq_foo {
24012        color: red;
24013      }
24014
24015      #EgL3uq_id {
24016        animation: 2s EgL3uq_test;
24017      }
24018
24019      @keyframes EgL3uq_test {
24020        from {
24021          color: red;
24022        }
24023
24024        to {
24025          color: #ff0;
24026        }
24027      }
24028
24029      @counter-style EgL3uq_circles {
24030        symbols: Ⓐ Ⓑ Ⓒ;
24031      }
24032
24033      ul {
24034        list-style: EgL3uq_circles;
24035      }
24036
24037      ol {
24038        list-style-type: none;
24039      }
24040
24041      li {
24042        list-style-type: disc;
24043      }
24044
24045      @keyframes EgL3uq_fade {
24046        from {
24047          opacity: 0;
24048        }
24049
24050        to {
24051          opacity: 1;
24052        }
24053      }
24054    "#},
24055      map! {
24056        "foo" => "EgL3uq_foo",
24057        "id" => "EgL3uq_id",
24058        "test" => "EgL3uq_test" referenced: true,
24059        "circles" => "EgL3uq_circles" referenced: true,
24060        "fade" => "EgL3uq_fade"
24061      },
24062      HashMap::new(),
24063      Default::default(),
24064      false,
24065    );
24066
24067    css_modules_test(
24068      r#"
24069      .foo {
24070        color: red;
24071      }
24072
24073      #id {
24074        animation: 2s test;
24075      }
24076
24077      @keyframes test {
24078        from { color: red }
24079        to { color: yellow }
24080      }
24081    "#,
24082      indoc! {r#"
24083      .EgL3uq_foo {
24084        color: red;
24085      }
24086
24087      #EgL3uq_id {
24088        animation: 2s test;
24089      }
24090
24091      @keyframes test {
24092        from {
24093          color: red;
24094        }
24095
24096        to {
24097          color: #ff0;
24098        }
24099      }
24100    "#},
24101      map! {
24102        "foo" => "EgL3uq_foo",
24103        "id" => "EgL3uq_id"
24104      },
24105      HashMap::new(),
24106      crate::css_modules::Config {
24107        animation: false,
24108        // custom_idents: false,
24109        ..Default::default()
24110      },
24111      false,
24112    );
24113
24114    css_modules_test(
24115      r#"
24116      @counter-style circles {
24117        symbols: Ⓐ Ⓑ Ⓒ;
24118      }
24119
24120      ul {
24121        list-style: circles;
24122      }
24123
24124      ol {
24125        list-style-type: none;
24126      }
24127
24128      li {
24129        list-style-type: disc;
24130      }
24131    "#,
24132      indoc! {r#"
24133      @counter-style circles {
24134        symbols: Ⓐ Ⓑ Ⓒ;
24135      }
24136
24137      ul {
24138        list-style: circles;
24139      }
24140
24141      ol {
24142        list-style-type: none;
24143      }
24144
24145      li {
24146        list-style-type: disc;
24147      }
24148    "#},
24149      map! {
24150        "circles" => "EgL3uq_circles" referenced: true
24151      },
24152      HashMap::new(),
24153      crate::css_modules::Config {
24154        custom_idents: false,
24155        ..Default::default()
24156      },
24157      false,
24158    );
24159
24160    #[cfg(feature = "grid")]
24161    css_modules_test(
24162      r#"
24163      body {
24164        grid: [header-top] "a a a" [header-bottom]
24165              [main-top] "b b b" 1fr [main-bottom]
24166              / auto 1fr auto;
24167      }
24168
24169      header {
24170        grid-area: a;
24171      }
24172
24173      main {
24174        grid-row: main-top / main-bottom;
24175      }
24176    "#,
24177      indoc! {r#"
24178      body {
24179        grid: [EgL3uq_header-top] "EgL3uq_a EgL3uq_a EgL3uq_a" [EgL3uq_header-bottom]
24180              [EgL3uq_main-top] "EgL3uq_b EgL3uq_b EgL3uq_b" 1fr [EgL3uq_main-bottom]
24181              / auto 1fr auto;
24182      }
24183
24184      header {
24185        grid-area: EgL3uq_a;
24186      }
24187
24188      main {
24189        grid-row: EgL3uq_main-top / EgL3uq_main-bottom;
24190      }
24191    "#},
24192      map! {
24193        "header-top" => "EgL3uq_header-top",
24194        "header-bottom" => "EgL3uq_header-bottom",
24195        "main-top" => "EgL3uq_main-top",
24196        "main-bottom" => "EgL3uq_main-bottom",
24197        "a" => "EgL3uq_a",
24198        "b" => "EgL3uq_b"
24199      },
24200      HashMap::new(),
24201      Default::default(),
24202      false,
24203    );
24204
24205    #[cfg(feature = "grid")]
24206    css_modules_test(
24207      r#"
24208        .grid {
24209          grid-template-areas: "foo";
24210        }
24211
24212        .foo {
24213          grid-area: foo;
24214        }
24215
24216        .bar {
24217          grid-column-start: foo-start;
24218        }
24219      "#,
24220      indoc! {r#"
24221        .EgL3uq_grid {
24222          grid-template-areas: "EgL3uq_foo";
24223        }
24224
24225        .EgL3uq_foo {
24226          grid-area: EgL3uq_foo;
24227        }
24228
24229        .EgL3uq_bar {
24230          grid-column-start: EgL3uq_foo-start;
24231        }
24232      "#},
24233      map! {
24234        "foo" => "EgL3uq_foo",
24235        "foo-start" => "EgL3uq_foo-start",
24236        "grid" => "EgL3uq_grid",
24237        "bar" => "EgL3uq_bar"
24238      },
24239      HashMap::new(),
24240      Default::default(),
24241      false,
24242    );
24243
24244    #[cfg(feature = "grid")]
24245    css_modules_test(
24246      r#"
24247        .grid {
24248          grid-template-areas: "foo";
24249        }
24250
24251        .foo {
24252          grid-area: foo;
24253        }
24254
24255        .bar {
24256          grid-column-start: foo-start;
24257        }
24258      "#,
24259      indoc! {r#"
24260        .EgL3uq_grid {
24261          grid-template-areas: "foo";
24262        }
24263
24264        .EgL3uq_foo {
24265          grid-area: foo;
24266        }
24267
24268        .EgL3uq_bar {
24269          grid-column-start: foo-start;
24270        }
24271      "#},
24272      map! {
24273        "foo" => "EgL3uq_foo",
24274        "grid" => "EgL3uq_grid",
24275        "bar" => "EgL3uq_bar"
24276      },
24277      HashMap::new(),
24278      crate::css_modules::Config {
24279        grid: false,
24280        ..Default::default()
24281      },
24282      false,
24283    );
24284
24285    css_modules_test(
24286      r#"
24287      test {
24288        transition-property: opacity;
24289      }
24290    "#,
24291      indoc! {r#"
24292      test {
24293        transition-property: opacity;
24294      }
24295    "#},
24296      map! {},
24297      HashMap::new(),
24298      Default::default(),
24299      false,
24300    );
24301
24302    css_modules_test(
24303      r#"
24304      :global(.foo) {
24305        color: red;
24306      }
24307
24308      :local(.bar) {
24309        color: yellow;
24310      }
24311
24312      .bar :global(.baz) {
24313        color: purple;
24314      }
24315    "#,
24316      indoc! {r#"
24317      .foo {
24318        color: red;
24319      }
24320
24321      .EgL3uq_bar {
24322        color: #ff0;
24323      }
24324
24325      .EgL3uq_bar .baz {
24326        color: purple;
24327      }
24328    "#},
24329      map! {
24330        "bar" => "EgL3uq_bar"
24331      },
24332      HashMap::new(),
24333      Default::default(),
24334      false,
24335    );
24336
24337    // :global(:local(.hi)) {
24338    //   color: green;
24339    // }
24340
24341    css_modules_test(
24342      r#"
24343      .test {
24344        composes: foo;
24345        background: white;
24346      }
24347
24348      .foo {
24349        color: red;
24350      }
24351    "#,
24352      indoc! {r#"
24353      .EgL3uq_test {
24354        background: #fff;
24355      }
24356
24357      .EgL3uq_foo {
24358        color: red;
24359      }
24360    "#},
24361      map! {
24362        "test" => "EgL3uq_test" "EgL3uq_foo",
24363        "foo" => "EgL3uq_foo"
24364      },
24365      HashMap::new(),
24366      Default::default(),
24367      false,
24368    );
24369
24370    css_modules_test(
24371      r#"
24372      .a, .b {
24373        composes: foo;
24374        background: white;
24375      }
24376
24377      .foo {
24378        color: red;
24379      }
24380    "#,
24381      indoc! {r#"
24382      .EgL3uq_a, .EgL3uq_b {
24383        background: #fff;
24384      }
24385
24386      .EgL3uq_foo {
24387        color: red;
24388      }
24389    "#},
24390      map! {
24391        "a" => "EgL3uq_a" "EgL3uq_foo",
24392        "b" => "EgL3uq_b" "EgL3uq_foo",
24393        "foo" => "EgL3uq_foo"
24394      },
24395      HashMap::new(),
24396      Default::default(),
24397      false,
24398    );
24399
24400    css_modules_test(
24401      r#"
24402      .test {
24403        composes: foo bar;
24404        background: white;
24405      }
24406
24407      .foo {
24408        color: red;
24409      }
24410
24411      .bar {
24412        color: yellow;
24413      }
24414    "#,
24415      indoc! {r#"
24416      .EgL3uq_test {
24417        background: #fff;
24418      }
24419
24420      .EgL3uq_foo {
24421        color: red;
24422      }
24423
24424      .EgL3uq_bar {
24425        color: #ff0;
24426      }
24427    "#},
24428      map! {
24429        "test" => "EgL3uq_test" "EgL3uq_foo" "EgL3uq_bar",
24430        "foo" => "EgL3uq_foo",
24431        "bar" => "EgL3uq_bar"
24432      },
24433      HashMap::new(),
24434      Default::default(),
24435      false,
24436    );
24437
24438    css_modules_test(
24439      r#"
24440      .test {
24441        composes: foo from global;
24442        background: white;
24443      }
24444    "#,
24445      indoc! {r#"
24446      .EgL3uq_test {
24447        background: #fff;
24448      }
24449    "#},
24450      map! {
24451        "test" => "EgL3uq_test" "foo" global: true
24452      },
24453      HashMap::new(),
24454      Default::default(),
24455      false,
24456    );
24457
24458    css_modules_test(
24459      r#"
24460      .test {
24461        composes: foo bar from global;
24462        background: white;
24463      }
24464    "#,
24465      indoc! {r#"
24466      .EgL3uq_test {
24467        background: #fff;
24468      }
24469    "#},
24470      map! {
24471        "test" => "EgL3uq_test" "foo" global: true "bar" global: true
24472      },
24473      HashMap::new(),
24474      Default::default(),
24475      false,
24476    );
24477
24478    css_modules_test(
24479      r#"
24480      .test {
24481        composes: foo from "foo.css";
24482        background: white;
24483      }
24484    "#,
24485      indoc! {r#"
24486      .EgL3uq_test {
24487        background: #fff;
24488      }
24489    "#},
24490      map! {
24491        "test" => "EgL3uq_test" "foo" from "foo.css"
24492      },
24493      HashMap::new(),
24494      Default::default(),
24495      false,
24496    );
24497
24498    css_modules_test(
24499      r#"
24500      .test {
24501        composes: foo bar from "foo.css";
24502        background: white;
24503      }
24504    "#,
24505      indoc! {r#"
24506      .EgL3uq_test {
24507        background: #fff;
24508      }
24509    "#},
24510      map! {
24511        "test" => "EgL3uq_test" "foo" from "foo.css" "bar" from "foo.css"
24512      },
24513      HashMap::new(),
24514      Default::default(),
24515      false,
24516    );
24517
24518    css_modules_test(
24519      r#"
24520      .test {
24521        composes: foo;
24522        composes: foo from "foo.css";
24523        composes: bar from "bar.css";
24524        background: white;
24525      }
24526
24527      .foo {
24528        color: red;
24529      }
24530    "#,
24531      indoc! {r#"
24532      .EgL3uq_test {
24533        background: #fff;
24534      }
24535
24536      .EgL3uq_foo {
24537        color: red;
24538      }
24539    "#},
24540      map! {
24541        "test" => "EgL3uq_test" "EgL3uq_foo" "foo" from "foo.css" "bar" from "bar.css",
24542        "foo" => "EgL3uq_foo"
24543      },
24544      HashMap::new(),
24545      Default::default(),
24546      false,
24547    );
24548
24549    css_modules_test(
24550      r#"
24551      .foo {
24552        color: red;
24553      }
24554    "#,
24555      indoc! {r#"
24556      .test-EgL3uq-foo {
24557        color: red;
24558      }
24559    "#},
24560      map! {
24561        "foo" => "test-EgL3uq-foo"
24562      },
24563      HashMap::new(),
24564      crate::css_modules::Config {
24565        pattern: crate::css_modules::Pattern::parse("test-[hash]-[local]").unwrap(),
24566        ..Default::default()
24567      },
24568      false,
24569    );
24570
24571    let stylesheet = StyleSheet::parse(
24572      r#"
24573        .grid {
24574          grid-template-areas: "foo";
24575        }
24576
24577        .foo {
24578          grid-area: foo;
24579        }
24580
24581        .bar {
24582          grid-column-start: foo-start;
24583        }
24584      "#,
24585      ParserOptions {
24586        css_modules: Some(crate::css_modules::Config {
24587          pattern: crate::css_modules::Pattern::parse("test-[local]-[hash]").unwrap(),
24588          ..Default::default()
24589        }),
24590        ..ParserOptions::default()
24591      },
24592    )
24593    .unwrap();
24594    if let Err(err) = stylesheet.to_css(PrinterOptions::default()) {
24595      assert_eq!(err.kind, PrinterErrorKind::InvalidCssModulesPatternInGrid);
24596    } else {
24597      unreachable!()
24598    }
24599
24600    css_modules_test(
24601      r#"
24602      @property --foo {
24603        syntax: '<color>';
24604        inherits: false;
24605        initial-value: yellow;
24606      }
24607
24608      .foo {
24609        --foo: red;
24610        color: var(--foo);
24611      }
24612    "#,
24613      indoc! {r#"
24614      @property --foo {
24615        syntax: "<color>";
24616        inherits: false;
24617        initial-value: #ff0;
24618      }
24619
24620      .EgL3uq_foo {
24621        --foo: red;
24622        color: var(--foo);
24623      }
24624    "#},
24625      map! {
24626        "foo" => "EgL3uq_foo"
24627      },
24628      HashMap::new(),
24629      Default::default(),
24630      false,
24631    );
24632
24633    css_modules_test(
24634      r#"
24635      @property --foo {
24636        syntax: '<color>';
24637        inherits: false;
24638        initial-value: yellow;
24639      }
24640
24641      @font-palette-values --Cooler {
24642        font-family: Bixa;
24643        base-palette: 1;
24644        override-colors: 1 #7EB7E4;
24645      }
24646
24647      .foo {
24648        --foo: red;
24649        --bar: green;
24650        color: var(--foo);
24651        font-palette: --Cooler;
24652      }
24653
24654      .bar {
24655        color: var(--color from "./b.css");
24656      }
24657    "#,
24658      indoc! {r#"
24659      @property --EgL3uq_foo {
24660        syntax: "<color>";
24661        inherits: false;
24662        initial-value: #ff0;
24663      }
24664
24665      @font-palette-values --EgL3uq_Cooler {
24666        font-family: Bixa;
24667        base-palette: 1;
24668        override-colors: 1 #7eb7e4;
24669      }
24670
24671      .EgL3uq_foo {
24672        --EgL3uq_foo: red;
24673        --EgL3uq_bar: green;
24674        color: var(--EgL3uq_foo);
24675        font-palette: --EgL3uq_Cooler;
24676      }
24677
24678      .EgL3uq_bar {
24679        color: var(--ma1CsG);
24680      }
24681    "#},
24682      map! {
24683        "foo" => "EgL3uq_foo",
24684        "--foo" => "--EgL3uq_foo" referenced: true,
24685        "--bar" => "--EgL3uq_bar",
24686        "bar" => "EgL3uq_bar",
24687        "--Cooler" => "--EgL3uq_Cooler" referenced: true
24688      },
24689      HashMap::from([(
24690        "--ma1CsG".into(),
24691        CssModuleReference::Dependency {
24692          name: "--color".into(),
24693          specifier: "./b.css".into(),
24694        },
24695      )]),
24696      crate::css_modules::Config {
24697        dashed_idents: true,
24698        ..Default::default()
24699      },
24700      false,
24701    );
24702
24703    css_modules_test(
24704      r#"
24705      .test {
24706        animation: rotate var(--duration) linear infinite;
24707      }
24708    "#,
24709      indoc! {r#"
24710      .EgL3uq_test {
24711        animation: EgL3uq_rotate var(--duration) linear infinite;
24712      }
24713    "#},
24714      map! {
24715        "test" => "EgL3uq_test",
24716        "rotate" => "EgL3uq_rotate" referenced: true
24717      },
24718      HashMap::new(),
24719      Default::default(),
24720      false,
24721    );
24722    css_modules_test(
24723      r#"
24724      .test {
24725        animation: none var(--duration);
24726      }
24727    "#,
24728      indoc! {r#"
24729      .EgL3uq_test {
24730        animation: none var(--duration);
24731      }
24732    "#},
24733      map! {
24734        "test" => "EgL3uq_test"
24735      },
24736      HashMap::new(),
24737      Default::default(),
24738      false,
24739    );
24740    css_modules_test(
24741      r#"
24742      .test {
24743        animation: var(--animation);
24744      }
24745    "#,
24746      indoc! {r#"
24747      .EgL3uq_test {
24748        animation: var(--animation);
24749      }
24750    "#},
24751      map! {
24752        "test" => "EgL3uq_test"
24753      },
24754      HashMap::new(),
24755      Default::default(),
24756      false,
24757    );
24758    css_modules_test(
24759      r#"
24760      .test {
24761        animation: rotate var(--duration);
24762      }
24763    "#,
24764      indoc! {r#"
24765      .EgL3uq_test {
24766        animation: rotate var(--duration);
24767      }
24768    "#},
24769      map! {
24770        "test" => "EgL3uq_test"
24771      },
24772      HashMap::new(),
24773      crate::css_modules::Config {
24774        animation: false,
24775        ..Default::default()
24776      },
24777      false,
24778    );
24779    css_modules_test(
24780      r#"
24781      .test {
24782        animation: "rotate" var(--duration);
24783      }
24784    "#,
24785      indoc! {r#"
24786      .EgL3uq_test {
24787        animation: EgL3uq_rotate var(--duration);
24788      }
24789    "#},
24790      map! {
24791        "test" => "EgL3uq_test",
24792        "rotate" => "EgL3uq_rotate" referenced: true
24793      },
24794      HashMap::new(),
24795      crate::css_modules::Config { ..Default::default() },
24796      false,
24797    );
24798
24799    css_modules_test(
24800      r#"
24801      .test {
24802        composes: foo bar from "foo.css";
24803        background: white;
24804      }
24805    "#,
24806      indoc! {r#"
24807      ._5h2kwG-test {
24808        background: #fff;
24809      }
24810    "#},
24811      map! {
24812        "test" => "_5h2kwG-test" "foo" from "foo.css" "bar" from "foo.css"
24813      },
24814      HashMap::new(),
24815      crate::css_modules::Config {
24816        pattern: crate::css_modules::Pattern::parse("[content-hash]-[local]").unwrap(),
24817        ..Default::default()
24818      },
24819      false,
24820    );
24821
24822    css_modules_test(
24823      r#"
24824      .box2 {
24825        @container main (width >= 0) {
24826          background-color: #90ee90;
24827        }
24828      }
24829    "#,
24830      indoc! {r#"
24831      .EgL3uq_box2 {
24832        @container EgL3uq_main (width >= 0) {
24833          & {
24834            background-color: #90ee90;
24835          }
24836        }
24837      }
24838    "#},
24839      map! {
24840        "main" => "EgL3uq_main",
24841        "box2" => "EgL3uq_box2"
24842      },
24843      HashMap::new(),
24844      crate::css_modules::Config { ..Default::default() },
24845      false,
24846    );
24847
24848    css_modules_test(
24849      r#"
24850      .box2 {
24851        @container main (width >= 0) {
24852          background-color: #90ee90;
24853        }
24854      }
24855    "#,
24856      indoc! {r#"
24857      .EgL3uq_box2 {
24858        @container main (width >= 0) {
24859          & {
24860            background-color: #90ee90;
24861          }
24862        }
24863      }
24864    "#},
24865      map! {
24866        "box2" => "EgL3uq_box2"
24867      },
24868      HashMap::new(),
24869      crate::css_modules::Config {
24870        container: false,
24871        ..Default::default()
24872      },
24873      false,
24874    );
24875
24876    css_modules_test(
24877      ".foo { view-transition-name: bar }",
24878      ".EgL3uq_foo{view-transition-name:EgL3uq_bar}",
24879      map! {
24880        "foo" => "EgL3uq_foo",
24881        "bar" => "EgL3uq_bar"
24882      },
24883      HashMap::new(),
24884      Default::default(),
24885      true,
24886    );
24887    css_modules_test(
24888      ".foo { view-transition-name: none }",
24889      ".EgL3uq_foo{view-transition-name:none}",
24890      map! {
24891        "foo" => "EgL3uq_foo"
24892      },
24893      HashMap::new(),
24894      Default::default(),
24895      true,
24896    );
24897    css_modules_test(
24898      ".foo { view-transition-name: auto }",
24899      ".EgL3uq_foo{view-transition-name:auto}",
24900      map! {
24901        "foo" => "EgL3uq_foo"
24902      },
24903      HashMap::new(),
24904      Default::default(),
24905      true,
24906    );
24907
24908    css_modules_test(
24909      ".foo { view-transition-class: bar baz qux }",
24910      ".EgL3uq_foo{view-transition-class:EgL3uq_bar EgL3uq_baz EgL3uq_qux}",
24911      map! {
24912        "foo" => "EgL3uq_foo",
24913        "bar" => "EgL3uq_bar",
24914        "baz" => "EgL3uq_baz",
24915        "qux" => "EgL3uq_qux"
24916      },
24917      HashMap::new(),
24918      Default::default(),
24919      true,
24920    );
24921
24922    css_modules_test(
24923      ".foo { view-transition-group: contain }",
24924      ".EgL3uq_foo{view-transition-group:contain}",
24925      map! {
24926        "foo" => "EgL3uq_foo"
24927      },
24928      HashMap::new(),
24929      Default::default(),
24930      true,
24931    );
24932    css_modules_test(
24933      ".foo { view-transition-group: bar }",
24934      ".EgL3uq_foo{view-transition-group:EgL3uq_bar}",
24935      map! {
24936        "foo" => "EgL3uq_foo",
24937        "bar" => "EgL3uq_bar"
24938      },
24939      HashMap::new(),
24940      Default::default(),
24941      true,
24942    );
24943
24944    css_modules_test(
24945      "@view-transition { types: foo bar baz }",
24946      "@view-transition{types:EgL3uq_foo EgL3uq_bar EgL3uq_baz}",
24947      map! {
24948        "foo" => "EgL3uq_foo",
24949        "bar" => "EgL3uq_bar",
24950        "baz" => "EgL3uq_baz"
24951      },
24952      HashMap::new(),
24953      Default::default(),
24954      true,
24955    );
24956
24957    css_modules_test(
24958      ":root:active-view-transition-type(foo, bar) { color: red }",
24959      ":root:active-view-transition-type(EgL3uq_foo,EgL3uq_bar){color:red}",
24960      map! {
24961        "foo" => "EgL3uq_foo",
24962        "bar" => "EgL3uq_bar"
24963      },
24964      HashMap::new(),
24965      Default::default(),
24966      true,
24967    );
24968
24969    for name in &[
24970      "view-transition-group",
24971      "view-transition-image-pair",
24972      "view-transition-new",
24973      "view-transition-old",
24974    ] {
24975      css_modules_test(
24976        &format!(":root::{}(foo) {{position: fixed}}", name),
24977        &format!(":root::{}(EgL3uq_foo){{position:fixed}}", name),
24978        map! {
24979          "foo" => "EgL3uq_foo"
24980        },
24981        HashMap::new(),
24982        Default::default(),
24983        true,
24984      );
24985      css_modules_test(
24986        &format!(":root::{}(.bar) {{position: fixed}}", name),
24987        &format!(":root::{}(.EgL3uq_bar){{position:fixed}}", name),
24988        map! {
24989          "bar" => "EgL3uq_bar"
24990        },
24991        HashMap::new(),
24992        Default::default(),
24993        true,
24994      );
24995      css_modules_test(
24996        &format!(":root::{}(foo.bar.baz) {{position: fixed}}", name),
24997        &format!(":root::{}(EgL3uq_foo.EgL3uq_bar.EgL3uq_baz){{position:fixed}}", name),
24998        map! {
24999          "foo" => "EgL3uq_foo",
25000          "bar" => "EgL3uq_bar",
25001          "baz" => "EgL3uq_baz"
25002        },
25003        HashMap::new(),
25004        Default::default(),
25005        true,
25006      );
25007
25008      css_modules_test(
25009        ":nth-child(1 of .foo) {width: 20px}",
25010        ":nth-child(1 of .EgL3uq_foo){width:20px}",
25011        map! {
25012          "foo" => "EgL3uq_foo"
25013        },
25014        HashMap::new(),
25015        Default::default(),
25016        true,
25017      );
25018      css_modules_test(
25019        ":nth-last-child(1 of .foo) {width: 20px}",
25020        ":nth-last-child(1 of .EgL3uq_foo){width:20px}",
25021        map! {
25022          "foo" => "EgL3uq_foo"
25023        },
25024        HashMap::new(),
25025        Default::default(),
25026        true,
25027      );
25028    }
25029
25030    // Stable hashes between project roots.
25031    fn test_project_root(project_root: &str, filename: &str, hash: &str) {
25032      let stylesheet = StyleSheet::parse(
25033        r#"
25034        .foo {
25035          background: red;
25036        }
25037        "#,
25038        ParserOptions {
25039          filename: filename.into(),
25040          css_modules: Some(Default::default()),
25041          ..ParserOptions::default()
25042        },
25043      )
25044      .unwrap();
25045      let res = stylesheet
25046        .to_css(PrinterOptions {
25047          project_root: Some(project_root),
25048          ..PrinterOptions::default()
25049        })
25050        .unwrap();
25051      assert_eq!(
25052        res.code,
25053        format!(
25054          indoc! {r#"
25055      .{}_foo {{
25056        background: red;
25057      }}
25058      "#},
25059          hash
25060        )
25061      );
25062    }
25063
25064    test_project_root("/foo/bar", "/foo/bar/test.css", "EgL3uq");
25065    test_project_root("/foo", "/foo/test.css", "EgL3uq");
25066    test_project_root("/foo/bar", "/foo/bar/baz/test.css", "xLEkNW");
25067    test_project_root("/foo", "/foo/baz/test.css", "xLEkNW");
25068  }
25069
25070  #[test]
25071  fn test_pseudo_replacement() {
25072    let source = r#"
25073      .foo:hover {
25074        color: red;
25075      }
25076
25077      .foo:active {
25078        color: yellow;
25079      }
25080
25081      .foo:focus-visible {
25082        color: purple;
25083      }
25084    "#;
25085
25086    let expected = indoc! { r#"
25087      .foo.is-hovered {
25088        color: red;
25089      }
25090
25091      .foo.is-active {
25092        color: #ff0;
25093      }
25094
25095      .foo.focus-visible {
25096        color: purple;
25097      }
25098    "#};
25099
25100    let stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
25101    let res = stylesheet
25102      .to_css(PrinterOptions {
25103        pseudo_classes: Some(PseudoClasses {
25104          hover: Some("is-hovered"),
25105          active: Some("is-active"),
25106          focus_visible: Some("focus-visible"),
25107          ..PseudoClasses::default()
25108        }),
25109        ..PrinterOptions::default()
25110      })
25111      .unwrap();
25112    assert_eq!(res.code, expected);
25113
25114    let source = r#"
25115      .foo:hover {
25116        color: red;
25117      }
25118    "#;
25119
25120    let expected = indoc! { r#"
25121      .EgL3uq_foo.EgL3uq_is-hovered {
25122        color: red;
25123      }
25124    "#};
25125
25126    let stylesheet = StyleSheet::parse(
25127      &source,
25128      ParserOptions {
25129        filename: "test.css".into(),
25130        css_modules: Some(Default::default()),
25131        ..ParserOptions::default()
25132      },
25133    )
25134    .unwrap();
25135    let res = stylesheet
25136      .to_css(PrinterOptions {
25137        pseudo_classes: Some(PseudoClasses {
25138          hover: Some("is-hovered"),
25139          ..PseudoClasses::default()
25140        }),
25141        ..PrinterOptions::default()
25142      })
25143      .unwrap();
25144    assert_eq!(res.code, expected);
25145  }
25146
25147  #[test]
25148  fn test_unused_symbols() {
25149    let source = r#"
25150      .foo {
25151        color: red;
25152      }
25153
25154      .bar {
25155        color: green;
25156      }
25157
25158      .bar:hover {
25159        color: purple;
25160      }
25161
25162      .bar .baz {
25163        background: red;
25164      }
25165
25166      .baz:is(.bar) {
25167        background: green;
25168      }
25169
25170      #id {
25171        animation: 2s test;
25172      }
25173
25174      #other_id {
25175        color: red;
25176      }
25177
25178      @keyframes test {
25179        from { color: red }
25180        to { color: yellow }
25181      }
25182
25183      @counter-style circles {
25184        symbols: Ⓐ Ⓑ Ⓒ;
25185      }
25186
25187      @keyframes fade {
25188        from { opacity: 0 }
25189        to { opacity: 1 }
25190      }
25191    "#;
25192
25193    let expected = indoc! {r#"
25194      .foo {
25195        color: red;
25196      }
25197
25198      #id {
25199        animation: 2s test;
25200      }
25201
25202      @keyframes test {
25203        from {
25204          color: red;
25205        }
25206
25207        to {
25208          color: #ff0;
25209        }
25210      }
25211    "#};
25212
25213    let mut stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
25214    stylesheet
25215      .minify(MinifyOptions {
25216        unused_symbols: vec!["bar", "other_id", "fade", "circles"]
25217          .iter()
25218          .map(|s| String::from(*s))
25219          .collect(),
25220        ..MinifyOptions::default()
25221      })
25222      .unwrap();
25223    let res = stylesheet.to_css(PrinterOptions::default()).unwrap();
25224    assert_eq!(res.code, expected);
25225
25226    let source = r#"
25227      .foo {
25228        color: red;
25229
25230        &.bar {
25231          color: green;
25232        }
25233      }
25234    "#;
25235
25236    let expected = indoc! {r#"
25237      .foo {
25238        color: red;
25239      }
25240    "#};
25241
25242    let mut stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
25243    stylesheet
25244      .minify(MinifyOptions {
25245        unused_symbols: vec!["bar"].iter().map(|s| String::from(*s)).collect(),
25246        ..MinifyOptions::default()
25247      })
25248      .unwrap();
25249    let res = stylesheet.to_css(PrinterOptions::default()).unwrap();
25250    assert_eq!(res.code, expected);
25251
25252    let source = r#"
25253      .foo {
25254        color: red;
25255
25256        &.bar {
25257          color: purple;
25258        }
25259
25260        @nest &.bar {
25261          color: orange;
25262        }
25263
25264        @nest :not(&) {
25265          color: green;
25266        }
25267
25268        @media (orientation: portrait) {
25269          color: brown;
25270        }
25271      }
25272
25273      .x {
25274        color: purple;
25275
25276        &.y {
25277          color: green;
25278        }
25279      }
25280    "#;
25281
25282    let expected = indoc! {r#"
25283      :not(.foo) {
25284        color: green;
25285      }
25286    "#};
25287
25288    let mut stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
25289    stylesheet
25290      .minify(MinifyOptions {
25291        unused_symbols: vec!["foo", "x"].iter().map(|s| String::from(*s)).collect(),
25292        ..MinifyOptions::default()
25293      })
25294      .unwrap();
25295    let res = stylesheet
25296      .to_css(PrinterOptions {
25297        targets: Browsers {
25298          chrome: Some(95 << 16),
25299          ..Browsers::default()
25300        }
25301        .into(),
25302        ..PrinterOptions::default()
25303      })
25304      .unwrap();
25305    assert_eq!(res.code, expected);
25306
25307    let source = r#"
25308      @property --EgL3uq_foo {
25309        syntax: "<color>";
25310        inherits: false;
25311        initial-value: #ff0;
25312      }
25313
25314      @font-palette-values --EgL3uq_Cooler {
25315        font-family: Bixa;
25316        base-palette: 1;
25317        override-colors: 1 #7EB7E4;
25318      }
25319
25320      .EgL3uq_foo {
25321        --EgL3uq_foo: red;
25322      }
25323
25324      .EgL3uq_bar {
25325        color: green;
25326      }
25327    "#;
25328
25329    let expected = indoc! {r#"
25330      .EgL3uq_bar {
25331        color: green;
25332      }
25333    "#};
25334
25335    let mut stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
25336    stylesheet
25337      .minify(MinifyOptions {
25338        unused_symbols: vec!["--EgL3uq_foo", "--EgL3uq_Cooler"]
25339          .iter()
25340          .map(|s| String::from(*s))
25341          .collect(),
25342        ..MinifyOptions::default()
25343      })
25344      .unwrap();
25345    let res = stylesheet.to_css(PrinterOptions::default()).unwrap();
25346    assert_eq!(res.code, expected);
25347  }
25348
25349  #[test]
25350  fn test_svg() {
25351    minify_test(".foo { fill: yellow; }", ".foo{fill:#ff0}");
25352    minify_test(".foo { fill: url(#foo); }", ".foo{fill:url(#foo)}");
25353    minify_test(".foo { fill: url(#foo) none; }", ".foo{fill:url(#foo) none}");
25354    minify_test(".foo { fill: url(#foo) yellow; }", ".foo{fill:url(#foo) #ff0}");
25355    minify_test(".foo { fill: none; }", ".foo{fill:none}");
25356    minify_test(".foo { fill: context-fill; }", ".foo{fill:context-fill}");
25357    minify_test(".foo { fill: context-stroke; }", ".foo{fill:context-stroke}");
25358
25359    minify_test(".foo { stroke: yellow; }", ".foo{stroke:#ff0}");
25360    minify_test(".foo { stroke: url(#foo); }", ".foo{stroke:url(#foo)}");
25361    minify_test(".foo { stroke: url(#foo) none; }", ".foo{stroke:url(#foo) none}");
25362    minify_test(".foo { stroke: url(#foo) yellow; }", ".foo{stroke:url(#foo) #ff0}");
25363    minify_test(".foo { stroke: none; }", ".foo{stroke:none}");
25364    minify_test(".foo { stroke: context-fill; }", ".foo{stroke:context-fill}");
25365    minify_test(".foo { stroke: context-stroke; }", ".foo{stroke:context-stroke}");
25366
25367    minify_test(".foo { marker-start: url(#foo); }", ".foo{marker-start:url(#foo)}");
25368
25369    minify_test(".foo { stroke-dasharray: 4 1 2; }", ".foo{stroke-dasharray:4 1 2}");
25370    minify_test(".foo { stroke-dasharray: 4,1,2; }", ".foo{stroke-dasharray:4 1 2}");
25371    minify_test(".foo { stroke-dasharray: 4, 1, 2; }", ".foo{stroke-dasharray:4 1 2}");
25372    minify_test(
25373      ".foo { stroke-dasharray: 4px, 1px, 2px; }",
25374      ".foo{stroke-dasharray:4 1 2}",
25375    );
25376
25377    minify_test(".foo { mask: url('foo.svg'); }", ".foo{mask:url(foo.svg)}");
25378    minify_test(
25379      ".foo { mask: url(masks.svg#star) luminance }",
25380      ".foo{mask:url(masks.svg#star) luminance}",
25381    );
25382    minify_test(
25383      ".foo { mask: url(masks.svg#star) 40px 20px }",
25384      ".foo{mask:url(masks.svg#star) 40px 20px}",
25385    );
25386    minify_test(
25387      ".foo { mask: url(masks.svg#star) 0 0 / 50px 50px }",
25388      ".foo{mask:url(masks.svg#star) 0 0/50px 50px}",
25389    );
25390    minify_test(
25391      ".foo { mask: url(masks.svg#star) repeat-x }",
25392      ".foo{mask:url(masks.svg#star) repeat-x}",
25393    );
25394    minify_test(
25395      ".foo { mask: url(masks.svg#star) stroke-box }",
25396      ".foo{mask:url(masks.svg#star) stroke-box}",
25397    );
25398    minify_test(
25399      ".foo { mask: url(masks.svg#star) stroke-box stroke-box }",
25400      ".foo{mask:url(masks.svg#star) stroke-box}",
25401    );
25402    minify_test(
25403      ".foo { mask: url(masks.svg#star) border-box }",
25404      ".foo{mask:url(masks.svg#star)}",
25405    );
25406    minify_test(
25407      ".foo { mask: url(masks.svg#star) left / 16px repeat-y, url(masks.svg#circle) right / 16px repeat-y }",
25408      ".foo{mask:url(masks.svg#star) 0/16px repeat-y,url(masks.svg#circle) 100%/16px repeat-y}",
25409    );
25410
25411    minify_test(
25412      ".foo { mask-border: url('border-mask.png') 25; }",
25413      ".foo{mask-border:url(border-mask.png) 25}",
25414    );
25415    minify_test(
25416      ".foo { mask-border: url('border-mask.png') 25 / 35px / 12px space alpha; }",
25417      ".foo{mask-border:url(border-mask.png) 25/35px/12px space}",
25418    );
25419    minify_test(
25420      ".foo { mask-border: url('border-mask.png') 25 / 35px / 12px space luminance; }",
25421      ".foo{mask-border:url(border-mask.png) 25/35px/12px space luminance}",
25422    );
25423    minify_test(
25424      ".foo { mask-border: url('border-mask.png') luminance 25 / 35px / 12px space; }",
25425      ".foo{mask-border:url(border-mask.png) 25/35px/12px space luminance}",
25426    );
25427
25428    minify_test(
25429      ".foo { clip-path: url('clip.svg#star'); }",
25430      ".foo{clip-path:url(clip.svg#star)}",
25431    );
25432    minify_test(".foo { clip-path: margin-box; }", ".foo{clip-path:margin-box}");
25433    minify_test(
25434      ".foo { clip-path: inset(100px 50px); }",
25435      ".foo{clip-path:inset(100px 50px)}",
25436    );
25437    minify_test(
25438      ".foo { clip-path: inset(100px 50px round 5px); }",
25439      ".foo{clip-path:inset(100px 50px round 5px)}",
25440    );
25441    minify_test(
25442      ".foo { clip-path: inset(100px 50px round 5px 5px 5px 5px); }",
25443      ".foo{clip-path:inset(100px 50px round 5px)}",
25444    );
25445    minify_test(".foo { clip-path: circle(50px); }", ".foo{clip-path:circle(50px)}");
25446    minify_test(
25447      ".foo { clip-path: circle(50px at center center); }",
25448      ".foo{clip-path:circle(50px)}",
25449    );
25450    minify_test(
25451      ".foo { clip-path: circle(50px at 50% 50%); }",
25452      ".foo{clip-path:circle(50px)}",
25453    );
25454    minify_test(
25455      ".foo { clip-path: circle(50px at 0 100px); }",
25456      ".foo{clip-path:circle(50px at 0 100px)}",
25457    );
25458    minify_test(
25459      ".foo { clip-path: circle(closest-side at 0 100px); }",
25460      ".foo{clip-path:circle(at 0 100px)}",
25461    );
25462    minify_test(
25463      ".foo { clip-path: circle(farthest-side at 0 100px); }",
25464      ".foo{clip-path:circle(farthest-side at 0 100px)}",
25465    );
25466    minify_test(
25467      ".foo { clip-path: circle(closest-side at 50% 50%); }",
25468      ".foo{clip-path:circle()}",
25469    );
25470    minify_test(
25471      ".foo { clip-path: ellipse(50px 60px at 0 10% 20%); }",
25472      ".foo{clip-path:ellipse(50px 60px at 0 10% 20%)}",
25473    );
25474    minify_test(
25475      ".foo { clip-path: ellipse(50px 60px at center center); }",
25476      ".foo{clip-path:ellipse(50px 60px)}",
25477    );
25478    minify_test(
25479      ".foo { clip-path: ellipse(closest-side closest-side at 50% 50%); }",
25480      ".foo{clip-path:ellipse()}",
25481    );
25482    minify_test(
25483      ".foo { clip-path: ellipse(closest-side closest-side at 10% 20%); }",
25484      ".foo{clip-path:ellipse(at 10% 20%)}",
25485    );
25486    minify_test(
25487      ".foo { clip-path: ellipse(farthest-side closest-side at 10% 20%); }",
25488      ".foo{clip-path:ellipse(farthest-side closest-side at 10% 20%)}",
25489    );
25490    minify_test(
25491      ".foo { clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); }",
25492      ".foo{clip-path:polygon(50% 0%,100% 50%,50% 100%,0% 50%)}",
25493    );
25494    minify_test(
25495      ".foo { clip-path: polygon(nonzero, 50% 0%, 100% 50%, 50% 100%, 0% 50%); }",
25496      ".foo{clip-path:polygon(50% 0%,100% 50%,50% 100%,0% 50%)}",
25497    );
25498    minify_test(
25499      ".foo { clip-path: polygon(evenodd, 50% 0%, 100% 50%, 50% 100%, 0% 50%); }",
25500      ".foo{clip-path:polygon(evenodd,50% 0%,100% 50%,50% 100%,0% 50%)}",
25501    );
25502    minify_test(
25503      ".foo { clip-path: padding-box circle(50px at 0 100px); }",
25504      ".foo{clip-path:circle(50px at 0 100px) padding-box}",
25505    );
25506    minify_test(
25507      ".foo { clip-path: circle(50px at 0 100px) padding-box; }",
25508      ".foo{clip-path:circle(50px at 0 100px) padding-box}",
25509    );
25510    minify_test(
25511      ".foo { clip-path: circle(50px at 0 100px) border-box; }",
25512      ".foo{clip-path:circle(50px at 0 100px)}",
25513    );
25514
25515    prefix_test(
25516      ".foo { clip-path: circle(50px); }",
25517      indoc! { r#"
25518        .foo {
25519          -webkit-clip-path: circle(50px);
25520          clip-path: circle(50px);
25521        }
25522      "#},
25523      Browsers {
25524        chrome: Some(30 << 16),
25525        ..Browsers::default()
25526      },
25527    );
25528
25529    prefix_test(
25530      ".foo { clip-path: circle(50px); }",
25531      indoc! { r#"
25532        .foo {
25533          clip-path: circle(50px);
25534        }
25535      "#},
25536      Browsers {
25537        chrome: Some(80 << 16),
25538        ..Browsers::default()
25539      },
25540    );
25541
25542    prefix_test(
25543      ".foo { clip-path: circle(50px); }",
25544      indoc! { r#"
25545        .foo {
25546          -webkit-clip-path: circle(50px);
25547          clip-path: circle(50px);
25548        }
25549      "#},
25550      Browsers {
25551        safari: Some(8 << 16),
25552        ..Browsers::default()
25553      },
25554    );
25555
25556    prefix_test(
25557      ".foo { clip-path: circle(50px); }",
25558      indoc! { r#"
25559        .foo {
25560          clip-path: circle(50px);
25561        }
25562      "#},
25563      Browsers {
25564        safari: Some(14 << 16),
25565        ..Browsers::default()
25566      },
25567    );
25568
25569    prefix_test(
25570      ".foo { fill: lch(50.998% 135.363 338) }",
25571      indoc! { r#"
25572        .foo {
25573          fill: #ee00be;
25574          fill: color(display-p3 .972962 -.362078 .804206);
25575          fill: lch(50.998% 135.363 338);
25576        }
25577      "#},
25578      Browsers {
25579        chrome: Some(90 << 16),
25580        safari: Some(14 << 16),
25581        ..Browsers::default()
25582      },
25583    );
25584
25585    prefix_test(
25586      ".foo { stroke: lch(50.998% 135.363 338) }",
25587      indoc! { r#"
25588        .foo {
25589          stroke: #ee00be;
25590          stroke: color(display-p3 .972962 -.362078 .804206);
25591          stroke: lch(50.998% 135.363 338);
25592        }
25593      "#},
25594      Browsers {
25595        chrome: Some(90 << 16),
25596        safari: Some(14 << 16),
25597        ..Browsers::default()
25598      },
25599    );
25600
25601    prefix_test(
25602      ".foo { fill: url(#foo) lch(50.998% 135.363 338) }",
25603      indoc! { r##"
25604        .foo {
25605          fill: url("#foo") #ee00be;
25606          fill: url("#foo") color(display-p3 .972962 -.362078 .804206);
25607          fill: url("#foo") lch(50.998% 135.363 338);
25608        }
25609      "##},
25610      Browsers {
25611        chrome: Some(90 << 16),
25612        safari: Some(14 << 16),
25613        ..Browsers::default()
25614      },
25615    );
25616
25617    prefix_test(
25618      ".foo { fill: var(--url) lch(50.998% 135.363 338) }",
25619      indoc! { r#"
25620        .foo {
25621          fill: var(--url) #ee00be;
25622        }
25623
25624        @supports (color: lab(0% 0 0)) {
25625          .foo {
25626            fill: var(--url) lab(50.998% 125.506 -50.7078);
25627          }
25628        }
25629      "#},
25630      Browsers {
25631        chrome: Some(90 << 16),
25632        ..Browsers::default()
25633      },
25634    );
25635
25636    prefix_test(
25637      ".foo { mask-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
25638      indoc! { r#"
25639        .foo {
25640          -webkit-mask-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0f0e), to(#7773ff));
25641          -webkit-mask-image: -webkit-linear-gradient(#ff0f0e, #7773ff);
25642          -webkit-mask-image: linear-gradient(#ff0f0e, #7773ff);
25643          mask-image: linear-gradient(#ff0f0e, #7773ff);
25644          -webkit-mask-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
25645          mask-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
25646        }
25647      "#},
25648      Browsers {
25649        chrome: Some(8 << 16),
25650        ..Browsers::default()
25651      },
25652    );
25653
25654    prefix_test(
25655      ".foo { mask-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) }",
25656      indoc! { r#"
25657        .foo {
25658          -webkit-mask-image: linear-gradient(#ff0f0e, #7773ff);
25659          mask-image: linear-gradient(#ff0f0e, #7773ff);
25660          -webkit-mask-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
25661          mask-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
25662        }
25663      "#},
25664      Browsers {
25665        chrome: Some(95 << 16),
25666        ..Browsers::default()
25667      },
25668    );
25669
25670    prefix_test(
25671      ".foo { mask-image: linear-gradient(red, green) }",
25672      indoc! { r#"
25673        .foo {
25674          -webkit-mask-image: linear-gradient(red, green);
25675          mask-image: linear-gradient(red, green);
25676        }
25677      "#},
25678      Browsers {
25679        chrome: Some(95 << 16),
25680        ..Browsers::default()
25681      },
25682    );
25683
25684    prefix_test(
25685      ".foo { -webkit-mask-image: url(x.svg); mask-image: url(x.svg); }",
25686      indoc! { r#"
25687        .foo {
25688          -webkit-mask-image: url("x.svg");
25689          mask-image: url("x.svg");
25690        }
25691      "#},
25692      Browsers {
25693        chrome: Some(95 << 16),
25694        ..Browsers::default()
25695      },
25696    );
25697
25698    prefix_test(
25699      ".foo { mask: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 40px 20px }",
25700      indoc! { r#"
25701        .foo {
25702          -webkit-mask: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0f0e), to(#7773ff)) 40px 20px;
25703          -webkit-mask: -webkit-linear-gradient(#ff0f0e, #7773ff) 40px 20px;
25704          -webkit-mask: linear-gradient(#ff0f0e, #7773ff) 40px 20px;
25705          mask: linear-gradient(#ff0f0e, #7773ff) 40px 20px;
25706          -webkit-mask: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 40px 20px;
25707          mask: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 40px 20px;
25708        }
25709      "#},
25710      Browsers {
25711        chrome: Some(8 << 16),
25712        ..Browsers::default()
25713      },
25714    );
25715
25716    prefix_test(
25717      ".foo { mask: -webkit-linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 40px 20px }",
25718      indoc! { r#"
25719        .foo {
25720          -webkit-mask: -webkit-gradient(linear, 0 0, 0 100%, from(#ff0f0e), to(#7773ff)) 40px 20px;
25721          -webkit-mask: -webkit-linear-gradient(#ff0f0e, #7773ff) 40px 20px;
25722        }
25723      "#},
25724      Browsers {
25725        chrome: Some(8 << 16),
25726        ..Browsers::default()
25727      },
25728    );
25729
25730    prefix_test(
25731      ".foo { mask: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 40px var(--foo) }",
25732      indoc! { r#"
25733        .foo {
25734          -webkit-mask: linear-gradient(#ff0f0e, #7773ff) 40px var(--foo);
25735          mask: linear-gradient(#ff0f0e, #7773ff) 40px var(--foo);
25736        }
25737
25738        @supports (color: lab(0% 0 0)) {
25739          .foo {
25740            -webkit-mask: linear-gradient(lab(56.208% 94.4644 98.8928), lab(51% 70.4544 -115.586)) 40px var(--foo);
25741            mask: linear-gradient(lab(56.208% 94.4644 98.8928), lab(51% 70.4544 -115.586)) 40px var(--foo);
25742          }
25743        }
25744      "#},
25745      Browsers {
25746        chrome: Some(90 << 16),
25747        ..Browsers::default()
25748      },
25749    );
25750
25751    prefix_test(
25752      ".foo { mask: url(masks.svg#star) luminance }",
25753      indoc! { r#"
25754        .foo {
25755          -webkit-mask: url("masks.svg#star");
25756          -webkit-mask-source-type: luminance;
25757          mask: url("masks.svg#star") luminance;
25758        }
25759    "#},
25760      Browsers {
25761        chrome: Some(90 << 16),
25762        ..Browsers::default()
25763      },
25764    );
25765
25766    prefix_test(
25767      ".foo { mask-image: url(masks.svg#star) }",
25768      indoc! { r#"
25769        .foo {
25770          -webkit-mask-image: url("masks.svg#star");
25771          mask-image: url("masks.svg#star");
25772        }
25773    "#},
25774      Browsers {
25775        chrome: Some(90 << 16),
25776        ..Browsers::default()
25777      },
25778    );
25779
25780    prefix_test(
25781      r#"
25782        .foo {
25783          mask-image: url(masks.svg#star);
25784          mask-position: 25% 75%;
25785          mask-size: cover;
25786          mask-repeat: no-repeat;
25787          mask-clip: padding-box;
25788          mask-origin: content-box;
25789          mask-composite: subtract;
25790          mask-mode: luminance;
25791        }
25792      "#,
25793      indoc! { r#"
25794        .foo {
25795          -webkit-mask: url("masks.svg#star") 25% 75% / cover no-repeat content-box padding-box;
25796          -webkit-mask-composite: source-out;
25797          -webkit-mask-source-type: luminance;
25798          mask: url("masks.svg#star") 25% 75% / cover no-repeat content-box padding-box subtract luminance;
25799        }
25800    "#},
25801      Browsers {
25802        chrome: Some(90 << 16),
25803        ..Browsers::default()
25804      },
25805    );
25806
25807    prefix_test(
25808      r#"
25809        .foo {
25810          mask-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
25811          mask-position: 25% 75%;
25812          mask-size: cover;
25813          mask-repeat: no-repeat;
25814          mask-clip: padding-box;
25815          mask-origin: content-box;
25816          mask-composite: subtract;
25817          mask-mode: luminance;
25818        }
25819      "#,
25820      indoc! { r#"
25821        .foo {
25822          -webkit-mask: linear-gradient(#ff0f0e, #7773ff) 25% 75% / cover no-repeat content-box padding-box;
25823          -webkit-mask-composite: source-out;
25824          -webkit-mask-source-type: luminance;
25825          mask: linear-gradient(#ff0f0e, #7773ff) 25% 75% / cover no-repeat content-box padding-box subtract luminance;
25826          -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;
25827          -webkit-mask-composite: source-out;
25828          -webkit-mask-source-type: luminance;
25829          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;
25830        }
25831    "#},
25832      Browsers {
25833        chrome: Some(90 << 16),
25834        ..Browsers::default()
25835      },
25836    );
25837
25838    test(
25839      r#"
25840        .foo {
25841          mask: none center / 100% no-repeat;
25842          mask-image: var(--svg);
25843        }
25844      "#,
25845      indoc! { r#"
25846        .foo {
25847          mask: none center / 100% no-repeat;
25848          mask-image: var(--svg);
25849        }
25850      "#},
25851    );
25852
25853    prefix_test(
25854      r#"
25855        .foo {
25856          mask-composite: subtract;
25857        }
25858      "#,
25859      indoc! { r#"
25860        .foo {
25861          -webkit-mask-composite: source-out;
25862          mask-composite: subtract;
25863        }
25864    "#},
25865      Browsers {
25866        chrome: Some(90 << 16),
25867        ..Browsers::default()
25868      },
25869    );
25870
25871    prefix_test(
25872      r#"
25873        .foo {
25874          mask-mode: luminance;
25875        }
25876      "#,
25877      indoc! { r#"
25878        .foo {
25879          -webkit-mask-source-type: luminance;
25880          mask-mode: luminance;
25881        }
25882    "#},
25883      Browsers {
25884        chrome: Some(90 << 16),
25885        ..Browsers::default()
25886      },
25887    );
25888
25889    prefix_test(
25890      r#"
25891        .foo {
25892          mask-border: url('border-mask.png') 25 / 35px / 12px space luminance;
25893        }
25894      "#,
25895      indoc! { r#"
25896        .foo {
25897          -webkit-mask-box-image: url("border-mask.png") 25 / 35px / 12px space;
25898          mask-border: url("border-mask.png") 25 / 35px / 12px space luminance;
25899        }
25900    "#},
25901      Browsers {
25902        chrome: Some(90 << 16),
25903        ..Browsers::default()
25904      },
25905    );
25906
25907    prefix_test(
25908      r#"
25909        .foo {
25910          mask-border: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 25 / 35px / 12px space luminance;
25911        }
25912      "#,
25913      indoc! { r#"
25914        .foo {
25915          -webkit-mask-box-image: linear-gradient(#ff0f0e, #7773ff) 25 / 35px / 12px space;
25916          mask-border: linear-gradient(#ff0f0e, #7773ff) 25 / 35px / 12px space luminance;
25917          -webkit-mask-box-image: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 25 / 35px / 12px space;
25918          mask-border: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) 25 / 35px / 12px space luminance;
25919        }
25920    "#},
25921      Browsers {
25922        chrome: Some(90 << 16),
25923        ..Browsers::default()
25924      },
25925    );
25926
25927    prefix_test(
25928      r#"
25929        .foo {
25930          mask-border-source: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
25931        }
25932      "#,
25933      indoc! { r#"
25934        .foo {
25935          -webkit-mask-box-image-source: linear-gradient(#ff0f0e, #7773ff);
25936          mask-border-source: linear-gradient(#ff0f0e, #7773ff);
25937          -webkit-mask-box-image-source: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
25938          mask-border-source: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364));
25939        }
25940    "#},
25941      Browsers {
25942        chrome: Some(90 << 16),
25943        ..Browsers::default()
25944      },
25945    );
25946
25947    prefix_test(
25948      r#"
25949        .foo {
25950          mask-border-source: url(foo.png);
25951          mask-border-slice: 10 40 10 40;
25952          mask-border-width: 10px;
25953          mask-border-outset: 0;
25954          mask-border-repeat: round round;
25955          mask-border-mode: luminance;
25956        }
25957      "#,
25958      indoc! { r#"
25959        .foo {
25960          -webkit-mask-box-image: url("foo.png") 10 40 / 10px round;
25961          mask-border: url("foo.png") 10 40 / 10px round luminance;
25962        }
25963    "#},
25964      Browsers {
25965        chrome: Some(90 << 16),
25966        ..Browsers::default()
25967      },
25968    );
25969
25970    prefix_test(
25971      r#"
25972        .foo {
25973          -webkit-mask-box-image-source: url(foo.png);
25974          -webkit-mask-box-image-slice: 10 40 10 40;
25975          -webkit-mask-box-image-width: 10px;
25976          -webkit-mask-box-image-outset: 0;
25977          -webkit-mask-box-image-repeat: round round;
25978        }
25979      "#,
25980      indoc! { r#"
25981        .foo {
25982          -webkit-mask-box-image: url("foo.png") 10 40 / 10px round;
25983        }
25984    "#},
25985      Browsers {
25986        chrome: Some(90 << 16),
25987        ..Browsers::default()
25988      },
25989    );
25990
25991    prefix_test(
25992      r#"
25993        .foo {
25994          mask-border-slice: 10 40 10 40;
25995        }
25996      "#,
25997      indoc! { r#"
25998        .foo {
25999          -webkit-mask-box-image-slice: 10 40;
26000          mask-border-slice: 10 40;
26001        }
26002    "#},
26003      Browsers {
26004        chrome: Some(90 << 16),
26005        ..Browsers::default()
26006      },
26007    );
26008
26009    prefix_test(
26010      r#"
26011        .foo {
26012          mask-border-slice: var(--foo);
26013        }
26014      "#,
26015      indoc! { r#"
26016        .foo {
26017          -webkit-mask-box-image-slice: var(--foo);
26018          mask-border-slice: var(--foo);
26019        }
26020    "#},
26021      Browsers {
26022        chrome: Some(90 << 16),
26023        ..Browsers::default()
26024      },
26025    );
26026
26027    prefix_test(
26028      r#"
26029        .foo {
26030          mask-border: linear-gradient(lch(56.208% 136.76 46.312), lch(51% 135.366 301.364)) var(--foo);
26031        }
26032      "#,
26033      indoc! { r#"
26034        .foo {
26035          -webkit-mask-box-image: linear-gradient(#ff0f0e, #7773ff) var(--foo);
26036          mask-border: linear-gradient(#ff0f0e, #7773ff) var(--foo);
26037        }
26038
26039        @supports (color: lab(0% 0 0)) {
26040          .foo {
26041            -webkit-mask-box-image: linear-gradient(lab(56.208% 94.4644 98.8928), lab(51% 70.4544 -115.586)) var(--foo);
26042            mask-border: linear-gradient(lab(56.208% 94.4644 98.8928), lab(51% 70.4544 -115.586)) var(--foo);
26043          }
26044        }
26045    "#},
26046      Browsers {
26047        chrome: Some(90 << 16),
26048        ..Browsers::default()
26049      },
26050    );
26051
26052    prefix_test(
26053      r#"
26054        .foo {
26055          transition: mask 200ms;
26056        }
26057      "#,
26058      indoc! { r#"
26059        .foo {
26060          transition: -webkit-mask .2s, mask .2s;
26061        }
26062    "#},
26063      Browsers {
26064        chrome: Some(90 << 16),
26065        ..Browsers::default()
26066      },
26067    );
26068
26069    prefix_test(
26070      r#"
26071        .foo {
26072          transition: mask-border 200ms;
26073        }
26074      "#,
26075      indoc! { r#"
26076        .foo {
26077          transition: -webkit-mask-box-image .2s, mask-border .2s;
26078        }
26079    "#},
26080      Browsers {
26081        chrome: Some(90 << 16),
26082        ..Browsers::default()
26083      },
26084    );
26085
26086    prefix_test(
26087      r#"
26088        .foo {
26089          transition-property: mask;
26090        }
26091      "#,
26092      indoc! { r#"
26093        .foo {
26094          transition-property: -webkit-mask, mask;
26095        }
26096    "#},
26097      Browsers {
26098        chrome: Some(90 << 16),
26099        ..Browsers::default()
26100      },
26101    );
26102
26103    prefix_test(
26104      r#"
26105        .foo {
26106          transition-property: mask-border;
26107        }
26108      "#,
26109      indoc! { r#"
26110        .foo {
26111          transition-property: -webkit-mask-box-image, mask-border;
26112        }
26113    "#},
26114      Browsers {
26115        chrome: Some(90 << 16),
26116        ..Browsers::default()
26117      },
26118    );
26119
26120    prefix_test(
26121      r#"
26122        .foo {
26123          transition-property: mask-composite, mask-mode;
26124        }
26125      "#,
26126      indoc! { r#"
26127        .foo {
26128          transition-property: -webkit-mask-composite, mask-composite, -webkit-mask-source-type, mask-mode;
26129        }
26130    "#},
26131      Browsers {
26132        chrome: Some(90 << 16),
26133        ..Browsers::default()
26134      },
26135    );
26136  }
26137
26138  #[test]
26139  fn test_filter() {
26140    minify_test(
26141      ".foo { filter: url('filters.svg#filter-id'); }",
26142      ".foo{filter:url(filters.svg#filter-id)}",
26143    );
26144    minify_test(".foo { filter: blur(5px); }", ".foo{filter:blur(5px)}");
26145    minify_test(".foo { filter: blur(0px); }", ".foo{filter:blur()}");
26146    minify_test(".foo { filter: brightness(10%); }", ".foo{filter:brightness(10%)}");
26147    minify_test(".foo { filter: brightness(100%); }", ".foo{filter:brightness()}");
26148    minify_test(
26149      ".foo { filter: drop-shadow(16px 16px 20px yellow); }",
26150      ".foo{filter:drop-shadow(16px 16px 20px #ff0)}",
26151    );
26152    minify_test(
26153      ".foo { filter: contrast(175%) brightness(3%); }",
26154      ".foo{filter:contrast(175%)brightness(3%)}",
26155    );
26156    minify_test(".foo { filter: hue-rotate(0) }", ".foo{filter:hue-rotate()}");
26157
26158    prefix_test(
26159      ".foo { filter: blur(5px) }",
26160      indoc! { r#"
26161        .foo {
26162          -webkit-filter: blur(5px);
26163          filter: blur(5px);
26164        }
26165      "#},
26166      Browsers {
26167        chrome: Some(20 << 16),
26168        ..Browsers::default()
26169      },
26170    );
26171
26172    prefix_test(
26173      ".foo { filter: blur(5px) }",
26174      indoc! { r#"
26175        .foo {
26176          filter: blur(5px);
26177        }
26178      "#},
26179      Browsers {
26180        chrome: Some(80 << 16),
26181        ..Browsers::default()
26182      },
26183    );
26184
26185    prefix_test(
26186      ".foo { backdrop-filter: blur(5px) }",
26187      indoc! { r#"
26188        .foo {
26189          backdrop-filter: blur(5px);
26190        }
26191      "#},
26192      Browsers {
26193        chrome: Some(80 << 16),
26194        ..Browsers::default()
26195      },
26196    );
26197
26198    prefix_test(
26199      ".foo { backdrop-filter: blur(5px) }",
26200      indoc! { r#"
26201        .foo {
26202          -webkit-backdrop-filter: blur(5px);
26203          backdrop-filter: blur(5px);
26204        }
26205      "#},
26206      Browsers {
26207        safari: Some(15 << 16),
26208        ..Browsers::default()
26209      },
26210    );
26211    prefix_test(
26212      r#"
26213      .foo {
26214        -webkit-backdrop-filter: blur(8px);
26215        backdrop-filter: blur(8px);
26216      }
26217      "#,
26218      indoc! {r#"
26219      .foo {
26220        -webkit-backdrop-filter: blur(8px);
26221        backdrop-filter: blur(8px);
26222      }
26223      "#},
26224      Browsers {
26225        safari: Some(16 << 16),
26226        ..Browsers::default()
26227      },
26228    );
26229
26230    prefix_test(
26231      ".foo { filter: var(--foo) }",
26232      indoc! { r#"
26233        .foo {
26234          -webkit-filter: var(--foo);
26235          filter: var(--foo);
26236        }
26237      "#},
26238      Browsers {
26239        chrome: Some(20 << 16),
26240        ..Browsers::default()
26241      },
26242    );
26243
26244    prefix_test(
26245      ".foo { filter: drop-shadow(16px 16px 20px lab(40% 56.6 39)) }",
26246      indoc! { r#"
26247        .foo {
26248          -webkit-filter: drop-shadow(16px 16px 20px #b32323);
26249          filter: drop-shadow(16px 16px 20px #b32323);
26250          filter: drop-shadow(16px 16px 20px lab(40% 56.6 39));
26251        }
26252      "#},
26253      Browsers {
26254        chrome: Some(20 << 16),
26255        ..Browsers::default()
26256      },
26257    );
26258
26259    prefix_test(
26260      ".foo { filter: contrast(175%) drop-shadow(16px 16px 20px lab(40% 56.6 39)) }",
26261      indoc! { r#"
26262        .foo {
26263          filter: contrast(175%) drop-shadow(16px 16px 20px #b32323);
26264          filter: contrast(175%) drop-shadow(16px 16px 20px lab(40% 56.6 39));
26265        }
26266      "#},
26267      Browsers {
26268        chrome: Some(4 << 16),
26269        ..Browsers::default()
26270      },
26271    );
26272
26273    prefix_test(
26274      ".foo { filter: drop-shadow(16px 16px 20px lab(40% 56.6 39)) drop-shadow(16px 16px 20px yellow) }",
26275      indoc! { r#"
26276        .foo {
26277          filter: drop-shadow(16px 16px 20px #b32323) drop-shadow(16px 16px 20px #ff0);
26278          filter: drop-shadow(16px 16px 20px lab(40% 56.6 39)) drop-shadow(16px 16px 20px #ff0);
26279        }
26280      "#},
26281      Browsers {
26282        chrome: Some(4 << 16),
26283        ..Browsers::default()
26284      },
26285    );
26286
26287    prefix_test(
26288      ".foo { filter: var(--foo) drop-shadow(16px 16px 20px lab(40% 56.6 39)) }",
26289      indoc! { r#"
26290        .foo {
26291          filter: var(--foo) drop-shadow(16px 16px 20px #b32323);
26292        }
26293
26294        @supports (color: lab(0% 0 0)) {
26295          .foo {
26296            filter: var(--foo) drop-shadow(16px 16px 20px lab(40% 56.6 39));
26297          }
26298        }
26299      "#},
26300      Browsers {
26301        chrome: Some(4 << 16),
26302        ..Browsers::default()
26303      },
26304    );
26305  }
26306
26307  #[test]
26308  fn test_viewport() {
26309    minify_test(
26310      r#"
26311    @viewport {
26312      width: 100vw;
26313    }"#,
26314      "@viewport{width:100vw}",
26315    );
26316    minify_test(
26317      r#"
26318    @-ms-viewport {
26319      width: device-width;
26320    }"#,
26321      "@-ms-viewport{width:device-width}",
26322    );
26323  }
26324
26325  #[test]
26326  fn test_at_scope() {
26327    minify_test(
26328      r#"
26329      @scope {
26330        .foo {
26331          display: flex;
26332        }
26333      }
26334      "#,
26335      "@scope{.foo{display:flex}}",
26336    );
26337    minify_test(
26338      r#"
26339      @scope {
26340        :scope {
26341          display: flex;
26342          color: lightblue;
26343        }
26344      }"#,
26345      "@scope{:scope{color:#add8e6;display:flex}}",
26346    );
26347    minify_test(
26348      r#"
26349      @scope (.light-scheme) {
26350        a { color: yellow; }
26351      }
26352      "#,
26353      "@scope(.light-scheme){a{color:#ff0}}",
26354    );
26355    minify_test(
26356      r#"
26357      @scope (.media-object) to (.content > *) {
26358        a { color: yellow; }
26359      }
26360      "#,
26361      "@scope(.media-object) to (.content>*){a{color:#ff0}}",
26362    );
26363    minify_test(
26364      r#"
26365      @scope to (.content > *) {
26366        a { color: yellow; }
26367      }
26368      "#,
26369      "@scope to (.content>*){a{color:#ff0}}",
26370    );
26371    minify_test(
26372      r#"
26373      @scope (#my-component) {
26374        & { color: yellow; }
26375      }
26376      "#,
26377      "@scope(#my-component){&{color:#ff0}}",
26378    );
26379    minify_test(
26380      r#"
26381      @scope (.parent-scope) {
26382        @scope (:scope > .child-scope) to (:scope .limit) {
26383          .content { color: yellow; }
26384        }
26385      }
26386      "#,
26387      "@scope(.parent-scope){@scope(:scope>.child-scope) to (:scope .limit){.content{color:#ff0}}}",
26388    );
26389    minify_test(
26390      r#"
26391      .foo {
26392        @scope (.bar) {
26393          color: yellow;
26394        }
26395      }
26396      "#,
26397      ".foo{@scope(.bar){&{color:#ff0}}}",
26398    );
26399    nesting_test(
26400      r#"
26401      .foo {
26402        @scope (.bar) {
26403          color: yellow;
26404        }
26405      }
26406      "#,
26407      indoc! {r#"
26408        @scope (.bar) {
26409          :scope {
26410            color: #ff0;
26411          }
26412        }
26413      "#},
26414    );
26415    nesting_test(
26416      r#"
26417      .parent {
26418        color: blue;
26419
26420        @scope (& > .scope) to (& .limit) {
26421          & .content {
26422            color: yellow;
26423          }
26424        }
26425      }
26426      "#,
26427      indoc! {r#"
26428        .parent {
26429          color: #00f;
26430        }
26431
26432        @scope (.parent > .scope) to (.parent > .scope .limit) {
26433          :scope .content {
26434            color: #ff0;
26435          }
26436        }
26437      "#},
26438    );
26439  }
26440
26441  #[test]
26442  fn test_custom_media() {
26443    custom_media_test(
26444      r#"
26445      @custom-media --modern (color), (hover);
26446
26447      @media (--modern) and (width > 1024px) {
26448        .a {
26449          color: green;
26450        }
26451      }
26452      "#,
26453      indoc! {r#"
26454      @media ((color) or (hover)) and (width > 1024px) {
26455        .a {
26456          color: green;
26457        }
26458      }
26459      "#},
26460    );
26461
26462    custom_media_test(
26463      r#"
26464      @custom-media --color (color);
26465
26466      @media (--color) and (width > 1024px) {
26467        .a {
26468          color: green;
26469        }
26470      }
26471      "#,
26472      indoc! {r#"
26473      @media (color) and (width > 1024px) {
26474        .a {
26475          color: green;
26476        }
26477      }
26478      "#},
26479    );
26480
26481    custom_media_test(
26482      r#"
26483      @custom-media --a (color);
26484      @custom-media --b (--a);
26485
26486      @media (--b) and (width > 1024px) {
26487        .a {
26488          color: green;
26489        }
26490      }
26491      "#,
26492      indoc! {r#"
26493      @media (color) and (width > 1024px) {
26494        .a {
26495          color: green;
26496        }
26497      }
26498      "#},
26499    );
26500
26501    custom_media_test(
26502      r#"
26503      @custom-media --not-color not (color);
26504
26505      @media not (--not-color) {
26506        .a {
26507          color: green;
26508        }
26509      }
26510      "#,
26511      indoc! {r#"
26512      @media (color) {
26513        .a {
26514          color: green;
26515        }
26516      }
26517      "#},
26518    );
26519
26520    custom_media_test(
26521      r#"
26522      @custom-media --color-print print and (color);
26523
26524      @media (--color-print) {
26525        .a {
26526          color: green;
26527        }
26528      }
26529      "#,
26530      indoc! {r#"
26531      @media print and (color) {
26532        .a {
26533          color: green;
26534        }
26535      }
26536      "#},
26537    );
26538
26539    custom_media_test(
26540      r#"
26541      @custom-media --color-print print and (color);
26542
26543      @media print and (--color-print) {
26544        .a {
26545          color: green;
26546        }
26547      }
26548      "#,
26549      indoc! {r#"
26550      @media print and (color) {
26551        .a {
26552          color: green;
26553        }
26554      }
26555      "#},
26556    );
26557
26558    custom_media_test(
26559      r#"
26560      @custom-media --not-color-print not print and (color);
26561
26562      @media not print and (--not-color-print) {
26563        .a {
26564          color: green;
26565        }
26566      }
26567      "#,
26568      indoc! {r#"
26569      @media not print and (color) {
26570        .a {
26571          color: green;
26572        }
26573      }
26574      "#},
26575    );
26576
26577    custom_media_test(
26578      r#"
26579      @custom-media --print print;
26580
26581      @media (--print) {
26582        .a {
26583          color: green;
26584        }
26585      }
26586      "#,
26587      indoc! {r#"
26588      @media print {
26589        .a {
26590          color: green;
26591        }
26592      }
26593      "#},
26594    );
26595
26596    custom_media_test(
26597      r#"
26598      @custom-media --print print;
26599
26600      @media not (--print) {
26601        .a {
26602          color: green;
26603        }
26604      }
26605      "#,
26606      indoc! {r#"
26607      @media not print {
26608        .a {
26609          color: green;
26610        }
26611      }
26612      "#},
26613    );
26614
26615    custom_media_test(
26616      r#"
26617      @custom-media --print not print;
26618
26619      @media not (--print) {
26620        .a {
26621          color: green;
26622        }
26623      }
26624      "#,
26625      indoc! {r#"
26626      @media print {
26627        .a {
26628          color: green;
26629        }
26630      }
26631      "#},
26632    );
26633
26634    custom_media_test(
26635      r#"
26636      @custom-media --print print;
26637
26638      @media ((--print)) {
26639        .a {
26640          color: green;
26641        }
26642      }
26643      "#,
26644      indoc! {r#"
26645      @media print {
26646        .a {
26647          color: green;
26648        }
26649      }
26650      "#},
26651    );
26652
26653    custom_media_test(
26654      r#"
26655      @custom-media --color (color);
26656      @custom-media --print print;
26657
26658      @media (--print) and (--color) {
26659        .a {
26660          color: green;
26661        }
26662      }
26663      "#,
26664      indoc! {r#"
26665      @media print and (color) {
26666        .a {
26667          color: green;
26668        }
26669      }
26670      "#},
26671    );
26672
26673    custom_media_test(
26674      r#"
26675      @custom-media --color (color);
26676      @custom-media --not-print not print;
26677
26678      @media (--not-print) and (--color) {
26679        .a {
26680          color: green;
26681        }
26682      }
26683      "#,
26684      indoc! {r#"
26685      @media not print and (color) {
26686        .a {
26687          color: green;
26688        }
26689      }
26690      "#},
26691    );
26692
26693    custom_media_test(
26694      r#"
26695      @custom-media --color (color);
26696      @custom-media --screen screen;
26697      @custom-media --print print;
26698
26699      @media (--print) and (--color), (--screen) and (--color) {
26700        .a {
26701          color: green;
26702        }
26703      }
26704      "#,
26705      indoc! {r#"
26706      @media print and (color), screen and (color) {
26707        .a {
26708          color: green;
26709        }
26710      }
26711      "#},
26712    );
26713
26714    custom_media_test(
26715      r#"
26716      @custom-media --color print and (color), print and (script);
26717
26718      @media (--color) {
26719        .a {
26720          color: green;
26721        }
26722      }
26723      "#,
26724      indoc! {r#"
26725      @media print and ((color) or (script)) {
26726        .a {
26727          color: green;
26728        }
26729      }
26730      "#},
26731    );
26732
26733    custom_media_test(
26734      r#"
26735      @custom-media --color (color);
26736      @custom-media --not-color not all and (--color);
26737
26738      @media (--not-color) {
26739        .a {
26740          color: green;
26741        }
26742      }
26743      "#,
26744      indoc! {r#"
26745        @media not all and (color) {
26746          .a {
26747            color: green;
26748          }
26749        }
26750      "#},
26751    );
26752
26753    custom_media_test(
26754      r#"
26755      @custom-media --color (color);
26756
26757      @media not all and (--color) {
26758        .a {
26759          color: green;
26760        }
26761      }
26762      "#,
26763      indoc! {r#"
26764        @media not all and (color) {
26765          .a {
26766            color: green;
26767          }
26768        }
26769      "#},
26770    );
26771
26772    custom_media_test(
26773      r#"
26774      @media (--print) {
26775        .a {
26776          color: green;
26777        }
26778      }
26779
26780      @custom-media --print print;
26781      "#,
26782      indoc! {r#"
26783      @media print {
26784        .a {
26785          color: green;
26786        }
26787      }
26788      "#},
26789    );
26790
26791    custom_media_test(
26792      r#"
26793      @custom-media --not-width not (min-width: 300px);
26794      @media screen and ((prefers-color-scheme: dark) or (--not-width)) {
26795        .foo {
26796          order: 6;
26797        }
26798      }
26799      "#,
26800      indoc! {r#"
26801      @media screen and ((prefers-color-scheme: dark) or ((width < 300px))) {
26802        .foo {
26803          order: 6;
26804        }
26805      }
26806      "#},
26807    );
26808
26809    fn custom_media_error_test(source: &str, err: Error<MinifyErrorKind>) {
26810      let mut stylesheet = StyleSheet::parse(
26811        &source,
26812        ParserOptions {
26813          filename: "test.css".into(),
26814          flags: ParserFlags::CUSTOM_MEDIA,
26815          ..ParserOptions::default()
26816        },
26817      )
26818      .unwrap();
26819      let res = stylesheet.minify(MinifyOptions {
26820        targets: Browsers {
26821          chrome: Some(95 << 16),
26822          ..Browsers::default()
26823        }
26824        .into(),
26825        ..MinifyOptions::default()
26826      });
26827      assert_eq!(res, Err(err))
26828    }
26829
26830    custom_media_error_test(
26831      r#"
26832      @custom-media --color-print print and (color);
26833
26834      @media screen and (--color-print) {
26835        .a {
26836          color: green;
26837        }
26838      }
26839      "#,
26840      Error {
26841        kind: MinifyErrorKind::UnsupportedCustomMediaBooleanLogic {
26842          custom_media_loc: Location {
26843            source_index: 0,
26844            line: 1,
26845            column: 7,
26846          },
26847        },
26848        loc: Some(ErrorLocation {
26849          filename: "test.css".into(),
26850          line: 3,
26851          column: 7,
26852        }),
26853      },
26854    );
26855
26856    custom_media_error_test(
26857      r#"
26858      @custom-media --color-print print and (color);
26859
26860      @media not print and (--color-print) {
26861        .a {
26862          color: green;
26863        }
26864      }
26865      "#,
26866      Error {
26867        kind: MinifyErrorKind::UnsupportedCustomMediaBooleanLogic {
26868          custom_media_loc: Location {
26869            source_index: 0,
26870            line: 1,
26871            column: 7,
26872          },
26873        },
26874        loc: Some(ErrorLocation {
26875          filename: "test.css".into(),
26876          line: 3,
26877          column: 7,
26878        }),
26879      },
26880    );
26881
26882    custom_media_error_test(
26883      r#"
26884      @custom-media --color-print print and (color);
26885      @custom-media --color-screen screen and (color);
26886
26887      @media (--color-print) or (--color-screen) {}
26888      "#,
26889      Error {
26890        kind: MinifyErrorKind::UnsupportedCustomMediaBooleanLogic {
26891          custom_media_loc: Location {
26892            source_index: 0,
26893            line: 2,
26894            column: 7,
26895          },
26896        },
26897        loc: Some(ErrorLocation {
26898          filename: "test.css".into(),
26899          line: 4,
26900          column: 7,
26901        }),
26902      },
26903    );
26904
26905    custom_media_error_test(
26906      r#"
26907      @custom-media --color-print print and (color);
26908      @custom-media --color-screen screen and (color);
26909
26910      @media (--color-print) and (--color-screen) {}
26911      "#,
26912      Error {
26913        kind: MinifyErrorKind::UnsupportedCustomMediaBooleanLogic {
26914          custom_media_loc: Location {
26915            source_index: 0,
26916            line: 2,
26917            column: 7,
26918          },
26919        },
26920        loc: Some(ErrorLocation {
26921          filename: "test.css".into(),
26922          line: 4,
26923          column: 7,
26924        }),
26925      },
26926    );
26927
26928    custom_media_error_test(
26929      r#"
26930      @custom-media --screen screen;
26931      @custom-media --print print;
26932
26933      @media (--print) and (--screen) {}
26934      "#,
26935      Error {
26936        kind: MinifyErrorKind::UnsupportedCustomMediaBooleanLogic {
26937          custom_media_loc: Location {
26938            source_index: 0,
26939            line: 1,
26940            column: 7,
26941          },
26942        },
26943        loc: Some(ErrorLocation {
26944          filename: "test.css".into(),
26945          line: 4,
26946          column: 7,
26947        }),
26948      },
26949    );
26950
26951    custom_media_error_test(
26952      r#"
26953      @custom-media --not-print not print and (color);
26954      @custom-media --not-screen not screen and (color);
26955
26956      @media ((script) or ((--not-print) and (--not-screen))) {
26957        .a {
26958          color: green;
26959        }
26960      }
26961      "#,
26962      Error {
26963        kind: MinifyErrorKind::UnsupportedCustomMediaBooleanLogic {
26964          custom_media_loc: Location {
26965            source_index: 0,
26966            line: 2,
26967            column: 7,
26968          },
26969        },
26970        loc: Some(ErrorLocation {
26971          filename: "test.css".into(),
26972          line: 4,
26973          column: 7,
26974        }),
26975      },
26976    );
26977
26978    custom_media_error_test(
26979      r#"
26980      @custom-media --color screen and (color), print and (color);
26981
26982      @media (--color) {
26983        .a {
26984          color: green;
26985        }
26986      }
26987      "#,
26988      Error {
26989        kind: MinifyErrorKind::UnsupportedCustomMediaBooleanLogic {
26990          custom_media_loc: Location {
26991            source_index: 0,
26992            line: 1,
26993            column: 7,
26994          },
26995        },
26996        loc: Some(ErrorLocation {
26997          filename: "test.css".into(),
26998          line: 3,
26999          column: 7,
27000        }),
27001      },
27002    );
27003
27004    custom_media_error_test(
27005      r#"
27006      @media (--not-defined) {
27007        .a {
27008          color: green;
27009        }
27010      }
27011      "#,
27012      Error {
27013        kind: MinifyErrorKind::CustomMediaNotDefined {
27014          name: "--not-defined".into(),
27015        },
27016        loc: Some(ErrorLocation {
27017          filename: "test.css".into(),
27018          line: 1,
27019          column: 7,
27020        }),
27021      },
27022    );
27023
27024    custom_media_error_test(
27025      r#"
27026      @custom-media --circular-mq-a (--circular-mq-b);
27027      @custom-media --circular-mq-b (--circular-mq-a);
27028
27029      @media (--circular-mq-a) {
27030        body {
27031          order: 3;
27032        }
27033      }
27034      "#,
27035      Error {
27036        kind: MinifyErrorKind::CircularCustomMedia {
27037          name: "--circular-mq-a".into(),
27038        },
27039        loc: Some(ErrorLocation {
27040          filename: "test.css".into(),
27041          line: 4,
27042          column: 7,
27043        }),
27044      },
27045    );
27046  }
27047
27048  #[test]
27049  fn test_dependencies() {
27050    fn dep_test(source: &str, expected: &str, deps: Vec<(&str, &str)>) {
27051      let mut stylesheet = StyleSheet::parse(
27052        &source,
27053        ParserOptions {
27054          filename: "test.css".into(),
27055          ..ParserOptions::default()
27056        },
27057      )
27058      .unwrap();
27059      stylesheet.minify(MinifyOptions::default()).unwrap();
27060      let res = stylesheet
27061        .to_css(PrinterOptions {
27062          analyze_dependencies: Some(Default::default()),
27063          minify: true,
27064          ..PrinterOptions::default()
27065        })
27066        .unwrap();
27067      assert_eq!(res.code, expected);
27068      let dependencies = res.dependencies.unwrap();
27069      assert_eq!(dependencies.len(), deps.len());
27070      for (i, (url, placeholder)) in deps.into_iter().enumerate() {
27071        match &dependencies[i] {
27072          Dependency::Url(dep) => {
27073            assert_eq!(dep.url, url);
27074            assert_eq!(dep.placeholder, placeholder);
27075          }
27076          Dependency::Import(dep) => {
27077            assert_eq!(dep.url, url);
27078            assert_eq!(dep.placeholder, placeholder);
27079          }
27080        }
27081      }
27082    }
27083
27084    fn dep_error_test(source: &str, error: PrinterErrorKind) {
27085      let stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
27086      let res = stylesheet.to_css(PrinterOptions {
27087        analyze_dependencies: Some(Default::default()),
27088        ..PrinterOptions::default()
27089      });
27090      match res {
27091        Err(e) => assert_eq!(e.kind, error),
27092        _ => unreachable!(),
27093      }
27094    }
27095
27096    dep_test(
27097      ".foo { background: image-set('./img12x.png', './img21x.png' 2x)}",
27098      ".foo{background:image-set(\"hXFI8W\" 1x,\"5TkpBa\" 2x)}",
27099      vec![("./img12x.png", "hXFI8W"), ("./img21x.png", "5TkpBa")],
27100    );
27101
27102    dep_test(
27103      ".foo { background: image-set(url(./img12x.png), url('./img21x.png') 2x)}",
27104      ".foo{background:image-set(\"hXFI8W\" 1x,\"5TkpBa\" 2x)}",
27105      vec![("./img12x.png", "hXFI8W"), ("./img21x.png", "5TkpBa")],
27106    );
27107
27108    dep_test(
27109      ".foo { --test: url(/foo.png) }",
27110      ".foo{--test:url(\"lDnnrG\")}",
27111      vec![("/foo.png", "lDnnrG")],
27112    );
27113
27114    dep_test(
27115      ".foo { --test: url(\"/foo.png\") }",
27116      ".foo{--test:url(\"lDnnrG\")}",
27117      vec![("/foo.png", "lDnnrG")],
27118    );
27119
27120    dep_test(
27121      ".foo { --test: url(\"http://example.com/foo.png\") }",
27122      ".foo{--test:url(\"3X1zSW\")}",
27123      vec![("http://example.com/foo.png", "3X1zSW")],
27124    );
27125
27126    dep_test(
27127      ".foo { --test: url(\"data:image/svg+xml;utf8,<svg></svg>\") }",
27128      ".foo{--test:url(\"-vl-rG\")}",
27129      vec![("data:image/svg+xml;utf8,<svg></svg>", "-vl-rG")],
27130    );
27131
27132    dep_test(
27133      ".foo { background: url(\"foo.png\") var(--test) }",
27134      ".foo{background:url(\"Vwkwkq\") var(--test)}",
27135      vec![("foo.png", "Vwkwkq")],
27136    );
27137
27138    dep_error_test(
27139      ".foo { --test: url(\"foo.png\") }",
27140      PrinterErrorKind::AmbiguousUrlInCustomProperty { url: "foo.png".into() },
27141    );
27142
27143    dep_error_test(
27144      ".foo { --test: url(foo.png) }",
27145      PrinterErrorKind::AmbiguousUrlInCustomProperty { url: "foo.png".into() },
27146    );
27147
27148    dep_error_test(
27149      ".foo { --test: url(./foo.png) }",
27150      PrinterErrorKind::AmbiguousUrlInCustomProperty {
27151        url: "./foo.png".into(),
27152      },
27153    );
27154
27155    dep_test(
27156      ".foo { behavior: url(#foo) }",
27157      ".foo{behavior:url(\"Zn9-2q\")}",
27158      vec![("#foo", "Zn9-2q")],
27159    );
27160
27161    dep_test(
27162      ".foo { --foo: url(#foo) }",
27163      ".foo{--foo:url(\"Zn9-2q\")}",
27164      vec![("#foo", "Zn9-2q")],
27165    );
27166
27167    dep_test(
27168      "@import \"test.css\"; .foo { color: red }",
27169      "@import \"hHsogW\";.foo{color:red}",
27170      vec![("test.css", "hHsogW")],
27171    );
27172  }
27173
27174  #[test]
27175  fn test_api() {
27176    let stylesheet = StyleSheet::parse(".foo:hover { color: red }", ParserOptions::default()).unwrap();
27177    match &stylesheet.rules.0[0] {
27178      CssRule::Style(s) => {
27179        assert_eq!(&s.selectors.to_string(), ".foo:hover");
27180      }
27181      _ => unreachable!(),
27182    }
27183
27184    let color = CssColor::parse_string("#f0f").unwrap();
27185    assert_eq!(color.to_css_string(PrinterOptions::default()).unwrap(), "#f0f");
27186
27187    let rule = CssRule::parse_string(".foo { color: red }", ParserOptions::default()).unwrap();
27188    assert_eq!(
27189      rule.to_css_string(PrinterOptions::default()).unwrap(),
27190      indoc! {r#"
27191    .foo {
27192      color: red;
27193    }"#}
27194    );
27195
27196    let property = Property::parse_string("color".into(), "#f0f", ParserOptions::default()).unwrap();
27197    assert_eq!(
27198      property.to_css_string(false, PrinterOptions::default()).unwrap(),
27199      "color: #f0f"
27200    );
27201    assert_eq!(
27202      property.to_css_string(true, PrinterOptions::default()).unwrap(),
27203      "color: #f0f !important"
27204    );
27205
27206    let code = indoc! { r#"
27207      .foo {
27208        color: green;
27209      }
27210
27211      .bar {
27212        color: red;
27213        background: pink;
27214      }
27215
27216      @media print {
27217        .baz {
27218          color: green;
27219        }
27220      }
27221    "#};
27222    let stylesheet = StyleSheet::parse(code, ParserOptions::default()).unwrap();
27223    if let CssRule::Style(style) = &stylesheet.rules.0[1] {
27224      let (key, val) = style.property_location(code, 0).unwrap();
27225      assert_eq!(
27226        key,
27227        SourceLocation { line: 5, column: 3 }..SourceLocation { line: 5, column: 8 }
27228      );
27229      assert_eq!(
27230        val,
27231        SourceLocation { line: 5, column: 10 }..SourceLocation { line: 5, column: 13 }
27232      );
27233    }
27234
27235    if let CssRule::Style(style) = &stylesheet.rules.0[1] {
27236      let (key, val) = style.property_location(code, 1).unwrap();
27237      assert_eq!(
27238        key,
27239        SourceLocation { line: 6, column: 3 }..SourceLocation { line: 6, column: 13 }
27240      );
27241      assert_eq!(
27242        val,
27243        SourceLocation { line: 6, column: 15 }..SourceLocation { line: 6, column: 19 }
27244      );
27245    }
27246    if let CssRule::Media(media) = &stylesheet.rules.0[2] {
27247      if let CssRule::Style(style) = &media.rules.0[0] {
27248        let (key, val) = style.property_location(code, 0).unwrap();
27249        assert_eq!(
27250          key,
27251          SourceLocation { line: 11, column: 5 }..SourceLocation { line: 11, column: 10 }
27252        );
27253        assert_eq!(
27254          val,
27255          SourceLocation { line: 11, column: 12 }..SourceLocation { line: 11, column: 17 }
27256        );
27257      }
27258    }
27259
27260    let mut property = Property::Transform(Default::default(), VendorPrefix::WebKit);
27261    property.set_prefix(VendorPrefix::None);
27262    assert_eq!(property, Property::Transform(Default::default(), VendorPrefix::None));
27263    property.set_prefix(VendorPrefix::Moz);
27264    assert_eq!(property, Property::Transform(Default::default(), VendorPrefix::Moz));
27265    property.set_prefix(VendorPrefix::WebKit | VendorPrefix::Moz);
27266    assert_eq!(
27267      property,
27268      Property::Transform(Default::default(), VendorPrefix::WebKit | VendorPrefix::Moz)
27269    );
27270
27271    let mut property = Property::TextDecorationLine(Default::default(), VendorPrefix::None);
27272    property.set_prefix(VendorPrefix::Ms);
27273    assert_eq!(
27274      property,
27275      Property::TextDecorationLine(Default::default(), VendorPrefix::None)
27276    );
27277    property.set_prefix(VendorPrefix::WebKit | VendorPrefix::Moz | VendorPrefix::Ms);
27278    assert_eq!(
27279      property,
27280      Property::TextDecorationLine(Default::default(), VendorPrefix::WebKit | VendorPrefix::Moz)
27281    );
27282
27283    let mut property = Property::AccentColor(Default::default());
27284    property.set_prefix(VendorPrefix::WebKit);
27285    assert_eq!(property, Property::AccentColor(Default::default()));
27286  }
27287
27288  #[cfg(feature = "substitute_variables")]
27289  #[test]
27290  fn test_substitute_vars() {
27291    use crate::properties::custom::TokenList;
27292    use crate::traits::ParseWithOptions;
27293
27294    fn test(property: Property, vars: HashMap<&str, &str>, expected: &str) {
27295      if let Property::Unparsed(unparsed) = property {
27296        let vars = vars
27297          .into_iter()
27298          .map(|(k, v)| {
27299            (
27300              k,
27301              TokenList::parse_string_with_options(v, ParserOptions::default()).unwrap(),
27302            )
27303          })
27304          .collect();
27305        let substituted = unparsed.substitute_variables(&vars).unwrap();
27306        assert_eq!(
27307          substituted.to_css_string(false, PrinterOptions::default()).unwrap(),
27308          expected
27309        );
27310      } else {
27311        panic!("Not an unparsed property");
27312      }
27313    }
27314
27315    let property = Property::parse_string("color".into(), "var(--test)", ParserOptions::default()).unwrap();
27316    test(property, HashMap::from([("--test", "yellow")]), "color: #ff0");
27317
27318    let property =
27319      Property::parse_string("color".into(), "var(--test, var(--foo))", ParserOptions::default()).unwrap();
27320    test(property, HashMap::from([("--foo", "yellow")]), "color: #ff0");
27321    let property = Property::parse_string(
27322      "color".into(),
27323      "var(--test, var(--foo, yellow))",
27324      ParserOptions::default(),
27325    )
27326    .unwrap();
27327    test(property, HashMap::new(), "color: #ff0");
27328
27329    let property =
27330      Property::parse_string("width".into(), "calc(var(--a) + var(--b))", ParserOptions::default()).unwrap();
27331    test(property, HashMap::from([("--a", "2px"), ("--b", "4px")]), "width: 6px");
27332
27333    let property = Property::parse_string("color".into(), "var(--a)", ParserOptions::default()).unwrap();
27334    test(
27335      property,
27336      HashMap::from([("--a", "var(--b)"), ("--b", "yellow")]),
27337      "color: #ff0",
27338    );
27339
27340    let property = Property::parse_string("color".into(), "var(--a)", ParserOptions::default()).unwrap();
27341    test(
27342      property,
27343      HashMap::from([("--a", "var(--b)"), ("--b", "var(--c)"), ("--c", "var(--a)")]),
27344      "color: var(--a)",
27345    );
27346  }
27347
27348  #[test]
27349  fn test_layer() {
27350    minify_test("@layer foo;", "@layer foo;");
27351    minify_test("@layer foo, bar;", "@layer foo,bar;");
27352    minify_test("@layer foo.bar;", "@layer foo.bar;");
27353    minify_test("@layer foo.bar, baz;", "@layer foo.bar,baz;");
27354
27355    minify_test(
27356      r#"
27357      @layer foo {
27358        .bar {
27359          color: red;
27360        }
27361      }
27362    "#,
27363      "@layer foo{.bar{color:red}}",
27364    );
27365    minify_test(
27366      r#"
27367      @layer foo.bar {
27368        .bar {
27369          color: red;
27370        }
27371      }
27372    "#,
27373      "@layer foo.bar{.bar{color:red}}",
27374    );
27375    minify_test(r#"
27376      @layer base {
27377        p { max-width: 70ch; }
27378      }
27379
27380      @layer framework {
27381        @layer base {
27382          p { margin-block: 0.75em; }
27383        }
27384
27385        @layer theme {
27386          p { color: #222; }
27387        }
27388      }
27389    "#, "@layer base{p{max-width:70ch}}@layer framework{@layer base{p{margin-block:.75em}}@layer theme{p{color:#222}}}");
27390    minify_test(
27391      r#"
27392      @layer {
27393        .bar {
27394          color: red;
27395        }
27396      }
27397    "#,
27398      "@layer{.bar{color:red}}",
27399    );
27400    minify_test(
27401      r#"
27402      @layer foo\20 bar, baz;
27403    "#,
27404      "@layer foo\\ bar,baz;",
27405    );
27406    minify_test(
27407      r#"
27408      @layer one.two\20 three\#four\.five {
27409        .bar {
27410          color: red;
27411        }
27412      }
27413    "#,
27414      "@layer one.two\\ three\\#four\\.five{.bar{color:red}}",
27415    );
27416
27417    error_test("@layer;", ParserError::UnexpectedToken(Token::Semicolon));
27418    error_test("@layer foo, bar {};", ParserError::AtRuleBodyInvalid);
27419    minify_test("@import 'test.css' layer;", "@import \"test.css\" layer;");
27420    minify_test("@import 'test.css' layer(foo);", "@import \"test.css\" layer(foo);");
27421    minify_test(
27422      "@import 'test.css' layer(foo.bar);",
27423      "@import \"test.css\" layer(foo.bar);",
27424    );
27425    minify_test(
27426      "@import 'test.css' layer(foo\\20 bar);",
27427      "@import \"test.css\" layer(foo\\ bar);",
27428    );
27429    error_test(
27430      "@import 'test.css' layer(foo, bar) {};",
27431      ParserError::UnexpectedToken(Token::Comma),
27432    );
27433    minify_test(
27434      r#"
27435      @layer one {
27436        body {
27437          background: red;
27438        }
27439      }
27440
27441      body {
27442        background: red;
27443      }
27444
27445      @layer two {
27446        body {
27447          background: green;
27448        }
27449      }
27450
27451      @layer one {
27452        body {
27453          background: yellow;
27454        }
27455      }
27456      "#,
27457      "@layer one{body{background:#ff0}}body{background:red}@layer two{body{background:green}}",
27458    );
27459  }
27460
27461  #[test]
27462  fn test_property() {
27463    minify_test(
27464      r#"
27465      @property --property-name {
27466        syntax: '<color>';
27467        inherits: false;
27468        initial-value: yellow;
27469      }
27470    "#,
27471      "@property --property-name{syntax:\"<color>\";inherits:false;initial-value:#ff0}",
27472    );
27473
27474    test(
27475      r#"
27476      @property --property-name {
27477        syntax: '*';
27478        inherits: false;
27479        initial-value: ;
27480      }
27481    "#,
27482      indoc! {r#"
27483      @property --property-name {
27484        syntax: "*";
27485        inherits: false;
27486        initial-value: ;
27487      }
27488    "#},
27489    );
27490
27491    minify_test(
27492      r#"
27493      @property --property-name {
27494        syntax: '*';
27495        inherits: false;
27496        initial-value: ;
27497      }
27498    "#,
27499      "@property --property-name{syntax:\"*\";inherits:false;initial-value:}",
27500    );
27501
27502    test(
27503      r#"
27504      @property --property-name {
27505        syntax: '*';
27506        inherits: false;
27507        initial-value:;
27508      }
27509    "#,
27510      indoc! {r#"
27511      @property --property-name {
27512        syntax: "*";
27513        inherits: false;
27514        initial-value: ;
27515      }
27516    "#},
27517    );
27518
27519    minify_test(
27520      r#"
27521      @property --property-name {
27522        syntax: '*';
27523        inherits: false;
27524        initial-value:;
27525      }
27526    "#,
27527      "@property --property-name{syntax:\"*\";inherits:false;initial-value:}",
27528    );
27529    minify_test(
27530      r#"
27531      @property --property-name {
27532        syntax: '*';
27533        inherits: false;
27534        initial-value: foo bar;
27535      }
27536    "#,
27537      "@property --property-name{syntax:\"*\";inherits:false;initial-value:foo bar}",
27538    );
27539
27540    minify_test(
27541      r#"
27542      @property --property-name {
27543        syntax: '<length>';
27544        inherits: true;
27545        initial-value: 25px;
27546      }
27547    "#,
27548      "@property --property-name{syntax:\"<length>\";inherits:true;initial-value:25px}",
27549    );
27550
27551    error_test(
27552      r#"
27553      @property --property-name {
27554        syntax: '<color>';
27555        inherits: false;
27556        initial-value: 25px;
27557      }
27558    "#,
27559      ParserError::UnexpectedToken(crate::properties::custom::Token::Dimension {
27560        has_sign: false,
27561        value: 25.0,
27562        int_value: Some(25),
27563        unit: "px".into(),
27564      }),
27565    );
27566
27567    error_test(
27568      r#"
27569      @property --property-name {
27570        syntax: '<length>';
27571        inherits: false;
27572        initial-value: var(--some-value);
27573      }
27574    "#,
27575      ParserError::UnexpectedToken(crate::properties::custom::Token::Function("var".into())),
27576    );
27577
27578    error_test(
27579      r#"
27580      @property --property-name {
27581        syntax: '<color>';
27582        inherits: false;
27583      }
27584    "#,
27585      ParserError::AtRuleBodyInvalid,
27586    );
27587
27588    minify_test(
27589      r#"
27590      @property --property-name {
27591        syntax: '*';
27592        inherits: false;
27593      }
27594    "#,
27595      "@property --property-name{syntax:\"*\";inherits:false}",
27596    );
27597
27598    error_test(
27599      r#"
27600      @property --property-name {
27601        syntax: '*';
27602      }
27603    "#,
27604      ParserError::AtRuleBodyInvalid,
27605    );
27606
27607    error_test(
27608      r#"
27609      @property --property-name {
27610        inherits: false;
27611      }
27612    "#,
27613      ParserError::AtRuleBodyInvalid,
27614    );
27615
27616    error_test(
27617      r#"
27618      @property property-name {
27619        syntax: '*';
27620        inherits: false;
27621      }
27622    "#,
27623      ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("property-name".into())),
27624    );
27625
27626    minify_test(
27627      r#"
27628      @property --property-name {
27629        syntax: 'custom | <color>';
27630        inherits: false;
27631        initial-value: yellow;
27632      }
27633    "#,
27634      "@property --property-name{syntax:\"custom|<color>\";inherits:false;initial-value:#ff0}",
27635    );
27636
27637    // TODO: Re-enable with a better solution
27638    //       See: https://github.com/parcel-bundler/lightningcss/issues/288
27639    // minify_test(r#"
27640    //   @property --property-name {
27641    //     syntax: '<transform-list>';
27642    //     inherits: false;
27643    //     initial-value: translate(200px,300px) translate(100px,200px) scale(2);
27644    //   }
27645    // "#, "@property --property-name{syntax:\"<transform-list>\";inherits:false;initial-value:matrix(2,0,0,2,300,500)}");
27646
27647    minify_test(
27648      r#"
27649      @property --property-name {
27650        syntax: '<time>';
27651        inherits: false;
27652        initial-value: 1000ms;
27653      }
27654    "#,
27655      "@property --property-name{syntax:\"<time>\";inherits:false;initial-value:1s}",
27656    );
27657
27658    minify_test(
27659      r#"
27660      @property --property-name {
27661        syntax: '<url>';
27662        inherits: false;
27663        initial-value: url("foo.png");
27664      }
27665    "#,
27666      "@property --property-name{syntax:\"<url>\";inherits:false;initial-value:url(foo.png)}",
27667    );
27668
27669    minify_test(
27670      r#"
27671      @property --property-name {
27672        syntax: '<image>';
27673        inherits: false;
27674        initial-value: linear-gradient(yellow, blue);
27675      }
27676    "#,
27677      "@property --property-name{syntax:\"<image>\";inherits:false;initial-value:linear-gradient(#ff0,#00f)}",
27678    );
27679
27680    minify_test(
27681      r#"
27682      @property --property-name {
27683        initial-value: linear-gradient(yellow, blue);
27684        inherits: false;
27685        syntax: '<image>';
27686      }
27687    "#,
27688      "@property --property-name{syntax:\"<image>\";inherits:false;initial-value:linear-gradient(#ff0,#00f)}",
27689    );
27690
27691    test(
27692      r#"
27693      @property --property-name {
27694        syntax: '<length>|none';
27695        inherits: false;
27696        initial-value: none;
27697      }
27698    "#,
27699      indoc! {r#"
27700      @property --property-name {
27701        syntax: "<length> | none";
27702        inherits: false;
27703        initial-value: none;
27704      }
27705    "#},
27706    );
27707
27708    minify_test(
27709      r#"
27710      @property --property-name {
27711        syntax: '<color>#';
27712        inherits: false;
27713        initial-value: yellow, blue;
27714      }
27715    "#,
27716      "@property --property-name{syntax:\"<color>#\";inherits:false;initial-value:#ff0,#00f}",
27717    );
27718    minify_test(
27719      r#"
27720      @property --property-name {
27721        syntax: '<color>+';
27722        inherits: false;
27723        initial-value: yellow blue;
27724      }
27725    "#,
27726      "@property --property-name{syntax:\"<color>+\";inherits:false;initial-value:#ff0 #00f}",
27727    );
27728    minify_test(
27729      r#"
27730      @property --property-name {
27731        syntax: '<color>';
27732        inherits: false;
27733        initial-value: yellow;
27734      }
27735      .foo {
27736        color: var(--property-name)
27737      }
27738      @property --property-name {
27739        syntax: '<color>';
27740        inherits: true;
27741        initial-value: blue;
27742      }
27743    "#,
27744      "@property --property-name{syntax:\"<color>\";inherits:true;initial-value:#00f}.foo{color:var(--property-name)}",
27745    );
27746  }
27747
27748  #[test]
27749  fn test_quoting_unquoting_urls() {
27750    // Quotes remain double quotes when not minifying
27751    test(
27752      r#".foo {
27753      background-image: url("0123abcd");
27754    }"#,
27755      r#".foo {
27756  background-image: url("0123abcd");
27757}
27758"#,
27759    );
27760
27761    // Quotes removed when minifying
27762    minify_test(
27763      r#".foo {
27764      background-image: url("0123abcd");
27765    }"#,
27766      r#".foo{background-image:url(0123abcd)}"#,
27767    );
27768
27769    // Doubles quotes added if not present when not minifying
27770    test(
27771      r#".foo {
27772      background-image: url(0123abcd);
27773    }"#,
27774      r#".foo {
27775  background-image: url("0123abcd");
27776}
27777"#,
27778    );
27779
27780    // No quotes changed if not present when not minifying
27781    minify_test(
27782      r#".foo {
27783      background-image: url(0123abcd);
27784    }"#,
27785      r#".foo{background-image:url(0123abcd)}"#,
27786    );
27787  }
27788
27789  #[test]
27790  fn test_zindex() {
27791    minify_test(".foo { z-index: 2 }", ".foo{z-index:2}");
27792    minify_test(".foo { z-index: -2 }", ".foo{z-index:-2}");
27793    minify_test(".foo { z-index: 999999 }", ".foo{z-index:999999}");
27794    minify_test(".foo { z-index: 9999999 }", ".foo{z-index:9999999}");
27795    minify_test(".foo { z-index: -9999999 }", ".foo{z-index:-9999999}");
27796  }
27797
27798  #[test]
27799  #[cfg(feature = "sourcemap")]
27800  fn test_input_source_map() {
27801    let source = r#".imported {
27802      content: "yay, file support!";
27803    }
27804
27805    .selector {
27806      margin: 1em;
27807      background-color: #f60;
27808    }
27809
27810    .selector .nested {
27811      margin: 0.5em;
27812    }
27813
27814    /*# sourceMappingURL=data:application/json;base64,ewoJInZlcnNpb24iOiAzLAoJInNvdXJjZVJvb3QiOiAicm9vdCIsCgkiZmlsZSI6ICJzdGRvdXQiLAoJInNvdXJjZXMiOiBbCgkJInN0ZGluIiwKCQkic2Fzcy9fdmFyaWFibGVzLnNjc3MiLAoJCSJzYXNzL19kZW1vLnNjc3MiCgldLAoJInNvdXJjZXNDb250ZW50IjogWwoJCSJAaW1wb3J0IFwiX3ZhcmlhYmxlc1wiO1xuQGltcG9ydCBcIl9kZW1vXCI7XG5cbi5zZWxlY3RvciB7XG4gIG1hcmdpbjogJHNpemU7XG4gIGJhY2tncm91bmQtY29sb3I6ICRicmFuZENvbG9yO1xuXG4gIC5uZXN0ZWQge1xuICAgIG1hcmdpbjogJHNpemUgLyAyO1xuICB9XG59IiwKCQkiJGJyYW5kQ29sb3I6ICNmNjA7XG4kc2l6ZTogMWVtOyIsCgkJIi5pbXBvcnRlZCB7XG4gIGNvbnRlbnQ6IFwieWF5LCBmaWxlIHN1cHBvcnQhXCI7XG59IgoJXSwKCSJtYXBwaW5ncyI6ICJBRUFBLFNBQVMsQ0FBQztFQUNSLE9BQU8sRUFBRSxvQkFBcUI7Q0FDL0I7O0FGQ0QsU0FBUyxDQUFDO0VBQ1IsTUFBTSxFQ0hELEdBQUc7RURJUixnQkFBZ0IsRUNMTCxJQUFJO0NEVWhCOztBQVBELFNBQVMsQ0FJUCxPQUFPLENBQUM7RUFDTixNQUFNLEVDUEgsS0FBRztDRFFQIiwKCSJuYW1lcyI6IFtdCn0= */"#;
27815
27816    let mut stylesheet = StyleSheet::parse(&source, ParserOptions::default()).unwrap();
27817    stylesheet.minify(MinifyOptions::default()).unwrap();
27818    let mut sm = parcel_sourcemap::SourceMap::new("/");
27819    stylesheet
27820      .to_css(PrinterOptions {
27821        source_map: Some(&mut sm),
27822        minify: true,
27823        ..PrinterOptions::default()
27824      })
27825      .unwrap();
27826    let map = sm.to_json(None).unwrap();
27827    assert_eq!(
27828      map,
27829      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":[]}"#
27830    );
27831  }
27832
27833  #[test]
27834  fn test_error_recovery() {
27835    use std::sync::{Arc, RwLock};
27836    let warnings = Some(Arc::new(RwLock::new(Vec::new())));
27837    test_with_options(
27838      r#"
27839      h1(>h1) {
27840        color: red;
27841      }
27842
27843      .foo {
27844        color: red;
27845      }
27846
27847      .clearfix {
27848        *zoom: 1;
27849        background: red;
27850      }
27851
27852      @media (hover) {
27853        h1(>h1) {
27854          color: red;
27855        }
27856
27857        .bar {
27858          color: red;
27859        }
27860      }
27861
27862      input:placeholder {
27863        color: red;
27864      }
27865
27866      input::hover {
27867        color: red;
27868      }
27869    "#,
27870      indoc! { r#"
27871      .foo {
27872        color: red;
27873      }
27874
27875      .clearfix {
27876        background: red;
27877      }
27878
27879      @media (hover) {
27880        .bar {
27881          color: red;
27882        }
27883      }
27884
27885      input:placeholder {
27886        color: red;
27887      }
27888
27889      input::hover {
27890        color: red;
27891      }
27892    "#},
27893      ParserOptions {
27894        filename: "test.css".into(),
27895        error_recovery: true,
27896        warnings: warnings.clone(),
27897        ..ParserOptions::default()
27898      },
27899    );
27900    let w = warnings.unwrap();
27901    let warnings = w.read().unwrap();
27902    assert_eq!(
27903      *warnings,
27904      vec![
27905        Error {
27906          kind: ParserError::SelectorError(SelectorError::EmptySelector),
27907          loc: Some(ErrorLocation {
27908            filename: "test.css".into(),
27909            line: 1,
27910            column: 7
27911          })
27912        },
27913        Error {
27914          kind: ParserError::UnexpectedToken(Token::Semicolon),
27915          loc: Some(ErrorLocation {
27916            filename: "test.css".into(),
27917            line: 10,
27918            column: 17
27919          })
27920        },
27921        Error {
27922          kind: ParserError::SelectorError(SelectorError::EmptySelector),
27923          loc: Some(ErrorLocation {
27924            filename: "test.css".into(),
27925            line: 15,
27926            column: 9
27927          })
27928        },
27929        Error {
27930          kind: ParserError::SelectorError(SelectorError::UnsupportedPseudoClass("placeholder".into())),
27931          loc: Some(ErrorLocation {
27932            filename: "test.css".into(),
27933            line: 24,
27934            column: 13,
27935          }),
27936        },
27937        Error {
27938          kind: ParserError::SelectorError(SelectorError::UnsupportedPseudoElement("hover".into())),
27939          loc: Some(ErrorLocation {
27940            filename: "test.css".into(),
27941            line: 28,
27942            column: 13,
27943          }),
27944        },
27945      ]
27946    )
27947  }
27948
27949  #[test]
27950  fn test_invalid() {
27951    error_test(
27952      ".a{color: hsla(120, 62.32%;}",
27953      ParserError::UnexpectedToken(Token::CloseCurlyBracket),
27954    );
27955    error_test(
27956      ".a{--foo: url(foo\\) b\\)ar)}",
27957      ParserError::UnexpectedToken(Token::BadUrl("foo\\) b\\)ar".into())),
27958    );
27959  }
27960
27961  #[test]
27962  fn test_container_queries() {
27963    // with name
27964    minify_test(
27965      r#"
27966      @container my-layout (inline-size > 45em) {
27967        .foo {
27968          color: red;
27969        }
27970      }
27971    "#,
27972      "@container my-layout (inline-size>45em){.foo{color:red}}",
27973    );
27974
27975    minify_test(
27976      r#"
27977      @container my-layout ( not (width > 500px) ) {
27978        .foo {
27979          color: red;
27980        }
27981      }
27982    "#,
27983      "@container my-layout not (width>500px){.foo{color:red}}",
27984    );
27985
27986    minify_test(
27987      r#"
27988      @container my-layout not (width > 500px) {
27989        .foo {
27990          color: red;
27991        }
27992      }
27993    "#,
27994      "@container my-layout not (width>500px){.foo{color:red}}",
27995    );
27996
27997    minify_test(
27998      r#"
27999      @container not (width > 500px) {
28000        .foo {
28001          color: red;
28002        }
28003      }
28004    "#,
28005      "@container not (width>500px){.foo{color:red}}",
28006    );
28007
28008    minify_test(
28009      r#"
28010      @container my-layout ((width: 100px) and (not (height: 100px))) {
28011        .foo {
28012          color: red;
28013        }
28014      }
28015    "#,
28016      "@container my-layout (width:100px) and (not (height:100px)){.foo{color:red}}",
28017    );
28018
28019    minify_test(
28020      r#"
28021      @container my-layout (width = max(10px, 10em)) {
28022        .foo {
28023          color: red;
28024        }
28025      }
28026    "#,
28027      "@container my-layout (width=max(10px,10em)){.foo{color:red}}",
28028    );
28029
28030    // without name
28031    minify_test(
28032      r#"
28033      @container (inline-size > 45em) {
28034        .foo {
28035          color: red;
28036        }
28037      }
28038    "#,
28039      "@container (inline-size>45em){.foo{color:red}}",
28040    );
28041
28042    minify_test(
28043      r#"
28044      @container (inline-size > 45em) and (inline-size < 100em) {
28045        .foo {
28046          color: red;
28047        }
28048      }
28049    "#,
28050      "@container (inline-size>45em) and (inline-size<100em){.foo{color:red}}",
28051    );
28052
28053    // calc()
28054    minify_test(
28055      r#"
28056      @container (width > calc(100vw - 50px)) {
28057        .foo {
28058          color: red;
28059        }
28060      }
28061    "#,
28062      "@container (width>calc(100vw - 50px)){.foo{color:red}}",
28063    );
28064
28065    minify_test(
28066      r#"
28067      @container (calc(100vh - 50px) <= height ) {
28068        .foo {
28069          color: red;
28070        }
28071      }
28072    "#,
28073      "@container (height>=calc(100vh - 50px)){.foo{color:red}}",
28074    );
28075
28076    // merge adjacent
28077    minify_test(
28078      r#"
28079      @container my-layout (inline-size > 45em) {
28080        .foo {
28081          color: red;
28082        }
28083      }
28084
28085      @container my-layout (inline-size > 45em) {
28086        .foo {
28087          background: yellow;
28088        }
28089
28090        .bar {
28091          color: white;
28092        }
28093      }
28094    "#,
28095      "@container my-layout (inline-size>45em){.foo{color:red;background:#ff0}.bar{color:#fff}}",
28096    );
28097
28098    minify_test(
28099      r#"
28100    .foo {
28101      container-name: foo bar;
28102      container-type: size;
28103    }
28104    "#,
28105      ".foo{container:foo bar/size}",
28106    );
28107    minify_test(
28108      r#"
28109    .foo {
28110      container-name: foo bar;
28111      container-type: normal;
28112    }
28113    "#,
28114      ".foo{container:foo bar}",
28115    );
28116    minify_test(
28117      ".foo{ container-type: inline-size }",
28118      ".foo{container-type:inline-size}",
28119    );
28120    minify_test(".foo{ container-name: none; }", ".foo{container-name:none}");
28121    minify_test(".foo{ container-name: foo; }", ".foo{container-name:foo}");
28122    minify_test(".foo{ container: foo / normal; }", ".foo{container:foo}");
28123    minify_test(
28124      ".foo{ container: foo / inline-size; }",
28125      ".foo{container:foo/inline-size}",
28126    );
28127    minify_test(".foo { width: calc(1cqw + 2cqw) }", ".foo{width:3cqw}");
28128    minify_test(".foo { width: calc(1cqh + 2cqh) }", ".foo{width:3cqh}");
28129    minify_test(".foo { width: calc(1cqi + 2cqi) }", ".foo{width:3cqi}");
28130    minify_test(".foo { width: calc(1cqb + 2cqb) }", ".foo{width:3cqb}");
28131    minify_test(".foo { width: calc(1cqmin + 2cqmin) }", ".foo{width:3cqmin}");
28132    minify_test(".foo { width: calc(1cqmax + 2cqmax) }", ".foo{width:3cqmax}");
28133
28134    // Unlike in @media, there is no need to convert the range syntax in @container,
28135    // because browsers all support this syntax.
28136    prefix_test(
28137      r#"
28138      @container (width > 100px) {
28139        .foo { padding: 5px; }
28140      }
28141      "#,
28142      indoc! { r#"
28143        @container (width > 100px) {
28144          .foo {
28145            padding: 5px;
28146          }
28147        }
28148      "#},
28149      Browsers {
28150        chrome: Some(105 << 16),
28151        ..Browsers::default()
28152      },
28153    );
28154    prefix_test(
28155      r#"
28156      @container (min-width: 100px) {
28157        .foo { padding: 5px; }
28158      }
28159      "#,
28160      indoc! { r#"
28161        @container (width >= 100px) {
28162          .foo {
28163            padding: 5px;
28164          }
28165        }
28166      "#},
28167      Browsers {
28168        chrome: Some(105 << 16),
28169        ..Browsers::default()
28170      },
28171    );
28172
28173    minify_test(
28174      r#"
28175      @container style(--responsive: true) {
28176        .foo {
28177          color: red;
28178        }
28179      }
28180    "#,
28181      "@container style(--responsive:true){.foo{color:red}}",
28182    );
28183    minify_test(
28184      r#"
28185      @container style(--responsive: true) and style(color: yellow) {
28186        .foo {
28187          color: red;
28188        }
28189      }
28190    "#,
28191      "@container style(--responsive:true) and style(color:#ff0){.foo{color:red}}",
28192    );
28193    minify_test(
28194      r#"
28195      @container not style(--responsive: true) {
28196        .foo {
28197          color: red;
28198        }
28199      }
28200    "#,
28201      "@container not style(--responsive:true){.foo{color:red}}",
28202    );
28203    minify_test(
28204      r#"
28205      @container (inline-size > 45em) and style(--responsive: true) {
28206        .foo {
28207          color: red;
28208        }
28209      }
28210    "#,
28211      "@container (inline-size>45em) and style(--responsive:true){.foo{color:red}}",
28212    );
28213    minify_test(
28214      r#"
28215      @container style((accent-color: yellow) or (--bar: 10px)) {
28216        .foo {
28217          color: red;
28218        }
28219      }
28220    "#,
28221      "@container style((accent-color:#ff0) or (--bar:10px)){.foo{color:red}}",
28222    );
28223    minify_test(
28224      r#"
28225      @container style(not ((width: calc(10px + 20px)) and ((--bar: url(x))))) {
28226        .foo {
28227          color: red;
28228        }
28229      }
28230    "#,
28231      "@container style(not ((width:30px) and (--bar:url(x)))){.foo{color:red}}",
28232    );
28233    minify_test(
28234      r#"
28235      @container style(color: yellow !important) {
28236        .foo {
28237          color: red;
28238        }
28239      }
28240    "#,
28241      "@container style(color:yellow){.foo{color:red}}",
28242    );
28243    minify_test(
28244      r#"
28245      @container style(--foo:) {
28246        .foo {
28247          color: red;
28248        }
28249      }
28250    "#,
28251      "@container style(--foo:){.foo{color:red}}",
28252    );
28253    minify_test(
28254      r#"
28255      @container style(--foo: ) {
28256        .foo {
28257          color: red;
28258        }
28259      }
28260    "#,
28261      "@container style(--foo:){.foo{color:red}}",
28262    );
28263    minify_test(
28264      r#"
28265      @container style(--my-prop: foo - bar ()) {
28266        .foo {
28267          color: red;
28268        }
28269      }
28270    "#,
28271      "@container style(--my-prop:foo - bar ()){.foo{color:red}}",
28272    );
28273    minify_test(
28274      r#"
28275      @container style(--test) {
28276        .foo {
28277          color: red;
28278        }
28279      }
28280    "#,
28281      "@container style(--test){.foo{color:red}}",
28282    );
28283    minify_test(
28284      r#"
28285      @container style(width) {
28286        .foo {
28287          color: red;
28288        }
28289      }
28290    "#,
28291      "@container style(width){.foo{color:red}}",
28292    );
28293
28294    // Disallow 'none', 'not', 'and', 'or' as a `<container-name>`
28295    // https://github.com/w3c/csswg-drafts/issues/7203#issuecomment-1144257312
28296    // https://chromium-review.googlesource.com/c/chromium/src/+/3698402
28297    error_test(
28298      "@container none (width < 100vw) {}",
28299      ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("none".into())),
28300    );
28301
28302    error_test(
28303      "@container and (width < 100vw) {}",
28304      ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("and".into())),
28305    );
28306
28307    error_test(
28308      "@container or (width < 100vw) {}",
28309      ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("or".into())),
28310    );
28311
28312    // Disallow CSS wide keywords as a `<container-name>`
28313    error_test(
28314      "@container revert-layer (width < 100vw) {}",
28315      ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("revert-layer".into())),
28316    );
28317
28318    error_test(
28319      "@container initial (width < 100vw) {}",
28320      ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("initial".into())),
28321    );
28322
28323    // <ident> contains spaces
28324    // https://github.com/web-platform-tests/wpt/blob/39f0da08fbbe33d0582a35749b6dbf8bd067a52d/css/css-contain/container-queries/at-container-parsing.html#L160-L178
28325    error_test(
28326      "@container foo bar (width < 100vw) {}",
28327      ParserError::UnexpectedToken(crate::properties::custom::Token::Ident("bar".into())),
28328    );
28329
28330    error_test("@container (inline-size <= foo) {}", ParserError::InvalidMediaQuery);
28331    error_test("@container (orientation <= 10px) {}", ParserError::InvalidMediaQuery);
28332
28333    error_test(
28334      "@container style(style(--foo: bar)) {}",
28335      ParserError::UnexpectedToken(crate::properties::custom::Token::Function("style".into())),
28336    );
28337  }
28338
28339  #[test]
28340  fn test_css_modules_value_rule() {
28341    css_modules_error_test(
28342      "@value compact: (max-width: 37.4375em);",
28343      ParserError::DeprecatedCssModulesValueRule,
28344    );
28345  }
28346
28347  #[test]
28348  fn test_unknown_at_rules() {
28349    minify_test("@foo;", "@foo;");
28350    minify_test("@foo bar;", "@foo bar;");
28351    minify_test("@foo (bar: baz);", "@foo (bar: baz);");
28352    test(
28353      r#"@foo test {
28354      div {
28355        color: red;
28356      }
28357    }"#,
28358      indoc! {r#"
28359      @foo test {
28360        div { color: red; }
28361      }
28362      "#},
28363    );
28364    minify_test(
28365      r#"@foo test {
28366      div {
28367        color: red;
28368      }
28369    }"#,
28370      "@foo test{div { color: red; }}",
28371    );
28372    minify_test(
28373      r#"@foo test {
28374        foo: bar;
28375      }"#,
28376      "@foo test{foo: bar;}",
28377    );
28378    test(
28379      r#"@foo {
28380        foo: bar;
28381      }"#,
28382      indoc! {r#"
28383      @foo {
28384        foo: bar;
28385      }
28386      "#},
28387    );
28388    minify_test(
28389      r#"@foo {
28390        foo: bar;
28391      }"#,
28392      "@foo{foo: bar;}",
28393    );
28394  }
28395
28396  #[test]
28397  fn test_resolution() {
28398    prefix_test(
28399      r#"
28400      @media (resolution: 1dppx) {
28401        body {
28402          background: red;
28403        }
28404      }
28405      "#,
28406      indoc! { r#"
28407      @media (resolution: 1dppx) {
28408        body {
28409          background: red;
28410        }
28411      }
28412      "#},
28413      Browsers {
28414        chrome: Some(50 << 16),
28415        ..Browsers::default()
28416      },
28417    );
28418
28419    prefix_test(
28420      r#"
28421      @media (resolution: 1dppx) {
28422        body {
28423          background: red;
28424        }
28425      }
28426      "#,
28427      indoc! { r#"
28428      @media (resolution: 1x) {
28429        body {
28430          background: red;
28431        }
28432      }
28433      "#},
28434      Browsers {
28435        chrome: Some(95 << 16),
28436        ..Browsers::default()
28437      },
28438    );
28439  }
28440
28441  #[test]
28442  fn test_environment() {
28443    minify_test(
28444      r#"
28445      @media (max-width: env(--branding-small)) {
28446        body {
28447          padding: env(--branding-padding);
28448        }
28449      }
28450    "#,
28451      "@media (width<=env(--branding-small)){body{padding:env(--branding-padding)}}",
28452    );
28453
28454    minify_test(
28455      r#"
28456      @media (max-width: env(--branding-small 1)) {
28457        body {
28458          padding: env(--branding-padding 2);
28459        }
28460      }
28461    "#,
28462      "@media (width<=env(--branding-small 1)){body{padding:env(--branding-padding 2)}}",
28463    );
28464
28465    minify_test(
28466      r#"
28467      @media (max-width: env(--branding-small 1, 20px)) {
28468        body {
28469          padding: env(--branding-padding 2, 20px);
28470        }
28471      }
28472    "#,
28473      "@media (width<=env(--branding-small 1,20px)){body{padding:env(--branding-padding 2,20px)}}",
28474    );
28475
28476    minify_test(
28477      r#"
28478      @media (max-width: env(safe-area-inset-top)) {
28479        body {
28480          padding: env(safe-area-inset-top);
28481        }
28482      }
28483    "#,
28484      "@media (width<=env(safe-area-inset-top)){body{padding:env(safe-area-inset-top)}}",
28485    );
28486
28487    minify_test(
28488      r#"
28489      @media (max-width: env(unknown)) {
28490        body {
28491          padding: env(unknown);
28492        }
28493      }
28494    "#,
28495      "@media (width<=env(unknown)){body{padding:env(unknown)}}",
28496    );
28497
28498    prefix_test(
28499      r#"
28500      .foo {
28501        color: env(--brand-color, color(display-p3 0 1 0));
28502      }
28503    "#,
28504      indoc! {r#"
28505      .foo {
28506        color: env(--brand-color, #00f942);
28507      }
28508
28509      @supports (color: color(display-p3 0 0 0)) {
28510        .foo {
28511          color: env(--brand-color, color(display-p3 0 1 0));
28512        }
28513      }
28514    "#},
28515      Browsers {
28516        safari: Some(15 << 16),
28517        chrome: Some(90 << 16),
28518        ..Browsers::default()
28519      },
28520    );
28521
28522    css_modules_test(
28523      r#"
28524      @media (max-width: env(--branding-small)) {
28525        .foo {
28526          color: env(--brand-color);
28527        }
28528      }
28529    "#,
28530      indoc! {r#"
28531      @media (width <= env(--EgL3uq_branding-small)) {
28532        .EgL3uq_foo {
28533          color: env(--EgL3uq_brand-color);
28534        }
28535      }
28536    "#},
28537      map! {
28538        "foo" => "EgL3uq_foo",
28539        "--brand-color" => "--EgL3uq_brand-color" referenced: true,
28540        "--branding-small" => "--EgL3uq_branding-small" referenced: true
28541      },
28542      HashMap::new(),
28543      crate::css_modules::Config {
28544        dashed_idents: true,
28545        ..Default::default()
28546      },
28547      false,
28548    );
28549  }
28550
28551  #[test]
28552  fn test_license_comments() {
28553    minify_test(
28554      r#"
28555      /*! Copyright 2023 Someone awesome */
28556      /* Some other comment */
28557      .foo {
28558        color: red;
28559      }
28560    "#,
28561      indoc! {r#"
28562      /*! Copyright 2023 Someone awesome */
28563      .foo{color:red}"#},
28564    );
28565
28566    minify_test(
28567      r#"
28568      /*! Copyright 2023 Someone awesome */
28569      /*! Copyright 2023 Someone else */
28570      .foo {
28571        color: red;
28572      }
28573    "#,
28574      indoc! {r#"
28575      /*! Copyright 2023 Someone awesome */
28576      /*! Copyright 2023 Someone else */
28577      .foo{color:red}"#},
28578    );
28579  }
28580
28581  #[test]
28582  fn test_starting_style() {
28583    minify_test(
28584      r#"
28585      @starting-style {
28586        h1 {
28587          background: yellow;
28588        }
28589      }
28590      "#,
28591      "@starting-style{h1{background:#ff0}}",
28592    );
28593    minify_test("@starting-style {}", "");
28594
28595    nesting_test(
28596      r#"
28597      h1 {
28598        background: red;
28599        @starting-style {
28600          background: yellow;
28601        }
28602      }
28603      "#,
28604      indoc! {r#"
28605      h1 {
28606        background: red;
28607      }
28608
28609      @starting-style {
28610        h1 {
28611          background: #ff0;
28612        }
28613      }
28614      "#},
28615    );
28616  }
28617
28618  #[test]
28619  fn test_color_scheme() {
28620    minify_test(".foo { color-scheme: normal; }", ".foo{color-scheme:normal}");
28621    minify_test(".foo { color-scheme: light; }", ".foo{color-scheme:light}");
28622    minify_test(".foo { color-scheme: dark; }", ".foo{color-scheme:dark}");
28623    minify_test(".foo { color-scheme: light dark; }", ".foo{color-scheme:light dark}");
28624    minify_test(".foo { color-scheme: dark light; }", ".foo{color-scheme:light dark}");
28625    minify_test(".foo { color-scheme: only light; }", ".foo{color-scheme:light only}");
28626    minify_test(".foo { color-scheme: only dark; }", ".foo{color-scheme:dark only}");
28627    minify_test(
28628      ".foo { color-scheme: dark light only; }",
28629      ".foo{color-scheme:light dark only}",
28630    );
28631    minify_test(".foo { color-scheme: foo bar light; }", ".foo{color-scheme:light}");
28632    minify_test(
28633      ".foo { color-scheme: only foo dark bar; }",
28634      ".foo{color-scheme:dark only}",
28635    );
28636    prefix_test(
28637      ".foo { color-scheme: dark; }",
28638      indoc! { r#"
28639      .foo {
28640        --lightningcss-light: ;
28641        --lightningcss-dark: initial;
28642        color-scheme: dark;
28643      }
28644      "#},
28645      Browsers {
28646        chrome: Some(90 << 16),
28647        ..Browsers::default()
28648      },
28649    );
28650    prefix_test(
28651      ".foo { color-scheme: light; }",
28652      indoc! { r#"
28653      .foo {
28654        --lightningcss-light: initial;
28655        --lightningcss-dark: ;
28656        color-scheme: light;
28657      }
28658      "#},
28659      Browsers {
28660        chrome: Some(90 << 16),
28661        ..Browsers::default()
28662      },
28663    );
28664    prefix_test(
28665      ".foo { color-scheme: light dark; }",
28666      indoc! { r#"
28667      .foo {
28668        --lightningcss-light: initial;
28669        --lightningcss-dark: ;
28670        color-scheme: light dark;
28671      }
28672
28673      @media (prefers-color-scheme: dark) {
28674        .foo {
28675          --lightningcss-light: ;
28676          --lightningcss-dark: initial;
28677        }
28678      }
28679      "#},
28680      Browsers {
28681        chrome: Some(90 << 16),
28682        ..Browsers::default()
28683      },
28684    );
28685    prefix_test(
28686      ".foo { color-scheme: light dark; }",
28687      indoc! { r#"
28688      .foo {
28689        color-scheme: light dark;
28690      }
28691      "#},
28692      Browsers {
28693        firefox: Some(120 << 16),
28694        ..Browsers::default()
28695      },
28696    );
28697
28698    minify_test(
28699      ".foo { color: light-dark(yellow, red); }",
28700      ".foo{color:light-dark(#ff0,red)}",
28701    );
28702    minify_test(
28703      ".foo { color: light-dark(light-dark(yellow, red), light-dark(yellow, red)); }",
28704      ".foo{color:light-dark(#ff0,red)}",
28705    );
28706    minify_test(
28707      ".foo { color: light-dark(rgb(0, 0, 255), hsl(120deg, 50%, 50%)); }",
28708      ".foo{color:light-dark(#00f,#40bf40)}",
28709    );
28710    prefix_test(
28711      ".foo { color: light-dark(oklch(40% 0.1268735435 34.568626), oklab(59.686% 0.1009 0.1192)); }",
28712      indoc! { r#"
28713      .foo {
28714        color: var(--lightningcss-light, #7e250f) var(--lightningcss-dark, #c65d07);
28715        color: var(--lightningcss-light, lab(29.2661% 38.2437 35.3889)) var(--lightningcss-dark, lab(52.2319% 40.1449 59.9171));
28716      }
28717      "#},
28718      Browsers {
28719        chrome: Some(90 << 16),
28720        ..Browsers::default()
28721      },
28722    );
28723    prefix_test(
28724      ".foo { color: light-dark(oklch(40% 0.1268735435 34.568626), oklab(59.686% 0.1009 0.1192)); }",
28725      indoc! { r#"
28726      .foo {
28727        color: light-dark(oklch(40% .126874 34.5686), oklab(59.686% .1009 .1192));
28728      }
28729      "#},
28730      Browsers {
28731        firefox: Some(120 << 16),
28732        ..Browsers::default()
28733      },
28734    );
28735    prefix_test(
28736      r#"
28737      .foo {
28738        box-shadow:
28739            oklch(100% 0 0deg / 50%) 0 0.63rem 0.94rem -0.19rem,
28740            currentColor 0 0.44rem 0.8rem -0.58rem;
28741      }
28742    "#,
28743      indoc! { r#"
28744      .foo {
28745        box-shadow: 0 .63rem .94rem -.19rem #ffffff80, 0 .44rem .8rem -.58rem;
28746        box-shadow: 0 .63rem .94rem -.19rem lab(100% 0 0 / .5), 0 .44rem .8rem -.58rem;
28747      }
28748      "#},
28749      Browsers {
28750        chrome: Some(95 << 16),
28751        ..Browsers::default()
28752      },
28753    );
28754    prefix_test(
28755      r#"
28756      .foo {
28757        box-shadow:
28758            oklch(100% 0 0deg / 50%) 0 0.63rem 0.94rem -0.19rem,
28759            currentColor 0 0.44rem 0.8rem -0.58rem;
28760      }
28761    "#,
28762      indoc! { r#"
28763      .foo {
28764        box-shadow: 0 .63rem .94rem -.19rem color(display-p3 1 1 1 / .5), 0 .44rem .8rem -.58rem;
28765        box-shadow: 0 .63rem .94rem -.19rem lab(100% 0 0 / .5), 0 .44rem .8rem -.58rem;
28766      }
28767      "#},
28768      Browsers {
28769        safari: Some(14 << 16),
28770        ..Browsers::default()
28771      },
28772    );
28773
28774    prefix_test(
28775      ".foo { color: light-dark(var(--light), var(--dark)); }",
28776      indoc! { r#"
28777      .foo {
28778        color: var(--lightningcss-light, var(--light)) var(--lightningcss-dark, var(--dark));
28779      }
28780      "#},
28781      Browsers {
28782        chrome: Some(90 << 16),
28783        ..Browsers::default()
28784      },
28785    );
28786    prefix_test(
28787      ".foo { color: rgb(from light-dark(yellow, red) r g b / 10%); }",
28788      indoc! { r#"
28789      .foo {
28790        color: var(--lightningcss-light, #ffff001a) var(--lightningcss-dark, #ff00001a);
28791      }
28792      "#},
28793      Browsers {
28794        chrome: Some(90 << 16),
28795        ..Browsers::default()
28796      },
28797    );
28798    prefix_test(
28799      ".foo { color: rgb(from light-dark(yellow, red) r g b / var(--alpha)); }",
28800      indoc! { r#"
28801      .foo {
28802        color: var(--lightningcss-light, rgb(255 255 0 / var(--alpha))) var(--lightningcss-dark, rgb(255 0 0 / var(--alpha)));
28803      }
28804      "#},
28805      Browsers {
28806        chrome: Some(90 << 16),
28807        ..Browsers::default()
28808      },
28809    );
28810    prefix_test(
28811      ".foo { color: color(from light-dark(yellow, red) srgb r g b / 10%); }",
28812      indoc! { r#"
28813      .foo {
28814        color: var(--lightningcss-light, #ffff001a) var(--lightningcss-dark, #ff00001a);
28815        color: var(--lightningcss-light, color(srgb 1 1 0 / .1)) var(--lightningcss-dark, color(srgb 1 0 0 / .1));
28816      }
28817      "#},
28818      Browsers {
28819        chrome: Some(90 << 16),
28820        ..Browsers::default()
28821      },
28822    );
28823    prefix_test(
28824      ".foo { color: color-mix(in srgb, light-dark(yellow, red), light-dark(red, pink)); }",
28825      indoc! { r#"
28826      .foo {
28827        color: var(--lightningcss-light, #ff8000) var(--lightningcss-dark, #ff6066);
28828      }
28829      "#},
28830      Browsers {
28831        chrome: Some(90 << 16),
28832        ..Browsers::default()
28833      },
28834    );
28835    nesting_test_with_targets(
28836      r#"
28837        .foo { color-scheme: light; }
28838        .bar { color: light-dark(red, green); }
28839      "#,
28840      indoc! {r#"
28841        .foo {
28842          color-scheme: light;
28843        }
28844
28845        .bar {
28846          color: light-dark(red, green);
28847        }
28848      "#},
28849      Targets {
28850        browsers: Some(Browsers {
28851          safari: Some(13 << 16),
28852          ..Browsers::default()
28853        }),
28854        include: Features::empty(),
28855        exclude: Features::LightDark,
28856      },
28857    );
28858  }
28859
28860  #[test]
28861  fn test_all() {
28862    minify_test(".foo { all: initial; all: initial }", ".foo{all:initial}");
28863    minify_test(".foo { all: initial; all: revert }", ".foo{all:revert}");
28864    minify_test(".foo { background: red; all: revert-layer }", ".foo{all:revert-layer}");
28865    minify_test(
28866      ".foo { background: red; all: revert-layer; background: green }",
28867      ".foo{all:revert-layer;background:green}",
28868    );
28869    minify_test(
28870      ".foo { --test: red; all: revert-layer }",
28871      ".foo{--test:red;all:revert-layer}",
28872    );
28873    minify_test(
28874      ".foo { unicode-bidi: embed; all: revert-layer }",
28875      ".foo{all:revert-layer;unicode-bidi:embed}",
28876    );
28877    minify_test(
28878      ".foo { direction: rtl; all: revert-layer }",
28879      ".foo{all:revert-layer;direction:rtl}",
28880    );
28881    minify_test(
28882      ".foo { direction: rtl; all: revert-layer; direction: ltr }",
28883      ".foo{all:revert-layer;direction:ltr}",
28884    );
28885    minify_test(".foo { background: var(--foo); all: unset; }", ".foo{all:unset}");
28886    minify_test(
28887      ".foo { all: unset; background: var(--foo); }",
28888      ".foo{all:unset;background:var(--foo)}",
28889    );
28890    minify_test(
28891      ".foo {--bar:currentcolor; --foo:1.1em; all:unset}",
28892      ".foo{--bar:currentcolor;--foo:1.1em;all:unset}",
28893    );
28894  }
28895
28896  #[test]
28897  fn test_view_transition() {
28898    minify_test(
28899      "@view-transition { navigation: auto }",
28900      "@view-transition{navigation:auto}",
28901    );
28902    minify_test(
28903      "@view-transition { navigation: auto; types: none; }",
28904      "@view-transition{navigation:auto;types:none}",
28905    );
28906    minify_test(
28907      "@view-transition { navigation: auto; types: foo bar; }",
28908      "@view-transition{navigation:auto;types:foo bar}",
28909    );
28910    minify_test(
28911      "@layer { @view-transition { navigation: auto; types: foo bar; } }",
28912      "@layer{@view-transition{navigation:auto;types:foo bar}}",
28913    );
28914  }
28915}