github.com/evanw/esbuild@v0.21.4/internal/css_parser/css_parser_test.go (about)

     1  package css_parser
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/evanw/esbuild/internal/ast"
     8  	"github.com/evanw/esbuild/internal/compat"
     9  	"github.com/evanw/esbuild/internal/config"
    10  	"github.com/evanw/esbuild/internal/css_printer"
    11  	"github.com/evanw/esbuild/internal/logger"
    12  	"github.com/evanw/esbuild/internal/test"
    13  )
    14  
    15  func expectPrintedCommon(t *testing.T, name string, contents string, expected string, expectedLog string, loader config.Loader, options config.Options) {
    16  	t.Helper()
    17  	t.Run(name, func(t *testing.T) {
    18  		t.Helper()
    19  		log := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)
    20  		tree := Parse(log, test.SourceForTest(contents), OptionsFromConfig(loader, &options))
    21  		msgs := log.Done()
    22  		text := ""
    23  		for _, msg := range msgs {
    24  			text += msg.String(logger.OutputOptions{}, logger.TerminalInfo{})
    25  		}
    26  		test.AssertEqualWithDiff(t, text, expectedLog)
    27  		symbols := ast.NewSymbolMap(1)
    28  		symbols.SymbolsForSource[0] = tree.Symbols
    29  		result := css_printer.Print(tree, symbols, css_printer.Options{
    30  			MinifyWhitespace: options.MinifyWhitespace,
    31  		})
    32  		test.AssertEqualWithDiff(t, string(result.CSS), expected)
    33  	})
    34  }
    35  
    36  func expectPrinted(t *testing.T, contents string, expected string, expectedLog string) {
    37  	t.Helper()
    38  	expectPrintedCommon(t, contents, contents, expected, expectedLog, config.LoaderCSS, config.Options{})
    39  }
    40  
    41  func expectPrintedLocal(t *testing.T, contents string, expected string, expectedLog string) {
    42  	t.Helper()
    43  	expectPrintedCommon(t, contents+" [local]", contents, expected, expectedLog, config.LoaderLocalCSS, config.Options{})
    44  }
    45  
    46  func expectPrintedLower(t *testing.T, contents string, expected string, expectedLog string) {
    47  	t.Helper()
    48  	expectPrintedCommon(t, contents+" [lower]", contents, expected, expectedLog, config.LoaderCSS, config.Options{
    49  		UnsupportedCSSFeatures: ^compat.CSSFeature(0),
    50  	})
    51  }
    52  
    53  func expectPrintedLowerUnsupported(t *testing.T, unsupportedCSSFeatures compat.CSSFeature, contents string, expected string, expectedLog string) {
    54  	t.Helper()
    55  	expectPrintedCommon(t, contents+" [lower]", contents, expected, expectedLog, config.LoaderCSS, config.Options{
    56  		UnsupportedCSSFeatures: unsupportedCSSFeatures,
    57  	})
    58  }
    59  
    60  func expectPrintedWithAllPrefixes(t *testing.T, contents string, expected string, expectedLog string) {
    61  	t.Helper()
    62  	expectPrintedCommon(t, contents+" [prefixed]", contents, expected, expectedLog, config.LoaderCSS, config.Options{
    63  		CSSPrefixData: compat.CSSPrefixData(map[compat.Engine]compat.Semver{
    64  			compat.Chrome:  {Parts: []int{0}},
    65  			compat.Edge:    {Parts: []int{0}},
    66  			compat.Firefox: {Parts: []int{0}},
    67  			compat.IE:      {Parts: []int{0}},
    68  			compat.IOS:     {Parts: []int{0}},
    69  			compat.Opera:   {Parts: []int{0}},
    70  			compat.Safari:  {Parts: []int{0}},
    71  		}),
    72  	})
    73  }
    74  
    75  func expectPrintedMinify(t *testing.T, contents string, expected string, expectedLog string) {
    76  	t.Helper()
    77  	expectPrintedCommon(t, contents+" [minify]", contents, expected, expectedLog, config.LoaderCSS, config.Options{
    78  		MinifyWhitespace: true,
    79  	})
    80  }
    81  
    82  func expectPrintedMangle(t *testing.T, contents string, expected string, expectedLog string) {
    83  	t.Helper()
    84  	expectPrintedCommon(t, contents+" [mangle]", contents, expected, expectedLog, config.LoaderCSS, config.Options{
    85  		MinifySyntax: true,
    86  	})
    87  }
    88  
    89  func expectPrintedLowerMangle(t *testing.T, contents string, expected string, expectedLog string) {
    90  	t.Helper()
    91  	expectPrintedCommon(t, contents+" [lower, mangle]", contents, expected, expectedLog, config.LoaderCSS, config.Options{
    92  		UnsupportedCSSFeatures: ^compat.CSSFeature(0),
    93  		MinifySyntax:           true,
    94  	})
    95  }
    96  
    97  func expectPrintedMangleMinify(t *testing.T, contents string, expected string, expectedLog string) {
    98  	t.Helper()
    99  	expectPrintedCommon(t, contents+" [mangle, minify]", contents, expected, expectedLog, config.LoaderCSS, config.Options{
   100  		MinifySyntax:     true,
   101  		MinifyWhitespace: true,
   102  	})
   103  }
   104  
   105  func expectPrintedLowerMinify(t *testing.T, contents string, expected string, expectedLog string) {
   106  	t.Helper()
   107  	expectPrintedCommon(t, contents+" [lower, minify]", contents, expected, expectedLog, config.LoaderCSS, config.Options{
   108  		UnsupportedCSSFeatures: ^compat.CSSFeature(0),
   109  		MinifyWhitespace:       true,
   110  	})
   111  }
   112  
   113  func TestSingleLineComment(t *testing.T) {
   114  	expectPrinted(t, "a, // a\nb // b\n{}", "a, // a b // b {\n}\n",
   115  		"<stdin>: WARNING: Comments in CSS use \"/* ... */\" instead of \"//\"\n"+
   116  			"<stdin>: WARNING: Comments in CSS use \"/* ... */\" instead of \"//\"\n")
   117  	expectPrinted(t, "a, ///// a /////\n{}", "a, ///// a ///// {\n}\n",
   118  		"<stdin>: WARNING: Comments in CSS use \"/* ... */\" instead of \"//\"\n")
   119  }
   120  
   121  func TestEscapes(t *testing.T) {
   122  	// TIdent
   123  	expectPrinted(t, "a { value: id\\65nt }", "a {\n  value: ident;\n}\n", "")
   124  	expectPrinted(t, "a { value: \\69 dent }", "a {\n  value: ident;\n}\n", "")
   125  	expectPrinted(t, "a { value: \\69dent }", "a {\n  value: \u69DEnt;\n}\n", "")
   126  	expectPrinted(t, "a { value: \\2cx }", "a {\n  value: \\,x;\n}\n", "")
   127  	expectPrinted(t, "a { value: \\,x }", "a {\n  value: \\,x;\n}\n", "")
   128  	expectPrinted(t, "a { value: x\\2c }", "a {\n  value: x\\,;\n}\n", "")
   129  	expectPrinted(t, "a { value: x\\, }", "a {\n  value: x\\,;\n}\n", "")
   130  	expectPrinted(t, "a { value: x\\0 }", "a {\n  value: x\uFFFD;\n}\n", "")
   131  	expectPrinted(t, "a { value: x\\1 }", "a {\n  value: x\\\x01;\n}\n", "")
   132  	expectPrinted(t, "a { value: x\x00 }", "a {\n  value: x\uFFFD;\n}\n", "")
   133  	expectPrinted(t, "a { value: x\x01 }", "a {\n  value: x\x01;\n}\n", "")
   134  
   135  	// THash
   136  	expectPrinted(t, "a { value: #0h\\61sh }", "a {\n  value: #0hash;\n}\n", "")
   137  	expectPrinted(t, "a { value: #\\30hash }", "a {\n  value: #0hash;\n}\n", "")
   138  	expectPrinted(t, "a { value: #\\2cx }", "a {\n  value: #\\,x;\n}\n", "")
   139  	expectPrinted(t, "a { value: #\\,x }", "a {\n  value: #\\,x;\n}\n", "")
   140  
   141  	// THashID
   142  	expectPrinted(t, "a { value: #h\\61sh }", "a {\n  value: #hash;\n}\n", "")
   143  	expectPrinted(t, "a { value: #\\68 ash }", "a {\n  value: #hash;\n}\n", "")
   144  	expectPrinted(t, "a { value: #\\68ash }", "a {\n  value: #\u068Ash;\n}\n", "")
   145  	expectPrinted(t, "a { value: #x\\2c }", "a {\n  value: #x\\,;\n}\n", "")
   146  	expectPrinted(t, "a { value: #x\\, }", "a {\n  value: #x\\,;\n}\n", "")
   147  
   148  	// TFunction
   149  	expectPrinted(t, "a { value: f\\6e() }", "a {\n  value: fn();\n}\n", "")
   150  	expectPrinted(t, "a { value: \\66n() }", "a {\n  value: fn();\n}\n", "")
   151  	expectPrinted(t, "a { value: \\2cx() }", "a {\n  value: \\,x();\n}\n", "")
   152  	expectPrinted(t, "a { value: \\,x() }", "a {\n  value: \\,x();\n}\n", "")
   153  	expectPrinted(t, "a { value: x\\2c() }", "a {\n  value: x\\,();\n}\n", "")
   154  	expectPrinted(t, "a { value: x\\,() }", "a {\n  value: x\\,();\n}\n", "")
   155  
   156  	// TString
   157  	expectPrinted(t, "a { value: 'a\\62 c' }", "a {\n  value: \"abc\";\n}\n", "")
   158  	expectPrinted(t, "a { value: 'a\\62c' }", "a {\n  value: \"a\u062C\";\n}\n", "")
   159  	expectPrinted(t, "a { value: '\\61 bc' }", "a {\n  value: \"abc\";\n}\n", "")
   160  	expectPrinted(t, "a { value: '\\61bc' }", "a {\n  value: \"\u61BC\";\n}\n", "")
   161  	expectPrinted(t, "a { value: '\\2c' }", "a {\n  value: \",\";\n}\n", "")
   162  	expectPrinted(t, "a { value: '\\,' }", "a {\n  value: \",\";\n}\n", "")
   163  	expectPrinted(t, "a { value: '\\0' }", "a {\n  value: \"\uFFFD\";\n}\n", "")
   164  	expectPrinted(t, "a { value: '\\1' }", "a {\n  value: \"\x01\";\n}\n", "")
   165  	expectPrinted(t, "a { value: '\x00' }", "a {\n  value: \"\uFFFD\";\n}\n", "")
   166  	expectPrinted(t, "a { value: '\x01' }", "a {\n  value: \"\x01\";\n}\n", "")
   167  
   168  	// TURL
   169  	expectPrinted(t, "a { value: url(a\\62 c) }", "a {\n  value: url(abc);\n}\n", "")
   170  	expectPrinted(t, "a { value: url(a\\62c) }", "a {\n  value: url(a\u062C);\n}\n", "")
   171  	expectPrinted(t, "a { value: url(\\61 bc) }", "a {\n  value: url(abc);\n}\n", "")
   172  	expectPrinted(t, "a { value: url(\\61bc) }", "a {\n  value: url(\u61BC);\n}\n", "")
   173  	expectPrinted(t, "a { value: url(\\2c) }", "a {\n  value: url(,);\n}\n", "")
   174  	expectPrinted(t, "a { value: url(\\,) }", "a {\n  value: url(,);\n}\n", "")
   175  
   176  	// TAtKeyword
   177  	expectPrinted(t, "a { value: @k\\65yword }", "a {\n  value: @keyword;\n}\n", "")
   178  	expectPrinted(t, "a { value: @\\6b eyword }", "a {\n  value: @keyword;\n}\n", "")
   179  	expectPrinted(t, "a { value: @\\6beyword }", "a {\n  value: @\u06BEyword;\n}\n", "")
   180  	expectPrinted(t, "a { value: @\\2cx }", "a {\n  value: @\\,x;\n}\n", "")
   181  	expectPrinted(t, "a { value: @\\,x }", "a {\n  value: @\\,x;\n}\n", "")
   182  	expectPrinted(t, "a { value: @x\\2c }", "a {\n  value: @x\\,;\n}\n", "")
   183  	expectPrinted(t, "a { value: @x\\, }", "a {\n  value: @x\\,;\n}\n", "")
   184  
   185  	// TDimension
   186  	expectPrinted(t, "a { value: 10\\65m }", "a {\n  value: 10em;\n}\n", "")
   187  	expectPrinted(t, "a { value: 10p\\32x }", "a {\n  value: 10p2x;\n}\n", "")
   188  	expectPrinted(t, "a { value: 10e\\32x }", "a {\n  value: 10\\65 2x;\n}\n", "")
   189  	expectPrinted(t, "a { value: 10e-\\32x }", "a {\n  value: 10\\65-2x;\n}\n", "")
   190  	expectPrinted(t, "a { value: 10E\\32x }", "a {\n  value: 10\\45 2x;\n}\n", "")
   191  	expectPrinted(t, "a { value: 10E-\\32x }", "a {\n  value: 10\\45-2x;\n}\n", "")
   192  	expectPrinted(t, "a { value: 10e1e\\32x }", "a {\n  value: 10e1e2x;\n}\n", "")
   193  	expectPrinted(t, "a { value: 10e1e-\\32x }", "a {\n  value: 10e1e-2x;\n}\n", "")
   194  	expectPrinted(t, "a { value: 10e1E\\32x }", "a {\n  value: 10e1E2x;\n}\n", "")
   195  	expectPrinted(t, "a { value: 10e1E-\\32x }", "a {\n  value: 10e1E-2x;\n}\n", "")
   196  	expectPrinted(t, "a { value: 10E1e\\32x }", "a {\n  value: 10E1e2x;\n}\n", "")
   197  	expectPrinted(t, "a { value: 10E1e-\\32x }", "a {\n  value: 10E1e-2x;\n}\n", "")
   198  	expectPrinted(t, "a { value: 10E1E\\32x }", "a {\n  value: 10E1E2x;\n}\n", "")
   199  	expectPrinted(t, "a { value: 10E1E-\\32x }", "a {\n  value: 10E1E-2x;\n}\n", "")
   200  	expectPrinted(t, "a { value: 10\\32x }", "a {\n  value: 10\\32x;\n}\n", "")
   201  	expectPrinted(t, "a { value: 10\\2cx }", "a {\n  value: 10\\,x;\n}\n", "")
   202  	expectPrinted(t, "a { value: 10\\,x }", "a {\n  value: 10\\,x;\n}\n", "")
   203  	expectPrinted(t, "a { value: 10x\\2c }", "a {\n  value: 10x\\,;\n}\n", "")
   204  	expectPrinted(t, "a { value: 10x\\, }", "a {\n  value: 10x\\,;\n}\n", "")
   205  
   206  	// This must remain unescaped. See https://github.com/evanw/esbuild/issues/2677
   207  	expectPrinted(t, "@font-face { unicode-range: U+0e2e-0e2f }", "@font-face {\n  unicode-range: U+0e2e-0e2f;\n}\n", "")
   208  
   209  	// RDeclaration
   210  	colorWarning := "<stdin>: WARNING: \",olor\" is not a known CSS property\nNOTE: Did you mean \"color\" instead?\n"
   211  	expectPrintedMangle(t, "a { c\\6flor: #f00 }", "a {\n  color: red;\n}\n", "")
   212  	expectPrintedMangle(t, "a { \\63olor: #f00 }", "a {\n  color: red;\n}\n", "")
   213  	expectPrintedMangle(t, "a { \\2color: #f00 }", "a {\n  \\,olor: #f00;\n}\n", colorWarning)
   214  	expectPrintedMangle(t, "a { \\,olor: #f00 }", "a {\n  \\,olor: #f00;\n}\n", colorWarning)
   215  
   216  	// RUnknownAt
   217  	expectPrinted(t, "@unknown;", "@unknown;\n", "")
   218  	expectPrinted(t, "@u\\6eknown;", "@unknown;\n", "")
   219  	expectPrinted(t, "@\\75nknown;", "@unknown;\n", "")
   220  	expectPrinted(t, "@u\\2cnknown;", "@u\\,nknown;\n", "")
   221  	expectPrinted(t, "@u\\,nknown;", "@u\\,nknown;\n", "")
   222  	expectPrinted(t, "@\\2cunknown;", "@\\,unknown;\n", "")
   223  	expectPrinted(t, "@\\,unknown;", "@\\,unknown;\n", "")
   224  
   225  	// RAtKeyframes
   226  	expectPrinted(t, "@k\\65yframes abc { from {} }", "@keyframes abc {\n  from {\n  }\n}\n", "")
   227  	expectPrinted(t, "@keyframes \\61 bc { from {} }", "@keyframes abc {\n  from {\n  }\n}\n", "")
   228  	expectPrinted(t, "@keyframes a\\62 c { from {} }", "@keyframes abc {\n  from {\n  }\n}\n", "")
   229  	expectPrinted(t, "@keyframes abc { \\66rom {} }", "@keyframes abc {\n  from {\n  }\n}\n", "")
   230  	expectPrinted(t, "@keyframes a\\2c c { \\66rom {} }", "@keyframes a\\,c {\n  from {\n  }\n}\n", "")
   231  	expectPrinted(t, "@keyframes a\\,c { \\66rom {} }", "@keyframes a\\,c {\n  from {\n  }\n}\n", "")
   232  
   233  	// RAtNamespace
   234  	namespaceWarning := "<stdin>: WARNING: \"@namespace\" rules are not supported\n"
   235  	expectPrinted(t, "@n\\61mespace ns 'path';", "@namespace ns \"path\";\n", namespaceWarning)
   236  	expectPrinted(t, "@namespace \\6es 'path';", "@namespace ns \"path\";\n", namespaceWarning)
   237  	expectPrinted(t, "@namespace ns 'p\\61th';", "@namespace ns \"path\";\n", namespaceWarning)
   238  	expectPrinted(t, "@namespace \\2cs 'p\\61th';", "@namespace \\,s \"path\";\n", namespaceWarning)
   239  	expectPrinted(t, "@namespace \\,s 'p\\61th';", "@namespace \\,s \"path\";\n", namespaceWarning)
   240  
   241  	// CompoundSelector
   242  	expectPrinted(t, "* {}", "* {\n}\n", "")
   243  	expectPrinted(t, "*|div {}", "*|div {\n}\n", "")
   244  	expectPrinted(t, "\\2a {}", "\\* {\n}\n", "")
   245  	expectPrinted(t, "\\2a|div {}", "\\*|div {\n}\n", "")
   246  	expectPrinted(t, "\\2d {}", "\\- {\n}\n", "")
   247  	expectPrinted(t, "\\2d- {}", "-- {\n}\n", "")
   248  	expectPrinted(t, "-\\2d {}", "-- {\n}\n", "")
   249  	expectPrinted(t, "\\2d 123 {}", "\\-123 {\n}\n", "")
   250  
   251  	// SSHash
   252  	expectPrinted(t, "#h\\61sh {}", "#hash {\n}\n", "")
   253  	expectPrinted(t, "#\\2chash {}", "#\\,hash {\n}\n", "")
   254  	expectPrinted(t, "#\\,hash {}", "#\\,hash {\n}\n", "")
   255  	expectPrinted(t, "#\\2d {}", "#\\- {\n}\n", "")
   256  	expectPrinted(t, "#\\2d- {}", "#-- {\n}\n", "")
   257  	expectPrinted(t, "#-\\2d {}", "#-- {\n}\n", "")
   258  	expectPrinted(t, "#\\2d 123 {}", "#\\-123 {\n}\n", "")
   259  	expectPrinted(t, "#\\61hash {}", "#ahash {\n}\n", "")
   260  	expectPrinted(t, "#\\30hash {}", "#\\30hash {\n}\n", "")
   261  	expectPrinted(t, "#0\\2chash {}", "#0\\,hash {\n}\n", "<stdin>: WARNING: Unexpected \"#0\\\\2chash\"\n")
   262  	expectPrinted(t, "#0\\,hash {}", "#0\\,hash {\n}\n", "<stdin>: WARNING: Unexpected \"#0\\\\,hash\"\n")
   263  
   264  	// SSClass
   265  	expectPrinted(t, ".cl\\61ss {}", ".class {\n}\n", "")
   266  	expectPrinted(t, ".\\2c class {}", ".\\,class {\n}\n", "")
   267  	expectPrinted(t, ".\\,class {}", ".\\,class {\n}\n", "")
   268  
   269  	// SSPseudoClass
   270  	expectPrinted(t, ":pseudocl\\61ss {}", ":pseudoclass {\n}\n", "")
   271  	expectPrinted(t, ":pseudo\\2c class {}", ":pseudo\\,class {\n}\n", "")
   272  	expectPrinted(t, ":pseudo\\,class {}", ":pseudo\\,class {\n}\n", "")
   273  	expectPrinted(t, ":pseudo(cl\\61ss) {}", ":pseudo(class) {\n}\n", "")
   274  	expectPrinted(t, ":pseudo(cl\\2css) {}", ":pseudo(cl\\,ss) {\n}\n", "")
   275  	expectPrinted(t, ":pseudo(cl\\,ss) {}", ":pseudo(cl\\,ss) {\n}\n", "")
   276  
   277  	// SSAttribute
   278  	expectPrinted(t, "[\\61ttr] {}", "[attr] {\n}\n", "")
   279  	expectPrinted(t, "[\\2c attr] {}", "[\\,attr] {\n}\n", "")
   280  	expectPrinted(t, "[\\,attr] {}", "[\\,attr] {\n}\n", "")
   281  	expectPrinted(t, "[attr\\7e=x] {}", "[attr\\~=x] {\n}\n", "")
   282  	expectPrinted(t, "[attr\\~=x] {}", "[attr\\~=x] {\n}\n", "")
   283  	expectPrinted(t, "[attr=\\2c] {}", "[attr=\",\"] {\n}\n", "")
   284  	expectPrinted(t, "[attr=\\,] {}", "[attr=\",\"] {\n}\n", "")
   285  	expectPrinted(t, "[attr=\"-\"] {}", "[attr=\"-\"] {\n}\n", "")
   286  	expectPrinted(t, "[attr=\"--\"] {}", "[attr=--] {\n}\n", "")
   287  	expectPrinted(t, "[attr=\"-a\"] {}", "[attr=-a] {\n}\n", "")
   288  	expectPrinted(t, "[\\6es|attr] {}", "[ns|attr] {\n}\n", "")
   289  	expectPrinted(t, "[ns|\\61ttr] {}", "[ns|attr] {\n}\n", "")
   290  	expectPrinted(t, "[\\2cns|attr] {}", "[\\,ns|attr] {\n}\n", "")
   291  	expectPrinted(t, "[ns|\\2c attr] {}", "[ns|\\,attr] {\n}\n", "")
   292  	expectPrinted(t, "[*|attr] {}", "[*|attr] {\n}\n", "")
   293  	expectPrinted(t, "[\\2a|attr] {}", "[\\*|attr] {\n}\n", "")
   294  }
   295  
   296  func TestString(t *testing.T) {
   297  	expectPrinted(t, "a:after { content: 'a\\\rb' }", "a:after {\n  content: \"ab\";\n}\n", "")
   298  	expectPrinted(t, "a:after { content: 'a\\\nb' }", "a:after {\n  content: \"ab\";\n}\n", "")
   299  	expectPrinted(t, "a:after { content: 'a\\\fb' }", "a:after {\n  content: \"ab\";\n}\n", "")
   300  	expectPrinted(t, "a:after { content: 'a\\\r\nb' }", "a:after {\n  content: \"ab\";\n}\n", "")
   301  	expectPrinted(t, "a:after { content: 'a\\62 c' }", "a:after {\n  content: \"abc\";\n}\n", "")
   302  
   303  	expectPrinted(t, "a:after { content: '\r' }", "a:after {\n  content: '\n  ' }\n  ;\n}\n",
   304  		`<stdin>: WARNING: Unterminated string token
   305  <stdin>: WARNING: Expected "}" to go with "{"
   306  <stdin>: NOTE: The unbalanced "{" is here:
   307  <stdin>: WARNING: Unterminated string token
   308  `)
   309  	expectPrinted(t, "a:after { content: '\n' }", "a:after {\n  content: '\n  ' }\n  ;\n}\n",
   310  		`<stdin>: WARNING: Unterminated string token
   311  <stdin>: WARNING: Expected "}" to go with "{"
   312  <stdin>: NOTE: The unbalanced "{" is here:
   313  <stdin>: WARNING: Unterminated string token
   314  `)
   315  	expectPrinted(t, "a:after { content: '\f' }", "a:after {\n  content: '\n  ' }\n  ;\n}\n",
   316  		`<stdin>: WARNING: Unterminated string token
   317  <stdin>: WARNING: Expected "}" to go with "{"
   318  <stdin>: NOTE: The unbalanced "{" is here:
   319  <stdin>: WARNING: Unterminated string token
   320  `)
   321  	expectPrinted(t, "a:after { content: '\r\n' }", "a:after {\n  content: '\n  ' }\n  ;\n}\n",
   322  		`<stdin>: WARNING: Unterminated string token
   323  <stdin>: WARNING: Expected "}" to go with "{"
   324  <stdin>: NOTE: The unbalanced "{" is here:
   325  <stdin>: WARNING: Unterminated string token
   326  `)
   327  
   328  	expectPrinted(t, "a:after { content: '\\1010101' }", "a:after {\n  content: \"\U001010101\";\n}\n", "")
   329  	expectPrinted(t, "a:after { content: '\\invalid' }", "a:after {\n  content: \"invalid\";\n}\n", "")
   330  }
   331  
   332  func TestNumber(t *testing.T) {
   333  	for _, ext := range []string{"", "%", "px+"} {
   334  		expectPrinted(t, "a { width: .0"+ext+"; }", "a {\n  width: .0"+ext+";\n}\n", "")
   335  		expectPrinted(t, "a { width: .00"+ext+"; }", "a {\n  width: .00"+ext+";\n}\n", "")
   336  		expectPrinted(t, "a { width: .10"+ext+"; }", "a {\n  width: .10"+ext+";\n}\n", "")
   337  		expectPrinted(t, "a { width: 0."+ext+"; }", "a {\n  width: 0."+ext+";\n}\n", "")
   338  		expectPrinted(t, "a { width: 0.0"+ext+"; }", "a {\n  width: 0.0"+ext+";\n}\n", "")
   339  		expectPrinted(t, "a { width: 0.1"+ext+"; }", "a {\n  width: 0.1"+ext+";\n}\n", "")
   340  
   341  		expectPrinted(t, "a { width: +.0"+ext+"; }", "a {\n  width: +.0"+ext+";\n}\n", "")
   342  		expectPrinted(t, "a { width: +.00"+ext+"; }", "a {\n  width: +.00"+ext+";\n}\n", "")
   343  		expectPrinted(t, "a { width: +.10"+ext+"; }", "a {\n  width: +.10"+ext+";\n}\n", "")
   344  		expectPrinted(t, "a { width: +0."+ext+"; }", "a {\n  width: +0."+ext+";\n}\n", "")
   345  		expectPrinted(t, "a { width: +0.0"+ext+"; }", "a {\n  width: +0.0"+ext+";\n}\n", "")
   346  		expectPrinted(t, "a { width: +0.1"+ext+"; }", "a {\n  width: +0.1"+ext+";\n}\n", "")
   347  
   348  		expectPrinted(t, "a { width: -.0"+ext+"; }", "a {\n  width: -.0"+ext+";\n}\n", "")
   349  		expectPrinted(t, "a { width: -.00"+ext+"; }", "a {\n  width: -.00"+ext+";\n}\n", "")
   350  		expectPrinted(t, "a { width: -.10"+ext+"; }", "a {\n  width: -.10"+ext+";\n}\n", "")
   351  		expectPrinted(t, "a { width: -0."+ext+"; }", "a {\n  width: -0."+ext+";\n}\n", "")
   352  		expectPrinted(t, "a { width: -0.0"+ext+"; }", "a {\n  width: -0.0"+ext+";\n}\n", "")
   353  		expectPrinted(t, "a { width: -0.1"+ext+"; }", "a {\n  width: -0.1"+ext+";\n}\n", "")
   354  
   355  		expectPrintedMangle(t, "a { width: .0"+ext+"; }", "a {\n  width: 0"+ext+";\n}\n", "")
   356  		expectPrintedMangle(t, "a { width: .00"+ext+"; }", "a {\n  width: 0"+ext+";\n}\n", "")
   357  		expectPrintedMangle(t, "a { width: .10"+ext+"; }", "a {\n  width: .1"+ext+";\n}\n", "")
   358  		expectPrintedMangle(t, "a { width: 0."+ext+"; }", "a {\n  width: 0"+ext+";\n}\n", "")
   359  		expectPrintedMangle(t, "a { width: 0.0"+ext+"; }", "a {\n  width: 0"+ext+";\n}\n", "")
   360  		expectPrintedMangle(t, "a { width: 0.1"+ext+"; }", "a {\n  width: .1"+ext+";\n}\n", "")
   361  
   362  		expectPrintedMangle(t, "a { width: +.0"+ext+"; }", "a {\n  width: +0"+ext+";\n}\n", "")
   363  		expectPrintedMangle(t, "a { width: +.00"+ext+"; }", "a {\n  width: +0"+ext+";\n}\n", "")
   364  		expectPrintedMangle(t, "a { width: +.10"+ext+"; }", "a {\n  width: +.1"+ext+";\n}\n", "")
   365  		expectPrintedMangle(t, "a { width: +0."+ext+"; }", "a {\n  width: +0"+ext+";\n}\n", "")
   366  		expectPrintedMangle(t, "a { width: +0.0"+ext+"; }", "a {\n  width: +0"+ext+";\n}\n", "")
   367  		expectPrintedMangle(t, "a { width: +0.1"+ext+"; }", "a {\n  width: +.1"+ext+";\n}\n", "")
   368  
   369  		expectPrintedMangle(t, "a { width: -.0"+ext+"; }", "a {\n  width: -0"+ext+";\n}\n", "")
   370  		expectPrintedMangle(t, "a { width: -.00"+ext+"; }", "a {\n  width: -0"+ext+";\n}\n", "")
   371  		expectPrintedMangle(t, "a { width: -.10"+ext+"; }", "a {\n  width: -.1"+ext+";\n}\n", "")
   372  		expectPrintedMangle(t, "a { width: -0."+ext+"; }", "a {\n  width: -0"+ext+";\n}\n", "")
   373  		expectPrintedMangle(t, "a { width: -0.0"+ext+"; }", "a {\n  width: -0"+ext+";\n}\n", "")
   374  		expectPrintedMangle(t, "a { width: -0.1"+ext+"; }", "a {\n  width: -.1"+ext+";\n}\n", "")
   375  	}
   376  }
   377  
   378  func TestURL(t *testing.T) {
   379  	expectPrinted(t, "a { background: url(foo.png) }", "a {\n  background: url(foo.png);\n}\n", "")
   380  	expectPrinted(t, "a { background: url('foo.png') }", "a {\n  background: url(foo.png);\n}\n", "")
   381  	expectPrinted(t, "a { background: url(\"foo.png\") }", "a {\n  background: url(foo.png);\n}\n", "")
   382  	expectPrinted(t, "a { background: url(\"foo.png\" ) }", "a {\n  background: url(foo.png);\n}\n", "")
   383  	expectPrinted(t, "a { background: url(\"foo.png\"\t) }", "a {\n  background: url(foo.png);\n}\n", "")
   384  	expectPrinted(t, "a { background: url(\"foo.png\"\r) }", "a {\n  background: url(foo.png);\n}\n", "")
   385  	expectPrinted(t, "a { background: url(\"foo.png\"\n) }", "a {\n  background: url(foo.png);\n}\n", "")
   386  	expectPrinted(t, "a { background: url(\"foo.png\"\f) }", "a {\n  background: url(foo.png);\n}\n", "")
   387  	expectPrinted(t, "a { background: url(\"foo.png\"\r\n) }", "a {\n  background: url(foo.png);\n}\n", "")
   388  	expectPrinted(t, "a { background: url( \"foo.png\") }", "a {\n  background: url(foo.png);\n}\n", "")
   389  	expectPrinted(t, "a { background: url(\t\"foo.png\") }", "a {\n  background: url(foo.png);\n}\n", "")
   390  	expectPrinted(t, "a { background: url(\r\"foo.png\") }", "a {\n  background: url(foo.png);\n}\n", "")
   391  	expectPrinted(t, "a { background: url(\n\"foo.png\") }", "a {\n  background: url(foo.png);\n}\n", "")
   392  	expectPrinted(t, "a { background: url(\f\"foo.png\") }", "a {\n  background: url(foo.png);\n}\n", "")
   393  	expectPrinted(t, "a { background: url(\r\n\"foo.png\") }", "a {\n  background: url(foo.png);\n}\n", "")
   394  	expectPrinted(t, "a { background: url( \"foo.png\" ) }", "a {\n  background: url(foo.png);\n}\n", "")
   395  	expectPrinted(t, "a { background: url(\"foo.png\" extra-stuff) }", "a {\n  background: url(\"foo.png\" extra-stuff);\n}\n", "")
   396  	expectPrinted(t, "a { background: url( \"foo.png\" extra-stuff ) }", "a {\n  background: url(\"foo.png\" extra-stuff);\n}\n", "")
   397  }
   398  
   399  func TestHexColor(t *testing.T) {
   400  	// "#RGBA"
   401  
   402  	expectPrinted(t, "a { color: #1234 }", "a {\n  color: #1234;\n}\n", "")
   403  	expectPrinted(t, "a { color: #123f }", "a {\n  color: #123f;\n}\n", "")
   404  	expectPrinted(t, "a { color: #abcd }", "a {\n  color: #abcd;\n}\n", "")
   405  	expectPrinted(t, "a { color: #abcf }", "a {\n  color: #abcf;\n}\n", "")
   406  	expectPrinted(t, "a { color: #ABCD }", "a {\n  color: #ABCD;\n}\n", "")
   407  	expectPrinted(t, "a { color: #ABCF }", "a {\n  color: #ABCF;\n}\n", "")
   408  
   409  	expectPrintedMangle(t, "a { color: #1234 }", "a {\n  color: #1234;\n}\n", "")
   410  	expectPrintedMangle(t, "a { color: #123f }", "a {\n  color: #123;\n}\n", "")
   411  	expectPrintedMangle(t, "a { color: #abcd }", "a {\n  color: #abcd;\n}\n", "")
   412  	expectPrintedMangle(t, "a { color: #abcf }", "a {\n  color: #abc;\n}\n", "")
   413  	expectPrintedMangle(t, "a { color: #ABCD }", "a {\n  color: #abcd;\n}\n", "")
   414  	expectPrintedMangle(t, "a { color: #ABCF }", "a {\n  color: #abc;\n}\n", "")
   415  
   416  	// "#RRGGBB"
   417  
   418  	expectPrinted(t, "a { color: #112233 }", "a {\n  color: #112233;\n}\n", "")
   419  	expectPrinted(t, "a { color: #122233 }", "a {\n  color: #122233;\n}\n", "")
   420  	expectPrinted(t, "a { color: #112333 }", "a {\n  color: #112333;\n}\n", "")
   421  	expectPrinted(t, "a { color: #112234 }", "a {\n  color: #112234;\n}\n", "")
   422  
   423  	expectPrintedMangle(t, "a { color: #112233 }", "a {\n  color: #123;\n}\n", "")
   424  	expectPrintedMangle(t, "a { color: #122233 }", "a {\n  color: #122233;\n}\n", "")
   425  	expectPrintedMangle(t, "a { color: #112333 }", "a {\n  color: #112333;\n}\n", "")
   426  	expectPrintedMangle(t, "a { color: #112234 }", "a {\n  color: #112234;\n}\n", "")
   427  
   428  	expectPrinted(t, "a { color: #aabbcc }", "a {\n  color: #aabbcc;\n}\n", "")
   429  	expectPrinted(t, "a { color: #abbbcc }", "a {\n  color: #abbbcc;\n}\n", "")
   430  	expectPrinted(t, "a { color: #aabccc }", "a {\n  color: #aabccc;\n}\n", "")
   431  	expectPrinted(t, "a { color: #aabbcd }", "a {\n  color: #aabbcd;\n}\n", "")
   432  
   433  	expectPrintedMangle(t, "a { color: #aabbcc }", "a {\n  color: #abc;\n}\n", "")
   434  	expectPrintedMangle(t, "a { color: #abbbcc }", "a {\n  color: #abbbcc;\n}\n", "")
   435  	expectPrintedMangle(t, "a { color: #aabccc }", "a {\n  color: #aabccc;\n}\n", "")
   436  	expectPrintedMangle(t, "a { color: #aabbcd }", "a {\n  color: #aabbcd;\n}\n", "")
   437  
   438  	expectPrinted(t, "a { color: #AABBCC }", "a {\n  color: #AABBCC;\n}\n", "")
   439  	expectPrinted(t, "a { color: #ABBBCC }", "a {\n  color: #ABBBCC;\n}\n", "")
   440  	expectPrinted(t, "a { color: #AABCCC }", "a {\n  color: #AABCCC;\n}\n", "")
   441  	expectPrinted(t, "a { color: #AABBCD }", "a {\n  color: #AABBCD;\n}\n", "")
   442  
   443  	expectPrintedMangle(t, "a { color: #AABBCC }", "a {\n  color: #abc;\n}\n", "")
   444  	expectPrintedMangle(t, "a { color: #ABBBCC }", "a {\n  color: #abbbcc;\n}\n", "")
   445  	expectPrintedMangle(t, "a { color: #AABCCC }", "a {\n  color: #aabccc;\n}\n", "")
   446  	expectPrintedMangle(t, "a { color: #AABBCD }", "a {\n  color: #aabbcd;\n}\n", "")
   447  
   448  	// "#RRGGBBAA"
   449  
   450  	expectPrinted(t, "a { color: #11223344 }", "a {\n  color: #11223344;\n}\n", "")
   451  	expectPrinted(t, "a { color: #12223344 }", "a {\n  color: #12223344;\n}\n", "")
   452  	expectPrinted(t, "a { color: #11233344 }", "a {\n  color: #11233344;\n}\n", "")
   453  	expectPrinted(t, "a { color: #11223444 }", "a {\n  color: #11223444;\n}\n", "")
   454  	expectPrinted(t, "a { color: #11223345 }", "a {\n  color: #11223345;\n}\n", "")
   455  
   456  	expectPrintedMangle(t, "a { color: #11223344 }", "a {\n  color: #1234;\n}\n", "")
   457  	expectPrintedMangle(t, "a { color: #12223344 }", "a {\n  color: #12223344;\n}\n", "")
   458  	expectPrintedMangle(t, "a { color: #11233344 }", "a {\n  color: #11233344;\n}\n", "")
   459  	expectPrintedMangle(t, "a { color: #11223444 }", "a {\n  color: #11223444;\n}\n", "")
   460  	expectPrintedMangle(t, "a { color: #11223345 }", "a {\n  color: #11223345;\n}\n", "")
   461  
   462  	expectPrinted(t, "a { color: #aabbccdd }", "a {\n  color: #aabbccdd;\n}\n", "")
   463  	expectPrinted(t, "a { color: #abbbccdd }", "a {\n  color: #abbbccdd;\n}\n", "")
   464  	expectPrinted(t, "a { color: #aabcccdd }", "a {\n  color: #aabcccdd;\n}\n", "")
   465  	expectPrinted(t, "a { color: #aabbcddd }", "a {\n  color: #aabbcddd;\n}\n", "")
   466  	expectPrinted(t, "a { color: #aabbccde }", "a {\n  color: #aabbccde;\n}\n", "")
   467  
   468  	expectPrintedMangle(t, "a { color: #aabbccdd }", "a {\n  color: #abcd;\n}\n", "")
   469  	expectPrintedMangle(t, "a { color: #abbbccdd }", "a {\n  color: #abbbccdd;\n}\n", "")
   470  	expectPrintedMangle(t, "a { color: #aabcccdd }", "a {\n  color: #aabcccdd;\n}\n", "")
   471  	expectPrintedMangle(t, "a { color: #aabbcddd }", "a {\n  color: #aabbcddd;\n}\n", "")
   472  	expectPrintedMangle(t, "a { color: #aabbccde }", "a {\n  color: #aabbccde;\n}\n", "")
   473  
   474  	expectPrinted(t, "a { color: #AABBCCDD }", "a {\n  color: #AABBCCDD;\n}\n", "")
   475  	expectPrinted(t, "a { color: #ABBBCCDD }", "a {\n  color: #ABBBCCDD;\n}\n", "")
   476  	expectPrinted(t, "a { color: #AABCCCDD }", "a {\n  color: #AABCCCDD;\n}\n", "")
   477  	expectPrinted(t, "a { color: #AABBCDDD }", "a {\n  color: #AABBCDDD;\n}\n", "")
   478  	expectPrinted(t, "a { color: #AABBCCDE }", "a {\n  color: #AABBCCDE;\n}\n", "")
   479  
   480  	expectPrintedMangle(t, "a { color: #AABBCCDD }", "a {\n  color: #abcd;\n}\n", "")
   481  	expectPrintedMangle(t, "a { color: #ABBBCCDD }", "a {\n  color: #abbbccdd;\n}\n", "")
   482  	expectPrintedMangle(t, "a { color: #AABCCCDD }", "a {\n  color: #aabcccdd;\n}\n", "")
   483  	expectPrintedMangle(t, "a { color: #AABBCDDD }", "a {\n  color: #aabbcddd;\n}\n", "")
   484  	expectPrintedMangle(t, "a { color: #AABBCCDE }", "a {\n  color: #aabbccde;\n}\n", "")
   485  
   486  	// "#RRGGBBFF"
   487  
   488  	expectPrinted(t, "a { color: #112233ff }", "a {\n  color: #112233ff;\n}\n", "")
   489  	expectPrinted(t, "a { color: #122233ff }", "a {\n  color: #122233ff;\n}\n", "")
   490  	expectPrinted(t, "a { color: #112333ff }", "a {\n  color: #112333ff;\n}\n", "")
   491  	expectPrinted(t, "a { color: #112234ff }", "a {\n  color: #112234ff;\n}\n", "")
   492  	expectPrinted(t, "a { color: #112233ef }", "a {\n  color: #112233ef;\n}\n", "")
   493  
   494  	expectPrintedMangle(t, "a { color: #112233ff }", "a {\n  color: #123;\n}\n", "")
   495  	expectPrintedMangle(t, "a { color: #122233ff }", "a {\n  color: #122233;\n}\n", "")
   496  	expectPrintedMangle(t, "a { color: #112333ff }", "a {\n  color: #112333;\n}\n", "")
   497  	expectPrintedMangle(t, "a { color: #112234ff }", "a {\n  color: #112234;\n}\n", "")
   498  	expectPrintedMangle(t, "a { color: #112233ef }", "a {\n  color: #112233ef;\n}\n", "")
   499  
   500  	expectPrinted(t, "a { color: #aabbccff }", "a {\n  color: #aabbccff;\n}\n", "")
   501  	expectPrinted(t, "a { color: #abbbccff }", "a {\n  color: #abbbccff;\n}\n", "")
   502  	expectPrinted(t, "a { color: #aabcccff }", "a {\n  color: #aabcccff;\n}\n", "")
   503  	expectPrinted(t, "a { color: #aabbcdff }", "a {\n  color: #aabbcdff;\n}\n", "")
   504  	expectPrinted(t, "a { color: #aabbccef }", "a {\n  color: #aabbccef;\n}\n", "")
   505  
   506  	expectPrintedMangle(t, "a { color: #aabbccff }", "a {\n  color: #abc;\n}\n", "")
   507  	expectPrintedMangle(t, "a { color: #abbbccff }", "a {\n  color: #abbbcc;\n}\n", "")
   508  	expectPrintedMangle(t, "a { color: #aabcccff }", "a {\n  color: #aabccc;\n}\n", "")
   509  	expectPrintedMangle(t, "a { color: #aabbcdff }", "a {\n  color: #aabbcd;\n}\n", "")
   510  	expectPrintedMangle(t, "a { color: #aabbccef }", "a {\n  color: #aabbccef;\n}\n", "")
   511  
   512  	expectPrinted(t, "a { color: #AABBCCFF }", "a {\n  color: #AABBCCFF;\n}\n", "")
   513  	expectPrinted(t, "a { color: #ABBBCCFF }", "a {\n  color: #ABBBCCFF;\n}\n", "")
   514  	expectPrinted(t, "a { color: #AABCCCFF }", "a {\n  color: #AABCCCFF;\n}\n", "")
   515  	expectPrinted(t, "a { color: #AABBCDFF }", "a {\n  color: #AABBCDFF;\n}\n", "")
   516  	expectPrinted(t, "a { color: #AABBCCEF }", "a {\n  color: #AABBCCEF;\n}\n", "")
   517  
   518  	expectPrintedMangle(t, "a { color: #AABBCCFF }", "a {\n  color: #abc;\n}\n", "")
   519  	expectPrintedMangle(t, "a { color: #ABBBCCFF }", "a {\n  color: #abbbcc;\n}\n", "")
   520  	expectPrintedMangle(t, "a { color: #AABCCCFF }", "a {\n  color: #aabccc;\n}\n", "")
   521  	expectPrintedMangle(t, "a { color: #AABBCDFF }", "a {\n  color: #aabbcd;\n}\n", "")
   522  	expectPrintedMangle(t, "a { color: #AABBCCEF }", "a {\n  color: #aabbccef;\n}\n", "")
   523  }
   524  
   525  func TestColorFunctions(t *testing.T) {
   526  	expectPrinted(t, "a { color: color(display-p3 0.5 0.0 0.0%) }", "a {\n  color: color(display-p3 0.5 0.0 0.0%);\n}\n", "")
   527  	expectPrinted(t, "a { color: color(display-p3 0.5 0.0 0.0% / 0.5) }", "a {\n  color: color(display-p3 0.5 0.0 0.0% / 0.5);\n}\n", "")
   528  
   529  	// Check minification of tokens
   530  	expectPrintedMangle(t, "a { color: color(display-p3 0.5 0.0 0.0%) }", "a {\n  color: color(display-p3 .5 0 0%);\n}\n", "")
   531  	expectPrintedMangle(t, "a { color: color(display-p3 0.5 0.0 0.0% / 0.5) }", "a {\n  color: color(display-p3 .5 0 0% / .5);\n}\n", "")
   532  
   533  	// Check out-of-range colors
   534  	expectPrintedLower(t, "a { before: 0; color: color(display-p3 1 0 0); after: 1 }",
   535  		"a {\n  before: 0;\n  color: #ff0f0e;\n  color: color(display-p3 1 0 0);\n  after: 1;\n}\n", "")
   536  	expectPrintedLowerMangle(t, "a { before: 0; color: color(display-p3 1 0 0); after: 1 }",
   537  		"a {\n  before: 0;\n  color: #ff0f0e;\n  color: color(display-p3 1 0 0);\n  after: 1;\n}\n", "")
   538  	expectPrintedLower(t, "a { before: 0; color: color(display-p3 1 0 0 / 0.5); after: 1 }",
   539  		"a {\n  before: 0;\n  color: rgba(255, 15, 14, .5);\n  color: color(display-p3 1 0 0 / 0.5);\n  after: 1;\n}\n", "")
   540  	expectPrintedLowerMangle(t, "a { before: 0; color: color(display-p3 1 0 0 / 0.5); after: 1 }",
   541  		"a {\n  before: 0;\n  color: rgba(255, 15, 14, .5);\n  color: color(display-p3 1 0 0 / .5);\n  after: 1;\n}\n", "")
   542  	expectPrintedLower(t, "a { before: 0; background: color(display-p3 1 0 0); after: 1 }",
   543  		"a {\n  before: 0;\n  background: #ff0f0e;\n  background: color(display-p3 1 0 0);\n  after: 1;\n}\n", "")
   544  	expectPrintedLowerMangle(t, "a { before: 0; background: color(display-p3 1 0 0); after: 1 }",
   545  		"a {\n  before: 0;\n  background: #ff0f0e;\n  background: color(display-p3 1 0 0);\n  after: 1;\n}\n", "")
   546  	expectPrintedLower(t, "a { before: 0; background: color(display-p3 1 0 0 / 0.5); after: 1 }",
   547  		"a {\n  before: 0;\n  background: rgba(255, 15, 14, .5);\n  background: color(display-p3 1 0 0 / 0.5);\n  after: 1;\n}\n", "")
   548  	expectPrintedLowerMangle(t, "a { before: 0; background: color(display-p3 1 0 0 / 0.5); after: 1 }",
   549  		"a {\n  before: 0;\n  background: rgba(255, 15, 14, .5);\n  background: color(display-p3 1 0 0 / .5);\n  after: 1;\n}\n", "")
   550  	expectPrintedLower(t, "a { before: 0; box-shadow: 1px color(display-p3 1 0 0); after: 1 }",
   551  		"a {\n  before: 0;\n  box-shadow: 1px #ff0f0e;\n  box-shadow: 1px color(display-p3 1 0 0);\n  after: 1;\n}\n", "")
   552  	expectPrintedLowerMangle(t, "a { before: 0; box-shadow: 1px color(display-p3 1 0 0); after: 1 }",
   553  		"a {\n  before: 0;\n  box-shadow: 1px #ff0f0e;\n  box-shadow: 1px color(display-p3 1 0 0);\n  after: 1;\n}\n", "")
   554  	expectPrintedLower(t, "a { before: 0; box-shadow: 1px color(display-p3 1 0 0 / 0.5); after: 1 }",
   555  		"a {\n  before: 0;\n  box-shadow: 1px rgba(255, 15, 14, .5);\n  box-shadow: 1px color(display-p3 1 0 0 / 0.5);\n  after: 1;\n}\n", "")
   556  	expectPrintedLowerMangle(t, "a { before: 0; box-shadow: 1px color(display-p3 1 0 0 / 0.5); after: 1 }",
   557  		"a {\n  before: 0;\n  box-shadow: 1px rgba(255, 15, 14, .5);\n  box-shadow: 1px color(display-p3 1 0 0 / .5);\n  after: 1;\n}\n", "")
   558  
   559  	// Don't insert a fallback after a previous instance of the same property
   560  	expectPrintedLower(t, "a { color: red; color: color(display-p3 1 0 0) }",
   561  		"a {\n  color: red;\n  color: color(display-p3 1 0 0);\n}\n", "")
   562  	expectPrintedLower(t, "a { color: color(display-p3 1 0 0); color: color(display-p3 0 1 0) }",
   563  		"a {\n  color: #ff0f0e;\n  color: color(display-p3 1 0 0);\n  color: color(display-p3 0 1 0);\n}\n", "")
   564  
   565  	// Check case sensitivity
   566  	expectPrintedLower(t, "a { color: color(srgb 0.87 0.98 0.807) }", "a {\n  color: #deface;\n}\n", "")
   567  	expectPrintedLower(t, "A { Color: Color(Srgb 0.87 0.98 0.807) }", "A {\n  Color: #deface;\n}\n", "")
   568  	expectPrintedLower(t, "A { COLOR: COLOR(SRGB 0.87 0.98 0.807) }", "A {\n  COLOR: #deface;\n}\n", "")
   569  
   570  	// Check in-range colors in various color spaces
   571  	expectPrintedLower(t, "a { color: color(a98-rgb 0.9 0.98 0.81) }", "a {\n  color: #deface;\n}\n", "")
   572  	expectPrintedLower(t, "a { color: color(a98-rgb 90% 98% 81%) }", "a {\n  color: #deface;\n}\n", "")
   573  	expectPrintedLower(t, "a { color: color(display-p3 0.89 0.977 0.823) }", "a {\n  color: #deface;\n}\n", "")
   574  	expectPrintedLower(t, "a { color: color(display-p3 89% 97.7% 82.3%) }", "a {\n  color: #deface;\n}\n", "")
   575  	expectPrintedLower(t, "a { color: color(prophoto-rgb 0.877 0.959 0.793) }", "a {\n  color: #deface;\n}\n", "")
   576  	expectPrintedLower(t, "a { color: color(prophoto-rgb 87.7% 95.9% 79.3%) }", "a {\n  color: #deface;\n}\n", "")
   577  	expectPrintedLower(t, "a { color: color(rec2020 0.895 0.968 0.805) }", "a {\n  color: #deface;\n}\n", "")
   578  	expectPrintedLower(t, "a { color: color(rec2020 89.5% 96.8% 80.5%) }", "a {\n  color: #deface;\n}\n", "")
   579  	expectPrintedLower(t, "a { color: color(srgb 0.87 0.98 0.807) }", "a {\n  color: #deface;\n}\n", "")
   580  	expectPrintedLower(t, "a { color: color(srgb 87% 98% 80.7%) }", "a {\n  color: #deface;\n}\n", "")
   581  	expectPrintedLower(t, "a { color: color(srgb-linear 0.73 0.96 0.62) }", "a {\n  color: #deface;\n}\n", "")
   582  	expectPrintedLower(t, "a { color: color(srgb-linear 73% 96% 62%) }", "a {\n  color: #deface;\n}\n", "")
   583  	expectPrintedLower(t, "a { color: color(xyz 0.754 0.883 0.715) }", "a {\n  color: #deface;\n}\n", "")
   584  	expectPrintedLower(t, "a { color: color(xyz 75.4% 88.3% 71.5%) }", "a {\n  color: #deface;\n}\n", "")
   585  	expectPrintedLower(t, "a { color: color(xyz-d50 0.773 0.883 0.545) }", "a {\n  color: #deface;\n}\n", "")
   586  	expectPrintedLower(t, "a { color: color(xyz-d50 77.3% 88.3% 54.5%) }", "a {\n  color: #deface;\n}\n", "")
   587  	expectPrintedLower(t, "a { color: color(xyz-d65 0.754 0.883 0.715) }", "a {\n  color: #deface;\n}\n", "")
   588  	expectPrintedLower(t, "a { color: color(xyz-d65 75.4% 88.3% 71.5%) }", "a {\n  color: #deface;\n}\n", "")
   589  
   590  	// Check color functions with unusual percent reference ranges
   591  	expectPrintedLower(t, "a { color: lab(95.38 -15 18) }", "a {\n  color: #deface;\n}\n", "")
   592  	expectPrintedLower(t, "a { color: lab(95.38% -15 18) }", "a {\n  color: #deface;\n}\n", "")
   593  	expectPrintedLower(t, "a { color: lab(95.38 -12% 18) }", "a {\n  color: #deface;\n}\n", "")
   594  	expectPrintedLower(t, "a { color: lab(95.38% -15 14.4%) }", "a {\n  color: #deface;\n}\n", "")
   595  	expectPrintedLower(t, "a { color: lch(95.38 23.57 130.22) }", "a {\n  color: #deface;\n}\n", "")
   596  	expectPrintedLower(t, "a { color: lch(95.38% 23.57 130.22) }", "a {\n  color: #deface;\n}\n", "")
   597  	expectPrintedLower(t, "a { color: lch(95.38 19% 130.22) }", "a {\n  color: #deface;\n}\n", "")
   598  	expectPrintedLower(t, "a { color: lch(95.38 23.57 0.362turn) }", "a {\n  color: #deface;\n}\n", "")
   599  	expectPrintedLower(t, "a { color: oklab(0.953 -0.045 0.046) }", "a {\n  color: #deface;\n}\n", "")
   600  	expectPrintedLower(t, "a { color: oklab(95.3% -0.045 0.046) }", "a {\n  color: #deface;\n}\n", "")
   601  	expectPrintedLower(t, "a { color: oklab(0.953 -11.2% 0.046) }", "a {\n  color: #deface;\n}\n", "")
   602  	expectPrintedLower(t, "a { color: oklab(0.953 -0.045 11.5%) }", "a {\n  color: #deface;\n}\n", "")
   603  	expectPrintedLower(t, "a { color: oklch(0.953 0.064 134) }", "a {\n  color: #deface;\n}\n", "")
   604  	expectPrintedLower(t, "a { color: oklch(95.3% 0.064 134) }", "a {\n  color: #deface;\n}\n", "")
   605  	expectPrintedLower(t, "a { color: oklch(0.953 16% 134) }", "a {\n  color: #deface;\n}\n", "")
   606  	expectPrintedLower(t, "a { color: oklch(0.953 0.064 0.372turn) }", "a {\n  color: #deface;\n}\n", "")
   607  
   608  	// Test alpha
   609  	expectPrintedLower(t, "a { color: color(srgb 0.87 0.98 0.807 / 0.5) }", "a {\n  color: rgba(222, 250, 206, .5);\n}\n", "")
   610  	expectPrintedLower(t, "a { color: lab(95.38 -15 18 / 0.5) }", "a {\n  color: rgba(222, 250, 206, .5);\n}\n", "")
   611  	expectPrintedLower(t, "a { color: lch(95.38 23.57 130.22 / 0.5) }", "a {\n  color: rgba(222, 250, 206, .5);\n}\n", "")
   612  	expectPrintedLower(t, "a { color: oklab(0.953 -0.045 0.046 / 0.5) }", "a {\n  color: rgba(222, 250, 206, .5);\n}\n", "")
   613  	expectPrintedLower(t, "a { color: oklch(0.953 0.064 134 / 0.5) }", "a {\n  color: rgba(222, 250, 206, .5);\n}\n", "")
   614  }
   615  
   616  func TestColorNames(t *testing.T) {
   617  	expectPrinted(t, "a { color: #f00 }", "a {\n  color: #f00;\n}\n", "")
   618  	expectPrinted(t, "a { color: #f00f }", "a {\n  color: #f00f;\n}\n", "")
   619  	expectPrinted(t, "a { color: #ff0000 }", "a {\n  color: #ff0000;\n}\n", "")
   620  	expectPrinted(t, "a { color: #ff0000ff }", "a {\n  color: #ff0000ff;\n}\n", "")
   621  
   622  	expectPrintedMangle(t, "a { color: #f00 }", "a {\n  color: red;\n}\n", "")
   623  	expectPrintedMangle(t, "a { color: #f00e }", "a {\n  color: #f00e;\n}\n", "")
   624  	expectPrintedMangle(t, "a { color: #f00f }", "a {\n  color: red;\n}\n", "")
   625  	expectPrintedMangle(t, "a { color: #ff0000 }", "a {\n  color: red;\n}\n", "")
   626  	expectPrintedMangle(t, "a { color: #ff0000ef }", "a {\n  color: #ff0000ef;\n}\n", "")
   627  	expectPrintedMangle(t, "a { color: #ff0000ff }", "a {\n  color: red;\n}\n", "")
   628  	expectPrintedMangle(t, "a { color: #ffc0cb }", "a {\n  color: pink;\n}\n", "")
   629  	expectPrintedMangle(t, "a { color: #ffc0cbef }", "a {\n  color: #ffc0cbef;\n}\n", "")
   630  	expectPrintedMangle(t, "a { color: #ffc0cbff }", "a {\n  color: pink;\n}\n", "")
   631  
   632  	expectPrinted(t, "a { color: white }", "a {\n  color: white;\n}\n", "")
   633  	expectPrinted(t, "a { color: tUrQuOiSe }", "a {\n  color: tUrQuOiSe;\n}\n", "")
   634  
   635  	expectPrintedMangle(t, "a { color: white }", "a {\n  color: #fff;\n}\n", "")
   636  	expectPrintedMangle(t, "a { color: tUrQuOiSe }", "a {\n  color: #40e0d0;\n}\n", "")
   637  }
   638  
   639  func TestColorRGBA(t *testing.T) {
   640  	expectPrintedMangle(t, "a { color: rgba(1 2 3 / 0.5) }", "a {\n  color: #01020380;\n}\n", "")
   641  	expectPrintedMangle(t, "a { color: rgba(1 2 3 / 50%) }", "a {\n  color: #0102037f;\n}\n", "")
   642  	expectPrintedMangle(t, "a { color: rgba(1, 2, 3, 0.5) }", "a {\n  color: #01020380;\n}\n", "")
   643  	expectPrintedMangle(t, "a { color: rgba(1, 2, 3, 50%) }", "a {\n  color: #0102037f;\n}\n", "")
   644  	expectPrintedMangle(t, "a { color: rgba(1% 2% 3% / 0.5) }", "a {\n  color: #03050880;\n}\n", "")
   645  	expectPrintedMangle(t, "a { color: rgba(1% 2% 3% / 50%) }", "a {\n  color: #0305087f;\n}\n", "")
   646  	expectPrintedMangle(t, "a { color: rgba(1%, 2%, 3%, 0.5) }", "a {\n  color: #03050880;\n}\n", "")
   647  	expectPrintedMangle(t, "a { color: rgba(1%, 2%, 3%, 50%) }", "a {\n  color: #0305087f;\n}\n", "")
   648  
   649  	expectPrintedLowerMangle(t, "a { color: rgb(1, 2, 3, 0.4) }", "a {\n  color: rgba(1, 2, 3, .4);\n}\n", "")
   650  	expectPrintedLowerMangle(t, "a { color: rgba(1, 2, 3, 40%) }", "a {\n  color: rgba(1, 2, 3, .4);\n}\n", "")
   651  
   652  	expectPrintedLowerMangle(t, "a { color: rgb(var(--x) var(--y) var(--z)) }", "a {\n  color: rgb(var(--x) var(--y) var(--z));\n}\n", "")
   653  }
   654  
   655  func TestColorHSLA(t *testing.T) {
   656  	expectPrintedMangle(t, ".red { color: hsl(0, 100%, 50%) }", ".red {\n  color: red;\n}\n", "")
   657  	expectPrintedMangle(t, ".orange { color: hsl(30deg, 100%, 50%) }", ".orange {\n  color: #ff8000;\n}\n", "")
   658  	expectPrintedMangle(t, ".yellow { color: hsl(60 100% 50%) }", ".yellow {\n  color: #ff0;\n}\n", "")
   659  	expectPrintedMangle(t, ".green { color: hsl(120, 100%, 50%) }", ".green {\n  color: #0f0;\n}\n", "")
   660  	expectPrintedMangle(t, ".cyan { color: hsl(200grad, 100%, 50%) }", ".cyan {\n  color: #0ff;\n}\n", "")
   661  	expectPrintedMangle(t, ".blue { color: hsl(240, 100%, 50%) }", ".blue {\n  color: #00f;\n}\n", "")
   662  	expectPrintedMangle(t, ".purple { color: hsl(0.75turn 100% 50%) }", ".purple {\n  color: #7f00ff;\n}\n", "")
   663  	expectPrintedMangle(t, ".magenta { color: hsl(300, 100%, 50%) }", ".magenta {\n  color: #f0f;\n}\n", "")
   664  
   665  	expectPrintedMangle(t, "a { color: hsl(30 25% 50% / 50%) }", "a {\n  color: #9f80607f;\n}\n", "")
   666  	expectPrintedMangle(t, "a { color: hsla(30 25% 50% / 50%) }", "a {\n  color: #9f80607f;\n}\n", "")
   667  
   668  	expectPrintedLowerMangle(t, "a { color: hsl(1, 2%, 3%, 0.4) }", "a {\n  color: rgba(8, 8, 7, .4);\n}\n", "")
   669  	expectPrintedLowerMangle(t, "a { color: hsla(1, 2%, 3%, 40%) }", "a {\n  color: rgba(8, 8, 7, .4);\n}\n", "")
   670  
   671  	expectPrintedLowerMangle(t, "a { color: hsl(var(--x) var(--y) var(--z)) }", "a {\n  color: hsl(var(--x) var(--y) var(--z));\n}\n", "")
   672  }
   673  
   674  func TestLowerColor(t *testing.T) {
   675  	expectPrintedLower(t, "a { color: rebeccapurple }", "a {\n  color: #663399;\n}\n", "")
   676  	expectPrintedLower(t, "a { color: ReBeCcApUrPlE }", "a {\n  color: #663399;\n}\n", "")
   677  
   678  	expectPrintedLower(t, "a { color: #0123 }", "a {\n  color: rgba(0, 17, 34, .2);\n}\n", "")
   679  	expectPrintedLower(t, "a { color: #1230 }", "a {\n  color: rgba(17, 34, 51, 0);\n}\n", "")
   680  	expectPrintedLower(t, "a { color: #1234 }", "a {\n  color: rgba(17, 34, 51, .267);\n}\n", "")
   681  	expectPrintedLower(t, "a { color: #123f }", "a {\n  color: #112233;\n}\n", "")
   682  	expectPrintedLower(t, "a { color: #12345678 }", "a {\n  color: rgba(18, 52, 86, .47);\n}\n", "")
   683  	expectPrintedLower(t, "a { color: #ff00007f }", "a {\n  color: rgba(255, 0, 0, .498);\n}\n", "")
   684  
   685  	expectPrintedLower(t, "a { color: rgb(1 2 3) }", "a {\n  color: rgb(1, 2, 3);\n}\n", "")
   686  	expectPrintedLower(t, "a { color: hsl(1 2% 3%) }", "a {\n  color: hsl(1, 2%, 3%);\n}\n", "")
   687  	expectPrintedLower(t, "a { color: rgba(1% 2% 3%) }", "a {\n  color: rgb(1%, 2%, 3%);\n}\n", "")
   688  	expectPrintedLower(t, "a { color: hsla(1deg 2% 3%) }", "a {\n  color: hsl(1, 2%, 3%);\n}\n", "")
   689  
   690  	expectPrintedLower(t, "a { color: hsla(200grad 2% 3%) }", "a {\n  color: hsl(180, 2%, 3%);\n}\n", "")
   691  	expectPrintedLower(t, "a { color: hsla(6.28319rad 2% 3%) }", "a {\n  color: hsl(360, 2%, 3%);\n}\n", "")
   692  	expectPrintedLower(t, "a { color: hsla(0.5turn 2% 3%) }", "a {\n  color: hsl(180, 2%, 3%);\n}\n", "")
   693  	expectPrintedLower(t, "a { color: hsla(+200grad 2% 3%) }", "a {\n  color: hsl(180, 2%, 3%);\n}\n", "")
   694  	expectPrintedLower(t, "a { color: hsla(-200grad 2% 3%) }", "a {\n  color: hsl(-180, 2%, 3%);\n}\n", "")
   695  
   696  	expectPrintedLower(t, "a { color: rgb(1 2 3 / 4) }", "a {\n  color: rgba(1, 2, 3, 4);\n}\n", "")
   697  	expectPrintedLower(t, "a { color: RGB(1 2 3 / 4) }", "a {\n  color: rgba(1, 2, 3, 4);\n}\n", "")
   698  	expectPrintedLower(t, "a { color: rgba(1% 2% 3% / 4%) }", "a {\n  color: rgba(1%, 2%, 3%, 0.04);\n}\n", "")
   699  	expectPrintedLower(t, "a { color: RGBA(1% 2% 3% / 4%) }", "a {\n  color: RGBA(1%, 2%, 3%, 0.04);\n}\n", "")
   700  	expectPrintedLower(t, "a { color: hsl(1 2% 3% / 4) }", "a {\n  color: hsla(1, 2%, 3%, 4);\n}\n", "")
   701  	expectPrintedLower(t, "a { color: HSL(1 2% 3% / 4) }", "a {\n  color: hsla(1, 2%, 3%, 4);\n}\n", "")
   702  	expectPrintedLower(t, "a { color: hsla(1 2% 3% / 4%) }", "a {\n  color: hsla(1, 2%, 3%, 0.04);\n}\n", "")
   703  	expectPrintedLower(t, "a { color: HSLA(1 2% 3% / 4%) }", "a {\n  color: HSLA(1, 2%, 3%, 0.04);\n}\n", "")
   704  
   705  	expectPrintedLower(t, "a { color: rgb(1, 2, 3, 4) }", "a {\n  color: rgba(1, 2, 3, 4);\n}\n", "")
   706  	expectPrintedLower(t, "a { color: rgba(1%, 2%, 3%, 4%) }", "a {\n  color: rgba(1%, 2%, 3%, 0.04);\n}\n", "")
   707  	expectPrintedLower(t, "a { color: rgb(1%, 2%, 3%, 0.4%) }", "a {\n  color: rgba(1%, 2%, 3%, 0.004);\n}\n", "")
   708  
   709  	expectPrintedLower(t, "a { color: hsl(1, 2%, 3%, 4) }", "a {\n  color: hsla(1, 2%, 3%, 4);\n}\n", "")
   710  	expectPrintedLower(t, "a { color: hsla(1deg, 2%, 3%, 4%) }", "a {\n  color: hsla(1, 2%, 3%, 0.04);\n}\n", "")
   711  	expectPrintedLower(t, "a { color: hsl(1deg, 2%, 3%, 0.4%) }", "a {\n  color: hsla(1, 2%, 3%, 0.004);\n}\n", "")
   712  
   713  	expectPrintedLower(t, "a { color: hwb(90deg 20% 40%) }", "a {\n  color: #669933;\n}\n", "")
   714  	expectPrintedLower(t, "a { color: HWB(90deg 20% 40%) }", "a {\n  color: #669933;\n}\n", "")
   715  	expectPrintedLower(t, "a { color: hwb(90deg 20% 40% / 0.2) }", "a {\n  color: rgba(102, 153, 51, .2);\n}\n", "")
   716  	expectPrintedLower(t, "a { color: hwb(1deg 40% 80%) }", "a {\n  color: #555555;\n}\n", "")
   717  	expectPrintedLower(t, "a { color: hwb(1deg 9000% 50%) }", "a {\n  color: #aaaaaa;\n}\n", "")
   718  	expectPrintedLower(t, "a { color: hwb(1deg 9000% 50% / 0.6) }", "a {\n  color: rgba(170, 170, 170, .6);\n}\n", "")
   719  	expectPrintedLower(t, "a { color: hwb(90deg, 20%, 40%) }", "a {\n  color: hwb(90deg, 20%, 40%);\n}\n", "") // This is invalid
   720  	expectPrintedLower(t, "a { color: hwb(none 20% 40%) }", "a {\n  color: hwb(none 20% 40%);\n}\n", "")       // Interpolation
   721  	expectPrintedLower(t, "a { color: hwb(90deg none 40%) }", "a {\n  color: hwb(90deg none 40%);\n}\n", "")   // Interpolation
   722  	expectPrintedLower(t, "a { color: hwb(90deg 20% none) }", "a {\n  color: hwb(90deg 20% none);\n}\n", "")   // Interpolation
   723  
   724  	expectPrintedMangle(t, "a { color: hwb(90deg 20% 40%) }", "a {\n  color: #693;\n}\n", "")
   725  	expectPrintedMangle(t, "a { color: hwb(0.75turn 20% 40% / 0.75) }", "a {\n  color: #663399bf;\n}\n", "")
   726  	expectPrintedLowerMangle(t, "a { color: hwb(90deg 20% 40%) }", "a {\n  color: #693;\n}\n", "")
   727  	expectPrintedLowerMangle(t, "a { color: hwb(0.75turn 20% 40% / 0.75) }", "a {\n  color: rgba(102, 51, 153, .75);\n}\n", "")
   728  }
   729  
   730  func TestBackground(t *testing.T) {
   731  	expectPrinted(t, "a { background: #11223344 }", "a {\n  background: #11223344;\n}\n", "")
   732  	expectPrintedMangle(t, "a { background: #11223344 }", "a {\n  background: #1234;\n}\n", "")
   733  	expectPrintedLower(t, "a { background: #11223344 }", "a {\n  background: rgba(17, 34, 51, .267);\n}\n", "")
   734  
   735  	expectPrinted(t, "a { background: border-box #11223344 }", "a {\n  background: border-box #11223344;\n}\n", "")
   736  	expectPrintedMangle(t, "a { background: border-box #11223344 }", "a {\n  background: border-box #1234;\n}\n", "")
   737  	expectPrintedLower(t, "a { background: border-box #11223344 }", "a {\n  background: border-box rgba(17, 34, 51, .267);\n}\n", "")
   738  }
   739  
   740  func TestGradient(t *testing.T) {
   741  	gradientKinds := []string{
   742  		"linear-gradient",
   743  		"radial-gradient",
   744  		"conic-gradient",
   745  		"repeating-linear-gradient",
   746  		"repeating-radial-gradient",
   747  		"repeating-conic-gradient",
   748  	}
   749  
   750  	for _, gradient := range gradientKinds {
   751  		var code string
   752  
   753  		// Different properties
   754  		expectPrinted(t, "a { background: "+gradient+"(red, blue) }", "a {\n  background: "+gradient+"(red, blue);\n}\n", "")
   755  		expectPrinted(t, "a { background-image: "+gradient+"(red, blue) }", "a {\n  background-image: "+gradient+"(red, blue);\n}\n", "")
   756  		expectPrinted(t, "a { border-image: "+gradient+"(red, blue) }", "a {\n  border-image: "+gradient+"(red, blue);\n}\n", "")
   757  		expectPrinted(t, "a { mask-image: "+gradient+"(red, blue) }", "a {\n  mask-image: "+gradient+"(red, blue);\n}\n", "")
   758  
   759  		// Basic
   760  		code = "a { background: " + gradient + "(yellow, #11223344) }"
   761  		expectPrinted(t, code, "a {\n  background: "+gradient+"(yellow, #11223344);\n}\n", "")
   762  		expectPrintedMangle(t, code, "a {\n  background: "+gradient+"(#ff0, #1234);\n}\n", "")
   763  		expectPrintedMinify(t, code, "a{background:"+gradient+"(yellow,#11223344)}", "")
   764  		expectPrintedLowerUnsupported(t, compat.HexRGBA, code,
   765  			"a {\n  background: "+gradient+"(yellow, rgba(17, 34, 51, .267));\n}\n", "")
   766  
   767  		// Basic with positions
   768  		code = "a { background: " + gradient + "(yellow 10%, #11223344 90%) }"
   769  		expectPrinted(t, code, "a {\n  background: "+gradient+"(yellow 10%, #11223344 90%);\n}\n", "")
   770  		expectPrintedMangle(t, code, "a {\n  background: "+gradient+"(#ff0 10%, #1234 90%);\n}\n", "")
   771  		expectPrintedMinify(t, code, "a{background:"+gradient+"(yellow 10%,#11223344 90%)}", "")
   772  		expectPrintedLowerUnsupported(t, compat.HexRGBA, code,
   773  			"a {\n  background: "+gradient+"(yellow 10%, rgba(17, 34, 51, .267) 90%);\n}\n", "")
   774  
   775  		// Basic with hints
   776  		code = "a { background: " + gradient + "(yellow, 25%, #11223344) }"
   777  		expectPrinted(t, code, "a {\n  background:\n    "+gradient+"(\n      yellow,\n      25%,\n      #11223344);\n}\n", "")
   778  		expectPrintedMangle(t, code, "a {\n  background:\n    "+gradient+"(\n      #ff0,\n      25%,\n      #1234);\n}\n", "")
   779  		expectPrintedMinify(t, code, "a{background:"+gradient+"(yellow,25%,#11223344)}", "")
   780  		expectPrintedLowerUnsupported(t, compat.HexRGBA, code,
   781  			"a {\n  background:\n    "+gradient+"(\n      yellow,\n      25%,\n      rgba(17, 34, 51, .267));\n}\n", "")
   782  		expectPrintedLowerUnsupported(t, compat.GradientMidpoints, code,
   783  			"a {\n  background:\n    "+gradient+"(\n      #ffff00,\n      #f2f303de,\n      #eced04d0 6.25%,\n      "+
   784  				"#e1e306bd 12.5%,\n      #cdd00ba2 25%,\n      #a2a8147b,\n      #6873205d,\n      #11223344);\n}\n", "")
   785  
   786  		// Double positions
   787  		code = "a { background: " + gradient + "(green, red 10%, red 20%, yellow 70% 80%, black) }"
   788  		expectPrinted(t, code, "a {\n  background:\n    "+gradient+"(\n      green,\n      red 10%,\n      "+
   789  			"red 20%,\n      yellow 70% 80%,\n      black);\n}\n", "")
   790  		expectPrintedMangle(t, code, "a {\n  background:\n    "+gradient+"(\n      green,\n      "+
   791  			"red 10% 20%,\n      #ff0 70% 80%,\n      #000);\n}\n", "")
   792  		expectPrintedMinify(t, code, "a{background:"+gradient+"(green,red 10%,red 20%,yellow 70% 80%,black)}", "")
   793  		expectPrintedLowerUnsupported(t, compat.GradientDoublePosition, code,
   794  			"a {\n  background:\n    "+gradient+"(\n      green,\n      red 10%,\n      red 20%,\n      "+
   795  				"yellow 70%,\n      yellow 80%,\n      black);\n}\n", "")
   796  
   797  		// Double positions with hints
   798  		code = "a { background: " + gradient + "(green, red 10%, red 20%, 30%, yellow 70% 80%, 85%, black) }"
   799  		expectPrinted(t, code, "a {\n  background:\n    "+gradient+"(\n      green,\n      red 10%,\n      red 20%,\n      "+
   800  			"30%,\n      yellow 70% 80%,\n      85%,\n      black);\n}\n", "")
   801  		expectPrintedMangle(t, code, "a {\n  background:\n    "+gradient+"(\n      green,\n      red 10% 20%,\n      "+
   802  			"30%,\n      #ff0 70% 80%,\n      85%,\n      #000);\n}\n", "")
   803  		expectPrintedMinify(t, code, "a{background:"+gradient+"(green,red 10%,red 20%,30%,yellow 70% 80%,85%,black)}", "")
   804  		expectPrintedLowerUnsupported(t, compat.GradientDoublePosition, code,
   805  			"a {\n  background:\n    "+gradient+"(\n      green,\n      red 10%,\n      red 20%,\n      30%,\n      "+
   806  				"yellow 70%,\n      yellow 80%,\n      85%,\n      black);\n}\n", "")
   807  
   808  		// Non-double positions with hints
   809  		code = "a { background: " + gradient + "(green, red 10%, 1%, red 20%, black) }"
   810  		expectPrinted(t, code, "a {\n  background:\n    "+gradient+"(\n      green,\n      red 10%,\n      1%,\n      "+
   811  			"red 20%,\n      black);\n}\n", "")
   812  		expectPrintedMangle(t, code, "a {\n  background:\n    "+gradient+"(\n      green,\n      red 10%,\n      "+
   813  			"1%,\n      red 20%,\n      #000);\n}\n", "")
   814  		expectPrintedMinify(t, code, "a{background:"+gradient+"(green,red 10%,1%,red 20%,black)}", "")
   815  		expectPrintedLowerUnsupported(t, compat.GradientDoublePosition, code,
   816  			"a {\n  background:\n    "+gradient+"(\n      green,\n      red 10%,\n      1%,\n      red 20%,\n      black);\n}\n", "")
   817  
   818  		// Out-of-gamut colors
   819  		code = "a { background: " + gradient + "(yellow, color(display-p3 1 0 0)) }"
   820  		expectPrinted(t, code, "a {\n  background: "+gradient+"(yellow, color(display-p3 1 0 0));\n}\n", "")
   821  		expectPrintedMangle(t, code, "a {\n  background: "+gradient+"(#ff0, color(display-p3 1 0 0));\n}\n", "")
   822  		expectPrintedMinify(t, code, "a{background:"+gradient+"(yellow,color(display-p3 1 0 0))}", "")
   823  		expectPrintedLowerUnsupported(t, compat.ColorFunctions, code,
   824  			"a {\n  background:\n    "+gradient+"(\n      #ffff00,\n      #ffe971,\n      #ffd472 25%,\n      "+
   825  				"#ffab5f,\n      #ff7b45 75%,\n      #ff5e38 87.5%,\n      #ff5534,\n      #ff4c30,\n      "+
   826  				"#ff412c,\n      #ff0e0e);\n  "+
   827  				"background:\n    "+gradient+"(\n      #ffff00,\n      color(xyz 0.734 0.805 0.111),\n      "+
   828  				"color(xyz 0.699 0.693 0.087) 25%,\n      color(xyz 0.627 0.501 0.048),\n      "+
   829  				"color(xyz 0.556 0.348 0.019) 75%,\n      color(xyz 0.521 0.284 0.009) 87.5%,\n      "+
   830  				"color(xyz 0.512 0.27 0.006),\n      color(xyz 0.504 0.256 0.004),\n      "+
   831  				"color(xyz 0.495 0.242 0.002),\n      color(xyz 0.487 0.229 0));\n}\n", "")
   832  
   833  		// Whitespace
   834  		code = "a { background: " + gradient + "(color-mix(in lab,red,green)calc(1px)calc(2px),color-mix(in lab,blue,red)calc(98%)calc(99%)) }"
   835  		expectPrinted(t, code, "a {\n  background: "+gradient+
   836  			"(color-mix(in lab, red, green)calc(1px)calc(2px), color-mix(in lab, blue, red)calc(98%)calc(99%));\n}\n", "")
   837  		expectPrintedMangle(t, code, "a {\n  background: "+gradient+
   838  			"(color-mix(in lab, red, green) 1px 2px, color-mix(in lab, blue, red) 98% 99%);\n}\n", "")
   839  		expectPrintedMinify(t, code, "a{background:"+gradient+
   840  			"(color-mix(in lab,red,green)calc(1px)calc(2px),color-mix(in lab,blue,red)calc(98%)calc(99%))}", "")
   841  		expectPrintedLowerUnsupported(t, compat.GradientDoublePosition, code, "a {\n  background:\n    "+gradient+
   842  			"(\n      color-mix(in lab, red, green) calc(1px),\n      color-mix(in lab, red, green) calc(2px),"+
   843  			"\n      color-mix(in lab, blue, red) calc(98%),\n      color-mix(in lab, blue, red) calc(99%));\n}\n", "")
   844  		expectPrintedLowerMangle(t, code, "a {\n  background:\n    "+gradient+
   845  			"(\n      color-mix(in lab, red, green) 1px,\n      color-mix(in lab, red, green) 2px,"+
   846  			"\n      color-mix(in lab, blue, red) 98%,\n      color-mix(in lab, blue, red) 99%);\n}\n", "")
   847  
   848  		// Color space interpolation
   849  		expectPrintedLowerUnsupported(t, compat.GradientInterpolation,
   850  			"a { background: "+gradient+"(in srgb, red, green) }",
   851  			"a {\n  background: "+gradient+"(#ff0000, #008000);\n}\n", "")
   852  		expectPrintedLowerUnsupported(t, compat.GradientInterpolation,
   853  			"a { background: "+gradient+"(in srgb-linear, red, green) }",
   854  			"a {\n  background:\n    "+gradient+"(\n      #ff0000,\n      #fb1300,\n      #f81f00 6.25%,\n      "+
   855  				"#f02e00 12.5%,\n      #e14200 25%,\n      #bc5c00,\n      #897000 75%,\n      #637800 87.5%,\n      "+
   856  				"#477c00 93.75%,\n      #317e00,\n      #008000);\n}\n", "")
   857  		expectPrintedLowerUnsupported(t, compat.GradientInterpolation,
   858  			"a { background: "+gradient+"(in lab, red, green) }",
   859  			"a {\n  background:\n    "+gradient+"(\n      #ff0000,\n      color(xyz 0.396 0.211 0.019),\n      "+
   860  				"color(xyz 0.38 0.209 0.02) 6.25%,\n      color(xyz 0.35 0.205 0.02) 12.5%,\n      "+
   861  				"color(xyz 0.294 0.198 0.02) 25%,\n      color(xyz 0.2 0.183 0.022),\n      "+
   862  				"color(xyz 0.129 0.168 0.024) 75%,\n      color(xyz 0.101 0.161 0.025) 87.5%,\n      "+
   863  				"color(xyz 0.089 0.158 0.025) 93.75%,\n      color(xyz 0.083 0.156 0.025),\n      #008000);\n}\n", "")
   864  
   865  		// Hue interpolation
   866  		expectPrintedLowerUnsupported(t, compat.GradientInterpolation,
   867  			"a { background: "+gradient+"(in hsl shorter hue, red, green) }",
   868  			"a {\n  background:\n    "+gradient+"(\n      #ff0000,\n      #df7000,\n      "+
   869  				"#bfbf00,\n      #50a000,\n      #008000);\n}\n", "")
   870  		expectPrintedLowerUnsupported(t, compat.GradientInterpolation,
   871  			"a { background: "+gradient+"(in hsl longer hue, red, green) }",
   872  			"a {\n  background:\n    "+gradient+"(\n      #ff0000,\n      #ef0078,\n      "+
   873  				"#df00df,\n      #6800cf,\n      #0000c0,\n      #0058b0,\n      "+
   874  				"#00a0a0,\n      #009048,\n      #008000);\n}\n", "")
   875  	}
   876  }
   877  
   878  func TestDeclaration(t *testing.T) {
   879  	expectPrinted(t, ".decl {}", ".decl {\n}\n", "")
   880  	expectPrinted(t, ".decl { a: b }", ".decl {\n  a: b;\n}\n", "")
   881  	expectPrinted(t, ".decl { a: b; }", ".decl {\n  a: b;\n}\n", "")
   882  	expectPrinted(t, ".decl { a: b; c: d }", ".decl {\n  a: b;\n  c: d;\n}\n", "")
   883  	expectPrinted(t, ".decl { a: b; c: d; }", ".decl {\n  a: b;\n  c: d;\n}\n", "")
   884  	expectPrinted(t, ".decl { a { b: c; } }", ".decl {\n  a {\n    b: c;\n  }\n}\n", "")
   885  	expectPrinted(t, ".decl { & a { b: c; } }", ".decl {\n  & a {\n    b: c;\n  }\n}\n", "")
   886  
   887  	// See http://browserhacks.com/
   888  	expectPrinted(t, ".selector { (;property: value;); }", ".selector {\n  (;property: value;);\n}\n", "<stdin>: WARNING: Expected identifier but found \"(\"\n")
   889  	expectPrinted(t, ".selector { [;property: value;]; }", ".selector {\n  [;property: value;];\n}\n", "<stdin>: WARNING: Expected identifier but found \"[\"\n")
   890  	expectPrinted(t, ".selector, {}", ".selector, {\n}\n", "<stdin>: WARNING: Unexpected \"{\"\n")
   891  	expectPrinted(t, ".selector\\ {}", ".selector\\  {\n}\n", "")
   892  	expectPrinted(t, ".selector { property: value\\9; }", ".selector {\n  property: value\\\t;\n}\n", "")
   893  	expectPrinted(t, "@media \\0screen\\,screen\\9 {}", "@media \uFFFDscreen\\,screen\\\t {\n}\n", "")
   894  }
   895  
   896  func TestSelector(t *testing.T) {
   897  	expectPrinted(t, "a{}", "a {\n}\n", "")
   898  	expectPrinted(t, "a {}", "a {\n}\n", "")
   899  	expectPrinted(t, "a b {}", "a b {\n}\n", "")
   900  
   901  	expectPrinted(t, "a/**/b {}", "ab {\n}\n", "<stdin>: WARNING: Unexpected \"b\"\n")
   902  	expectPrinted(t, "a/**/.b {}", "a.b {\n}\n", "")
   903  	expectPrinted(t, "a/**/:b {}", "a:b {\n}\n", "")
   904  	expectPrinted(t, "a/**/[b] {}", "a[b] {\n}\n", "")
   905  	expectPrinted(t, "a>/**/b {}", "a > b {\n}\n", "")
   906  	expectPrinted(t, "a+/**/b {}", "a + b {\n}\n", "")
   907  	expectPrinted(t, "a~/**/b {}", "a ~ b {\n}\n", "")
   908  
   909  	expectPrinted(t, "[b]{}", "[b] {\n}\n", "")
   910  	expectPrinted(t, "[b] {}", "[b] {\n}\n", "")
   911  	expectPrinted(t, "a[b] {}", "a[b] {\n}\n", "")
   912  	expectPrinted(t, "a [b] {}", "a [b] {\n}\n", "")
   913  	expectPrinted(t, "[] {}", "[] {\n}\n", "<stdin>: WARNING: Expected identifier but found \"]\"\n")
   914  	expectPrinted(t, "[b {}", "[b] {\n}\n", "<stdin>: WARNING: Expected \"]\" to go with \"[\"\n<stdin>: NOTE: The unbalanced \"[\" is here:\n")
   915  	expectPrinted(t, "[b]] {}", "[b]] {\n}\n", "<stdin>: WARNING: Unexpected \"]\"\n")
   916  	expectPrinted(t, "a[b {}", "a[b] {\n}\n", "<stdin>: WARNING: Expected \"]\" to go with \"[\"\n<stdin>: NOTE: The unbalanced \"[\" is here:\n")
   917  	expectPrinted(t, "a[b]] {}", "a[b]] {\n}\n", "<stdin>: WARNING: Unexpected \"]\"\n")
   918  	expectPrinted(t, "[b]a {}", "[b]a {\n}\n", "<stdin>: WARNING: Unexpected \"a\"\n")
   919  
   920  	expectPrinted(t, "[|b]{}", "[b] {\n}\n", "") // "[|b]" is equivalent to "[b]"
   921  	expectPrinted(t, "[*|b]{}", "[*|b] {\n}\n", "")
   922  	expectPrinted(t, "[a|b]{}", "[a|b] {\n}\n", "")
   923  	expectPrinted(t, "[a|b|=\"c\"]{}", "[a|b|=c] {\n}\n", "")
   924  	expectPrinted(t, "[a|b |= \"c\"]{}", "[a|b|=c] {\n}\n", "")
   925  	expectPrinted(t, "[a||b] {}", "[a||b] {\n}\n", "<stdin>: WARNING: Expected identifier but found \"|\"\n")
   926  	expectPrinted(t, "[* | b] {}", "[* | b] {\n}\n", "<stdin>: WARNING: Expected \"|\" but found whitespace\n")
   927  	expectPrinted(t, "[a | b] {}", "[a | b] {\n}\n", "<stdin>: WARNING: Expected \"=\" but found whitespace\n")
   928  
   929  	expectPrinted(t, "[b=\"c\"] {}", "[b=c] {\n}\n", "")
   930  	expectPrinted(t, "[b=\"c d\"] {}", "[b=\"c d\"] {\n}\n", "")
   931  	expectPrinted(t, "[b=\"0c\"] {}", "[b=\"0c\"] {\n}\n", "")
   932  	expectPrinted(t, "[b~=\"c\"] {}", "[b~=c] {\n}\n", "")
   933  	expectPrinted(t, "[b^=\"c\"] {}", "[b^=c] {\n}\n", "")
   934  	expectPrinted(t, "[b$=\"c\"] {}", "[b$=c] {\n}\n", "")
   935  	expectPrinted(t, "[b*=\"c\"] {}", "[b*=c] {\n}\n", "")
   936  	expectPrinted(t, "[b|=\"c\"] {}", "[b|=c] {\n}\n", "")
   937  	expectPrinted(t, "[b?=\"c\"] {}", "[b?=\"c\"] {\n}\n", "<stdin>: WARNING: Expected \"]\" to go with \"[\"\n<stdin>: NOTE: The unbalanced \"[\" is here:\n")
   938  
   939  	expectPrinted(t, "[b = \"c\"] {}", "[b=c] {\n}\n", "")
   940  	expectPrinted(t, "[b ~= \"c\"] {}", "[b~=c] {\n}\n", "")
   941  	expectPrinted(t, "[b ^= \"c\"] {}", "[b^=c] {\n}\n", "")
   942  	expectPrinted(t, "[b $= \"c\"] {}", "[b$=c] {\n}\n", "")
   943  	expectPrinted(t, "[b *= \"c\"] {}", "[b*=c] {\n}\n", "")
   944  	expectPrinted(t, "[b |= \"c\"] {}", "[b|=c] {\n}\n", "")
   945  	expectPrinted(t, "[b ?= \"c\"] {}", "[b ?= \"c\"] {\n}\n", "<stdin>: WARNING: Expected \"]\" to go with \"[\"\n<stdin>: NOTE: The unbalanced \"[\" is here:\n")
   946  
   947  	expectPrinted(t, "[b = \"c\" i] {}", "[b=c i] {\n}\n", "")
   948  	expectPrinted(t, "[b = \"c\" I] {}", "[b=c I] {\n}\n", "")
   949  	expectPrinted(t, "[b = \"c\" s] {}", "[b=c s] {\n}\n", "")
   950  	expectPrinted(t, "[b = \"c\" S] {}", "[b=c S] {\n}\n", "")
   951  	expectPrinted(t, "[b i] {}", "[b i] {\n}\n", "<stdin>: WARNING: Expected \"]\" to go with \"[\"\n<stdin>: NOTE: The unbalanced \"[\" is here:\n")
   952  	expectPrinted(t, "[b I] {}", "[b I] {\n}\n", "<stdin>: WARNING: Expected \"]\" to go with \"[\"\n<stdin>: NOTE: The unbalanced \"[\" is here:\n")
   953  	expectPrinted(t, "[b s] {}", "[b s] {\n}\n", "<stdin>: WARNING: Expected \"]\" to go with \"[\"\n<stdin>: NOTE: The unbalanced \"[\" is here:\n")
   954  	expectPrinted(t, "[b S] {}", "[b S] {\n}\n", "<stdin>: WARNING: Expected \"]\" to go with \"[\"\n<stdin>: NOTE: The unbalanced \"[\" is here:\n")
   955  
   956  	expectPrinted(t, "|b {}", "|b {\n}\n", "")
   957  	expectPrinted(t, "|* {}", "|* {\n}\n", "")
   958  	expectPrinted(t, "a|b {}", "a|b {\n}\n", "")
   959  	expectPrinted(t, "a|* {}", "a|* {\n}\n", "")
   960  	expectPrinted(t, "*|b {}", "*|b {\n}\n", "")
   961  	expectPrinted(t, "*|* {}", "*|* {\n}\n", "")
   962  	expectPrinted(t, "a||b {}", "a||b {\n}\n", "<stdin>: WARNING: Expected identifier but found \"|\"\n")
   963  
   964  	expectPrinted(t, "a+b {}", "a + b {\n}\n", "")
   965  	expectPrinted(t, "a>b {}", "a > b {\n}\n", "")
   966  	expectPrinted(t, "a+b {}", "a + b {\n}\n", "")
   967  	expectPrinted(t, "a~b {}", "a ~ b {\n}\n", "")
   968  
   969  	expectPrinted(t, "a + b {}", "a + b {\n}\n", "")
   970  	expectPrinted(t, "a > b {}", "a > b {\n}\n", "")
   971  	expectPrinted(t, "a + b {}", "a + b {\n}\n", "")
   972  	expectPrinted(t, "a ~ b {}", "a ~ b {\n}\n", "")
   973  
   974  	expectPrinted(t, "::b {}", "::b {\n}\n", "")
   975  	expectPrinted(t, "*::b {}", "*::b {\n}\n", "")
   976  	expectPrinted(t, "a::b {}", "a::b {\n}\n", "")
   977  	expectPrinted(t, "::b(c) {}", "::b(c) {\n}\n", "")
   978  	expectPrinted(t, "*::b(c) {}", "*::b(c) {\n}\n", "")
   979  	expectPrinted(t, "a::b(c) {}", "a::b(c) {\n}\n", "")
   980  	expectPrinted(t, "a:b:c {}", "a:b:c {\n}\n", "")
   981  	expectPrinted(t, "a:b(:c) {}", "a:b(:c) {\n}\n", "")
   982  	expectPrinted(t, "a: b {}", "a: b {\n}\n", "<stdin>: WARNING: Expected identifier but found whitespace\n")
   983  	expectPrinted(t, ":is(a)b {}", ":is(a)b {\n}\n", "<stdin>: WARNING: Unexpected \"b\"\n")
   984  	expectPrinted(t, "a:b( c ) {}", "a:b(c) {\n}\n", "")
   985  	expectPrinted(t, "a:b( c , d ) {}", "a:b(c, d) {\n}\n", "")
   986  	expectPrinted(t, "a:is( c ) {}", "a:is(c) {\n}\n", "")
   987  	expectPrinted(t, "a:is( c , d ) {}", "a:is(c, d) {\n}\n", "")
   988  
   989  	// These test cases previously caused a hang (see https://github.com/evanw/esbuild/issues/2276)
   990  	expectPrinted(t, ":x(", ":x() {\n}\n", "<stdin>: WARNING: Unexpected end of file\n")
   991  	expectPrinted(t, ":x( {}", ":x({}) {\n}\n", "<stdin>: WARNING: Expected \")\" to go with \"(\"\n<stdin>: NOTE: The unbalanced \"(\" is here:\n")
   992  	expectPrinted(t, ":x(, :y() {}", ":x(, :y() {}) {\n}\n", "<stdin>: WARNING: Expected \")\" to go with \"(\"\n<stdin>: NOTE: The unbalanced \"(\" is here:\n")
   993  
   994  	expectPrinted(t, "#id {}", "#id {\n}\n", "")
   995  	expectPrinted(t, "#--0 {}", "#--0 {\n}\n", "")
   996  	expectPrinted(t, "#\\-0 {}", "#\\-0 {\n}\n", "")
   997  	expectPrinted(t, "#\\30 {}", "#\\30  {\n}\n", "")
   998  	expectPrinted(t, "div#id {}", "div#id {\n}\n", "")
   999  	expectPrinted(t, "div#--0 {}", "div#--0 {\n}\n", "")
  1000  	expectPrinted(t, "div#\\-0 {}", "div#\\-0 {\n}\n", "")
  1001  	expectPrinted(t, "div#\\30 {}", "div#\\30  {\n}\n", "")
  1002  	expectPrinted(t, "#0 {}", "#0 {\n}\n", "<stdin>: WARNING: Unexpected \"#0\"\n")
  1003  	expectPrinted(t, "#-0 {}", "#-0 {\n}\n", "<stdin>: WARNING: Unexpected \"#-0\"\n")
  1004  	expectPrinted(t, "div#0 {}", "div#0 {\n}\n", "<stdin>: WARNING: Unexpected \"#0\"\n")
  1005  	expectPrinted(t, "div#-0 {}", "div#-0 {\n}\n", "<stdin>: WARNING: Unexpected \"#-0\"\n")
  1006  
  1007  	expectPrinted(t, "div::before::after::selection::first-line::first-letter {color:red}",
  1008  		"div::before::after::selection::first-line::first-letter {\n  color: red;\n}\n", "")
  1009  	expectPrintedMangle(t, "div::before::after::selection::first-line::first-letter {color:red}",
  1010  		"div:before:after::selection:first-line:first-letter {\n  color: red;\n}\n", "")
  1011  
  1012  	// Make sure '-' and '\\' consume an ident-like token instead of a name
  1013  	expectPrinted(t, "_:-ms-lang(x) {}", "_:-ms-lang(x) {\n}\n", "")
  1014  	expectPrinted(t, "_:\\ms-lang(x) {}", "_:ms-lang(x) {\n}\n", "")
  1015  
  1016  	expectPrinted(t, ":local(a, b) {}", ":local(a, b) {\n}\n", "<stdin>: WARNING: Unexpected \",\" inside \":local(...)\"\n"+
  1017  		"NOTE: Different CSS tools behave differently in this case, so esbuild doesn't allow it. Either remove "+
  1018  		"this comma or split this selector up into multiple comma-separated \":local(...)\" selectors instead.\n")
  1019  	expectPrinted(t, ":global(a, b) {}", ":global(a, b) {\n}\n", "<stdin>: WARNING: Unexpected \",\" inside \":global(...)\"\n"+
  1020  		"NOTE: Different CSS tools behave differently in this case, so esbuild doesn't allow it. Either remove "+
  1021  		"this comma or split this selector up into multiple comma-separated \":global(...)\" selectors instead.\n")
  1022  }
  1023  
  1024  func TestNestedSelector(t *testing.T) {
  1025  	sassWarningWrap := "NOTE: CSS nesting syntax does not allow the \"&\" selector to come before " +
  1026  		"a type selector. You can wrap this selector in \":is(...)\" as a workaround. " +
  1027  		"This restriction exists to avoid problems with SASS nesting, where the same syntax " +
  1028  		"means something very different that has no equivalent in real CSS (appending a suffix to the parent selector).\n"
  1029  	sassWarningMove := "NOTE: CSS nesting syntax does not allow the \"&\" selector to come before " +
  1030  		"a type selector. You can move the \"&\" to the end of this selector as a workaround. " +
  1031  		"This restriction exists to avoid problems with SASS nesting, where the same syntax " +
  1032  		"means something very different that has no equivalent in real CSS (appending a suffix to the parent selector).\n"
  1033  
  1034  	expectPrinted(t, "& {}", "& {\n}\n", "")
  1035  	expectPrinted(t, "& b {}", "& b {\n}\n", "")
  1036  	expectPrinted(t, "&:b {}", "&:b {\n}\n", "")
  1037  	expectPrinted(t, "&* {}", "&* {\n}\n", "<stdin>: WARNING: Cannot use type selector \"*\" directly after nesting selector \"&\"\n"+sassWarningWrap)
  1038  	expectPrinted(t, "&|b {}", "&|b {\n}\n", "<stdin>: WARNING: Cannot use type selector \"|b\" directly after nesting selector \"&\"\n"+sassWarningWrap)
  1039  	expectPrinted(t, "&*|b {}", "&*|b {\n}\n", "<stdin>: WARNING: Cannot use type selector \"*|b\" directly after nesting selector \"&\"\n"+sassWarningWrap)
  1040  	expectPrinted(t, "&a|b {}", "&a|b {\n}\n", "<stdin>: WARNING: Cannot use type selector \"a|b\" directly after nesting selector \"&\"\n"+sassWarningWrap)
  1041  	expectPrinted(t, "&[a] {}", "&[a] {\n}\n", "")
  1042  
  1043  	expectPrinted(t, "a { & {} }", "a {\n  & {\n  }\n}\n", "")
  1044  	expectPrinted(t, "a { & b {} }", "a {\n  & b {\n  }\n}\n", "")
  1045  	expectPrinted(t, "a { &:b {} }", "a {\n  &:b {\n  }\n}\n", "")
  1046  	expectPrinted(t, "a { &* {} }", "a {\n  &* {\n  }\n}\n", "<stdin>: WARNING: Cannot use type selector \"*\" directly after nesting selector \"&\"\n"+sassWarningWrap)
  1047  	expectPrinted(t, "a { &|b {} }", "a {\n  &|b {\n  }\n}\n", "<stdin>: WARNING: Cannot use type selector \"|b\" directly after nesting selector \"&\"\n"+sassWarningWrap)
  1048  	expectPrinted(t, "a { &*|b {} }", "a {\n  &*|b {\n  }\n}\n", "<stdin>: WARNING: Cannot use type selector \"*|b\" directly after nesting selector \"&\"\n"+sassWarningWrap)
  1049  	expectPrinted(t, "a { &a|b {} }", "a {\n  &a|b {\n  }\n}\n", "<stdin>: WARNING: Cannot use type selector \"a|b\" directly after nesting selector \"&\"\n"+sassWarningWrap)
  1050  	expectPrinted(t, "a { &[b] {} }", "a {\n  &[b] {\n  }\n}\n", "")
  1051  
  1052  	expectPrinted(t, "a { && {} }", "a {\n  & {\n  }\n}\n", "")
  1053  	expectPrinted(t, "a { & + & {} }", "a {\n  & + & {\n  }\n}\n", "")
  1054  	expectPrinted(t, "a { & > & {} }", "a {\n  & > & {\n  }\n}\n", "")
  1055  	expectPrinted(t, "a { & ~ & {} }", "a {\n  & ~ & {\n  }\n}\n", "")
  1056  	expectPrinted(t, "a { & + c& {} }", "a {\n  & + c& {\n  }\n}\n", "")
  1057  	expectPrinted(t, "a { .b& + & {} }", "a {\n  &.b + & {\n  }\n}\n", "")
  1058  	expectPrinted(t, "a { .b& + c& {} }", "a {\n  &.b + c& {\n  }\n}\n", "")
  1059  	expectPrinted(t, "a { & + & > & ~ & {} }", "a {\n  & + & > & ~ & {\n  }\n}\n", "")
  1060  
  1061  	// CSS nesting works for all tokens except identifiers and functions
  1062  	expectPrinted(t, "a { .b {} }", "a {\n  .b {\n  }\n}\n", "")
  1063  	expectPrinted(t, "a { #b {} }", "a {\n  #b {\n  }\n}\n", "")
  1064  	expectPrinted(t, "a { :b {} }", "a {\n  :b {\n  }\n}\n", "")
  1065  	expectPrinted(t, "a { [b] {} }", "a {\n  [b] {\n  }\n}\n", "")
  1066  	expectPrinted(t, "a { * {} }", "a {\n  * {\n  }\n}\n", "")
  1067  	expectPrinted(t, "a { |b {} }", "a {\n  |b {\n  }\n}\n", "")
  1068  	expectPrinted(t, "a { >b {} }", "a {\n  > b {\n  }\n}\n", "")
  1069  	expectPrinted(t, "a { +b {} }", "a {\n  + b {\n  }\n}\n", "")
  1070  	expectPrinted(t, "a { ~b {} }", "a {\n  ~ b {\n  }\n}\n", "")
  1071  	expectPrinted(t, "a { b {} }", "a {\n  b {\n  }\n}\n", "")
  1072  	expectPrinted(t, "a { b() {} }", "a {\n  b() {\n  }\n}\n", "<stdin>: WARNING: Unexpected \"b(\"\n")
  1073  
  1074  	// Note: CSS nesting no longer requires each complex selector to contain "&"
  1075  	expectPrinted(t, "a { & b, c {} }", "a {\n  & b,\n  c {\n  }\n}\n", "")
  1076  	expectPrinted(t, "a { & b, & c {} }", "a {\n  & b,\n  & c {\n  }\n}\n", "")
  1077  
  1078  	// Note: CSS nesting no longer requires the rule to be nested inside a parent
  1079  	// (instead un-nested CSS nesting refers to ":scope" or to ":root")
  1080  	expectPrinted(t, "& b, c {}", "& b,\nc {\n}\n", "")
  1081  	expectPrinted(t, "& b, & c {}", "& b,\n& c {\n}\n", "")
  1082  	expectPrinted(t, "b & {}", "b & {\n}\n", "")
  1083  	expectPrinted(t, "b &, c {}", "b &,\nc {\n}\n", "")
  1084  
  1085  	expectPrinted(t, "a { .b & { color: red } }", "a {\n  .b & {\n    color: red;\n  }\n}\n", "")
  1086  	expectPrinted(t, "a { .b& { color: red } }", "a {\n  &.b {\n    color: red;\n  }\n}\n", "")
  1087  	expectPrinted(t, "a { .b&[c] { color: red } }", "a {\n  &.b[c] {\n    color: red;\n  }\n}\n", "")
  1088  	expectPrinted(t, "a { &[c] { color: red } }", "a {\n  &[c] {\n    color: red;\n  }\n}\n", "")
  1089  	expectPrinted(t, "a { [c]& { color: red } }", "a {\n  &[c] {\n    color: red;\n  }\n}\n", "")
  1090  	expectPrintedMinify(t, "a { .b & { color: red } }", "a{.b &{color:red}}", "")
  1091  	expectPrintedMinify(t, "a { .b& { color: red } }", "a{&.b{color:red}}", "")
  1092  
  1093  	// Nested at-rules
  1094  	expectPrinted(t, "a { @media screen { color: red } }", "a {\n  @media screen {\n    color: red;\n  }\n}\n", "")
  1095  	expectPrinted(t, "a { @media screen { .b { color: green } color: red } }",
  1096  		"a {\n  @media screen {\n    .b {\n      color: green;\n    }\n    color: red;\n  }\n}\n", "")
  1097  	expectPrinted(t, "a { @media screen { color: red; .b { color: green } } }",
  1098  		"a {\n  @media screen {\n    color: red;\n    .b {\n      color: green;\n    }\n  }\n}\n", "")
  1099  	expectPrinted(t, "html { @layer base { block-size: 100%; @layer support { & body { min-block-size: 100%; } } } }",
  1100  		"html {\n  @layer base {\n    block-size: 100%;\n    @layer support {\n      & body {\n        min-block-size: 100%;\n      }\n    }\n  }\n}\n", "")
  1101  	expectPrinted(t, ".card { aspect-ratio: 3/4; @scope (&) { :scope { border: 1px solid white } } }",
  1102  		".card {\n  aspect-ratio: 3/4;\n  @scope (&) {\n    :scope {\n      border: 1px solid white;\n    }\n  }\n}\n", "")
  1103  
  1104  	// Minify an implicit leading "&"
  1105  	expectPrintedMangle(t, "& { color: red }", "& {\n  color: red;\n}\n", "")
  1106  	expectPrintedMangle(t, "& a { color: red }", "a {\n  color: red;\n}\n", "")
  1107  	expectPrintedMangle(t, "& a, & b { color: red }", "a,\nb {\n  color: red;\n}\n", "")
  1108  	expectPrintedMangle(t, "& a, b { color: red }", "a,\nb {\n  color: red;\n}\n", "")
  1109  	expectPrintedMangle(t, "a, & b { color: red }", "a,\nb {\n  color: red;\n}\n", "")
  1110  	expectPrintedMangle(t, "& &a { color: red }", "& &a {\n  color: red;\n}\n", "<stdin>: WARNING: Cannot use type selector \"a\" directly after nesting selector \"&\"\n"+sassWarningMove)
  1111  	expectPrintedMangle(t, "& .x { color: red }", ".x {\n  color: red;\n}\n", "")
  1112  	expectPrintedMangle(t, "& &.x { color: red }", "& &.x {\n  color: red;\n}\n", "")
  1113  	expectPrintedMangle(t, "& + a { color: red }", "+ a {\n  color: red;\n}\n", "")
  1114  	expectPrintedMangle(t, "& + a& { color: red }", "+ a& {\n  color: red;\n}\n", "")
  1115  	expectPrintedMangle(t, "&.x { color: red }", "&.x {\n  color: red;\n}\n", "")
  1116  	expectPrintedMangle(t, "a & { color: red }", "a & {\n  color: red;\n}\n", "")
  1117  	expectPrintedMangle(t, ".x & { color: red }", ".x & {\n  color: red;\n}\n", "")
  1118  	expectPrintedMangle(t, "div { & a { color: red } }", "div {\n  & a {\n    color: red;\n  }\n}\n", "")
  1119  	expectPrintedMangle(t, "div { & .x { color: red } }", "div {\n  .x {\n    color: red;\n  }\n}\n", "")
  1120  	expectPrintedMangle(t, "div { & .x, & a { color: red } }", "div {\n  .x,\n  a {\n    color: red;\n  }\n}\n", "")
  1121  	expectPrintedMangle(t, "div { .x, & a { color: red } }", "div {\n  .x,\n  a {\n    color: red;\n  }\n}\n", "")
  1122  	expectPrintedMangle(t, "div { & a& { color: red } }", "div {\n  & a& {\n    color: red;\n  }\n}\n", "")
  1123  	expectPrintedMangle(t, "div { & .x { color: red } }", "div {\n  .x {\n    color: red;\n  }\n}\n", "")
  1124  	expectPrintedMangle(t, "div { & &.x { color: red } }", "div {\n  & &.x {\n    color: red;\n  }\n}\n", "")
  1125  	expectPrintedMangle(t, "div { & + a { color: red } }", "div {\n  + a {\n    color: red;\n  }\n}\n", "")
  1126  	expectPrintedMangle(t, "div { & + a& { color: red } }", "div {\n  + a& {\n    color: red;\n  }\n}\n", "")
  1127  	expectPrintedMangle(t, "div { .x & { color: red } }", "div {\n  .x & {\n    color: red;\n  }\n}\n", "")
  1128  	expectPrintedMangle(t, "@media screen { & div { color: red } }", "@media screen {\n  div {\n    color: red;\n  }\n}\n", "")
  1129  	expectPrintedMangle(t, "a { @media screen { & div { color: red } } }", "a {\n  @media screen {\n    & div {\n      color: red;\n    }\n  }\n}\n", "")
  1130  
  1131  	// Reorder selectors to enable removing "&"
  1132  	expectPrintedMangle(t, "reorder { & first, .second { color: red } }", "reorder {\n  .second,\n  first {\n    color: red;\n  }\n}\n", "")
  1133  	expectPrintedMangle(t, "reorder { & first, & .second { color: red } }", "reorder {\n  .second,\n  first {\n    color: red;\n  }\n}\n", "")
  1134  	expectPrintedMangle(t, "reorder { & first, #second { color: red } }", "reorder {\n  #second,\n  first {\n    color: red;\n  }\n}\n", "")
  1135  	expectPrintedMangle(t, "reorder { & first, [second] { color: red } }", "reorder {\n  [second],\n  first {\n    color: red;\n  }\n}\n", "")
  1136  	expectPrintedMangle(t, "reorder { & first, :second { color: red } }", "reorder {\n  :second,\n  first {\n    color: red;\n  }\n}\n", "")
  1137  	expectPrintedMangle(t, "reorder { & first, + second { color: red } }", "reorder {\n  + second,\n  first {\n    color: red;\n  }\n}\n", "")
  1138  	expectPrintedMangle(t, "reorder { & first, ~ second { color: red } }", "reorder {\n  ~ second,\n  first {\n    color: red;\n  }\n}\n", "")
  1139  	expectPrintedMangle(t, "reorder { & first, > second { color: red } }", "reorder {\n  > second,\n  first {\n    color: red;\n  }\n}\n", "")
  1140  	expectPrintedMangle(t, "reorder { & first, second, .third { color: red } }", "reorder {\n  .third,\n  second,\n  first {\n    color: red;\n  }\n}\n", "")
  1141  
  1142  	// Inline no-op nesting
  1143  	expectPrintedMangle(t, "div { & { color: red } }", "div {\n  color: red;\n}\n", "")
  1144  	expectPrintedMangle(t, "div { && { color: red } }", "div {\n  color: red;\n}\n", "")
  1145  	expectPrintedMangle(t, "div { zoom: 2; & { color: red } }", "div {\n  zoom: 2;\n  color: red;\n}\n", "")
  1146  	expectPrintedMangle(t, "div { zoom: 2; && { color: red } }", "div {\n  zoom: 2;\n  color: red;\n}\n", "")
  1147  	expectPrintedMangle(t, "div { &, && { color: red } zoom: 2 }", "div {\n  zoom: 2;\n  color: red;\n}\n", "")
  1148  	expectPrintedMangle(t, "div { &&, & { color: red } zoom: 2 }", "div {\n  zoom: 2;\n  color: red;\n}\n", "")
  1149  	expectPrintedMangle(t, "div { a: 1; & { b: 4 } b: 2; && { c: 5 } c: 3 }", "div {\n  a: 1;\n  b: 2;\n  c: 3;\n  b: 4;\n  c: 5;\n}\n", "")
  1150  	expectPrintedMangle(t, "div { .b { x: 1 } & { x: 2 } }", "div {\n  .b {\n    x: 1;\n  }\n  x: 2;\n}\n", "")
  1151  	expectPrintedMangle(t, "div { & { & { & { color: red } } & { & { zoom: 2 } } } }", "div {\n  color: red;\n  zoom: 2;\n}\n", "")
  1152  
  1153  	// Cannot inline no-op nesting with pseudo-elements (https://github.com/w3c/csswg-drafts/issues/7433)
  1154  	expectPrintedMangle(t, "div, span:hover { & { color: red } }", "div,\nspan:hover {\n  color: red;\n}\n", "")
  1155  	expectPrintedMangle(t, "div, span::before { & { color: red } }", "div,\nspan:before {\n  & {\n    color: red;\n  }\n}\n", "")
  1156  	expectPrintedMangle(t, "div, span:before { & { color: red } }", "div,\nspan:before {\n  & {\n    color: red;\n  }\n}\n", "")
  1157  	expectPrintedMangle(t, "div, span::after { & { color: red } }", "div,\nspan:after {\n  & {\n    color: red;\n  }\n}\n", "")
  1158  	expectPrintedMangle(t, "div, span:after { & { color: red } }", "div,\nspan:after {\n  & {\n    color: red;\n  }\n}\n", "")
  1159  	expectPrintedMangle(t, "div, span::first-line { & { color: red } }", "div,\nspan:first-line {\n  & {\n    color: red;\n  }\n}\n", "")
  1160  	expectPrintedMangle(t, "div, span:first-line { & { color: red } }", "div,\nspan:first-line {\n  & {\n    color: red;\n  }\n}\n", "")
  1161  	expectPrintedMangle(t, "div, span::first-letter { & { color: red } }", "div,\nspan:first-letter {\n  & {\n    color: red;\n  }\n}\n", "")
  1162  	expectPrintedMangle(t, "div, span:first-letter { & { color: red } }", "div,\nspan:first-letter {\n  & {\n    color: red;\n  }\n}\n", "")
  1163  	expectPrintedMangle(t, "div, span::pseudo { & { color: red } }", "div,\nspan::pseudo {\n  & {\n    color: red;\n  }\n}\n", "")
  1164  	expectPrintedMangle(t, "div, span:hover { @layer foo { & { color: red } } }", "div,\nspan:hover {\n  @layer foo {\n    color: red;\n  }\n}\n", "")
  1165  	expectPrintedMangle(t, "div, span:hover { @media screen { & { color: red } } }", "div,\nspan:hover {\n  @media screen {\n    color: red;\n  }\n}\n", "")
  1166  	expectPrintedMangle(t, "div, span::pseudo { @layer foo { & { color: red } } }", "div,\nspan::pseudo {\n  @layer foo {\n    & {\n      color: red;\n    }\n  }\n}\n", "")
  1167  	expectPrintedMangle(t, "div, span::pseudo { @media screen { & { color: red } } }", "div,\nspan::pseudo {\n  @media screen {\n    & {\n      color: red;\n    }\n  }\n}\n", "")
  1168  
  1169  	// Lowering tests for nesting
  1170  	nestingWarningIs := "<stdin>: WARNING: Transforming this CSS nesting syntax is not supported in the configured target environment\n" +
  1171  		"NOTE: The nesting transform for this case must generate an \":is(...)\" but the configured target environment does not support the \":is\" pseudo-class.\n"
  1172  	nesting := compat.Nesting
  1173  	everything := ^compat.CSSFeature(0)
  1174  	expectPrintedLowerUnsupported(t, nesting, ".foo { .bar { color: red } }", ".foo .bar {\n  color: red;\n}\n", "")
  1175  	expectPrintedLowerUnsupported(t, nesting, ".foo { &.bar { color: red } }", ".foo.bar {\n  color: red;\n}\n", "")
  1176  	expectPrintedLowerUnsupported(t, nesting, ".foo { & .bar { color: red } }", ".foo .bar {\n  color: red;\n}\n", "")
  1177  	expectPrintedLowerUnsupported(t, nesting, ".foo .bar { .baz { color: red } }", ".foo .bar .baz {\n  color: red;\n}\n", "")
  1178  	expectPrintedLowerUnsupported(t, nesting, ".foo .bar { &.baz { color: red } }", ".foo .bar.baz {\n  color: red;\n}\n", "")
  1179  	expectPrintedLowerUnsupported(t, nesting, ".foo .bar { & .baz { color: red } }", ".foo .bar .baz {\n  color: red;\n}\n", "")
  1180  	expectPrintedLowerUnsupported(t, nesting, ".foo .bar { & > .baz { color: red } }", ".foo .bar > .baz {\n  color: red;\n}\n", "")
  1181  	expectPrintedLowerUnsupported(t, nesting, ".foo .bar { .baz & { color: red } }", ".baz :is(.foo .bar) {\n  color: red;\n}\n", "") // NOT the same as ".baz .foo .bar
  1182  	expectPrintedLowerUnsupported(t, nesting, ".foo .bar { & .baz & { color: red } }", ".foo .bar .baz :is(.foo .bar) {\n  color: red;\n}\n", "")
  1183  	expectPrintedLowerUnsupported(t, nesting, ".foo, .bar { .baz & { color: red } }", ".baz :is(.foo, .bar) {\n  color: red;\n}\n", "")
  1184  	expectPrintedLowerUnsupported(t, everything, ".foo, .bar { .baz & { color: red } }", ".baz .foo,\n.baz .bar {\n  color: red;\n}\n", "")
  1185  	expectPrintedLowerUnsupported(t, nesting, ".foo, [bar~='abc'] { .baz { color: red } }", ":is(.foo, [bar~=abc]) .baz {\n  color: red;\n}\n", "")
  1186  	expectPrintedLowerUnsupported(t, everything, ".foo, [bar~='abc'] { .baz { color: red } }", ".foo .baz,\n[bar~=abc] .baz {\n  color: red;\n}\n", "")
  1187  	expectPrintedLowerUnsupported(t, nesting, ".foo, [bar~='a b c'] { .baz { color: red } }", ":is(.foo, [bar~=\"a b c\"]) .baz {\n  color: red;\n}\n", "")
  1188  	expectPrintedLowerUnsupported(t, everything, ".foo, [bar~='a b c'] { .baz { color: red } }", ".foo .baz,\n[bar~=\"a b c\"] .baz {\n  color: red;\n}\n", "")
  1189  	expectPrintedLowerUnsupported(t, nesting, ".baz { .foo, .bar { color: red } }", ".baz :is(.foo, .bar) {\n  color: red;\n}\n", "")
  1190  	expectPrintedLowerUnsupported(t, everything, ".baz { .foo, .bar { color: red } }", ".baz .foo,\n.baz .bar {\n  color: red;\n}\n", "")
  1191  	expectPrintedLowerUnsupported(t, nesting, ".baz { .foo, & .bar { color: red } }", ".baz :is(.foo, .bar) {\n  color: red;\n}\n", "")
  1192  	expectPrintedLowerUnsupported(t, everything, ".baz { .foo, & .bar { color: red } }", ".baz .foo,\n.baz .bar {\n  color: red;\n}\n", "")
  1193  	expectPrintedLowerUnsupported(t, nesting, ".baz { & .foo, .bar { color: red } }", ".baz :is(.foo, .bar) {\n  color: red;\n}\n", "")
  1194  	expectPrintedLowerUnsupported(t, everything, ".baz { & .foo, .bar { color: red } }", ".baz .foo,\n.baz .bar {\n  color: red;\n}\n", "")
  1195  	expectPrintedLowerUnsupported(t, nesting, ".baz { & .foo, & .bar { color: red } }", ".baz :is(.foo, .bar) {\n  color: red;\n}\n", "")
  1196  	expectPrintedLowerUnsupported(t, everything, ".baz { & .foo, & .bar { color: red } }", ".baz .foo,\n.baz .bar {\n  color: red;\n}\n", "")
  1197  	expectPrintedLowerUnsupported(t, nesting, ".baz { .foo, &.bar { color: red } }", ".baz .foo,\n.baz.bar {\n  color: red;\n}\n", "")
  1198  	expectPrintedLowerUnsupported(t, everything, ".baz { &.foo, .bar { color: red } }", ".baz.foo,\n.baz .bar {\n  color: red;\n}\n", "")
  1199  	expectPrintedLowerUnsupported(t, nesting, ".baz { &.foo, &.bar { color: red } }", ".baz:is(.foo, .bar) {\n  color: red;\n}\n", "")
  1200  	expectPrintedLowerUnsupported(t, everything, ".baz { &.foo, &.bar { color: red } }", ".baz.foo,\n.baz.bar {\n  color: red;\n}\n", "")
  1201  	expectPrintedLowerUnsupported(t, nesting, ".foo { color: blue; & .bar { color: red } }", ".foo {\n  color: blue;\n}\n.foo .bar {\n  color: red;\n}\n", "")
  1202  	expectPrintedLowerUnsupported(t, nesting, ".foo { & .bar { color: red } color: blue }", ".foo {\n  color: blue;\n}\n.foo .bar {\n  color: red;\n}\n", "")
  1203  	expectPrintedLowerUnsupported(t, nesting, ".foo { color: blue; & .bar { color: red } zoom: 2 }", ".foo {\n  color: blue;\n  zoom: 2;\n}\n.foo .bar {\n  color: red;\n}\n", "")
  1204  	expectPrintedLowerUnsupported(t, nesting, ".a, .b { .c, .d { color: red } }", ":is(.a, .b) :is(.c, .d) {\n  color: red;\n}\n", "")
  1205  	expectPrintedLowerUnsupported(t, everything, ".a, .b { .c, .d { color: red } }", ".a .c,\n.a .d,\n.b .c,\n.b .d {\n  color: red;\n}\n", "")
  1206  	expectPrintedLowerUnsupported(t, nesting, ".a, .b { & > & { color: red } }", ":is(.a, .b) > :is(.a, .b) {\n  color: red;\n}\n", "")
  1207  	expectPrintedLowerUnsupported(t, everything, ".a, .b { & > & { color: red } }", ".a > .a,\n.a > .b,\n.b > .a,\n.b > .b {\n  color: red;\n}\n", "")
  1208  	expectPrintedLowerUnsupported(t, nesting, ".a { color: red; > .b { color: green; > .c { color: blue } } }", ".a {\n  color: red;\n}\n.a > .b {\n  color: green;\n}\n.a > .b > .c {\n  color: blue;\n}\n", "")
  1209  	expectPrintedLowerUnsupported(t, nesting, "> .a { color: red; > .b { color: green; > .c { color: blue } } }", "> .a {\n  color: red;\n}\n> .a > .b {\n  color: green;\n}\n> .a > .b > .c {\n  color: blue;\n}\n", "")
  1210  	expectPrintedLowerUnsupported(t, nesting, ".foo, .bar, .foo:before, .bar:after { &:hover { color: red } }", ":is(.foo, .bar):hover {\n  color: red;\n}\n", "")
  1211  	expectPrintedLowerUnsupported(t, everything, ".foo, .bar, .foo:before, .bar:after { &:hover { color: red } }", ".foo:hover,\n.bar:hover {\n  color: red;\n}\n", "")
  1212  	expectPrintedLowerUnsupported(t, nesting, ".foo, .bar:before { &:hover { color: red } }", ".foo:hover {\n  color: red;\n}\n", "")
  1213  	expectPrintedLowerUnsupported(t, nesting, ".foo, .bar:before { :hover & { color: red } }", ":hover .foo {\n  color: red;\n}\n", "")
  1214  	expectPrintedLowerUnsupported(t, nesting, ".bar:before { &:hover { color: red } }", ":is():hover {\n  color: red;\n}\n", "")
  1215  	expectPrintedLowerUnsupported(t, nesting, ".bar:before { :hover & { color: red } }", ":hover :is() {\n  color: red;\n}\n", "")
  1216  	expectPrintedLowerUnsupported(t, nesting, ".foo { &:after, & .bar { color: red } }", ".foo:after,\n.foo .bar {\n  color: red;\n}\n", "")
  1217  	expectPrintedLowerUnsupported(t, nesting, ".foo { & .bar, &:after { color: red } }", ".foo .bar,\n.foo:after {\n  color: red;\n}\n", "")
  1218  	expectPrintedLowerUnsupported(t, nesting, ".xy { :where(&.foo) { color: red } }", ":where(.xy.foo) {\n  color: red;\n}\n", "")
  1219  	expectPrintedLowerUnsupported(t, nesting, "div { :where(&.foo) { color: red } }", ":where(div.foo) {\n  color: red;\n}\n", "")
  1220  	expectPrintedLowerUnsupported(t, nesting, ".xy { :where(.foo&) { color: red } }", ":where(.xy.foo) {\n  color: red;\n}\n", "")
  1221  	expectPrintedLowerUnsupported(t, nesting, "div { :where(.foo&) { color: red } }", ":where(div.foo) {\n  color: red;\n}\n", "")
  1222  	expectPrintedLowerUnsupported(t, nesting, ".xy { :where([href]&) { color: red } }", ":where(.xy[href]) {\n  color: red;\n}\n", "")
  1223  	expectPrintedLowerUnsupported(t, nesting, "div { :where([href]&) { color: red } }", ":where(div[href]) {\n  color: red;\n}\n", "")
  1224  	expectPrintedLowerUnsupported(t, nesting, ".xy { :where(:hover&) { color: red } }", ":where(.xy:hover) {\n  color: red;\n}\n", "")
  1225  	expectPrintedLowerUnsupported(t, nesting, "div { :where(:hover&) { color: red } }", ":where(div:hover) {\n  color: red;\n}\n", "")
  1226  	expectPrintedLowerUnsupported(t, nesting, ".xy { :where(:is(.foo)&) { color: red } }", ":where(.xy:is(.foo)) {\n  color: red;\n}\n", "")
  1227  	expectPrintedLowerUnsupported(t, nesting, "div { :where(:is(.foo)&) { color: red } }", ":where(div:is(.foo)) {\n  color: red;\n}\n", "")
  1228  	expectPrintedLowerUnsupported(t, nesting, ".xy { :where(.foo + &) { color: red } }", ":where(.foo + .xy) {\n  color: red;\n}\n", "")
  1229  	expectPrintedLowerUnsupported(t, nesting, "div { :where(.foo + &) { color: red } }", ":where(.foo + div) {\n  color: red;\n}\n", "")
  1230  	expectPrintedLowerUnsupported(t, nesting, ".xy { :where(&, span:is(.foo &)) { color: red } }", ":where(.xy, span:is(.foo .xy)) {\n  color: red;\n}\n", "")
  1231  	expectPrintedLowerUnsupported(t, nesting, "div { :where(&, span:is(.foo &)) { color: red } }", ":where(div, span:is(.foo div)) {\n  color: red;\n}\n", "")
  1232  	expectPrintedLowerUnsupported(t, nesting, "&, a { color: red }", ":scope,\na {\n  color: red;\n}\n", "")
  1233  	expectPrintedLowerUnsupported(t, nesting, "&, a { .b { color: red } }", ":is(:scope, a) .b {\n  color: red;\n}\n", "")
  1234  	expectPrintedLowerUnsupported(t, everything, "&, a { .b { color: red } }", ":scope .b,\na .b {\n  color: red;\n}\n", "")
  1235  	expectPrintedLowerUnsupported(t, nesting, "&, a { .b { .c { color: red } } }", ":is(:scope, a) .b .c {\n  color: red;\n}\n", "")
  1236  	expectPrintedLowerUnsupported(t, everything, "&, a { .b { .c { color: red } } }", ":scope .b .c,\na .b .c {\n  color: red;\n}\n", "")
  1237  	expectPrintedLowerUnsupported(t, nesting, "a { > b, > c { color: red } }", "a > :is(b, c) {\n  color: red;\n}\n", "")
  1238  	expectPrintedLowerUnsupported(t, everything, "a { > b, > c { color: red } }", "a > b,\na > c {\n  color: red;\n}\n", "")
  1239  	expectPrintedLowerUnsupported(t, nesting, "a { > b, + c { color: red } }", "a > b,\na + c {\n  color: red;\n}\n", "")
  1240  	expectPrintedLowerUnsupported(t, nesting, "a { & > b, & > c { color: red } }", "a > :is(b, c) {\n  color: red;\n}\n", "")
  1241  	expectPrintedLowerUnsupported(t, everything, "a { & > b, & > c { color: red } }", "a > b,\na > c {\n  color: red;\n}\n", "")
  1242  	expectPrintedLowerUnsupported(t, nesting, "a { & > b, & + c { color: red } }", "a > b,\na + c {\n  color: red;\n}\n", "")
  1243  	expectPrintedLowerUnsupported(t, nesting, "a { > b&, > c& { color: red } }", "a > :is(a:is(b), a:is(c)) {\n  color: red;\n}\n", "")
  1244  	expectPrintedLowerUnsupported(t, everything, "a { > b&, > c& { color: red } }", "a > a:is(b),\na > a:is(c) {\n  color: red;\n}\n", nestingWarningIs+nestingWarningIs)
  1245  	expectPrintedLowerUnsupported(t, nesting, "a { > b&, + c& { color: red } }", "a > a:is(b),\na + a:is(c) {\n  color: red;\n}\n", "")
  1246  	expectPrintedLowerUnsupported(t, nesting, "a { > &.b, > &.c { color: red } }", "a > :is(a.b, a.c) {\n  color: red;\n}\n", "")
  1247  	expectPrintedLowerUnsupported(t, everything, "a { > &.b, > &.c { color: red } }", "a > a.b,\na > a.c {\n  color: red;\n}\n", "")
  1248  	expectPrintedLowerUnsupported(t, nesting, "a { > &.b, + &.c { color: red } }", "a > a.b,\na + a.c {\n  color: red;\n}\n", "")
  1249  	expectPrintedLowerUnsupported(t, nesting, ".a { > b&, > c& { color: red } }", ".a > :is(b.a, c.a) {\n  color: red;\n}\n", "")
  1250  	expectPrintedLowerUnsupported(t, everything, ".a { > b&, > c& { color: red } }", ".a > b.a,\n.a > c.a {\n  color: red;\n}\n", "")
  1251  	expectPrintedLowerUnsupported(t, nesting, ".a { > b&, + c& { color: red } }", ".a > b.a,\n.a + c.a {\n  color: red;\n}\n", "")
  1252  	expectPrintedLowerUnsupported(t, nesting, ".a { > &.b, > &.c { color: red } }", ".a > :is(.a.b, .a.c) {\n  color: red;\n}\n", "")
  1253  	expectPrintedLowerUnsupported(t, everything, ".a { > &.b, > &.c { color: red } }", ".a > .a.b,\n.a > .a.c {\n  color: red;\n}\n", "")
  1254  	expectPrintedLowerUnsupported(t, nesting, ".a { > &.b, + &.c { color: red } }", ".a > .a.b,\n.a + .a.c {\n  color: red;\n}\n", "")
  1255  	expectPrintedLowerUnsupported(t, nesting, "~ .a { > &.b, > &.c { color: red } }", "~ .a > :is(.a.b, .a.c) {\n  color: red;\n}\n", "")
  1256  	expectPrintedLowerUnsupported(t, everything, "~ .a { > &.b, > &.c { color: red } }", "~ .a > .a.b,\n~ .a > .a.c {\n  color: red;\n}\n", "")
  1257  	expectPrintedLowerUnsupported(t, nesting, "~ .a { > &.b, + &.c { color: red } }", "~ .a > .a.b,\n~ .a + .a.c {\n  color: red;\n}\n", "")
  1258  	expectPrintedLowerUnsupported(t, nesting, ".foo .bar { > &.a, > &.b { color: red } }", ".foo .bar > :is(.foo .bar.a, .foo .bar.b) {\n  color: red;\n}\n", "")
  1259  	expectPrintedLowerUnsupported(t, everything, ".foo .bar { > &.a, > &.b { color: red } }", ".foo .bar > :is(.foo .bar).a,\n.foo .bar > :is(.foo .bar).b {\n  color: red;\n}\n", nestingWarningIs+nestingWarningIs)
  1260  	expectPrintedLowerUnsupported(t, nesting, ".foo .bar { > &.a, + &.b { color: red } }", ".foo .bar > :is(.foo .bar).a,\n.foo .bar + :is(.foo .bar).b {\n  color: red;\n}\n", "")
  1261  	expectPrintedLowerUnsupported(t, nesting, ".demo { .lg { &.triangle, &.circle { color: red } } }", ".demo .lg:is(.triangle, .circle) {\n  color: red;\n}\n", "")
  1262  	expectPrintedLowerUnsupported(t, nesting, ".demo { .lg { .triangle, .circle { color: red } } }", ".demo .lg :is(.triangle, .circle) {\n  color: red;\n}\n", "")
  1263  	expectPrintedLowerUnsupported(t, nesting, ".card { .featured & & & { color: red } }", ".featured .card .card .card {\n  color: red;\n}\n", "")
  1264  
  1265  	// These are invalid SASS-style nested suffixes
  1266  	expectPrintedLower(t, ".card { &--header { color: red } }", ".card {\n  &--header {\n    color: red;\n  }\n}\n",
  1267  		"<stdin>: WARNING: Cannot use type selector \"--header\" directly after nesting selector \"&\"\n"+sassWarningWrap)
  1268  	expectPrintedLower(t, ".card { &__header { color: red } }", ".card {\n  &__header {\n    color: red;\n  }\n}\n",
  1269  		"<stdin>: WARNING: Cannot use type selector \"__header\" directly after nesting selector \"&\"\n"+sassWarningWrap)
  1270  	expectPrintedLower(t, ".card { .nav &--header { color: red } }", ".card {\n  .nav &--header {\n    color: red;\n  }\n}\n",
  1271  		"<stdin>: WARNING: Cannot use type selector \"--header\" directly after nesting selector \"&\"\n"+sassWarningMove)
  1272  	expectPrintedLower(t, ".card { .nav &__header { color: red } }", ".card {\n  .nav &__header {\n    color: red;\n  }\n}\n",
  1273  		"<stdin>: WARNING: Cannot use type selector \"__header\" directly after nesting selector \"&\"\n"+sassWarningMove)
  1274  	expectPrinted(t, ".card { &__header { color: red } }", ".card {\n  &__header {\n    color: red;\n  }\n}\n",
  1275  		"<stdin>: WARNING: Cannot use type selector \"__header\" directly after nesting selector \"&\"\n"+sassWarningWrap)
  1276  	expectPrinted(t, ".card { .nav &__header { color: red } }", ".card {\n  .nav &__header {\n    color: red;\n  }\n}\n",
  1277  		"<stdin>: WARNING: Cannot use type selector \"__header\" directly after nesting selector \"&\"\n"+sassWarningMove)
  1278  	expectPrinted(t, ".card { .nav, &__header { color: red } }", ".card {\n  .nav, &__header {\n    color: red;\n  }\n}\n",
  1279  		"<stdin>: WARNING: Cannot use type selector \"__header\" directly after nesting selector \"&\"\n"+sassWarningMove)
  1280  
  1281  	// Check pseudo-elements (those coming through "&" must be dropped)
  1282  	expectPrintedLower(t, "a, b::before { &.foo { color: red } }", "a.foo {\n  color: red;\n}\n", "")
  1283  	expectPrintedLower(t, "a, b::before { & .foo { color: red } }", "a .foo {\n  color: red;\n}\n", "")
  1284  	expectPrintedLower(t, "a { &.foo, &::before { color: red } }", "a.foo,\na::before {\n  color: red;\n}\n", "")
  1285  	expectPrintedLower(t, "a { & .foo, & ::before { color: red } }", "a .foo,\na ::before {\n  color: red;\n}\n", "")
  1286  	expectPrintedLower(t, "a, b::before { color: blue; &.foo, &::after { color: red } }", "a,\nb::before {\n  color: blue;\n}\na.foo,\na::after {\n  color: red;\n}\n", "")
  1287  
  1288  	// Test at-rules
  1289  	expectPrintedLower(t, ".foo { @media screen {} }", "", "")
  1290  	expectPrintedLower(t, ".foo { @media screen { color: red } }", "@media screen {\n  .foo {\n    color: red;\n  }\n}\n", "")
  1291  	expectPrintedLower(t, ".foo { @media screen { &:hover { color: red } } }", "@media screen {\n  .foo:hover {\n    color: red;\n  }\n}\n", "")
  1292  	expectPrintedLower(t, ".foo { @media screen { :hover { color: red } } }", "@media screen {\n  .foo :hover {\n    color: red;\n  }\n}\n", "")
  1293  	expectPrintedLower(t, ".foo, .bar { @media screen { color: red } }", "@media screen {\n  .foo,\n  .bar {\n    color: red;\n  }\n}\n", "")
  1294  	expectPrintedLower(t, ".foo, .bar { @media screen { &:hover { color: red } } }", "@media screen {\n  .foo:hover,\n  .bar:hover {\n    color: red;\n  }\n}\n", "")
  1295  	expectPrintedLower(t, ".foo, .bar { @media screen { :hover { color: red } } }", "@media screen {\n  .foo :hover,\n  .bar :hover {\n    color: red;\n  }\n}\n", "")
  1296  	expectPrintedLower(t, ".foo { @layer xyz {} }", "@layer xyz;\n", "")
  1297  	expectPrintedLower(t, ".foo { @layer xyz { color: red } }", "@layer xyz {\n  .foo {\n    color: red;\n  }\n}\n", "")
  1298  	expectPrintedLower(t, ".foo { @layer xyz { &:hover { color: red } } }", "@layer xyz {\n  .foo:hover {\n    color: red;\n  }\n}\n", "")
  1299  	expectPrintedLower(t, ".foo { @layer xyz { :hover { color: red } } }", "@layer xyz {\n  .foo :hover {\n    color: red;\n  }\n}\n", "")
  1300  	expectPrintedLower(t, ".foo, .bar { @layer xyz { color: red } }", "@layer xyz {\n  .foo,\n  .bar {\n    color: red;\n  }\n}\n", "")
  1301  	expectPrintedLower(t, ".foo, .bar { @layer xyz { &:hover { color: red } } }", "@layer xyz {\n  .foo:hover,\n  .bar:hover {\n    color: red;\n  }\n}\n", "")
  1302  	expectPrintedLower(t, ".foo, .bar { @layer xyz { :hover { color: red } } }", "@layer xyz {\n  .foo :hover,\n  .bar :hover {\n    color: red;\n  }\n}\n", "")
  1303  	expectPrintedLower(t, "@media screen { @media (min-width: 900px) { a, b { &:hover { color: red } } } }",
  1304  		"@media screen {\n  @media (min-width: 900px) {\n    a:hover,\n    b:hover {\n      color: red;\n    }\n  }\n}\n", "")
  1305  	expectPrintedLower(t, "@supports (display: flex) { @supports selector(h2 > p) { a, b { &:hover { color: red } } } }",
  1306  		"@supports (display: flex) {\n  @supports selector(h2 > p) {\n    a:hover,\n    b:hover {\n      color: red;\n    }\n  }\n}\n", "")
  1307  	expectPrintedLower(t, "@layer foo { @layer bar { a, b { &:hover { color: red } } } }",
  1308  		"@layer foo {\n  @layer bar {\n    a:hover,\n    b:hover {\n      color: red;\n    }\n  }\n}\n", "")
  1309  	expectPrintedLower(t, ".card { @supports (selector(&)) { &:hover { color: red } } }",
  1310  		"@supports (selector(&)) {\n  .card:hover {\n    color: red;\n  }\n}\n", "")
  1311  	expectPrintedLower(t, "html { @layer base { color: blue; @layer support { & body { color: red } } } }",
  1312  		"@layer base {\n  html {\n    color: blue;\n  }\n  @layer support {\n    html body {\n      color: red;\n    }\n  }\n}\n", "")
  1313  
  1314  	// https://github.com/w3c/csswg-drafts/issues/7961#issuecomment-1549874958
  1315  	expectPrinted(t, "@media screen { a { x: y } x: y; b { x: y } }", "@media screen {\n  a {\n    x: y;\n  }\n  x: y;\n  b {\n    x: y;\n  }\n}\n", "")
  1316  	expectPrinted(t, ":root { @media screen { a { x: y } x: y; b { x: y } } }", ":root {\n  @media screen {\n    a {\n      x: y;\n    }\n    x: y;\n    b {\n      x: y;\n    }\n  }\n}\n", "")
  1317  }
  1318  
  1319  func TestBadQualifiedRules(t *testing.T) {
  1320  	expectPrinted(t, "$bad: rule;", "$bad: rule; {\n}\n", "<stdin>: WARNING: Unexpected \"$\"\n")
  1321  	expectPrinted(t, "$bad: rule; div { color: red }", "$bad: rule; div {\n  color: red;\n}\n", "<stdin>: WARNING: Unexpected \"$\"\n")
  1322  	expectPrinted(t, "$bad { color: red }", "$bad {\n  color: red;\n}\n", "<stdin>: WARNING: Unexpected \"$\"\n")
  1323  	expectPrinted(t, "a { div.major { color: blue } color: red }", "a {\n  div.major {\n    color: blue;\n  }\n  color: red;\n}\n", "")
  1324  	expectPrinted(t, "a { div:hover { color: blue } color: red }", "a {\n  div:hover {\n    color: blue;\n  }\n  color: red;\n}\n", "")
  1325  	expectPrinted(t, "a { div:hover { color: blue }; color: red }", "a {\n  div:hover {\n    color: blue;\n  }\n  color: red;\n}\n", "")
  1326  	expectPrinted(t, "a { div:hover { color: blue } ; color: red }", "a {\n  div:hover {\n    color: blue;\n  }\n  color: red;\n}\n", "")
  1327  	expectPrinted(t, "! { x: y; }", "! {\n  x: y;\n}\n", "<stdin>: WARNING: Unexpected \"!\"\n")
  1328  	expectPrinted(t, "! { x: {} }", "! {\n  x: {\n  }\n}\n", "<stdin>: WARNING: Unexpected \"!\"\n<stdin>: WARNING: Expected identifier but found whitespace\n")
  1329  	expectPrinted(t, "a { *width: 100%; height: 1px }", "a {\n  *width: 100%;\n  height: 1px;\n}\n", "<stdin>: WARNING: Expected identifier but found \"*\"\n")
  1330  	expectPrinted(t, "a { garbage; height: 1px }", "a {\n  garbage;\n  height: 1px;\n}\n", "<stdin>: WARNING: Expected \":\"\n")
  1331  	expectPrinted(t, "a { !; height: 1px }", "a {\n  !;\n  height: 1px;\n}\n", "<stdin>: WARNING: Expected identifier but found \"!\"\n")
  1332  }
  1333  
  1334  func TestAtRule(t *testing.T) {
  1335  	expectPrinted(t, "@unknown", "@unknown;\n", "<stdin>: WARNING: Expected \"{\" but found end of file\n")
  1336  	expectPrinted(t, "@unknown;", "@unknown;\n", "")
  1337  	expectPrinted(t, "@unknown{}", "@unknown {}\n", "")
  1338  	expectPrinted(t, "@unknown x;", "@unknown x;\n", "")
  1339  	expectPrinted(t, "@unknown{\na: b;\nc: d;\n}", "@unknown { a: b; c: d; }\n", "")
  1340  
  1341  	expectPrinted(t, "@unknown", "@unknown;\n", "<stdin>: WARNING: Expected \"{\" but found end of file\n")
  1342  	expectPrinted(t, "@", "@ {\n}\n", "<stdin>: WARNING: Unexpected \"@\"\n")
  1343  	expectPrinted(t, "@;", "@; {\n}\n", "<stdin>: WARNING: Unexpected \"@\"\n")
  1344  	expectPrinted(t, "@{}", "@ {\n}\n", "<stdin>: WARNING: Unexpected \"@\"\n")
  1345  
  1346  	expectPrinted(t, "@viewport { width: 100vw }", "@viewport {\n  width: 100vw;\n}\n", "")
  1347  	expectPrinted(t, "@-ms-viewport { width: 100vw }", "@-ms-viewport {\n  width: 100vw;\n}\n", "")
  1348  
  1349  	expectPrinted(t, "@document url(\"https://www.example.com/\") { h1 { color: green } }",
  1350  		"@document url(https://www.example.com/) {\n  h1 {\n    color: green;\n  }\n}\n", "")
  1351  	expectPrinted(t, "@-moz-document url-prefix() { h1 { color: green } }",
  1352  		"@-moz-document url-prefix() {\n  h1 {\n    color: green;\n  }\n}\n", "")
  1353  
  1354  	expectPrinted(t, "@media foo { bar }", "@media foo {\n  bar {\n  }\n}\n", "<stdin>: WARNING: Unexpected \"}\"\n")
  1355  	expectPrinted(t, "@media foo { bar {}", "@media foo {\n  bar {\n  }\n}\n", "<stdin>: WARNING: Expected \"}\" to go with \"{\"\n<stdin>: NOTE: The unbalanced \"{\" is here:\n")
  1356  	expectPrinted(t, "@media foo {", "@media foo {\n}\n", "<stdin>: WARNING: Expected \"}\" to go with \"{\"\n<stdin>: NOTE: The unbalanced \"{\" is here:\n")
  1357  	expectPrinted(t, "@media foo", "@media foo {\n}\n", "<stdin>: WARNING: Expected \"{\" but found end of file\n")
  1358  	expectPrinted(t, "@media", "@media {\n}\n", "<stdin>: WARNING: Expected \"{\" but found end of file\n")
  1359  
  1360  	// https://www.w3.org/TR/css-page-3/#syntax-page-selector
  1361  	expectPrinted(t, `
  1362  		@page :first { margin: 0 }
  1363  		@page {
  1364  			@top-left-corner { content: 'tlc' }
  1365  			@top-left { content: 'tl' }
  1366  			@top-center { content: 'tc' }
  1367  			@top-right { content: 'tr' }
  1368  			@top-right-corner { content: 'trc' }
  1369  			@bottom-left-corner { content: 'blc' }
  1370  			@bottom-left { content: 'bl' }
  1371  			@bottom-center { content: 'bc' }
  1372  			@bottom-right { content: 'br' }
  1373  			@bottom-right-corner { content: 'brc' }
  1374  			@left-top { content: 'lt' }
  1375  			@left-middle { content: 'lm' }
  1376  			@left-bottom { content: 'lb' }
  1377  			@right-top { content: 'rt' }
  1378  			@right-middle { content: 'rm' }
  1379  			@right-bottom { content: 'rb' }
  1380  		}
  1381  	`, `@page :first {
  1382    margin: 0;
  1383  }
  1384  @page {
  1385    @top-left-corner {
  1386      content: "tlc";
  1387    }
  1388    @top-left {
  1389      content: "tl";
  1390    }
  1391    @top-center {
  1392      content: "tc";
  1393    }
  1394    @top-right {
  1395      content: "tr";
  1396    }
  1397    @top-right-corner {
  1398      content: "trc";
  1399    }
  1400    @bottom-left-corner {
  1401      content: "blc";
  1402    }
  1403    @bottom-left {
  1404      content: "bl";
  1405    }
  1406    @bottom-center {
  1407      content: "bc";
  1408    }
  1409    @bottom-right {
  1410      content: "br";
  1411    }
  1412    @bottom-right-corner {
  1413      content: "brc";
  1414    }
  1415    @left-top {
  1416      content: "lt";
  1417    }
  1418    @left-middle {
  1419      content: "lm";
  1420    }
  1421    @left-bottom {
  1422      content: "lb";
  1423    }
  1424    @right-top {
  1425      content: "rt";
  1426    }
  1427    @right-middle {
  1428      content: "rm";
  1429    }
  1430    @right-bottom {
  1431      content: "rb";
  1432    }
  1433  }
  1434  `, "")
  1435  
  1436  	// https://drafts.csswg.org/css-fonts-4/#font-palette-values
  1437  	expectPrinted(t, `
  1438  		@font-palette-values --Augusta {
  1439  			font-family: Handover Sans;
  1440  			base-palette: 3;
  1441  			override-colors: 1 rgb(43, 12, 9), 2 #000, 3 var(--highlight)
  1442  		}
  1443  	`, `@font-palette-values --Augusta {
  1444    font-family: Handover Sans;
  1445    base-palette: 3;
  1446    override-colors:
  1447      1 rgb(43, 12, 9),
  1448      2 #000,
  1449      3 var(--highlight);
  1450  }
  1451  `, "")
  1452  
  1453  	// https://drafts.csswg.org/css-contain-3/#container-rule
  1454  	expectPrinted(t, `
  1455  		@container my-layout (inline-size > 45em) {
  1456  			.foo {
  1457  				color: skyblue;
  1458  			}
  1459  		}
  1460  	`, `@container my-layout (inline-size > 45em) {
  1461    .foo {
  1462      color: skyblue;
  1463    }
  1464  }
  1465  `, "")
  1466  	expectPrintedMinify(t, `@container card ( inline-size > 30em ) and style( --responsive = true ) {
  1467  	.foo {
  1468  		color: skyblue;
  1469  	}
  1470  }`, "@container card (inline-size > 30em) and style(--responsive = true){.foo{color:skyblue}}", "")
  1471  	expectPrintedMangleMinify(t, `@supports ( container-type: size ) {
  1472  	@container ( width <= 150px ) {
  1473  		#inner {
  1474  			background-color: skyblue;
  1475  		}
  1476  	}
  1477  }`, "@supports (container-type: size){@container (width <= 150px){#inner{background-color:#87ceeb}}}", "")
  1478  
  1479  	// https://drafts.csswg.org/css-transitions-2/#defining-before-change-style-the-starting-style-rule
  1480  	expectPrinted(t, `
  1481  		@starting-style {
  1482  			h1 {
  1483  				background-color: transparent;
  1484  			}
  1485  			@layer foo {
  1486  				div {
  1487  					height: 100px;
  1488  				}
  1489  			}
  1490  		}
  1491  	`, `@starting-style {
  1492    h1 {
  1493      background-color: transparent;
  1494    }
  1495    @layer foo {
  1496      div {
  1497        height: 100px;
  1498      }
  1499    }
  1500  }
  1501  `, "")
  1502  
  1503  	expectPrintedMinify(t, `@starting-style {
  1504  	h1 {
  1505  		background-color: transparent;
  1506  	}
  1507  }`, "@starting-style{h1{background-color:transparent}}", "")
  1508  
  1509  	// https://drafts.csswg.org/css-counter-styles/#the-counter-style-rule
  1510  	expectPrinted(t, `
  1511  		@counter-style box-corner {
  1512  			system: fixed;
  1513  			symbols: â—° â—³ â—² â—±;
  1514  			suffix: ': '
  1515  		}
  1516  	`, `@counter-style box-corner {
  1517    system: fixed;
  1518    symbols: â—° â—³ â—² â—±;
  1519    suffix: ": ";
  1520  }
  1521  `, "")
  1522  
  1523  	// https://drafts.csswg.org/css-fonts/#font-feature-values
  1524  	expectPrinted(t, `
  1525  		@font-feature-values Roboto {
  1526  			font-display: swap;
  1527  		}
  1528  	`, `@font-feature-values Roboto {
  1529    font-display: swap;
  1530  }
  1531  `, "")
  1532  	expectPrinted(t, `
  1533  		@font-feature-values Bongo {
  1534  			@swash { ornate: 1 }
  1535  		}
  1536  	`, `@font-feature-values Bongo {
  1537    @swash {
  1538      ornate: 1;
  1539    }
  1540  }
  1541  `, "")
  1542  
  1543  	// https://drafts.csswg.org/css-anchor-position-1/#at-ruledef-position-try
  1544  	expectPrinted(t, `@position-try --foo { top: 0 }`,
  1545  		`@position-try --foo {
  1546    top: 0;
  1547  }
  1548  `, "")
  1549  	expectPrintedMinify(t, `@position-try --foo { top: 0; }`, `@position-try --foo{top:0}`, "")
  1550  }
  1551  
  1552  func TestAtCharset(t *testing.T) {
  1553  	expectPrinted(t, "@charset \"UTF-8\";", "@charset \"UTF-8\";\n", "")
  1554  	expectPrinted(t, "@charset 'UTF-8';", "@charset \"UTF-8\";\n", "")
  1555  	expectPrinted(t, "@charset \"utf-8\";", "@charset \"utf-8\";\n", "")
  1556  	expectPrinted(t, "@charset \"Utf-8\";", "@charset \"Utf-8\";\n", "")
  1557  	expectPrinted(t, "@charset \"US-ASCII\";", "@charset \"US-ASCII\";\n", "<stdin>: WARNING: \"UTF-8\" will be used instead of unsupported charset \"US-ASCII\"\n")
  1558  	expectPrinted(t, "@charset;", "@charset;\n", "<stdin>: WARNING: Expected whitespace but found \";\"\n")
  1559  	expectPrinted(t, "@charset ;", "@charset;\n", "<stdin>: WARNING: Expected string token but found \";\"\n")
  1560  	expectPrinted(t, "@charset\"UTF-8\";", "@charset \"UTF-8\";\n", "<stdin>: WARNING: Expected whitespace but found \"\\\"UTF-8\\\"\"\n")
  1561  	expectPrinted(t, "@charset \"UTF-8\"", "@charset \"UTF-8\";\n", "<stdin>: WARNING: Expected \";\" but found end of file\n")
  1562  	expectPrinted(t, "@charset url(UTF-8);", "@charset url(UTF-8);\n", "<stdin>: WARNING: Expected string token but found \"url(UTF-8)\"\n")
  1563  	expectPrinted(t, "@charset url(\"UTF-8\");", "@charset url(UTF-8);\n", "<stdin>: WARNING: Expected string token but found \"url(\"\n")
  1564  	expectPrinted(t, "@charset \"UTF-8\" ", "@charset \"UTF-8\";\n", "<stdin>: WARNING: Expected \";\" but found whitespace\n")
  1565  	expectPrinted(t, "@charset \"UTF-8\"{}", "@charset \"UTF-8\";\n {\n}\n", "<stdin>: WARNING: Expected \";\" but found \"{\"\n")
  1566  }
  1567  
  1568  func TestAtImport(t *testing.T) {
  1569  	expectPrinted(t, "@import\"foo.css\";", "@import \"foo.css\";\n", "")
  1570  	expectPrinted(t, "@import \"foo.css\";", "@import \"foo.css\";\n", "")
  1571  	expectPrinted(t, "@import \"foo.css\" ;", "@import \"foo.css\";\n", "")
  1572  	expectPrinted(t, "@import url();", "@import \"\";\n", "")
  1573  	expectPrinted(t, "@import url(foo.css);", "@import \"foo.css\";\n", "")
  1574  	expectPrinted(t, "@import url(foo.css) ;", "@import \"foo.css\";\n", "")
  1575  	expectPrinted(t, "@import url( foo.css );", "@import \"foo.css\";\n", "")
  1576  	expectPrinted(t, "@import url(\"foo.css\");", "@import \"foo.css\";\n", "")
  1577  	expectPrinted(t, "@import url(\"foo.css\") ;", "@import \"foo.css\";\n", "")
  1578  	expectPrinted(t, "@import url( \"foo.css\" );", "@import \"foo.css\";\n", "")
  1579  	expectPrinted(t, "@import url(\"foo.css\") print;", "@import \"foo.css\" print;\n", "")
  1580  	expectPrinted(t, "@import url(\"foo.css\") screen and (orientation:landscape);", "@import \"foo.css\" screen and (orientation:landscape);\n", "")
  1581  
  1582  	expectPrinted(t, "@import;", "@import;\n", "<stdin>: WARNING: Expected URL token but found \";\"\n")
  1583  	expectPrinted(t, "@import ;", "@import;\n", "<stdin>: WARNING: Expected URL token but found \";\"\n")
  1584  	expectPrinted(t, "@import \"foo.css\"", "@import \"foo.css\";\n", "<stdin>: WARNING: Expected \";\" but found end of file\n")
  1585  	expectPrinted(t, "@import url(\"foo.css\" extra-stuff);", "@import url(\"foo.css\" extra-stuff);\n", "<stdin>: WARNING: Expected URL token but found \"url(\"\n")
  1586  	expectPrinted(t, "@import url(\"foo.css\";", "@import url(\"foo.css\";);\n",
  1587  		"<stdin>: WARNING: Expected URL token but found \"url(\"\n<stdin>: WARNING: Expected \")\" to go with \"(\"\n<stdin>: NOTE: The unbalanced \"(\" is here:\n")
  1588  	expectPrinted(t, "@import noturl(\"foo.css\");", "@import noturl(\"foo.css\");\n", "<stdin>: WARNING: Expected URL token but found \"noturl(\"\n")
  1589  	expectPrinted(t, "@import url(foo.css", "@import \"foo.css\";\n", `<stdin>: WARNING: Expected ")" to end URL token
  1590  <stdin>: NOTE: The unbalanced "(" is here:
  1591  <stdin>: WARNING: Expected ";" but found end of file
  1592  `)
  1593  
  1594  	expectPrinted(t, "@import \"foo.css\" {}", "@import \"foo.css\" {}\n", "<stdin>: WARNING: Expected \";\"\n")
  1595  	expectPrinted(t, "@import \"foo\"\na { color: red }\nb { color: blue }", "@import \"foo\" a { color: red }\nb {\n  color: blue;\n}\n", "<stdin>: WARNING: Expected \";\"\n")
  1596  
  1597  	expectPrinted(t, "a { @import \"foo.css\" }", "a {\n  @import \"foo.css\";\n}\n", "<stdin>: WARNING: \"@import\" is only valid at the top level\n<stdin>: WARNING: Expected \";\"\n")
  1598  }
  1599  
  1600  func TestLegalComment(t *testing.T) {
  1601  	expectPrinted(t, "/*!*/@import \"x\";", "/*!*/\n@import \"x\";\n", "")
  1602  	expectPrinted(t, "/*!*/@charset \"UTF-8\";", "/*!*/\n@charset \"UTF-8\";\n", "")
  1603  	expectPrinted(t, "/*!*/ @import \"x\";", "/*!*/\n@import \"x\";\n", "")
  1604  	expectPrinted(t, "/*!*/ @charset \"UTF-8\";", "/*!*/\n@charset \"UTF-8\";\n", "")
  1605  	expectPrinted(t, "/*!*/ @charset \"UTF-8\"; @import \"x\";", "/*!*/\n@charset \"UTF-8\";\n@import \"x\";\n", "")
  1606  	expectPrinted(t, "/*!*/ @import \"x\"; @charset \"UTF-8\";", "/*!*/\n@import \"x\";\n@charset \"UTF-8\";\n",
  1607  		"<stdin>: WARNING: \"@charset\" must be the first rule in the file\n"+
  1608  			"<stdin>: NOTE: This rule cannot come before a \"@charset\" rule\n")
  1609  
  1610  	expectPrinted(t, "@import \"x\";/*!*/", "@import \"x\";\n/*!*/\n", "")
  1611  	expectPrinted(t, "@charset \"UTF-8\";/*!*/", "@charset \"UTF-8\";\n/*!*/\n", "")
  1612  	expectPrinted(t, "@import \"x\"; /*!*/", "@import \"x\";\n/*!*/\n", "")
  1613  	expectPrinted(t, "@charset \"UTF-8\"; /*!*/", "@charset \"UTF-8\";\n/*!*/\n", "")
  1614  
  1615  	expectPrinted(t, "/*! before */ a { --b: var(--c, /*!*/ /*!*/); } /*! after */\n", "/*! before */\na {\n  --b: var(--c, );\n}\n/*! after */\n", "")
  1616  }
  1617  
  1618  func TestAtKeyframes(t *testing.T) {
  1619  	expectPrinted(t, "@keyframes {}", "@keyframes {}\n", "<stdin>: WARNING: Expected identifier but found \"{\"\n")
  1620  	expectPrinted(t, "@keyframes name{}", "@keyframes name {\n}\n", "")
  1621  	expectPrinted(t, "@keyframes name {}", "@keyframes name {\n}\n", "")
  1622  	expectPrinted(t, "@keyframes name{0%,50%{color:red}25%,75%{color:blue}}",
  1623  		"@keyframes name {\n  0%, 50% {\n    color: red;\n  }\n  25%, 75% {\n    color: blue;\n  }\n}\n", "")
  1624  	expectPrinted(t, "@keyframes name { 0%, 50% { color: red } 25%, 75% { color: blue } }",
  1625  		"@keyframes name {\n  0%, 50% {\n    color: red;\n  }\n  25%, 75% {\n    color: blue;\n  }\n}\n", "")
  1626  	expectPrinted(t, "@keyframes name{from{color:red}to{color:blue}}",
  1627  		"@keyframes name {\n  from {\n    color: red;\n  }\n  to {\n    color: blue;\n  }\n}\n", "")
  1628  	expectPrinted(t, "@keyframes name { from { color: red } to { color: blue } }",
  1629  		"@keyframes name {\n  from {\n    color: red;\n  }\n  to {\n    color: blue;\n  }\n}\n", "")
  1630  
  1631  	// Note: Strings as names is allowed in the CSS specification and works in
  1632  	// Firefox and Safari but Chrome has strangely decided to deliberately not
  1633  	// support this. We always turn all string names into identifiers to avoid
  1634  	// them silently breaking in Chrome.
  1635  	expectPrinted(t, "@keyframes 'name' {}", "@keyframes name {\n}\n", "")
  1636  	expectPrinted(t, "@keyframes 'name 2' {}", "@keyframes name\\ 2 {\n}\n", "")
  1637  	expectPrinted(t, "@keyframes 'none' {}", "@keyframes \"none\" {}\n", "")
  1638  	expectPrinted(t, "@keyframes 'None' {}", "@keyframes \"None\" {}\n", "")
  1639  	expectPrinted(t, "@keyframes 'unset' {}", "@keyframes \"unset\" {}\n", "")
  1640  	expectPrinted(t, "@keyframes 'revert' {}", "@keyframes \"revert\" {}\n", "")
  1641  	expectPrinted(t, "@keyframes None {}", "@keyframes None {}\n",
  1642  		"<stdin>: WARNING: Cannot use \"None\" as a name for \"@keyframes\" without quotes\n"+
  1643  			"NOTE: You can put \"None\" in quotes to prevent it from becoming a CSS keyword.\n")
  1644  	expectPrinted(t, "@keyframes REVERT {}", "@keyframes REVERT {}\n",
  1645  		"<stdin>: WARNING: Cannot use \"REVERT\" as a name for \"@keyframes\" without quotes\n"+
  1646  			"NOTE: You can put \"REVERT\" in quotes to prevent it from becoming a CSS keyword.\n")
  1647  
  1648  	expectPrinted(t, "@keyframes name { from { color: red } }", "@keyframes name {\n  from {\n    color: red;\n  }\n}\n", "")
  1649  	expectPrinted(t, "@keyframes name { 100% { color: red } }", "@keyframes name {\n  100% {\n    color: red;\n  }\n}\n", "")
  1650  	expectPrintedMangle(t, "@keyframes name { from { color: red } }", "@keyframes name {\n  0% {\n    color: red;\n  }\n}\n", "")
  1651  	expectPrintedMangle(t, "@keyframes name { 100% { color: red } }", "@keyframes name {\n  to {\n    color: red;\n  }\n}\n", "")
  1652  
  1653  	expectPrinted(t, "@-webkit-keyframes name {}", "@-webkit-keyframes name {\n}\n", "")
  1654  	expectPrinted(t, "@-moz-keyframes name {}", "@-moz-keyframes name {\n}\n", "")
  1655  	expectPrinted(t, "@-ms-keyframes name {}", "@-ms-keyframes name {\n}\n", "")
  1656  	expectPrinted(t, "@-o-keyframes name {}", "@-o-keyframes name {\n}\n", "")
  1657  
  1658  	expectPrinted(t, "@keyframes {}", "@keyframes {}\n", "<stdin>: WARNING: Expected identifier but found \"{\"\n")
  1659  	expectPrinted(t, "@keyframes name { 0% 100% {} }", "@keyframes name { 0% 100% {} }\n", "<stdin>: WARNING: Expected \",\" but found \"100%\"\n")
  1660  	expectPrinted(t, "@keyframes name { {} 0% {} }", "@keyframes name { {} 0% {} }\n", "<stdin>: WARNING: Expected percentage but found \"{\"\n")
  1661  	expectPrinted(t, "@keyframes name { 100 {} }", "@keyframes name { 100 {} }\n", "<stdin>: WARNING: Expected percentage but found \"100\"\n")
  1662  	expectPrinted(t, "@keyframes name { into {} }", "@keyframes name {\n  into {\n  }\n}\n", "<stdin>: WARNING: Expected percentage but found \"into\"\n")
  1663  	expectPrinted(t, "@keyframes name { 1,2 {} }", "@keyframes name { 1, 2 {} }\n", "<stdin>: WARNING: Expected percentage but found \"1\"\n")
  1664  	expectPrinted(t, "@keyframes name { 1, 2 {} }", "@keyframes name { 1, 2 {} }\n", "<stdin>: WARNING: Expected percentage but found \"1\"\n")
  1665  	expectPrinted(t, "@keyframes name { 1 ,2 {} }", "@keyframes name { 1, 2 {} }\n", "<stdin>: WARNING: Expected percentage but found \"1\"\n")
  1666  	expectPrinted(t, "@keyframes name { 1%, {} }", "@keyframes name { 1%, {} }\n", "<stdin>: WARNING: Expected percentage but found \"{\"\n")
  1667  	expectPrinted(t, "@keyframes name { 1%, x {} }", "@keyframes name {\n  1%, x {\n  }\n}\n", "<stdin>: WARNING: Expected percentage but found \"x\"\n")
  1668  	expectPrinted(t, "@keyframes name { 1%, ! {} }", "@keyframes name { 1%, ! {} }\n", "<stdin>: WARNING: Expected percentage but found \"!\"\n")
  1669  	expectPrinted(t, "@keyframes name { .x {} }", "@keyframes name { .x {} }\n", "<stdin>: WARNING: Expected percentage but found \".\"\n")
  1670  	expectPrinted(t, "@keyframes name { {} }", "@keyframes name { {} }\n", "<stdin>: WARNING: Expected percentage but found \"{\"\n")
  1671  	expectPrinted(t, "@keyframes name { 1% }", "@keyframes name { 1% }\n", "<stdin>: WARNING: Expected \"{\" but found \"}\"\n")
  1672  	expectPrinted(t, "@keyframes name { 1%", "@keyframes name { 1% }\n", "<stdin>: WARNING: Expected \"{\" but found end of file\n")
  1673  	expectPrinted(t, "@keyframes name { 1%,,2% {} }", "@keyframes name { 1%,, 2% {} }\n", "<stdin>: WARNING: Expected percentage but found \",\"\n")
  1674  	expectPrinted(t, "@keyframes name {", "@keyframes name {}\n", "<stdin>: WARNING: Expected \"}\" to go with \"{\"\n<stdin>: NOTE: The unbalanced \"{\" is here:\n")
  1675  
  1676  	expectPrinted(t, "@keyframes x { 1%, {} } @keyframes z { 1% {} }", "@keyframes x { 1%, {} }\n@keyframes z {\n  1% {\n  }\n}\n", "<stdin>: WARNING: Expected percentage but found \"{\"\n")
  1677  	expectPrinted(t, "@keyframes x { .y {} } @keyframes z { 1% {} }", "@keyframes x { .y {} }\n@keyframes z {\n  1% {\n  }\n}\n", "<stdin>: WARNING: Expected percentage but found \".\"\n")
  1678  	expectPrinted(t, "@keyframes x { x {} } @keyframes z { 1% {} }", "@keyframes x {\n  x {\n  }\n}\n@keyframes z {\n  1% {\n  }\n}\n", "<stdin>: WARNING: Expected percentage but found \"x\"\n")
  1679  	expectPrinted(t, "@keyframes x { {} } @keyframes z { 1% {} }", "@keyframes x { {} }\n@keyframes z {\n  1% {\n  }\n}\n", "<stdin>: WARNING: Expected percentage but found \"{\"\n")
  1680  	expectPrinted(t, "@keyframes x { 1% {}", "@keyframes x { 1% {} }\n", "<stdin>: WARNING: Expected \"}\" to go with \"{\"\n<stdin>: NOTE: The unbalanced \"{\" is here:\n")
  1681  	expectPrinted(t, "@keyframes x { 1% {", "@keyframes x { 1% {} }\n", "<stdin>: WARNING: Expected \"}\" to go with \"{\"\n<stdin>: NOTE: The unbalanced \"{\" is here:\n")
  1682  	expectPrinted(t, "@keyframes x { 1%", "@keyframes x { 1% }\n", "<stdin>: WARNING: Expected \"{\" but found end of file\n")
  1683  	expectPrinted(t, "@keyframes x {", "@keyframes x {}\n", "<stdin>: WARNING: Expected \"}\" to go with \"{\"\n<stdin>: NOTE: The unbalanced \"{\" is here:\n")
  1684  }
  1685  
  1686  func TestAnimationName(t *testing.T) {
  1687  	// Note: Strings as names is allowed in the CSS specification and works in
  1688  	// Firefox and Safari but Chrome has strangely decided to deliberately not
  1689  	// support this. We always turn all string names into identifiers to avoid
  1690  	// them silently breaking in Chrome.
  1691  	expectPrinted(t, "div { animation-name: 'name' }", "div {\n  animation-name: name;\n}\n", "")
  1692  	expectPrinted(t, "div { animation-name: 'name 2' }", "div {\n  animation-name: name\\ 2;\n}\n", "")
  1693  	expectPrinted(t, "div { animation-name: 'none' }", "div {\n  animation-name: \"none\";\n}\n", "")
  1694  	expectPrinted(t, "div { animation-name: 'None' }", "div {\n  animation-name: \"None\";\n}\n", "")
  1695  	expectPrinted(t, "div { animation-name: 'unset' }", "div {\n  animation-name: \"unset\";\n}\n", "")
  1696  	expectPrinted(t, "div { animation-name: 'revert' }", "div {\n  animation-name: \"revert\";\n}\n", "")
  1697  	expectPrinted(t, "div { animation-name: none }", "div {\n  animation-name: none;\n}\n", "")
  1698  	expectPrinted(t, "div { animation-name: unset }", "div {\n  animation-name: unset;\n}\n", "")
  1699  	expectPrinted(t, "div { animation: 2s linear 'name 2', 3s infinite 'name 3' }", "div {\n  animation: 2s linear name\\ 2, 3s infinite name\\ 3;\n}\n", "")
  1700  }
  1701  
  1702  func TestAtRuleValidation(t *testing.T) {
  1703  	expectPrinted(t, "a {} b {} c {} @charset \"UTF-8\";", "a {\n}\nb {\n}\nc {\n}\n@charset \"UTF-8\";\n",
  1704  		"<stdin>: WARNING: \"@charset\" must be the first rule in the file\n"+
  1705  			"<stdin>: NOTE: This rule cannot come before a \"@charset\" rule\n")
  1706  
  1707  	expectPrinted(t, "a {} b {} c {} @import \"foo\";", "a {\n}\nb {\n}\nc {\n}\n@import \"foo\";\n",
  1708  		"<stdin>: WARNING: All \"@import\" rules must come first\n"+
  1709  			"<stdin>: NOTE: This rule cannot come before an \"@import\" rule\n")
  1710  }
  1711  
  1712  func TestAtLayer(t *testing.T) {
  1713  	expectPrinted(t, "@layer a, b;", "@layer a, b;\n", "")
  1714  	expectPrinted(t, "@layer a {}", "@layer a {\n}\n", "")
  1715  	expectPrinted(t, "@layer {}", "@layer {\n}\n", "")
  1716  	expectPrinted(t, "@layer a, b {}", "@layer a, b {\n}\n", "<stdin>: WARNING: Expected \";\"\n")
  1717  	expectPrinted(t, "@layer;", "@layer;\n", "<stdin>: WARNING: Unexpected \";\"\n")
  1718  	expectPrinted(t, "@layer , b {}", "@layer , b {\n}\n", "<stdin>: WARNING: Unexpected \",\"\n")
  1719  	expectPrinted(t, "@layer a", "@layer a;\n", "<stdin>: WARNING: Expected \";\" but found end of file\n")
  1720  	expectPrinted(t, "@layer a { @layer b }", "@layer a {\n  @layer b;\n}\n", "<stdin>: WARNING: Expected \";\"\n")
  1721  	expectPrinted(t, "@layer a b", "@layer a b;\n", "<stdin>: WARNING: Unexpected \"b\"\n<stdin>: WARNING: Expected \";\" but found end of file\n")
  1722  	expectPrinted(t, "@layer a b ;", "@layer a b;\n", "<stdin>: WARNING: Unexpected \"b\"\n")
  1723  	expectPrinted(t, "@layer a b {}", "@layer a b {\n}\n", "<stdin>: WARNING: Unexpected \"b\"\n")
  1724  
  1725  	expectPrinted(t, "@layer a, b;", "@layer a, b;\n", "")
  1726  	expectPrinted(t, "@layer a {}", "@layer a {\n}\n", "")
  1727  	expectPrinted(t, "@layer {}", "@layer {\n}\n", "")
  1728  	expectPrinted(t, "@layer foo { div { color: red } }", "@layer foo {\n  div {\n    color: red;\n  }\n}\n", "")
  1729  
  1730  	// Check semicolon error recovery
  1731  	expectPrinted(t, "@layer", "@layer;\n", "<stdin>: WARNING: Expected \";\" but found end of file\n")
  1732  	expectPrinted(t, "@layer a", "@layer a;\n", "<stdin>: WARNING: Expected \";\" but found end of file\n")
  1733  	expectPrinted(t, "@layer a { @layer }", "@layer a {\n  @layer;\n}\n", "<stdin>: WARNING: Expected \";\"\n")
  1734  	expectPrinted(t, "@layer a { @layer b }", "@layer a {\n  @layer b;\n}\n", "<stdin>: WARNING: Expected \";\"\n")
  1735  	expectPrintedMangle(t, "@layer", "@layer;\n", "<stdin>: WARNING: Expected \";\" but found end of file\n")
  1736  	expectPrintedMangle(t, "@layer a", "@layer a;\n", "<stdin>: WARNING: Expected \";\" but found end of file\n")
  1737  	expectPrintedMangle(t, "@layer a { @layer }", "@layer a {\n  @layer;\n}\n", "<stdin>: WARNING: Expected \";\"\n")
  1738  	expectPrintedMangle(t, "@layer a { @layer b }", "@layer a.b;\n", "<stdin>: WARNING: Expected \";\"\n")
  1739  
  1740  	// Check mangling
  1741  	expectPrintedMangle(t, "@layer foo { div {} }", "@layer foo;\n", "")
  1742  	expectPrintedMangle(t, "@layer foo { div { color: yellow } }", "@layer foo {\n  div {\n    color: #ff0;\n  }\n}\n", "")
  1743  	expectPrintedMangle(t, "@layer a { @layer b {} }", "@layer a.b;\n", "")
  1744  	expectPrintedMangle(t, "@layer a { @layer {} }", "@layer a {\n  @layer {\n  }\n}\n", "")
  1745  	expectPrintedMangle(t, "@layer { @layer a {} }", "@layer {\n  @layer a;\n}\n", "")
  1746  	expectPrintedMangle(t, "@layer a.b { @layer c.d {} }", "@layer a.b.c.d;\n", "")
  1747  	expectPrintedMangle(t, "@layer a.b { @layer c.d {} @layer e.f {} }", "@layer a.b {\n  @layer c.d;\n  @layer e.f;\n}\n", "")
  1748  	expectPrintedMangle(t, "@layer a.b { @layer c.d { e { f: g } } }", "@layer a.b.c.d {\n  e {\n    f: g;\n  }\n}\n", "")
  1749  
  1750  	// Invalid layer names should not be merged, since that causes the rule to
  1751  	// become invalid. It would be a change in semantics if we merged an invalid
  1752  	// rule with a valid rule since then the other valid rule would be invalid.
  1753  	initial := "<stdin>: WARNING: \"initial\" cannot be used as a layer name\n"
  1754  	inherit := "<stdin>: WARNING: \"inherit\" cannot be used as a layer name\n"
  1755  	unset := "<stdin>: WARNING: \"unset\" cannot be used as a layer name\n"
  1756  	expectPrinted(t, "@layer foo { @layer initial; }", "@layer foo {\n  @layer initial;\n}\n", initial)
  1757  	expectPrinted(t, "@layer foo { @layer inherit; }", "@layer foo {\n  @layer inherit;\n}\n", inherit)
  1758  	expectPrinted(t, "@layer foo { @layer unset; }", "@layer foo {\n  @layer unset;\n}\n", unset)
  1759  	expectPrinted(t, "@layer initial { @layer foo; }", "@layer initial {\n  @layer foo;\n}\n", initial)
  1760  	expectPrinted(t, "@layer inherit { @layer foo; }", "@layer inherit {\n  @layer foo;\n}\n", inherit)
  1761  	expectPrinted(t, "@layer unset { @layer foo; }", "@layer unset {\n  @layer foo;\n}\n", unset)
  1762  	expectPrintedMangle(t, "@layer foo { @layer initial { a { b: c } } }", "@layer foo {\n  @layer initial {\n    a {\n      b: c;\n    }\n  }\n}\n", initial)
  1763  	expectPrintedMangle(t, "@layer initial { @layer foo { a { b: c } } }", "@layer initial {\n  @layer foo {\n    a {\n      b: c;\n    }\n  }\n}\n", initial)
  1764  
  1765  	// Order matters here. Do not drop the first "@layer a;" or the order will be changed.
  1766  	expectPrintedMangle(t, "@layer a; @layer b; @layer a;", "@layer a;\n@layer b;\n@layer a;\n", "")
  1767  
  1768  	// Validate ordering with "@layer" and "@import"
  1769  	expectPrinted(t, "@layer a; @import url(b);", "@layer a;\n@import \"b\";\n", "")
  1770  	expectPrinted(t, "@layer a; @layer b; @import url(c);", "@layer a;\n@layer b;\n@import \"c\";\n", "")
  1771  	expectPrinted(t, "@layer a {} @import url(b);", "@layer a {\n}\n@import url(b);\n",
  1772  		"<stdin>: WARNING: All \"@import\" rules must come first\n<stdin>: NOTE: This rule cannot come before an \"@import\" rule\n")
  1773  	expectPrinted(t, "@import url(a); @layer b; @import url(c);", "@import \"a\";\n@layer b;\n@import url(c);\n",
  1774  		"<stdin>: WARNING: All \"@import\" rules must come first\n<stdin>: NOTE: This rule cannot come before an \"@import\" rule\n")
  1775  	expectPrinted(t, "@layer a; @charset \"UTF-8\";", "@layer a;\n@charset \"UTF-8\";\n",
  1776  		"<stdin>: WARNING: \"@charset\" must be the first rule in the file\n<stdin>: NOTE: This rule cannot come before a \"@charset\" rule\n")
  1777  }
  1778  
  1779  func TestEmptyRule(t *testing.T) {
  1780  	expectPrinted(t, "div {}", "div {\n}\n", "")
  1781  	expectPrinted(t, "@media screen {}", "@media screen {\n}\n", "")
  1782  	expectPrinted(t, "@page { @top-left {} }", "@page {\n  @top-left {\n  }\n}\n", "")
  1783  	expectPrinted(t, "@keyframes test { from {} to {} }", "@keyframes test {\n  from {\n  }\n  to {\n  }\n}\n", "")
  1784  
  1785  	expectPrintedMangle(t, "div {}", "", "")
  1786  	expectPrintedMangle(t, "@media screen {}", "", "")
  1787  	expectPrintedMangle(t, "@page { @top-left {} }", "", "")
  1788  	expectPrintedMangle(t, "@keyframes test { from {} to {} }", "@keyframes test {\n}\n", "")
  1789  
  1790  	expectPrinted(t, "$invalid {}", "$invalid {\n}\n", "<stdin>: WARNING: Unexpected \"$\"\n")
  1791  	expectPrinted(t, "@page { color: red; @top-left {} }", "@page {\n  color: red;\n  @top-left {\n  }\n}\n", "")
  1792  	expectPrinted(t, "@keyframes test { from {} to { color: red } }", "@keyframes test {\n  from {\n  }\n  to {\n    color: red;\n  }\n}\n", "")
  1793  	expectPrinted(t, "@keyframes test { from { color: red } to {} }", "@keyframes test {\n  from {\n    color: red;\n  }\n  to {\n  }\n}\n", "")
  1794  
  1795  	expectPrintedMangle(t, "$invalid {}", "$invalid {\n}\n", "<stdin>: WARNING: Unexpected \"$\"\n")
  1796  	expectPrintedMangle(t, "@page { color: red; @top-left {} }", "@page {\n  color: red;\n}\n", "")
  1797  	expectPrintedMangle(t, "@keyframes test { from {} to { color: red } }", "@keyframes test {\n  to {\n    color: red;\n  }\n}\n", "")
  1798  	expectPrintedMangle(t, "@keyframes test { from { color: red } to {} }", "@keyframes test {\n  0% {\n    color: red;\n  }\n}\n", "")
  1799  
  1800  	expectPrintedMangleMinify(t, "$invalid {}", "$invalid{}", "<stdin>: WARNING: Unexpected \"$\"\n")
  1801  	expectPrintedMangleMinify(t, "@page { color: red; @top-left {} }", "@page{color:red}", "")
  1802  	expectPrintedMangleMinify(t, "@keyframes test { from {} to { color: red } }", "@keyframes test{to{color:red}}", "")
  1803  	expectPrintedMangleMinify(t, "@keyframes test { from { color: red } to {} }", "@keyframes test{0%{color:red}}", "")
  1804  
  1805  	expectPrinted(t, "invalid", "invalid {\n}\n", "<stdin>: WARNING: Expected \"{\" but found end of file\n")
  1806  	expectPrinted(t, "invalid }", "invalid } {\n}\n", "<stdin>: WARNING: Unexpected \"}\"\n")
  1807  }
  1808  
  1809  func TestMarginAndPaddingAndInset(t *testing.T) {
  1810  	for _, x := range []string{"margin", "padding", "inset"} {
  1811  		xTop := x + "-top"
  1812  		xRight := x + "-right"
  1813  		xBottom := x + "-bottom"
  1814  		xLeft := x + "-left"
  1815  		if x == "inset" {
  1816  			xTop = "top"
  1817  			xRight = "right"
  1818  			xBottom = "bottom"
  1819  			xLeft = "left"
  1820  		}
  1821  
  1822  		expectPrinted(t, "a { "+x+": 0 1px 0 1px }", "a {\n  "+x+": 0 1px 0 1px;\n}\n", "")
  1823  		expectPrinted(t, "a { "+x+": 0 1px 0px 1px }", "a {\n  "+x+": 0 1px 0px 1px;\n}\n", "")
  1824  
  1825  		expectPrintedMangle(t, "a { "+xTop+": 0px }", "a {\n  "+xTop+": 0;\n}\n", "")
  1826  		expectPrintedMangle(t, "a { "+xRight+": 0px }", "a {\n  "+xRight+": 0;\n}\n", "")
  1827  		expectPrintedMangle(t, "a { "+xBottom+": 0px }", "a {\n  "+xBottom+": 0;\n}\n", "")
  1828  		expectPrintedMangle(t, "a { "+xLeft+": 0px }", "a {\n  "+xLeft+": 0;\n}\n", "")
  1829  
  1830  		expectPrintedMangle(t, "a { "+xTop+": 1px }", "a {\n  "+xTop+": 1px;\n}\n", "")
  1831  		expectPrintedMangle(t, "a { "+xRight+": 1px }", "a {\n  "+xRight+": 1px;\n}\n", "")
  1832  		expectPrintedMangle(t, "a { "+xBottom+": 1px }", "a {\n  "+xBottom+": 1px;\n}\n", "")
  1833  		expectPrintedMangle(t, "a { "+xLeft+": 1px }", "a {\n  "+xLeft+": 1px;\n}\n", "")
  1834  
  1835  		expectPrintedMangle(t, "a { "+x+": 0 1px 0 0 }", "a {\n  "+x+": 0 1px 0 0;\n}\n", "")
  1836  		expectPrintedMangle(t, "a { "+x+": 0 1px 2px 1px }", "a {\n  "+x+": 0 1px 2px;\n}\n", "")
  1837  		expectPrintedMangle(t, "a { "+x+": 0 1px 0 1px }", "a {\n  "+x+": 0 1px;\n}\n", "")
  1838  		expectPrintedMangle(t, "a { "+x+": 0 0 0 0 }", "a {\n  "+x+": 0;\n}\n", "")
  1839  		expectPrintedMangle(t, "a { "+x+": 0 0 0 0 !important }", "a {\n  "+x+": 0 !important;\n}\n", "")
  1840  		expectPrintedMangle(t, "a { "+x+": 0 1px 0px 1px }", "a {\n  "+x+": 0 1px;\n}\n", "")
  1841  		expectPrintedMangle(t, "a { "+x+": 0 1 0px 1px }", "a {\n  "+x+": 0 1 0px 1px;\n}\n", "")
  1842  
  1843  		expectPrintedMangle(t, "a { "+x+": 1px 2px 3px 4px; "+xTop+": 5px }", "a {\n  "+x+": 5px 2px 3px 4px;\n}\n", "")
  1844  		expectPrintedMangle(t, "a { "+x+": 1px 2px 3px 4px; "+xRight+": 5px }", "a {\n  "+x+": 1px 5px 3px 4px;\n}\n", "")
  1845  		expectPrintedMangle(t, "a { "+x+": 1px 2px 3px 4px; "+xBottom+": 5px }", "a {\n  "+x+": 1px 2px 5px 4px;\n}\n", "")
  1846  		expectPrintedMangle(t, "a { "+x+": 1px 2px 3px 4px; "+xLeft+": 5px }", "a {\n  "+x+": 1px 2px 3px 5px;\n}\n", "")
  1847  
  1848  		expectPrintedMangle(t, "a { "+xTop+": 5px; "+x+": 1px 2px 3px 4px }", "a {\n  "+x+": 1px 2px 3px 4px;\n}\n", "")
  1849  		expectPrintedMangle(t, "a { "+xRight+": 5px; "+x+": 1px 2px 3px 4px }", "a {\n  "+x+": 1px 2px 3px 4px;\n}\n", "")
  1850  		expectPrintedMangle(t, "a { "+xBottom+": 5px; "+x+": 1px 2px 3px 4px }", "a {\n  "+x+": 1px 2px 3px 4px;\n}\n", "")
  1851  		expectPrintedMangle(t, "a { "+xLeft+": 5px; "+x+": 1px 2px 3px 4px }", "a {\n  "+x+": 1px 2px 3px 4px;\n}\n", "")
  1852  
  1853  		expectPrintedMangle(t, "a { "+xTop+": 1px; "+xTop+": 2px }", "a {\n  "+xTop+": 2px;\n}\n", "")
  1854  		expectPrintedMangle(t, "a { "+xRight+": 1px; "+xRight+": 2px }", "a {\n  "+xRight+": 2px;\n}\n", "")
  1855  		expectPrintedMangle(t, "a { "+xBottom+": 1px; "+xBottom+": 2px }", "a {\n  "+xBottom+": 2px;\n}\n", "")
  1856  		expectPrintedMangle(t, "a { "+xLeft+": 1px; "+xLeft+": 2px }", "a {\n  "+xLeft+": 2px;\n}\n", "")
  1857  
  1858  		expectPrintedMangle(t, "a { "+x+": 1px; "+x+": 2px !important }",
  1859  			"a {\n  "+x+": 1px;\n  "+x+": 2px !important;\n}\n", "")
  1860  		expectPrintedMangle(t, "a { "+xTop+": 1px; "+xTop+": 2px !important }",
  1861  			"a {\n  "+xTop+": 1px;\n  "+xTop+": 2px !important;\n}\n", "")
  1862  		expectPrintedMangle(t, "a { "+xRight+": 1px; "+xRight+": 2px !important }",
  1863  			"a {\n  "+xRight+": 1px;\n  "+xRight+": 2px !important;\n}\n", "")
  1864  		expectPrintedMangle(t, "a { "+xBottom+": 1px; "+xBottom+": 2px !important }",
  1865  			"a {\n  "+xBottom+": 1px;\n  "+xBottom+": 2px !important;\n}\n", "")
  1866  		expectPrintedMangle(t, "a { "+xLeft+": 1px; "+xLeft+": 2px !important }",
  1867  			"a {\n  "+xLeft+": 1px;\n  "+xLeft+": 2px !important;\n}\n", "")
  1868  
  1869  		expectPrintedMangle(t, "a { "+x+": 1px !important; "+x+": 2px }",
  1870  			"a {\n  "+x+": 1px !important;\n  "+x+": 2px;\n}\n", "")
  1871  		expectPrintedMangle(t, "a { "+xTop+": 1px !important; "+xTop+": 2px }",
  1872  			"a {\n  "+xTop+": 1px !important;\n  "+xTop+": 2px;\n}\n", "")
  1873  		expectPrintedMangle(t, "a { "+xRight+": 1px !important; "+xRight+": 2px }",
  1874  			"a {\n  "+xRight+": 1px !important;\n  "+xRight+": 2px;\n}\n", "")
  1875  		expectPrintedMangle(t, "a { "+xBottom+": 1px !important; "+xBottom+": 2px }",
  1876  			"a {\n  "+xBottom+": 1px !important;\n  "+xBottom+": 2px;\n}\n", "")
  1877  		expectPrintedMangle(t, "a { "+xLeft+": 1px !important; "+xLeft+": 2px }",
  1878  			"a {\n  "+xLeft+": 1px !important;\n  "+xLeft+": 2px;\n}\n", "")
  1879  
  1880  		expectPrintedMangle(t, "a { "+xTop+": 1px; "+xTop+": }", "a {\n  "+xTop+": 1px;\n  "+xTop+":;\n}\n", "")
  1881  		expectPrintedMangle(t, "a { "+xTop+": 1px; "+xTop+": 2px 3px }", "a {\n  "+xTop+": 1px;\n  "+xTop+": 2px 3px;\n}\n", "")
  1882  		expectPrintedMangle(t, "a { "+x+": 1px 2px 3px 4px; "+xLeft+": -4px; "+xRight+": -2px }", "a {\n  "+x+": 1px -2px 3px -4px;\n}\n", "")
  1883  		expectPrintedMangle(t, "a { "+x+": 1px 2px; "+xTop+": 5px }", "a {\n  "+x+": 5px 2px 1px;\n}\n", "")
  1884  		expectPrintedMangle(t, "a { "+x+": 1px; "+xTop+": 5px }", "a {\n  "+x+": 5px 1px 1px;\n}\n", "")
  1885  
  1886  		// This doesn't collapse because if the "calc" has an error it
  1887  		// will be ignored and the original rule will show through
  1888  		expectPrintedMangle(t, "a { "+x+": 1px 2px 3px 4px; "+xRight+": calc(1px + var(--x)) }",
  1889  			"a {\n  "+x+": 1px 2px 3px 4px;\n  "+xRight+": calc(1px + var(--x));\n}\n", "")
  1890  
  1891  		expectPrintedMangle(t, "a { "+xLeft+": 1px; "+xRight+": 2px; "+xTop+": 3px; "+xBottom+": 4px }", "a {\n  "+x+": 3px 2px 4px 1px;\n}\n", "")
  1892  		expectPrintedMangle(t, "a { "+x+": 1px 2px 3px 4px; "+xRight+": 5px !important }",
  1893  			"a {\n  "+x+": 1px 2px 3px 4px;\n  "+xRight+": 5px !important;\n}\n", "")
  1894  		expectPrintedMangle(t, "a { "+x+": 1px 2px 3px 4px !important; "+xRight+": 5px }",
  1895  			"a {\n  "+x+": 1px 2px 3px 4px !important;\n  "+xRight+": 5px;\n}\n", "")
  1896  		expectPrintedMangle(t, "a { "+xLeft+": 1px !important; "+xRight+": 2px; "+xTop+": 3px !important; "+xBottom+": 4px }",
  1897  			"a {\n  "+xLeft+": 1px !important;\n  "+xRight+": 2px;\n  "+xTop+": 3px !important;\n  "+xBottom+": 4px;\n}\n", "")
  1898  
  1899  		// This should not be changed because "--x" and "--z" could be empty
  1900  		expectPrintedMangle(t, "a { "+x+": var(--x) var(--y) var(--z) var(--y) }", "a {\n  "+x+": var(--x) var(--y) var(--z) var(--y);\n}\n", "")
  1901  
  1902  		// Don't merge different units
  1903  		expectPrintedMangle(t, "a { "+x+": 1px; "+x+": 2px; }", "a {\n  "+x+": 2px;\n}\n", "")
  1904  		expectPrintedMangle(t, "a { "+x+": 1px; "+x+": 2vw; }", "a {\n  "+x+": 1px;\n  "+x+": 2vw;\n}\n", "")
  1905  		expectPrintedMangle(t, "a { "+xLeft+": 1px; "+xLeft+": 2px; }", "a {\n  "+xLeft+": 2px;\n}\n", "")
  1906  		expectPrintedMangle(t, "a { "+xLeft+": 1px; "+xLeft+": 2vw; }", "a {\n  "+xLeft+": 1px;\n  "+xLeft+": 2vw;\n}\n", "")
  1907  		expectPrintedMangle(t, "a { "+x+": 0 1px 2cm 3%; "+x+": 4px; }", "a {\n  "+x+": 4px;\n}\n", "")
  1908  		expectPrintedMangle(t, "a { "+x+": 0 1px 2cm 3%; "+x+": 4vw; }", "a {\n  "+x+": 0 1px 2cm 3%;\n  "+x+": 4vw;\n}\n", "")
  1909  		expectPrintedMangle(t, "a { "+x+": 0 1px 2cm 3%; "+xLeft+": 4px; }", "a {\n  "+x+": 0 1px 2cm 4px;\n}\n", "")
  1910  		expectPrintedMangle(t, "a { "+x+": 0 1px 2cm 3%; "+xLeft+": 4vw; }", "a {\n  "+x+": 0 1px 2cm 3%;\n  "+xLeft+": 4vw;\n}\n", "")
  1911  		expectPrintedMangle(t, "a { "+xLeft+": 1Q; "+xRight+": 2Q; "+xTop+": 3Q; "+xBottom+": 4Q; }", "a {\n  "+x+": 3Q 2Q 4Q 1Q;\n}\n", "")
  1912  		expectPrintedMangle(t, "a { "+xLeft+": 1Q; "+xRight+": 2Q; "+xTop+": 3Q; "+xBottom+": 0; }",
  1913  			"a {\n  "+xLeft+": 1Q;\n  "+xRight+": 2Q;\n  "+xTop+": 3Q;\n  "+xBottom+": 0;\n}\n", "")
  1914  	}
  1915  
  1916  	// "auto" is the only keyword allowed in a quad, and only for "margin" and "inset" not for "padding"
  1917  	expectPrintedMangle(t, "a { margin: 1px auto 3px 4px; margin-left: auto }", "a {\n  margin: 1px auto 3px;\n}\n", "")
  1918  	expectPrintedMangle(t, "a { inset: 1px auto 3px 4px; left: auto }", "a {\n  inset: 1px auto 3px;\n}\n", "")
  1919  	expectPrintedMangle(t, "a { padding: 1px auto 3px 4px; padding-left: auto }", "a {\n  padding: 1px auto 3px 4px;\n  padding-left: auto;\n}\n", "")
  1920  	expectPrintedMangle(t, "a { margin: auto; margin-left: 1px }", "a {\n  margin: auto auto auto 1px;\n}\n", "")
  1921  	expectPrintedMangle(t, "a { inset: auto; left: 1px }", "a {\n  inset: auto auto auto 1px;\n}\n", "")
  1922  	expectPrintedMangle(t, "a { padding: auto; padding-left: 1px }", "a {\n  padding: auto;\n  padding-left: 1px;\n}\n", "")
  1923  	expectPrintedMangle(t, "a { margin: inherit; margin-left: 1px }", "a {\n  margin: inherit;\n  margin-left: 1px;\n}\n", "")
  1924  	expectPrintedMangle(t, "a { inset: inherit; left: 1px }", "a {\n  inset: inherit;\n  left: 1px;\n}\n", "")
  1925  	expectPrintedMangle(t, "a { padding: inherit; padding-left: 1px }", "a {\n  padding: inherit;\n  padding-left: 1px;\n}\n", "")
  1926  
  1927  	expectPrintedLowerMangle(t, "a { top: 0; right: 0; bottom: 0; left: 0; }", "a {\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n}\n", "")
  1928  
  1929  	// "inset" should be expanded when not supported
  1930  	expectPrintedLower(t, "a { inset: 0; }", "a {\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n}\n", "")
  1931  	expectPrintedLower(t, "a { inset: 0px; }", "a {\n  top: 0px;\n  right: 0px;\n  bottom: 0px;\n  left: 0px;\n}\n", "")
  1932  	expectPrintedLower(t, "a { inset: 1px 2px; }", "a {\n  top: 1px;\n  right: 2px;\n  bottom: 1px;\n  left: 2px;\n}\n", "")
  1933  	expectPrintedLower(t, "a { inset: 1px 2px 3px; }", "a {\n  top: 1px;\n  right: 2px;\n  bottom: 3px;\n  left: 2px;\n}\n", "")
  1934  	expectPrintedLower(t, "a { inset: 1px 2px 3px 4px; }", "a {\n  top: 1px;\n  right: 2px;\n  bottom: 3px;\n  left: 4px;\n}\n", "")
  1935  
  1936  	// When "inset" isn't supported, other mangling should still work
  1937  	expectPrintedLowerMangle(t, "a { top: 0px; }", "a {\n  top: 0;\n}\n", "")
  1938  	expectPrintedLowerMangle(t, "a { right: 0px; }", "a {\n  right: 0;\n}\n", "")
  1939  	expectPrintedLowerMangle(t, "a { bottom: 0px; }", "a {\n  bottom: 0;\n}\n", "")
  1940  	expectPrintedLowerMangle(t, "a { left: 0px; }", "a {\n  left: 0;\n}\n", "")
  1941  	expectPrintedLowerMangle(t, "a { inset: 0px; }", "a {\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n}\n", "")
  1942  
  1943  	// When "inset" isn't supported, whitespace minifying should still work
  1944  	expectPrintedLowerMinify(t, "a { top: 0px; }", "a{top:0px}", "")
  1945  	expectPrintedLowerMinify(t, "a { right: 0px; }", "a{right:0px}", "")
  1946  	expectPrintedLowerMinify(t, "a { bottom: 0px; }", "a{bottom:0px}", "")
  1947  	expectPrintedLowerMinify(t, "a { left: 0px; }", "a{left:0px}", "")
  1948  	expectPrintedLowerMinify(t, "a { inset: 0px; }", "a{top:0px;right:0px;bottom:0px;left:0px}", "")
  1949  	expectPrintedLowerMinify(t, "a { inset: 1px 2px; }", "a{top:1px;right:2px;bottom:1px;left:2px}", "")
  1950  	expectPrintedLowerMinify(t, "a { inset: 1px 2px 3px; }", "a{top:1px;right:2px;bottom:3px;left:2px}", "")
  1951  	expectPrintedLowerMinify(t, "a { inset: 1px 2px 3px 4px; }", "a{top:1px;right:2px;bottom:3px;left:4px}", "")
  1952  }
  1953  
  1954  func TestBorderRadius(t *testing.T) {
  1955  	expectPrinted(t, "a { border-top-left-radius: 0 0 }", "a {\n  border-top-left-radius: 0 0;\n}\n", "")
  1956  	expectPrintedMangle(t, "a { border-top-left-radius: 0 0 }", "a {\n  border-top-left-radius: 0;\n}\n", "")
  1957  	expectPrintedMangle(t, "a { border-top-left-radius: 0 0px }", "a {\n  border-top-left-radius: 0;\n}\n", "")
  1958  	expectPrintedMangle(t, "a { border-top-left-radius: 0 1px }", "a {\n  border-top-left-radius: 0 1px;\n}\n", "")
  1959  
  1960  	expectPrintedMangle(t, "a { border-top-left-radius: 0; border-radius: 1px }", "a {\n  border-radius: 1px;\n}\n", "")
  1961  
  1962  	expectPrintedMangle(t, "a { border-radius: 1px 2px 3px 4px }", "a {\n  border-radius: 1px 2px 3px 4px;\n}\n", "")
  1963  	expectPrintedMangle(t, "a { border-radius: 1px 2px 1px 3px }", "a {\n  border-radius: 1px 2px 1px 3px;\n}\n", "")
  1964  	expectPrintedMangle(t, "a { border-radius: 1px 2px 3px 2px }", "a {\n  border-radius: 1px 2px 3px;\n}\n", "")
  1965  	expectPrintedMangle(t, "a { border-radius: 1px 2px 1px 2px }", "a {\n  border-radius: 1px 2px;\n}\n", "")
  1966  	expectPrintedMangle(t, "a { border-radius: 1px 1px 1px 1px }", "a {\n  border-radius: 1px;\n}\n", "")
  1967  
  1968  	expectPrintedMangle(t, "a { border-radius: 0/1px 2px 3px 4px }", "a {\n  border-radius: 0 / 1px 2px 3px 4px;\n}\n", "")
  1969  	expectPrintedMangle(t, "a { border-radius: 0/1px 2px 1px 3px }", "a {\n  border-radius: 0 / 1px 2px 1px 3px;\n}\n", "")
  1970  	expectPrintedMangle(t, "a { border-radius: 0/1px 2px 3px 2px }", "a {\n  border-radius: 0 / 1px 2px 3px;\n}\n", "")
  1971  	expectPrintedMangle(t, "a { border-radius: 0/1px 2px 1px 2px }", "a {\n  border-radius: 0 / 1px 2px;\n}\n", "")
  1972  	expectPrintedMangle(t, "a { border-radius: 0/1px 1px 1px 1px }", "a {\n  border-radius: 0 / 1px;\n}\n", "")
  1973  
  1974  	expectPrintedMangle(t, "a { border-radius: 1px 2px; border-top-left-radius: 3px; }", "a {\n  border-radius: 3px 2px 1px;\n}\n", "")
  1975  	expectPrintedMangle(t, "a { border-radius: 1px; border-top-left-radius: 3px; }", "a {\n  border-radius: 3px 1px 1px;\n}\n", "")
  1976  	expectPrintedMangle(t, "a { border-radius: 0/1px; border-top-left-radius: 3px; }", "a {\n  border-radius: 3px 0 0 / 3px 1px 1px;\n}\n", "")
  1977  	expectPrintedMangle(t, "a { border-radius: 0/1px 2px; border-top-left-radius: 3px; }", "a {\n  border-radius: 3px 0 0 / 3px 2px 1px;\n}\n", "")
  1978  
  1979  	for _, x := range []string{"", "-top-left", "-top-right", "-bottom-left", "-bottom-right"} {
  1980  		y := "border" + x + "-radius"
  1981  		expectPrintedMangle(t, "a { "+y+": 1px; "+y+": 2px }",
  1982  			"a {\n  "+y+": 2px;\n}\n", "")
  1983  		expectPrintedMangle(t, "a { "+y+": 1px !important; "+y+": 2px }",
  1984  			"a {\n  "+y+": 1px !important;\n  "+y+": 2px;\n}\n", "")
  1985  		expectPrintedMangle(t, "a { "+y+": 1px; "+y+": 2px !important }",
  1986  			"a {\n  "+y+": 1px;\n  "+y+": 2px !important;\n}\n", "")
  1987  		expectPrintedMangle(t, "a { "+y+": 1px !important; "+y+": 2px !important }",
  1988  			"a {\n  "+y+": 2px !important;\n}\n", "")
  1989  
  1990  		expectPrintedMangle(t, "a { border-radius: 1px; "+y+": 2px !important; }",
  1991  			"a {\n  border-radius: 1px;\n  "+y+": 2px !important;\n}\n", "")
  1992  		expectPrintedMangle(t, "a { border-radius: 1px !important; "+y+": 2px; }",
  1993  			"a {\n  border-radius: 1px !important;\n  "+y+": 2px;\n}\n", "")
  1994  	}
  1995  
  1996  	expectPrintedMangle(t, "a { border-top-left-radius: ; border-radius: 1px }",
  1997  		"a {\n  border-top-left-radius:;\n  border-radius: 1px;\n}\n", "")
  1998  	expectPrintedMangle(t, "a { border-top-left-radius: 1px; border-radius: / }",
  1999  		"a {\n  border-top-left-radius: 1px;\n  border-radius: /;\n}\n", "")
  2000  
  2001  	expectPrintedMangleMinify(t, "a { border-radius: 1px 2px 3px 4px; border-top-right-radius: 5px; }", "a{border-radius:1px 5px 3px 4px}", "")
  2002  	expectPrintedMangleMinify(t, "a { border-radius: 1px 2px 3px 4px; border-top-right-radius: 5px 6px; }", "a{border-radius:1px 5px 3px 4px/1px 6px 3px 4px}", "")
  2003  
  2004  	// These should not be changed because "--x" and "--z" could be empty
  2005  	expectPrintedMangle(t, "a { border-radius: var(--x) var(--y) var(--z) var(--y) }", "a {\n  border-radius: var(--x) var(--y) var(--z) var(--y);\n}\n", "")
  2006  	expectPrintedMangle(t, "a { border-radius: 0 / var(--x) var(--y) var(--z) var(--y) }", "a {\n  border-radius: 0 / var(--x) var(--y) var(--z) var(--y);\n}\n", "")
  2007  
  2008  	// "inherit" should not be merged
  2009  	expectPrintedMangle(t, "a { border-radius: 1px; border-top-left-radius: 0 }", "a {\n  border-radius: 0 1px 1px;\n}\n", "")
  2010  	expectPrintedMangle(t, "a { border-radius: inherit; border-top-left-radius: 0 }", "a {\n  border-radius: inherit;\n  border-top-left-radius: 0;\n}\n", "")
  2011  	expectPrintedMangle(t, "a { border-radius: 0; border-top-left-radius: inherit }", "a {\n  border-radius: 0;\n  border-top-left-radius: inherit;\n}\n", "")
  2012  	expectPrintedMangle(t, "a { border-top-left-radius: 0; border-radius: inherit }", "a {\n  border-top-left-radius: 0;\n  border-radius: inherit;\n}\n", "")
  2013  	expectPrintedMangle(t, "a { border-top-left-radius: inherit; border-radius: 0 }", "a {\n  border-top-left-radius: inherit;\n  border-radius: 0;\n}\n", "")
  2014  
  2015  	// Don't merge different units
  2016  	expectPrintedMangle(t, "a { border-radius: 1px; border-radius: 2px; }", "a {\n  border-radius: 2px;\n}\n", "")
  2017  	expectPrintedMangle(t, "a { border-radius: 1px; border-top-left-radius: 2px; }", "a {\n  border-radius: 2px 1px 1px;\n}\n", "")
  2018  	expectPrintedMangle(t, "a { border-top-left-radius: 1px; border-radius: 2px; }", "a {\n  border-radius: 2px;\n}\n", "")
  2019  	expectPrintedMangle(t, "a { border-top-left-radius: 1px; border-top-left-radius: 2px; }", "a {\n  border-top-left-radius: 2px;\n}\n", "")
  2020  	expectPrintedMangle(t, "a { border-radius: 1rem; border-radius: 1vw; }", "a {\n  border-radius: 1rem;\n  border-radius: 1vw;\n}\n", "")
  2021  	expectPrintedMangle(t, "a { border-radius: 1rem; border-top-left-radius: 1vw; }", "a {\n  border-radius: 1rem;\n  border-top-left-radius: 1vw;\n}\n", "")
  2022  	expectPrintedMangle(t, "a { border-top-left-radius: 1rem; border-radius: 1vw; }", "a {\n  border-top-left-radius: 1rem;\n  border-radius: 1vw;\n}\n", "")
  2023  	expectPrintedMangle(t, "a { border-top-left-radius: 1rem; border-top-left-radius: 1vw; }", "a {\n  border-top-left-radius: 1rem;\n  border-top-left-radius: 1vw;\n}\n", "")
  2024  	expectPrintedMangle(t, "a { border-radius: 0; border-top-left-radius: 2px; }", "a {\n  border-radius: 2px 0 0;\n}\n", "")
  2025  	expectPrintedMangle(t, "a { border-radius: 0; border-top-left-radius: 2rem; }", "a {\n  border-radius: 0;\n  border-top-left-radius: 2rem;\n}\n", "")
  2026  }
  2027  
  2028  func TestBoxShadow(t *testing.T) {
  2029  	expectPrinted(t, "a { box-shadow: inset 0px 0px 0px 0px black }", "a {\n  box-shadow: inset 0px 0px 0px 0px black;\n}\n", "")
  2030  	expectPrintedMangle(t, "a { box-shadow: 0px 0px 0px 0px inset black }", "a {\n  box-shadow: 0 0 inset #000;\n}\n", "")
  2031  	expectPrintedMangle(t, "a { box-shadow: 0px 0px 0px 0px black inset }", "a {\n  box-shadow: 0 0 #000 inset;\n}\n", "")
  2032  	expectPrintedMangle(t, "a { box-shadow: black 0px 0px 0px 0px inset }", "a {\n  box-shadow: #000 0 0 inset;\n}\n", "")
  2033  	expectPrintedMangle(t, "a { box-shadow: inset 0px 0px 0px 0px black }", "a {\n  box-shadow: inset 0 0 #000;\n}\n", "")
  2034  	expectPrintedMangle(t, "a { box-shadow: inset black 0px 0px 0px 0px }", "a {\n  box-shadow: inset #000 0 0;\n}\n", "")
  2035  	expectPrintedMangle(t, "a { box-shadow: black inset 0px 0px 0px 0px }", "a {\n  box-shadow: #000 inset 0 0;\n}\n", "")
  2036  	expectPrintedMangle(t, "a { box-shadow: yellow 1px 0px 0px 1px inset }", "a {\n  box-shadow: #ff0 1px 0 0 1px inset;\n}\n", "")
  2037  	expectPrintedMangle(t, "a { box-shadow: yellow 1px 0px 1px 0px inset }", "a {\n  box-shadow: #ff0 1px 0 1px inset;\n}\n", "")
  2038  	expectPrintedMangle(t, "a { box-shadow: rebeccapurple, yellow, black }", "a {\n  box-shadow:\n    #639,\n    #ff0,\n    #000;\n}\n", "")
  2039  	expectPrintedMangle(t, "a { box-shadow: 0px 0px 0px var(--foo) black }", "a {\n  box-shadow: 0 0 0 var(--foo) #000;\n}\n", "")
  2040  	expectPrintedMangle(t, "a { box-shadow: 0px 0px 0px 0px var(--foo) black }", "a {\n  box-shadow: 0 0 0 0 var(--foo) #000;\n}\n", "")
  2041  	expectPrintedMangle(t, "a { box-shadow: calc(1px + var(--foo)) 0px 0px 0px black }", "a {\n  box-shadow: calc(1px + var(--foo)) 0 0 0 #000;\n}\n", "")
  2042  	expectPrintedMangle(t, "a { box-shadow: inset 0px 0px 0px 0px 0px magenta; }", "a {\n  box-shadow: inset 0 0 0 0 0 #f0f;\n}\n", "")
  2043  	expectPrintedMangleMinify(t, "a { box-shadow: rebeccapurple , yellow , black }", "a{box-shadow:#639,#ff0,#000}", "")
  2044  	expectPrintedMangleMinify(t, "a { box-shadow: rgb(255, 0, 17) 0 0 1 inset }", "a{box-shadow:#f01 0 0 1 inset}", "")
  2045  }
  2046  
  2047  func TestMangleTime(t *testing.T) {
  2048  	expectPrintedMangle(t, "a { animation: b 1s }", "a {\n  animation: b 1s;\n}\n", "")
  2049  	expectPrintedMangle(t, "a { animation: b 1.s }", "a {\n  animation: b 1s;\n}\n", "")
  2050  	expectPrintedMangle(t, "a { animation: b 1.0s }", "a {\n  animation: b 1s;\n}\n", "")
  2051  	expectPrintedMangle(t, "a { animation: b 1.02s }", "a {\n  animation: b 1.02s;\n}\n", "")
  2052  	expectPrintedMangle(t, "a { animation: b .1s }", "a {\n  animation: b .1s;\n}\n", "")
  2053  	expectPrintedMangle(t, "a { animation: b .01s }", "a {\n  animation: b .01s;\n}\n", "")
  2054  	expectPrintedMangle(t, "a { animation: b .001s }", "a {\n  animation: b 1ms;\n}\n", "")
  2055  	expectPrintedMangle(t, "a { animation: b .0012s }", "a {\n  animation: b 1.2ms;\n}\n", "")
  2056  	expectPrintedMangle(t, "a { animation: b -.001s }", "a {\n  animation: b -1ms;\n}\n", "")
  2057  	expectPrintedMangle(t, "a { animation: b -.0012s }", "a {\n  animation: b -1.2ms;\n}\n", "")
  2058  	expectPrintedMangle(t, "a { animation: b .0001s }", "a {\n  animation: b .1ms;\n}\n", "")
  2059  	expectPrintedMangle(t, "a { animation: b .00012s }", "a {\n  animation: b .12ms;\n}\n", "")
  2060  	expectPrintedMangle(t, "a { animation: b .000123s }", "a {\n  animation: b .123ms;\n}\n", "")
  2061  	expectPrintedMangle(t, "a { animation: b .01S }", "a {\n  animation: b .01S;\n}\n", "")
  2062  	expectPrintedMangle(t, "a { animation: b .001S }", "a {\n  animation: b 1ms;\n}\n", "")
  2063  
  2064  	expectPrintedMangle(t, "a { animation: b 1ms }", "a {\n  animation: b 1ms;\n}\n", "")
  2065  	expectPrintedMangle(t, "a { animation: b 10ms }", "a {\n  animation: b 10ms;\n}\n", "")
  2066  	expectPrintedMangle(t, "a { animation: b 100ms }", "a {\n  animation: b .1s;\n}\n", "")
  2067  	expectPrintedMangle(t, "a { animation: b 120ms }", "a {\n  animation: b .12s;\n}\n", "")
  2068  	expectPrintedMangle(t, "a { animation: b 123ms }", "a {\n  animation: b 123ms;\n}\n", "")
  2069  	expectPrintedMangle(t, "a { animation: b 1000ms }", "a {\n  animation: b 1s;\n}\n", "")
  2070  	expectPrintedMangle(t, "a { animation: b 1200ms }", "a {\n  animation: b 1.2s;\n}\n", "")
  2071  	expectPrintedMangle(t, "a { animation: b 1230ms }", "a {\n  animation: b 1.23s;\n}\n", "")
  2072  	expectPrintedMangle(t, "a { animation: b 1234ms }", "a {\n  animation: b 1234ms;\n}\n", "")
  2073  	expectPrintedMangle(t, "a { animation: b -100ms }", "a {\n  animation: b -.1s;\n}\n", "")
  2074  	expectPrintedMangle(t, "a { animation: b -120ms }", "a {\n  animation: b -.12s;\n}\n", "")
  2075  	expectPrintedMangle(t, "a { animation: b 120mS }", "a {\n  animation: b .12s;\n}\n", "")
  2076  	expectPrintedMangle(t, "a { animation: b 120Ms }", "a {\n  animation: b .12s;\n}\n", "")
  2077  	expectPrintedMangle(t, "a { animation: b 123mS }", "a {\n  animation: b 123mS;\n}\n", "")
  2078  	expectPrintedMangle(t, "a { animation: b 123Ms }", "a {\n  animation: b 123Ms;\n}\n", "")
  2079  
  2080  	// Mangling times with exponents is not currently supported
  2081  	expectPrintedMangle(t, "a { animation: b 1e3ms }", "a {\n  animation: b 1e3ms;\n}\n", "")
  2082  	expectPrintedMangle(t, "a { animation: b 1E3ms }", "a {\n  animation: b 1E3ms;\n}\n", "")
  2083  }
  2084  
  2085  func TestCalc(t *testing.T) {
  2086  	expectPrinted(t, "a { b: calc(+(2)) }", "a {\n  b: calc(+(2));\n}\n", "<stdin>: WARNING: \"+\" can only be used as an infix operator, not a prefix operator\n")
  2087  	expectPrinted(t, "a { b: calc(-(2)) }", "a {\n  b: calc(-(2));\n}\n", "<stdin>: WARNING: \"-\" can only be used as an infix operator, not a prefix operator\n")
  2088  	expectPrinted(t, "a { b: calc(*(2)) }", "a {\n  b: calc(*(2));\n}\n", "")
  2089  	expectPrinted(t, "a { b: calc(/(2)) }", "a {\n  b: calc(/(2));\n}\n", "")
  2090  
  2091  	expectPrinted(t, "a { b: calc(1 + 2) }", "a {\n  b: calc(1 + 2);\n}\n", "")
  2092  	expectPrinted(t, "a { b: calc(1 - 2) }", "a {\n  b: calc(1 - 2);\n}\n", "")
  2093  	expectPrinted(t, "a { b: calc(1 * 2) }", "a {\n  b: calc(1 * 2);\n}\n", "")
  2094  	expectPrinted(t, "a { b: calc(1 / 2) }", "a {\n  b: calc(1 / 2);\n}\n", "")
  2095  
  2096  	expectPrinted(t, "a { b: calc(1+ 2) }", "a {\n  b: calc(1+ 2);\n}\n", "<stdin>: WARNING: The \"+\" operator only works if there is whitespace on both sides\n")
  2097  	expectPrinted(t, "a { b: calc(1- 2) }", "a {\n  b: calc(1- 2);\n}\n", "<stdin>: WARNING: The \"-\" operator only works if there is whitespace on both sides\n")
  2098  	expectPrinted(t, "a { b: calc(1* 2) }", "a {\n  b: calc(1* 2);\n}\n", "")
  2099  	expectPrinted(t, "a { b: calc(1/ 2) }", "a {\n  b: calc(1/ 2);\n}\n", "")
  2100  
  2101  	expectPrinted(t, "a { b: calc(1 +2) }", "a {\n  b: calc(1 +2);\n}\n", "<stdin>: WARNING: The \"+\" operator only works if there is whitespace on both sides\n")
  2102  	expectPrinted(t, "a { b: calc(1 -2) }", "a {\n  b: calc(1 -2);\n}\n", "<stdin>: WARNING: The \"-\" operator only works if there is whitespace on both sides\n")
  2103  	expectPrinted(t, "a { b: calc(1 *2) }", "a {\n  b: calc(1 *2);\n}\n", "")
  2104  	expectPrinted(t, "a { b: calc(1 /2) }", "a {\n  b: calc(1 /2);\n}\n", "")
  2105  
  2106  	expectPrinted(t, "a { b: calc(1 +(2)) }", "a {\n  b: calc(1 +(2));\n}\n", "<stdin>: WARNING: The \"+\" operator only works if there is whitespace on both sides\n")
  2107  	expectPrinted(t, "a { b: calc(1 -(2)) }", "a {\n  b: calc(1 -(2));\n}\n", "<stdin>: WARNING: The \"-\" operator only works if there is whitespace on both sides\n")
  2108  	expectPrinted(t, "a { b: calc(1 *(2)) }", "a {\n  b: calc(1 *(2));\n}\n", "")
  2109  	expectPrinted(t, "a { b: calc(1 /(2)) }", "a {\n  b: calc(1 /(2));\n}\n", "")
  2110  }
  2111  
  2112  func TestMinifyCalc(t *testing.T) {
  2113  	expectPrintedMangleMinify(t, "a { b: calc(x + y) }", "a{b:calc(x + y)}", "")
  2114  	expectPrintedMangleMinify(t, "a { b: calc(x - y) }", "a{b:calc(x - y)}", "")
  2115  	expectPrintedMangleMinify(t, "a { b: calc(x * y) }", "a{b:calc(x*y)}", "")
  2116  	expectPrintedMangleMinify(t, "a { b: calc(x / y) }", "a{b:calc(x/y)}", "")
  2117  }
  2118  
  2119  func TestMangleCalc(t *testing.T) {
  2120  	expectPrintedMangle(t, "a { b: calc(1) }", "a {\n  b: 1;\n}\n", "")
  2121  	expectPrintedMangle(t, "a { b: calc((1)) }", "a {\n  b: 1;\n}\n", "")
  2122  	expectPrintedMangle(t, "a { b: calc(calc(1)) }", "a {\n  b: 1;\n}\n", "")
  2123  	expectPrintedMangle(t, "a { b: calc(x + y * z) }", "a {\n  b: calc(x + y * z);\n}\n", "")
  2124  	expectPrintedMangle(t, "a { b: calc(x * y + z) }", "a {\n  b: calc(x * y + z);\n}\n", "")
  2125  
  2126  	// Test sum
  2127  	expectPrintedMangle(t, "a { b: calc(2 + 3) }", "a {\n  b: 5;\n}\n", "")
  2128  	expectPrintedMangle(t, "a { b: calc(6 - 2) }", "a {\n  b: 4;\n}\n", "")
  2129  
  2130  	// Test product
  2131  	expectPrintedMangle(t, "a { b: calc(2 * 3) }", "a {\n  b: 6;\n}\n", "")
  2132  	expectPrintedMangle(t, "a { b: calc(6 / 2) }", "a {\n  b: 3;\n}\n", "")
  2133  	expectPrintedMangle(t, "a { b: calc(2px * 3 + 4px * 5) }", "a {\n  b: 26px;\n}\n", "")
  2134  	expectPrintedMangle(t, "a { b: calc(2 * 3px + 4 * 5px) }", "a {\n  b: 26px;\n}\n", "")
  2135  	expectPrintedMangle(t, "a { b: calc(2px * 3 - 4px * 5) }", "a {\n  b: -14px;\n}\n", "")
  2136  	expectPrintedMangle(t, "a { b: calc(2 * 3px - 4 * 5px) }", "a {\n  b: -14px;\n}\n", "")
  2137  
  2138  	// Test negation
  2139  	expectPrintedMangle(t, "a { b: calc(x + 1) }", "a {\n  b: calc(x + 1);\n}\n", "")
  2140  	expectPrintedMangle(t, "a { b: calc(x - 1) }", "a {\n  b: calc(x - 1);\n}\n", "")
  2141  	expectPrintedMangle(t, "a { b: calc(x + -1) }", "a {\n  b: calc(x - 1);\n}\n", "")
  2142  	expectPrintedMangle(t, "a { b: calc(x - -1) }", "a {\n  b: calc(x + 1);\n}\n", "")
  2143  	expectPrintedMangle(t, "a { b: calc(1 + x) }", "a {\n  b: calc(1 + x);\n}\n", "")
  2144  	expectPrintedMangle(t, "a { b: calc(1 - x) }", "a {\n  b: calc(1 - x);\n}\n", "")
  2145  	expectPrintedMangle(t, "a { b: calc(-1 + x) }", "a {\n  b: calc(-1 + x);\n}\n", "")
  2146  	expectPrintedMangle(t, "a { b: calc(-1 - x) }", "a {\n  b: calc(-1 - x);\n}\n", "")
  2147  
  2148  	// Test inversion
  2149  	expectPrintedMangle(t, "a { b: calc(x * 4) }", "a {\n  b: calc(x * 4);\n}\n", "")
  2150  	expectPrintedMangle(t, "a { b: calc(x / 4) }", "a {\n  b: calc(x / 4);\n}\n", "")
  2151  	expectPrintedMangle(t, "a { b: calc(x * 0.25) }", "a {\n  b: calc(x / 4);\n}\n", "")
  2152  	expectPrintedMangle(t, "a { b: calc(x / 0.25) }", "a {\n  b: calc(x * 4);\n}\n", "")
  2153  
  2154  	// Test operator precedence
  2155  	expectPrintedMangle(t, "a { b: calc((a + b) + c) }", "a {\n  b: calc(a + b + c);\n}\n", "")
  2156  	expectPrintedMangle(t, "a { b: calc(a + (b + c)) }", "a {\n  b: calc(a + b + c);\n}\n", "")
  2157  	expectPrintedMangle(t, "a { b: calc((a - b) - c) }", "a {\n  b: calc(a - b - c);\n}\n", "")
  2158  	expectPrintedMangle(t, "a { b: calc(a - (b - c)) }", "a {\n  b: calc(a - (b - c));\n}\n", "")
  2159  	expectPrintedMangle(t, "a { b: calc((a * b) * c) }", "a {\n  b: calc(a * b * c);\n}\n", "")
  2160  	expectPrintedMangle(t, "a { b: calc(a * (b * c)) }", "a {\n  b: calc(a * b * c);\n}\n", "")
  2161  	expectPrintedMangle(t, "a { b: calc((a / b) / c) }", "a {\n  b: calc(a / b / c);\n}\n", "")
  2162  	expectPrintedMangle(t, "a { b: calc(a / (b / c)) }", "a {\n  b: calc(a / (b / c));\n}\n", "")
  2163  	expectPrintedMangle(t, "a { b: calc(a + b * c / d - e) }", "a {\n  b: calc(a + b * c / d - e);\n}\n", "")
  2164  	expectPrintedMangle(t, "a { b: calc((a + ((b * c) / d)) - e) }", "a {\n  b: calc(a + b * c / d - e);\n}\n", "")
  2165  	expectPrintedMangle(t, "a { b: calc((a + b) * c / (d - e)) }", "a {\n  b: calc((a + b) * c / (d - e));\n}\n", "")
  2166  
  2167  	// Using "var()" should bail because it can expand to any number of tokens
  2168  	expectPrintedMangle(t, "a { b: calc(1px - x + 2px) }", "a {\n  b: calc(3px - x);\n}\n", "")
  2169  	expectPrintedMangle(t, "a { b: calc(1px - var(x) + 2px) }", "a {\n  b: calc(1px - var(x) + 2px);\n}\n", "")
  2170  
  2171  	// Test values that can't be accurately represented as decimals
  2172  	expectPrintedMangle(t, "a { b: calc(100% / 1) }", "a {\n  b: 100%;\n}\n", "")
  2173  	expectPrintedMangle(t, "a { b: calc(100% / 2) }", "a {\n  b: 50%;\n}\n", "")
  2174  	expectPrintedMangle(t, "a { b: calc(100% / 3) }", "a {\n  b: calc(100% / 3);\n}\n", "")
  2175  	expectPrintedMangle(t, "a { b: calc(100% / 4) }", "a {\n  b: 25%;\n}\n", "")
  2176  	expectPrintedMangle(t, "a { b: calc(100% / 5) }", "a {\n  b: 20%;\n}\n", "")
  2177  	expectPrintedMangle(t, "a { b: calc(100% / 6) }", "a {\n  b: calc(100% / 6);\n}\n", "")
  2178  	expectPrintedMangle(t, "a { b: calc(100% / 7) }", "a {\n  b: calc(100% / 7);\n}\n", "")
  2179  	expectPrintedMangle(t, "a { b: calc(100% / 8) }", "a {\n  b: 12.5%;\n}\n", "")
  2180  	expectPrintedMangle(t, "a { b: calc(100% / 9) }", "a {\n  b: calc(100% / 9);\n}\n", "")
  2181  	expectPrintedMangle(t, "a { b: calc(100% / 10) }", "a {\n  b: 10%;\n}\n", "")
  2182  	expectPrintedMangle(t, "a { b: calc(100% / 100) }", "a {\n  b: 1%;\n}\n", "")
  2183  	expectPrintedMangle(t, "a { b: calc(100% / 1000) }", "a {\n  b: .1%;\n}\n", "")
  2184  	expectPrintedMangle(t, "a { b: calc(100% / 10000) }", "a {\n  b: .01%;\n}\n", "")
  2185  	expectPrintedMangle(t, "a { b: calc(100% / 100000) }", "a {\n  b: .001%;\n}\n", "")
  2186  	expectPrintedMangle(t, "a { b: calc(100% / 1000000) }", "a {\n  b: calc(100% / 1000000);\n}\n", "") // This actually ends up as "100% * (1 / 1000000)" which is less precise
  2187  	expectPrintedMangle(t, "a { b: calc(100% / -1000000) }", "a {\n  b: calc(100% / -1000000);\n}\n", "")
  2188  	expectPrintedMangle(t, "a { b: calc(100% / -100000) }", "a {\n  b: -.001%;\n}\n", "")
  2189  	expectPrintedMangle(t, "a { b: calc(3 * (2px + 1em / 7)) }", "a {\n  b: calc(3 * (2px + 1em / 7));\n}\n", "")
  2190  	expectPrintedMangle(t, "a { b: calc(3 * (2px + 1em / 8)) }", "a {\n  b: calc(3 * (2px + .125em));\n}\n", "")
  2191  
  2192  	// Non-finite numbers
  2193  	expectPrintedMangle(t, "a { b: calc(0px / 0) }", "a {\n  b: calc(0px / 0);\n}\n", "")
  2194  	expectPrintedMangle(t, "a { b: calc(1px / 0) }", "a {\n  b: calc(1px / 0);\n}\n", "")
  2195  	expectPrintedMangle(t, "a { b: calc(-1px / 0) }", "a {\n  b: calc(-1px / 0);\n}\n", "")
  2196  	expectPrintedMangle(t, "a { b: calc(nan) }", "a {\n  b: calc(nan);\n}\n", "")
  2197  	expectPrintedMangle(t, "a { b: calc(infinity) }", "a {\n  b: calc(infinity);\n}\n", "")
  2198  	expectPrintedMangle(t, "a { b: calc(-infinity) }", "a {\n  b: calc(-infinity);\n}\n", "")
  2199  	expectPrintedMangle(t, "a { b: calc(1px / nan) }", "a {\n  b: calc(1px / nan);\n}\n", "")
  2200  	expectPrintedMangle(t, "a { b: calc(1px / infinity) }", "a {\n  b: 0px;\n}\n", "")
  2201  	expectPrintedMangle(t, "a { b: calc(1px / -infinity) }", "a {\n  b: -0px;\n}\n", "")
  2202  }
  2203  
  2204  func TestTransform(t *testing.T) {
  2205  	expectPrintedMangle(t, "a { transform: matrix(1, 0, 0, 1, 0, 0) }", "a {\n  transform: scale(1);\n}\n", "")
  2206  	expectPrintedMangle(t, "a { transform: matrix(2, 0, 0, 1, 0, 0) }", "a {\n  transform: scaleX(2);\n}\n", "")
  2207  	expectPrintedMangle(t, "a { transform: matrix(1, 0, 0, 2, 0, 0) }", "a {\n  transform: scaleY(2);\n}\n", "")
  2208  	expectPrintedMangle(t, "a { transform: matrix(2, 0, 0, 3, 0, 0) }", "a {\n  transform: scale(2, 3);\n}\n", "")
  2209  	expectPrintedMangle(t, "a { transform: matrix(2, 0, 0, 2, 0, 0) }", "a {\n  transform: scale(2);\n}\n", "")
  2210  	expectPrintedMangle(t, "a { transform: matrix(1, 0, 0, 1, 1, 2) }",
  2211  		"a {\n  transform:\n    matrix(\n      1, 0,\n      0, 1,\n      1, 2);\n}\n", "")
  2212  
  2213  	expectPrintedMangle(t, "a { transform: translate(0, 0) }", "a {\n  transform: translate(0);\n}\n", "")
  2214  	expectPrintedMangle(t, "a { transform: translate(0px, 0px) }", "a {\n  transform: translate(0);\n}\n", "")
  2215  	expectPrintedMangle(t, "a { transform: translate(0%, 0%) }", "a {\n  transform: translate(0);\n}\n", "")
  2216  	expectPrintedMangle(t, "a { transform: translate(1px, 0) }", "a {\n  transform: translate(1px);\n}\n", "")
  2217  	expectPrintedMangle(t, "a { transform: translate(1px, 0px) }", "a {\n  transform: translate(1px);\n}\n", "")
  2218  	expectPrintedMangle(t, "a { transform: translate(1px, 0%) }", "a {\n  transform: translate(1px);\n}\n", "")
  2219  	expectPrintedMangle(t, "a { transform: translate(0, 1px) }", "a {\n  transform: translateY(1px);\n}\n", "")
  2220  	expectPrintedMangle(t, "a { transform: translate(0px, 1px) }", "a {\n  transform: translateY(1px);\n}\n", "")
  2221  	expectPrintedMangle(t, "a { transform: translate(0%, 1px) }", "a {\n  transform: translateY(1px);\n}\n", "")
  2222  	expectPrintedMangle(t, "a { transform: translate(1px, 2px) }", "a {\n  transform: translate(1px, 2px);\n}\n", "")
  2223  	expectPrintedMangle(t, "a { transform: translate(40%, 60%) }", "a {\n  transform: translate(40%, 60%);\n}\n", "")
  2224  
  2225  	expectPrintedMangle(t, "a { transform: translateX(0) }", "a {\n  transform: translate(0);\n}\n", "")
  2226  	expectPrintedMangle(t, "a { transform: translateX(0px) }", "a {\n  transform: translate(0);\n}\n", "")
  2227  	expectPrintedMangle(t, "a { transform: translateX(0%) }", "a {\n  transform: translate(0);\n}\n", "")
  2228  	expectPrintedMangle(t, "a { transform: translateX(1px) }", "a {\n  transform: translate(1px);\n}\n", "")
  2229  	expectPrintedMangle(t, "a { transform: translateX(50%) }", "a {\n  transform: translate(50%);\n}\n", "")
  2230  
  2231  	expectPrintedMangle(t, "a { transform: translateY(0) }", "a {\n  transform: translateY(0);\n}\n", "")
  2232  	expectPrintedMangle(t, "a { transform: translateY(0px) }", "a {\n  transform: translateY(0);\n}\n", "")
  2233  	expectPrintedMangle(t, "a { transform: translateY(0%) }", "a {\n  transform: translateY(0);\n}\n", "")
  2234  	expectPrintedMangle(t, "a { transform: translateY(1px) }", "a {\n  transform: translateY(1px);\n}\n", "")
  2235  	expectPrintedMangle(t, "a { transform: translateY(50%) }", "a {\n  transform: translateY(50%);\n}\n", "")
  2236  
  2237  	expectPrintedMangle(t, "a { transform: scale(1) }", "a {\n  transform: scale(1);\n}\n", "")
  2238  	expectPrintedMangle(t, "a { transform: scale(100%) }", "a {\n  transform: scale(1);\n}\n", "")
  2239  	expectPrintedMangle(t, "a { transform: scale(10%) }", "a {\n  transform: scale(.1);\n}\n", "")
  2240  	expectPrintedMangle(t, "a { transform: scale(99%) }", "a {\n  transform: scale(99%);\n}\n", "")
  2241  	expectPrintedMangle(t, "a { transform: scale(1, 1) }", "a {\n  transform: scale(1);\n}\n", "")
  2242  	expectPrintedMangle(t, "a { transform: scale(100%, 1) }", "a {\n  transform: scale(1);\n}\n", "")
  2243  	expectPrintedMangle(t, "a { transform: scale(10%, 0.1) }", "a {\n  transform: scale(.1);\n}\n", "")
  2244  	expectPrintedMangle(t, "a { transform: scale(99%, 0.99) }", "a {\n  transform: scale(99%, .99);\n}\n", "")
  2245  	expectPrintedMangle(t, "a { transform: scale(60%, 40%) }", "a {\n  transform: scale(.6, .4);\n}\n", "")
  2246  	expectPrintedMangle(t, "a { transform: scale(3, 1) }", "a {\n  transform: scaleX(3);\n}\n", "")
  2247  	expectPrintedMangle(t, "a { transform: scale(300%, 1) }", "a {\n  transform: scaleX(3);\n}\n", "")
  2248  	expectPrintedMangle(t, "a { transform: scale(1, 3) }", "a {\n  transform: scaleY(3);\n}\n", "")
  2249  	expectPrintedMangle(t, "a { transform: scale(1, 300%) }", "a {\n  transform: scaleY(3);\n}\n", "")
  2250  
  2251  	expectPrintedMangle(t, "a { transform: scaleX(1) }", "a {\n  transform: scaleX(1);\n}\n", "")
  2252  	expectPrintedMangle(t, "a { transform: scaleX(2) }", "a {\n  transform: scaleX(2);\n}\n", "")
  2253  	expectPrintedMangle(t, "a { transform: scaleX(300%) }", "a {\n  transform: scaleX(3);\n}\n", "")
  2254  	expectPrintedMangle(t, "a { transform: scaleX(99%) }", "a {\n  transform: scaleX(99%);\n}\n", "")
  2255  
  2256  	expectPrintedMangle(t, "a { transform: scaleY(1) }", "a {\n  transform: scaleY(1);\n}\n", "")
  2257  	expectPrintedMangle(t, "a { transform: scaleY(2) }", "a {\n  transform: scaleY(2);\n}\n", "")
  2258  	expectPrintedMangle(t, "a { transform: scaleY(300%) }", "a {\n  transform: scaleY(3);\n}\n", "")
  2259  	expectPrintedMangle(t, "a { transform: scaleY(99%) }", "a {\n  transform: scaleY(99%);\n}\n", "")
  2260  
  2261  	expectPrintedMangle(t, "a { transform: rotate(0) }", "a {\n  transform: rotate(0);\n}\n", "")
  2262  	expectPrintedMangle(t, "a { transform: rotate(0deg) }", "a {\n  transform: rotate(0);\n}\n", "")
  2263  	expectPrintedMangle(t, "a { transform: rotate(1deg) }", "a {\n  transform: rotate(1deg);\n}\n", "")
  2264  
  2265  	expectPrintedMangle(t, "a { transform: skew(0) }", "a {\n  transform: skew(0);\n}\n", "")
  2266  	expectPrintedMangle(t, "a { transform: skew(0deg) }", "a {\n  transform: skew(0);\n}\n", "")
  2267  	expectPrintedMangle(t, "a { transform: skew(1deg) }", "a {\n  transform: skew(1deg);\n}\n", "")
  2268  	expectPrintedMangle(t, "a { transform: skew(1deg, 0) }", "a {\n  transform: skew(1deg);\n}\n", "")
  2269  	expectPrintedMangle(t, "a { transform: skew(1deg, 0deg) }", "a {\n  transform: skew(1deg);\n}\n", "")
  2270  	expectPrintedMangle(t, "a { transform: skew(0, 1deg) }", "a {\n  transform: skew(0, 1deg);\n}\n", "")
  2271  	expectPrintedMangle(t, "a { transform: skew(0deg, 1deg) }", "a {\n  transform: skew(0, 1deg);\n}\n", "")
  2272  	expectPrintedMangle(t, "a { transform: skew(1deg, 2deg) }", "a {\n  transform: skew(1deg, 2deg);\n}\n", "")
  2273  
  2274  	expectPrintedMangle(t, "a { transform: skewX(0) }", "a {\n  transform: skew(0);\n}\n", "")
  2275  	expectPrintedMangle(t, "a { transform: skewX(0deg) }", "a {\n  transform: skew(0);\n}\n", "")
  2276  	expectPrintedMangle(t, "a { transform: skewX(1deg) }", "a {\n  transform: skew(1deg);\n}\n", "")
  2277  
  2278  	expectPrintedMangle(t, "a { transform: skewY(0) }", "a {\n  transform: skewY(0);\n}\n", "")
  2279  	expectPrintedMangle(t, "a { transform: skewY(0deg) }", "a {\n  transform: skewY(0);\n}\n", "")
  2280  	expectPrintedMangle(t, "a { transform: skewY(1deg) }", "a {\n  transform: skewY(1deg);\n}\n", "")
  2281  
  2282  	expectPrintedMangle(t,
  2283  		"a { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2) }",
  2284  		"a {\n  transform:\n    matrix3d(\n      1, 0, 0, 0,\n      0, 1, 0, 0,\n      0, 0, 1, 0,\n      0, 0, 0, 2);\n}\n", "")
  2285  	expectPrintedMangle(t,
  2286  		"a { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2, 3, 4, 1) }",
  2287  		"a {\n  transform:\n    matrix3d(\n      1, 0, 0, 0,\n      0, 1, 0, 0,\n      0, 0, 1, 0,\n      2, 3, 4, 1);\n}\n", "")
  2288  	expectPrintedMangle(t,
  2289  		"a { transform: matrix3d(1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1) }",
  2290  		"a {\n  transform:\n    matrix3d(\n      1, 0, 1, 0,\n      0, 1, 0, 0,\n      1, 0, 1, 0,\n      0, 0, 0, 1);\n}\n", "")
  2291  	expectPrintedMangle(t,
  2292  		"a { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) }",
  2293  		"a {\n  transform: scaleZ(1);\n}\n", "")
  2294  	expectPrintedMangle(t,
  2295  		"a { transform: matrix3d(2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) }",
  2296  		"a {\n  transform: scale3d(2, 1, 1);\n}\n", "")
  2297  	expectPrintedMangle(t,
  2298  		"a { transform: matrix3d(1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) }",
  2299  		"a {\n  transform: scale3d(1, 2, 1);\n}\n", "")
  2300  	expectPrintedMangle(t,
  2301  		"a { transform: matrix3d(2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) }",
  2302  		"a {\n  transform: scale3d(2, 2, 1);\n}\n", "")
  2303  	expectPrintedMangle(t,
  2304  		"a { transform: matrix3d(2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) }",
  2305  		"a {\n  transform: scale3d(2, 3, 1);\n}\n", "")
  2306  	expectPrintedMangle(t,
  2307  		"a { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1) }",
  2308  		"a {\n  transform: scaleZ(2);\n}\n", "")
  2309  	expectPrintedMangle(t,
  2310  		"a { transform: matrix3d(1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1) }",
  2311  		"a {\n  transform: scale3d(1, 2, 3);\n}\n", "")
  2312  	expectPrintedMangle(t,
  2313  		"a { transform: matrix3d(2, 3, 0, 0, 4, 5, 0, 0, 0, 0, 1, 0, 6, 7, 0, 1) }",
  2314  		"a {\n  transform:\n    matrix3d(\n      2, 3, 0, 0,\n      4, 5, 0, 0,\n      0, 0, 1, 0,\n      6, 7, 0, 1);\n}\n", "")
  2315  
  2316  	expectPrintedMangle(t, "a { transform: translate3d(0, 0, 0) }", "a {\n  transform: translateZ(0);\n}\n", "")
  2317  	expectPrintedMangle(t, "a { transform: translate3d(0%, 0%, 0) }", "a {\n  transform: translateZ(0);\n}\n", "")
  2318  	expectPrintedMangle(t, "a { transform: translate3d(0px, 0px, 0px) }", "a {\n  transform: translateZ(0);\n}\n", "")
  2319  	expectPrintedMangle(t, "a { transform: translate3d(1px, 0px, 0px) }", "a {\n  transform: translate3d(1px, 0, 0);\n}\n", "")
  2320  	expectPrintedMangle(t, "a { transform: translate3d(0px, 1px, 0px) }", "a {\n  transform: translate3d(0, 1px, 0);\n}\n", "")
  2321  	expectPrintedMangle(t, "a { transform: translate3d(0px, 0px, 1px) }", "a {\n  transform: translateZ(1px);\n}\n", "")
  2322  	expectPrintedMangle(t, "a { transform: translate3d(1px, 2px, 3px) }", "a {\n  transform: translate3d(1px, 2px, 3px);\n}\n", "")
  2323  	expectPrintedMangle(t, "a { transform: translate3d(1px, 0, 3px) }", "a {\n  transform: translate3d(1px, 0, 3px);\n}\n", "")
  2324  	expectPrintedMangle(t, "a { transform: translate3d(0, 2px, 3px) }", "a {\n  transform: translate3d(0, 2px, 3px);\n}\n", "")
  2325  	expectPrintedMangle(t, "a { transform: translate3d(1px, 2px, 0px) }", "a {\n  transform: translate3d(1px, 2px, 0);\n}\n", "")
  2326  	expectPrintedMangle(t, "a { transform: translate3d(40%, 60%, 0px) }", "a {\n  transform: translate3d(40%, 60%, 0);\n}\n", "")
  2327  
  2328  	expectPrintedMangle(t, "a { transform: translateZ(0) }", "a {\n  transform: translateZ(0);\n}\n", "")
  2329  	expectPrintedMangle(t, "a { transform: translateZ(0px) }", "a {\n  transform: translateZ(0);\n}\n", "")
  2330  	expectPrintedMangle(t, "a { transform: translateZ(1px) }", "a {\n  transform: translateZ(1px);\n}\n", "")
  2331  
  2332  	expectPrintedMangle(t, "a { transform: scale3d(1, 1, 1) }", "a {\n  transform: scaleZ(1);\n}\n", "")
  2333  	expectPrintedMangle(t, "a { transform: scale3d(2, 1, 1) }", "a {\n  transform: scale3d(2, 1, 1);\n}\n", "")
  2334  	expectPrintedMangle(t, "a { transform: scale3d(1, 2, 1) }", "a {\n  transform: scale3d(1, 2, 1);\n}\n", "")
  2335  	expectPrintedMangle(t, "a { transform: scale3d(1, 1, 2) }", "a {\n  transform: scaleZ(2);\n}\n", "")
  2336  	expectPrintedMangle(t, "a { transform: scale3d(1, 2, 3) }", "a {\n  transform: scale3d(1, 2, 3);\n}\n", "")
  2337  	expectPrintedMangle(t, "a { transform: scale3d(2, 3, 1) }", "a {\n  transform: scale3d(2, 3, 1);\n}\n", "")
  2338  	expectPrintedMangle(t, "a { transform: scale3d(2, 2, 1) }", "a {\n  transform: scale3d(2, 2, 1);\n}\n", "")
  2339  	expectPrintedMangle(t, "a { transform: scale3d(3, 300%, 100.00%) }", "a {\n  transform: scale3d(3, 3, 1);\n}\n", "")
  2340  	expectPrintedMangle(t, "a { transform: scale3d(1%, 2%, 3%) }", "a {\n  transform: scale3d(1%, 2%, 3%);\n}\n", "")
  2341  
  2342  	expectPrintedMangle(t, "a { transform: scaleZ(1) }", "a {\n  transform: scaleZ(1);\n}\n", "")
  2343  	expectPrintedMangle(t, "a { transform: scaleZ(100%) }", "a {\n  transform: scaleZ(1);\n}\n", "")
  2344  	expectPrintedMangle(t, "a { transform: scaleZ(2) }", "a {\n  transform: scaleZ(2);\n}\n", "")
  2345  	expectPrintedMangle(t, "a { transform: scaleZ(200%) }", "a {\n  transform: scaleZ(2);\n}\n", "")
  2346  	expectPrintedMangle(t, "a { transform: scaleZ(99%) }", "a {\n  transform: scaleZ(99%);\n}\n", "")
  2347  
  2348  	expectPrintedMangle(t, "a { transform: rotate3d(0, 0, 0, 0) }", "a {\n  transform: rotate3d(0, 0, 0, 0);\n}\n", "")
  2349  	expectPrintedMangle(t, "a { transform: rotate3d(0, 0, 0, 0deg) }", "a {\n  transform: rotate3d(0, 0, 0, 0);\n}\n", "")
  2350  	expectPrintedMangle(t, "a { transform: rotate3d(0, 0, 0, 45deg) }", "a {\n  transform: rotate3d(0, 0, 0, 45deg);\n}\n", "")
  2351  	expectPrintedMangle(t, "a { transform: rotate3d(1, 0, 0, 45deg) }", "a {\n  transform: rotateX(45deg);\n}\n", "")
  2352  	expectPrintedMangle(t, "a { transform: rotate3d(0, 1, 0, 45deg) }", "a {\n  transform: rotateY(45deg);\n}\n", "")
  2353  	expectPrintedMangle(t, "a { transform: rotate3d(0, 0, 1, 45deg) }", "a {\n  transform: rotate3d(0, 0, 1, 45deg);\n}\n", "")
  2354  
  2355  	expectPrintedMangle(t, "a { transform: rotateX(0) }", "a {\n  transform: rotateX(0);\n}\n", "")
  2356  	expectPrintedMangle(t, "a { transform: rotateX(0deg) }", "a {\n  transform: rotateX(0);\n}\n", "")
  2357  	expectPrintedMangle(t, "a { transform: rotateX(1deg) }", "a {\n  transform: rotateX(1deg);\n}\n", "")
  2358  
  2359  	expectPrintedMangle(t, "a { transform: rotateY(0) }", "a {\n  transform: rotateY(0);\n}\n", "")
  2360  	expectPrintedMangle(t, "a { transform: rotateY(0deg) }", "a {\n  transform: rotateY(0);\n}\n", "")
  2361  	expectPrintedMangle(t, "a { transform: rotateY(1deg) }", "a {\n  transform: rotateY(1deg);\n}\n", "")
  2362  
  2363  	expectPrintedMangle(t, "a { transform: rotateZ(0) }", "a {\n  transform: rotate(0);\n}\n", "")
  2364  	expectPrintedMangle(t, "a { transform: rotateZ(0deg) }", "a {\n  transform: rotate(0);\n}\n", "")
  2365  	expectPrintedMangle(t, "a { transform: rotateZ(1deg) }", "a {\n  transform: rotate(1deg);\n}\n", "")
  2366  
  2367  	expectPrintedMangle(t, "a { transform: perspective(0) }", "a {\n  transform: perspective(0);\n}\n", "")
  2368  	expectPrintedMangle(t, "a { transform: perspective(0px) }", "a {\n  transform: perspective(0);\n}\n", "")
  2369  	expectPrintedMangle(t, "a { transform: perspective(1px) }", "a {\n  transform: perspective(1px);\n}\n", "")
  2370  }
  2371  
  2372  func TestMangleAlpha(t *testing.T) {
  2373  	alphas := []string{
  2374  		"0", ".004", ".008", ".01", ".016", ".02", ".024", ".027", ".03", ".035", ".04", ".043", ".047", ".05", ".055", ".06",
  2375  		".063", ".067", ".07", ".075", ".08", ".082", ".086", ".09", ".094", ".098", ".1", ".106", ".11", ".114", ".118", ".12",
  2376  		".125", ".13", ".133", ".137", ".14", ".145", ".15", ".153", ".157", ".16", ".165", ".17", ".173", ".176", ".18", ".184",
  2377  		".19", ".192", ".196", ".2", ".204", ".208", ".21", ".216", ".22", ".224", ".227", ".23", ".235", ".24", ".243", ".247",
  2378  		".25", ".255", ".26", ".263", ".267", ".27", ".275", ".28", ".282", ".286", ".29", ".294", ".298", ".3", ".306", ".31",
  2379  		".314", ".318", ".32", ".325", ".33", ".333", ".337", ".34", ".345", ".35", ".353", ".357", ".36", ".365", ".37", ".373",
  2380  		".376", ".38", ".384", ".39", ".392", ".396", ".4", ".404", ".408", ".41", ".416", ".42", ".424", ".427", ".43", ".435",
  2381  		".44", ".443", ".447", ".45", ".455", ".46", ".463", ".467", ".47", ".475", ".48", ".482", ".486", ".49", ".494", ".498",
  2382  		".5", ".506", ".51", ".514", ".518", ".52", ".525", ".53", ".533", ".537", ".54", ".545", ".55", ".553", ".557", ".56",
  2383  		".565", ".57", ".573", ".576", ".58", ".584", ".59", ".592", ".596", ".6", ".604", ".608", ".61", ".616", ".62", ".624",
  2384  		".627", ".63", ".635", ".64", ".643", ".647", ".65", ".655", ".66", ".663", ".667", ".67", ".675", ".68", ".682", ".686",
  2385  		".69", ".694", ".698", ".7", ".706", ".71", ".714", ".718", ".72", ".725", ".73", ".733", ".737", ".74", ".745", ".75",
  2386  		".753", ".757", ".76", ".765", ".77", ".773", ".776", ".78", ".784", ".79", ".792", ".796", ".8", ".804", ".808", ".81",
  2387  		".816", ".82", ".824", ".827", ".83", ".835", ".84", ".843", ".847", ".85", ".855", ".86", ".863", ".867", ".87", ".875",
  2388  		".88", ".882", ".886", ".89", ".894", ".898", ".9", ".906", ".91", ".914", ".918", ".92", ".925", ".93", ".933", ".937",
  2389  		".94", ".945", ".95", ".953", ".957", ".96", ".965", ".97", ".973", ".976", ".98", ".984", ".99", ".992", ".996",
  2390  	}
  2391  
  2392  	for i, alpha := range alphas {
  2393  		expectPrintedLowerMangle(t, fmt.Sprintf("a { color: #%08X }", i), "a {\n  color: rgba(0, 0, 0, "+alpha+");\n}\n", "")
  2394  	}
  2395  
  2396  	// An alpha value of 100% does not use "rgba(...)"
  2397  	expectPrintedLowerMangle(t, "a { color: #000000FF }", "a {\n  color: #000;\n}\n", "")
  2398  }
  2399  
  2400  func TestMangleDuplicateSelectors(t *testing.T) {
  2401  	expectPrinted(t, "a, a { color: red }", "a,\na {\n  color: red;\n}\n", "")
  2402  	expectPrintedMangle(t, "a, a { color: red }", "a {\n  color: red;\n}\n", "")
  2403  	expectPrintedMangle(t, "a, b { color: red }", "a,\nb {\n  color: red;\n}\n", "")
  2404  	expectPrintedMangle(t, "a, a.foo, a.foo, a.bar, a { color: red }", "a,\na.foo,\na.bar {\n  color: red;\n}\n", "")
  2405  
  2406  	expectPrintedMangle(t, "@media screen { a, a { color: red } }", "@media screen {\n  a {\n    color: red;\n  }\n}\n", "")
  2407  	expectPrintedMangle(t, "@media screen { a, b { color: red } }", "@media screen {\n  a,\n  b {\n    color: red;\n  }\n}\n", "")
  2408  	expectPrintedMangle(t, "@media screen { a, a.foo, a.foo, a.bar, a { color: red } }", "@media screen {\n  a,\n  a.foo,\n  a.bar {\n    color: red;\n  }\n}\n", "")
  2409  }
  2410  
  2411  func TestMangleDuplicateSelectorRules(t *testing.T) {
  2412  	expectPrinted(t, "a { color: red } b { color: red }", "a {\n  color: red;\n}\nb {\n  color: red;\n}\n", "")
  2413  	expectPrintedMangle(t, "a { color: red } b { color: red }", "a,\nb {\n  color: red;\n}\n", "")
  2414  	expectPrintedMangle(t, "a { color: red } div {} b { color: red }", "a,\nb {\n  color: red;\n}\n", "")
  2415  	expectPrintedMangle(t, "a { color: red } div { color: red } b { color: red }", "a,\ndiv,\nb {\n  color: red;\n}\n", "")
  2416  	expectPrintedMangle(t, "a { color: red } div { color: red } a { color: red }", "a,\ndiv {\n  color: red;\n}\n", "")
  2417  	expectPrintedMangle(t, "a { color: red } div { color: blue } b { color: red }", "a {\n  color: red;\n}\ndiv {\n  color: #00f;\n}\nb {\n  color: red;\n}\n", "")
  2418  	expectPrintedMangle(t, "a { color: red } div { color: blue } a { color: red }", "a {\n  color: red;\n}\ndiv {\n  color: #00f;\n}\na {\n  color: red;\n}\n", "")
  2419  	expectPrintedMangle(t, "a { color: red; color: red } b { color: red }", "a,\nb {\n  color: red;\n}\n", "")
  2420  	expectPrintedMangle(t, "a { color: red } b { color: red; color: red }", "a,\nb {\n  color: red;\n}\n", "")
  2421  	expectPrintedMangle(t, "a { color: red } b { color: blue }", "a {\n  color: red;\n}\nb {\n  color: #00f;\n}\n", "")
  2422  
  2423  	// Do not merge duplicates if they are "unsafe"
  2424  	expectPrintedMangle(t, "a { color: red } unknown { color: red }", "a {\n  color: red;\n}\nunknown {\n  color: red;\n}\n", "")
  2425  	expectPrintedMangle(t, "unknown { color: red } a { color: red }", "unknown {\n  color: red;\n}\na {\n  color: red;\n}\n", "")
  2426  	expectPrintedMangle(t, "a { color: red } video { color: red }", "a {\n  color: red;\n}\nvideo {\n  color: red;\n}\n", "")
  2427  	expectPrintedMangle(t, "video { color: red } a { color: red }", "video {\n  color: red;\n}\na {\n  color: red;\n}\n", "")
  2428  	expectPrintedMangle(t, "a { color: red } a:last-child { color: red }", "a {\n  color: red;\n}\na:last-child {\n  color: red;\n}\n", "")
  2429  	expectPrintedMangle(t, "a { color: red } a[b=c i] { color: red }", "a {\n  color: red;\n}\na[b=c i] {\n  color: red;\n}\n", "")
  2430  	expectPrintedMangle(t, "a { color: red } & { color: red }", "a {\n  color: red;\n}\n& {\n  color: red;\n}\n", "")
  2431  	expectPrintedMangle(t, "a { color: red } a + b { color: red }", "a {\n  color: red;\n}\na + b {\n  color: red;\n}\n", "")
  2432  	expectPrintedMangle(t, "a { color: red } a|b { color: red }", "a {\n  color: red;\n}\na|b {\n  color: red;\n}\n", "")
  2433  	expectPrintedMangle(t, "a { color: red } a::hover { color: red }", "a {\n  color: red;\n}\na::hover {\n  color: red;\n}\n", "")
  2434  
  2435  	// Still merge duplicates if they are "safe"
  2436  	expectPrintedMangle(t, "a { color: red } a:hover { color: red }", "a,\na:hover {\n  color: red;\n}\n", "")
  2437  	expectPrintedMangle(t, "a { color: red } a[b=c] { color: red }", "a,\na[b=c] {\n  color: red;\n}\n", "")
  2438  	expectPrintedMangle(t, "a { color: red } a#id { color: red }", "a,\na#id {\n  color: red;\n}\n", "")
  2439  	expectPrintedMangle(t, "a { color: red } a.cls { color: red }", "a,\na.cls {\n  color: red;\n}\n", "")
  2440  
  2441  	// Skip over comments
  2442  	expectPrintedMangle(t, "c { color: green } a { color: red } /*!x*/ /*!y*/ b { color: blue }", "c {\n  color: green;\n}\na {\n  color: red;\n}\n/*!x*/\n/*!y*/\nb {\n  color: #00f;\n}\n", "")
  2443  	expectPrintedMangle(t, "c { color: green } a { color: red } /*!x*/ /*!y*/ b { color: red }", "c {\n  color: green;\n}\na,\nb {\n  color: red;\n}\n/*!x*/\n/*!y*/\n", "")
  2444  	expectPrintedMangle(t, "c { color: green } a { color: red } /*!x*/ /*!y*/ a { color: red }", "c {\n  color: green;\n}\na {\n  color: red;\n}\n/*!x*/\n/*!y*/\n", "")
  2445  }
  2446  
  2447  func TestMangleAtMedia(t *testing.T) {
  2448  	expectPrinted(t, "@media screen { @media screen { a { color: red } } }", "@media screen {\n  @media screen {\n    a {\n      color: red;\n    }\n  }\n}\n", "")
  2449  	expectPrintedMangle(t, "@media screen { @media screen { a { color: red } } }", "@media screen {\n  a {\n    color: red;\n  }\n}\n", "")
  2450  	expectPrintedMangle(t, "@media screen { @media not print { a { color: red } } }", "@media screen {\n  @media not print {\n    a {\n      color: red;\n    }\n  }\n}\n", "")
  2451  	expectPrintedMangle(t, "@media screen { @media not print { @media screen { a { color: red } } } }", "@media screen {\n  @media not print {\n    a {\n      color: red;\n    }\n  }\n}\n", "")
  2452  	expectPrintedMangle(t, "@media screen { a { color: red } @media screen { a { color: red } } }", "@media screen {\n  a {\n    color: red;\n  }\n}\n", "")
  2453  	expectPrintedMangle(t, "@media screen { a { color: red } @media screen { a { color: blue } } }", "@media screen {\n  a {\n    color: red;\n  }\n  a {\n    color: #00f;\n  }\n}\n", "")
  2454  	expectPrintedMangle(t, "@media screen { .a { color: red; @media screen { .b { color: blue } } } }", "@media screen {\n  .a {\n    color: red;\n    .b {\n      color: #00f;\n    }\n  }\n}\n", "")
  2455  	expectPrintedMangle(t, "@media screen { a { color: red } } @media screen { b { color: red } }", "@media screen {\n  a {\n    color: red;\n  }\n}\n@media screen {\n  b {\n    color: red;\n  }\n}\n", "")
  2456  }
  2457  
  2458  func TestFontWeight(t *testing.T) {
  2459  	expectPrintedMangle(t, "a { font-weight: normal }", "a {\n  font-weight: 400;\n}\n", "")
  2460  	expectPrintedMangle(t, "a { font-weight: bold }", "a {\n  font-weight: 700;\n}\n", "")
  2461  	expectPrintedMangle(t, "a { font-weight: 400 }", "a {\n  font-weight: 400;\n}\n", "")
  2462  	expectPrintedMangle(t, "a { font-weight: bolder }", "a {\n  font-weight: bolder;\n}\n", "")
  2463  	expectPrintedMangle(t, "a { font-weight: var(--var) }", "a {\n  font-weight: var(--var);\n}\n", "")
  2464  
  2465  	expectPrintedMangleMinify(t, "a { font-weight: normal }", "a{font-weight:400}", "")
  2466  }
  2467  
  2468  func TestFontFamily(t *testing.T) {
  2469  	expectPrintedMangle(t, "a {font-family: aaa }", "a {\n  font-family: aaa;\n}\n", "")
  2470  	expectPrintedMangle(t, "a {font-family: serif }", "a {\n  font-family: serif;\n}\n", "")
  2471  	expectPrintedMangle(t, "a {font-family: 'serif' }", "a {\n  font-family: \"serif\";\n}\n", "")
  2472  	expectPrintedMangle(t, "a {font-family: aaa bbb, serif }", "a {\n  font-family: aaa bbb, serif;\n}\n", "")
  2473  	expectPrintedMangle(t, "a {font-family: 'aaa', serif }", "a {\n  font-family: aaa, serif;\n}\n", "")
  2474  	expectPrintedMangle(t, "a {font-family: '\"', serif }", "a {\n  font-family: '\"', serif;\n}\n", "")
  2475  	expectPrintedMangle(t, "a {font-family: 'aaa ', serif }", "a {\n  font-family: \"aaa \", serif;\n}\n", "")
  2476  	expectPrintedMangle(t, "a {font-family: 'aaa bbb', serif }", "a {\n  font-family: aaa bbb, serif;\n}\n", "")
  2477  	expectPrintedMangle(t, "a {font-family: 'aaa bbb', 'ccc ddd' }", "a {\n  font-family: aaa bbb, ccc ddd;\n}\n", "")
  2478  	expectPrintedMangle(t, "a {font-family: 'aaa  bbb', serif }", "a {\n  font-family: \"aaa  bbb\", serif;\n}\n", "")
  2479  	expectPrintedMangle(t, "a {font-family: 'aaa serif' }", "a {\n  font-family: \"aaa serif\";\n}\n", "")
  2480  	expectPrintedMangle(t, "a {font-family: 'aaa bbb', var(--var) }", "a {\n  font-family: \"aaa bbb\", var(--var);\n}\n", "")
  2481  	expectPrintedMangle(t, "a {font-family: 'aaa bbb', }", "a {\n  font-family: \"aaa bbb\", ;\n}\n", "")
  2482  	expectPrintedMangle(t, "a {font-family: , 'aaa bbb' }", "a {\n  font-family: , \"aaa bbb\";\n}\n", "")
  2483  	expectPrintedMangle(t, "a {font-family: 'aaa',, 'bbb' }", "a {\n  font-family:\n    \"aaa\",,\n    \"bbb\";\n}\n", "")
  2484  	expectPrintedMangle(t, "a {font-family: 'aaa bbb', x serif }", "a {\n  font-family: \"aaa bbb\", x serif;\n}\n", "")
  2485  
  2486  	expectPrintedMangleMinify(t, "a {font-family: 'aaa bbb', serif }", "a{font-family:aaa bbb,serif}", "")
  2487  	expectPrintedMangleMinify(t, "a {font-family: 'aaa bbb', 'ccc ddd' }", "a{font-family:aaa bbb,ccc ddd}", "")
  2488  	expectPrintedMangleMinify(t, "a {font-family: 'initial', serif;}", "a{font-family:\"initial\",serif}", "")
  2489  	expectPrintedMangleMinify(t, "a {font-family: 'inherit', serif;}", "a{font-family:\"inherit\",serif}", "")
  2490  	expectPrintedMangleMinify(t, "a {font-family: 'unset', serif;}", "a{font-family:\"unset\",serif}", "")
  2491  	expectPrintedMangleMinify(t, "a {font-family: 'revert', serif;}", "a{font-family:\"revert\",serif}", "")
  2492  	expectPrintedMangleMinify(t, "a {font-family: 'revert-layer', 'Segoe UI', serif;}", "a{font-family:\"revert-layer\",Segoe UI,serif}", "")
  2493  	expectPrintedMangleMinify(t, "a {font-family: 'default', serif;}", "a{font-family:\"default\",serif}", "")
  2494  }
  2495  
  2496  func TestFont(t *testing.T) {
  2497  	expectPrintedMangle(t, "a { font: caption }", "a {\n  font: caption;\n}\n", "")
  2498  	expectPrintedMangle(t, "a { font: normal 1px }", "a {\n  font: normal 1px;\n}\n", "")
  2499  	expectPrintedMangle(t, "a { font: normal bold }", "a {\n  font: normal bold;\n}\n", "")
  2500  	expectPrintedMangle(t, "a { font: 1rem 'aaa bbb' }", "a {\n  font: 1rem aaa bbb;\n}\n", "")
  2501  	expectPrintedMangle(t, "a { font: 1rem/1.2 'aaa bbb' }", "a {\n  font: 1rem/1.2 aaa bbb;\n}\n", "")
  2502  	expectPrintedMangle(t, "a { font: normal 1rem 'aaa bbb' }", "a {\n  font: 1rem aaa bbb;\n}\n", "")
  2503  	expectPrintedMangle(t, "a { font: normal 1rem 'aaa bbb', serif }", "a {\n  font: 1rem aaa bbb, serif;\n}\n", "")
  2504  	expectPrintedMangle(t, "a { font: italic small-caps bold ultra-condensed 1rem/1.2 'aaa bbb' }", "a {\n  font: italic small-caps 700 ultra-condensed 1rem/1.2 aaa bbb;\n}\n", "")
  2505  	expectPrintedMangle(t, "a { font: oblique 1px 'aaa bbb' }", "a {\n  font: oblique 1px aaa bbb;\n}\n", "")
  2506  	expectPrintedMangle(t, "a { font: oblique 45deg 1px 'aaa bbb' }", "a {\n  font: oblique 45deg 1px aaa bbb;\n}\n", "")
  2507  
  2508  	expectPrintedMangle(t, "a { font: var(--var) 'aaa bbb' }", "a {\n  font: var(--var) \"aaa bbb\";\n}\n", "")
  2509  	expectPrintedMangle(t, "a { font: normal var(--var) 'aaa bbb' }", "a {\n  font: normal var(--var) \"aaa bbb\";\n}\n", "")
  2510  	expectPrintedMangle(t, "a { font: normal 1rem var(--var), 'aaa bbb' }", "a {\n  font: normal 1rem var(--var), \"aaa bbb\";\n}\n", "")
  2511  
  2512  	expectPrintedMangleMinify(t, "a { font: italic small-caps bold ultra-condensed 1rem/1.2 'aaa bbb' }", "a{font:italic small-caps 700 ultra-condensed 1rem/1.2 aaa bbb}", "")
  2513  	expectPrintedMangleMinify(t, "a { font: italic small-caps bold ultra-condensed 1rem / 1.2 'aaa bbb' }", "a{font:italic small-caps 700 ultra-condensed 1rem/1.2 aaa bbb}", "")
  2514  
  2515  	// See: https://github.com/evanw/esbuild/issues/3452
  2516  	expectPrinted(t, "a { font: 10px'foo' }", "a {\n  font: 10px\"foo\";\n}\n", "")
  2517  	expectPrinted(t, "a { font: 10px'123' }", "a {\n  font: 10px\"123\";\n}\n", "")
  2518  	expectPrintedMangle(t, "a { font: 10px'foo' }", "a {\n  font: 10px foo;\n}\n", "")
  2519  	expectPrintedMangle(t, "a { font: 10px'123' }", "a {\n  font: 10px\"123\";\n}\n", "")
  2520  	expectPrintedMangleMinify(t, "a { font: 10px'foo' }", "a{font:10px foo}", "")
  2521  	expectPrintedMangleMinify(t, "a { font: 10px'123' }", "a{font:10px\"123\"}", "")
  2522  }
  2523  
  2524  func TestWarningUnexpectedCloseBrace(t *testing.T) {
  2525  	expectPrinted(t, ".red {\n  color: red;\n}\n}\n.blue {\n  color: blue;\n}\n.green {\n color: green;\n}\n",
  2526  		`.red {
  2527    color: red;
  2528  }
  2529  } .blue {
  2530    color: blue;
  2531  }
  2532  .green {
  2533    color: green;
  2534  }
  2535  `,
  2536  		`<stdin>: WARNING: Unexpected "}"
  2537  `)
  2538  }
  2539  
  2540  func TestPropertyTypoWarning(t *testing.T) {
  2541  	expectPrinted(t, "a { z-idnex: 0 }", "a {\n  z-idnex: 0;\n}\n", "<stdin>: WARNING: \"z-idnex\" is not a known CSS property\nNOTE: Did you mean \"z-index\" instead?\n")
  2542  	expectPrinted(t, "a { x-index: 0 }", "a {\n  x-index: 0;\n}\n", "<stdin>: WARNING: \"x-index\" is not a known CSS property\nNOTE: Did you mean \"z-index\" instead?\n")
  2543  
  2544  	// CSS variables should not be corrected
  2545  	expectPrinted(t, "a { --index: 0 }", "a {\n  --index: 0 ;\n}\n", "")
  2546  
  2547  	// Short names should not be corrected ("alt" is actually valid in WebKit, and should not become "all")
  2548  	expectPrinted(t, "a { alt: \"\" }", "a {\n  alt: \"\";\n}\n", "")
  2549  }
  2550  
  2551  func TestParseErrorRecovery(t *testing.T) {
  2552  	expectPrinted(t, "x { y: z", "x {\n  y: z;\n}\n", "<stdin>: WARNING: Expected \"}\" to go with \"{\"\n<stdin>: NOTE: The unbalanced \"{\" is here:\n")
  2553  	expectPrinted(t, "x { y: (", "x {\n  y: ();\n}\n", "<stdin>: WARNING: Expected \")\" to go with \"(\"\n<stdin>: NOTE: The unbalanced \"(\" is here:\n")
  2554  	expectPrinted(t, "x { y: [", "x {\n  y: [];\n}\n", "<stdin>: WARNING: Expected \"]\" to go with \"[\"\n<stdin>: NOTE: The unbalanced \"[\" is here:\n")
  2555  	expectPrinted(t, "x { y: {", "x {\n  y: {\n  }\n}\n",
  2556  		"<stdin>: WARNING: Expected identifier but found whitespace\n<stdin>: WARNING: Expected \"}\" to go with \"{\"\n<stdin>: NOTE: The unbalanced \"{\" is here:\n")
  2557  	expectPrinted(t, "x { y: z(", "x {\n  y: z();\n}\n", "<stdin>: WARNING: Expected \")\" to go with \"(\"\n<stdin>: NOTE: The unbalanced \"(\" is here:\n")
  2558  	expectPrinted(t, "x { y: z(abc", "x {\n  y: z(abc);\n}\n", "<stdin>: WARNING: Expected \")\" to go with \"(\"\n<stdin>: NOTE: The unbalanced \"(\" is here:\n")
  2559  	expectPrinted(t, "x { y: url(", "x {\n  y: url();\n}\n",
  2560  		"<stdin>: WARNING: Expected \")\" to end URL token\n<stdin>: NOTE: The unbalanced \"(\" is here:\n<stdin>: WARNING: Expected \"}\" to go with \"{\"\n<stdin>: NOTE: The unbalanced \"{\" is here:\n")
  2561  	expectPrinted(t, "x { y: url(abc", "x {\n  y: url(abc);\n}\n",
  2562  		"<stdin>: WARNING: Expected \")\" to end URL token\n<stdin>: NOTE: The unbalanced \"(\" is here:\n<stdin>: WARNING: Expected \"}\" to go with \"{\"\n<stdin>: NOTE: The unbalanced \"{\" is here:\n")
  2563  	expectPrinted(t, "x { y: url(; }", "x {\n  y: url(; };\n}\n",
  2564  		"<stdin>: WARNING: Expected \")\" to end URL token\n<stdin>: NOTE: The unbalanced \"(\" is here:\n<stdin>: WARNING: Expected \"}\" to go with \"{\"\n<stdin>: NOTE: The unbalanced \"{\" is here:\n")
  2565  	expectPrinted(t, "x { y: url(abc;", "x {\n  y: url(abc;);\n}\n",
  2566  		"<stdin>: WARNING: Expected \")\" to end URL token\n<stdin>: NOTE: The unbalanced \"(\" is here:\n<stdin>: WARNING: Expected \"}\" to go with \"{\"\n<stdin>: NOTE: The unbalanced \"{\" is here:\n")
  2567  	expectPrinted(t, "/* @license */ x {} /* @preserve", "/* @license */\nx {\n}\n",
  2568  		"<stdin>: ERROR: Expected \"*/\" to terminate multi-line comment\n<stdin>: NOTE: The multi-line comment starts here:\n")
  2569  	expectPrinted(t, "a { b: c; d: 'e\n f: g; h: i }", "a {\n  b: c;\n  d: 'e\n  f: g;\n  h: i;\n}\n", "<stdin>: WARNING: Unterminated string token\n")
  2570  	expectPrintedMinify(t, "a { b: c; d: 'e\n f: g; h: i }", "a{b:c;d:'e\nf: g;h:i}", "<stdin>: WARNING: Unterminated string token\n")
  2571  }
  2572  
  2573  func TestPrefixInsertion(t *testing.T) {
  2574  	// General "-webkit-" tests
  2575  	for _, key := range []string{
  2576  		"backdrop-filter",
  2577  		"box-decoration-break",
  2578  		"clip-path",
  2579  		"font-kerning",
  2580  		"initial-letter",
  2581  		"mask-image",
  2582  		"mask-origin",
  2583  		"mask-position",
  2584  		"mask-repeat",
  2585  		"mask-size",
  2586  		"print-color-adjust",
  2587  		"text-decoration-skip",
  2588  		"text-emphasis-color",
  2589  		"text-emphasis-position",
  2590  		"text-emphasis-style",
  2591  		"text-orientation",
  2592  	} {
  2593  		expectPrintedWithAllPrefixes(t,
  2594  			"a { "+key+": url(x.png) }",
  2595  			"a {\n  -webkit-"+key+": url(x.png);\n  "+key+": url(x.png);\n}\n", "")
  2596  
  2597  		expectPrintedWithAllPrefixes(t,
  2598  			"a { before: value; "+key+": url(x.png) }",
  2599  			"a {\n  before: value;\n  -webkit-"+key+": url(x.png);\n  "+key+": url(x.png);\n}\n", "")
  2600  
  2601  		expectPrintedWithAllPrefixes(t,
  2602  			"a { "+key+": url(x.png); after: value }",
  2603  			"a {\n  -webkit-"+key+": url(x.png);\n  "+key+": url(x.png);\n  after: value;\n}\n", "")
  2604  
  2605  		expectPrintedWithAllPrefixes(t,
  2606  			"a { before: value; "+key+": url(x.png); after: value }",
  2607  			"a {\n  before: value;\n  -webkit-"+key+": url(x.png);\n  "+key+": url(x.png);\n  after: value;\n}\n", "")
  2608  
  2609  		expectPrintedWithAllPrefixes(t,
  2610  			"a {\n  -webkit-"+key+": url(x.png);\n  "+key+": url(y.png);\n}\n",
  2611  			"a {\n  -webkit-"+key+": url(x.png);\n  "+key+": url(y.png);\n}\n", "")
  2612  
  2613  		expectPrintedWithAllPrefixes(t,
  2614  			"a {\n  "+key+": url(y.png);\n  -webkit-"+key+": url(x.png);\n}\n",
  2615  			"a {\n  "+key+": url(y.png);\n  -webkit-"+key+": url(x.png);\n}\n", "")
  2616  
  2617  		expectPrintedWithAllPrefixes(t,
  2618  			"a { "+key+": url(x.png); "+key+": url(y.png) }",
  2619  			"a {\n  -webkit-"+key+": url(x.png);\n  "+key+": url(x.png);\n  -webkit-"+key+": url(y.png);\n  "+key+": url(y.png);\n}\n", "")
  2620  	}
  2621  
  2622  	// Special-case tests
  2623  	expectPrintedWithAllPrefixes(t, "a { appearance: none }", "a {\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n}\n", "")
  2624  	expectPrintedWithAllPrefixes(t, "a { background-clip: not-text }", "a {\n  background-clip: not-text;\n}\n", "")
  2625  	expectPrintedWithAllPrefixes(t, "a { background-clip: text !important }", "a {\n  -webkit-background-clip: text !important;\n  -ms-background-clip: text !important;\n  background-clip: text !important;\n}\n", "")
  2626  	expectPrintedWithAllPrefixes(t, "a { background-clip: text }", "a {\n  -webkit-background-clip: text;\n  -ms-background-clip: text;\n  background-clip: text;\n}\n", "")
  2627  	expectPrintedWithAllPrefixes(t, "a { hyphens: auto }", "a {\n  -webkit-hyphens: auto;\n  -moz-hyphens: auto;\n  -ms-hyphens: auto;\n  hyphens: auto;\n}\n", "")
  2628  	expectPrintedWithAllPrefixes(t, "a { position: absolute }", "a {\n  position: absolute;\n}\n", "")
  2629  	expectPrintedWithAllPrefixes(t, "a { position: sticky !important }", "a {\n  position: -webkit-sticky !important;\n  position: sticky !important;\n}\n", "")
  2630  	expectPrintedWithAllPrefixes(t, "a { position: sticky }", "a {\n  position: -webkit-sticky;\n  position: sticky;\n}\n", "")
  2631  	expectPrintedWithAllPrefixes(t, "a { tab-size: 2 }", "a {\n  -moz-tab-size: 2;\n  -o-tab-size: 2;\n  tab-size: 2;\n}\n", "")
  2632  	expectPrintedWithAllPrefixes(t, "a { text-decoration-color: none }", "a {\n  -webkit-text-decoration-color: none;\n  -moz-text-decoration-color: none;\n  text-decoration-color: none;\n}\n", "")
  2633  	expectPrintedWithAllPrefixes(t, "a { text-decoration-line: none }", "a {\n  -webkit-text-decoration-line: none;\n  -moz-text-decoration-line: none;\n  text-decoration-line: none;\n}\n", "")
  2634  	expectPrintedWithAllPrefixes(t, "a { text-size-adjust: none }", "a {\n  -webkit-text-size-adjust: none;\n  -ms-text-size-adjust: none;\n  text-size-adjust: none;\n}\n", "")
  2635  	expectPrintedWithAllPrefixes(t, "a { user-select: none }", "a {\n  -webkit-user-select: none;\n  -khtml-user-select: none;\n  -moz-user-select: -moz-none;\n  -ms-user-select: none;\n  user-select: none;\n}\n", "")
  2636  	expectPrintedWithAllPrefixes(t, "a { mask-composite: add, subtract, intersect, exclude }",
  2637  		"a {\n  -webkit-mask-composite:\n    source-over,\n    source-out,\n    source-in,\n    xor;\n  mask-composite:\n    add,\n    subtract,\n    intersect,\n    exclude;\n}\n", "")
  2638  
  2639  	// Check that we insert prefixed rules each time an unprefixed rule is
  2640  	// encountered. This matches the behavior of the popular "autoprefixer" tool.
  2641  	expectPrintedWithAllPrefixes(t,
  2642  		"a { before: value; mask-image: a; middle: value; mask-image: b; after: value }",
  2643  		"a {\n  before: value;\n  -webkit-mask-image: a;\n  mask-image: a;\n  middle: value;\n  -webkit-mask-image: b;\n  mask-image: b;\n  after: value;\n}\n", "")
  2644  
  2645  	// Test that we don't insert duplicated rules when source code is processed
  2646  	// twice. This matches the behavior of the popular "autoprefixer" tool.
  2647  	expectPrintedWithAllPrefixes(t,
  2648  		"a { before: value; -webkit-text-size-adjust: 1; -ms-text-size-adjust: 2; text-size-adjust: 3; after: value }",
  2649  		"a {\n  before: value;\n  -webkit-text-size-adjust: 1;\n  -ms-text-size-adjust: 2;\n  text-size-adjust: 3;\n  after: value;\n}\n", "")
  2650  	expectPrintedWithAllPrefixes(t,
  2651  		"a { before: value; -webkit-text-size-adjust: 1; text-size-adjust: 3; after: value }",
  2652  		"a {\n  before: value;\n  -webkit-text-size-adjust: 1;\n  -ms-text-size-adjust: 3;\n  text-size-adjust: 3;\n  after: value;\n}\n", "")
  2653  	expectPrintedWithAllPrefixes(t,
  2654  		"a { before: value; -ms-text-size-adjust: 2; text-size-adjust: 3; after: value }",
  2655  		"a {\n  before: value;\n  -ms-text-size-adjust: 2;\n  -webkit-text-size-adjust: 3;\n  text-size-adjust: 3;\n  after: value;\n}\n", "")
  2656  }
  2657  
  2658  func TestNthChild(t *testing.T) {
  2659  	for _, nth := range []string{"nth-child", "nth-last-child"} {
  2660  		expectPrinted(t, ":"+nth+"(x) {}", ":"+nth+"(x) {\n}\n", "<stdin>: WARNING: Unexpected \"x\"\n")
  2661  		expectPrinted(t, ":"+nth+"(1e2) {}", ":"+nth+"(1e2) {\n}\n", "<stdin>: WARNING: Unexpected \"1e2\"\n")
  2662  		expectPrinted(t, ":"+nth+"(-n-) {}", ":"+nth+"(-n-) {\n}\n", "<stdin>: WARNING: Expected number but found \")\"\n")
  2663  		expectPrinted(t, ":"+nth+"(-nn) {}", ":"+nth+"(-nn) {\n}\n", "<stdin>: WARNING: Unexpected \"-nn\"\n")
  2664  		expectPrinted(t, ":"+nth+"(-n-n) {}", ":"+nth+"(-n-n) {\n}\n", "<stdin>: WARNING: Unexpected \"-n-n\"\n")
  2665  		expectPrinted(t, ":"+nth+"(-2n-) {}", ":"+nth+"(-2n-) {\n}\n", "<stdin>: WARNING: Expected number but found \")\"\n")
  2666  		expectPrinted(t, ":"+nth+"(-2n-2n) {}", ":"+nth+"(-2n-2n) {\n}\n", "<stdin>: WARNING: Unexpected \"-2n-2n\"\n")
  2667  		expectPrinted(t, ":"+nth+"(+) {}", ":"+nth+"(+) {\n}\n", "<stdin>: WARNING: Unexpected \")\"\n")
  2668  		expectPrinted(t, ":"+nth+"(-) {}", ":"+nth+"(-) {\n}\n", "<stdin>: WARNING: Unexpected \"-\"\n")
  2669  		expectPrinted(t, ":"+nth+"(+ 2) {}", ":"+nth+"(+ 2) {\n}\n", "<stdin>: WARNING: Unexpected whitespace\n")
  2670  		expectPrinted(t, ":"+nth+"(- 2) {}", ":"+nth+"(- 2) {\n}\n", "<stdin>: WARNING: Unexpected \"-\"\n")
  2671  
  2672  		expectPrinted(t, ":"+nth+"(0) {}", ":"+nth+"(0) {\n}\n", "")
  2673  		expectPrinted(t, ":"+nth+"(0 ) {}", ":"+nth+"(0) {\n}\n", "")
  2674  		expectPrinted(t, ":"+nth+"( 0) {}", ":"+nth+"(0) {\n}\n", "")
  2675  		expectPrinted(t, ":"+nth+"(00) {}", ":"+nth+"(0) {\n}\n", "")
  2676  		expectPrinted(t, ":"+nth+"(01) {}", ":"+nth+"(1) {\n}\n", "")
  2677  		expectPrinted(t, ":"+nth+"(0n) {}", ":"+nth+"(0n) {\n}\n", "")
  2678  		expectPrinted(t, ":"+nth+"(n) {}", ":"+nth+"(n) {\n}\n", "")
  2679  		expectPrinted(t, ":"+nth+"(-n) {}", ":"+nth+"(-n) {\n}\n", "")
  2680  		expectPrinted(t, ":"+nth+"(1n) {}", ":"+nth+"(n) {\n}\n", "")
  2681  		expectPrinted(t, ":"+nth+"(-1n) {}", ":"+nth+"(-n) {\n}\n", "")
  2682  		expectPrinted(t, ":"+nth+"(2n) {}", ":"+nth+"(2n) {\n}\n", "")
  2683  		expectPrinted(t, ":"+nth+"(-2n) {}", ":"+nth+"(-2n) {\n}\n", "")
  2684  
  2685  		expectPrinted(t, ":"+nth+"(odd) {}", ":"+nth+"(odd) {\n}\n", "")
  2686  		expectPrinted(t, ":"+nth+"(odd ) {}", ":"+nth+"(odd) {\n}\n", "")
  2687  		expectPrinted(t, ":"+nth+"( odd) {}", ":"+nth+"(odd) {\n}\n", "")
  2688  		expectPrinted(t, ":"+nth+"(even) {}", ":"+nth+"(even) {\n}\n", "")
  2689  		expectPrinted(t, ":"+nth+"(even ) {}", ":"+nth+"(even) {\n}\n", "")
  2690  		expectPrinted(t, ":"+nth+"( even) {}", ":"+nth+"(even) {\n}\n", "")
  2691  
  2692  		expectPrinted(t, ":"+nth+"(n+3) {}", ":"+nth+"(n+3) {\n}\n", "")
  2693  		expectPrinted(t, ":"+nth+"(n-3) {}", ":"+nth+"(n-3) {\n}\n", "")
  2694  		expectPrinted(t, ":"+nth+"(n +3) {}", ":"+nth+"(n+3) {\n}\n", "")
  2695  		expectPrinted(t, ":"+nth+"(n -3) {}", ":"+nth+"(n-3) {\n}\n", "")
  2696  		expectPrinted(t, ":"+nth+"(n+ 3) {}", ":"+nth+"(n+3) {\n}\n", "")
  2697  		expectPrinted(t, ":"+nth+"(n- 3) {}", ":"+nth+"(n-3) {\n}\n", "")
  2698  		expectPrinted(t, ":"+nth+"( n + 3 ) {}", ":"+nth+"(n+3) {\n}\n", "")
  2699  		expectPrinted(t, ":"+nth+"( n - 3 ) {}", ":"+nth+"(n-3) {\n}\n", "")
  2700  		expectPrinted(t, ":"+nth+"(+n+3) {}", ":"+nth+"(n+3) {\n}\n", "")
  2701  		expectPrinted(t, ":"+nth+"(+n-3) {}", ":"+nth+"(n-3) {\n}\n", "")
  2702  		expectPrinted(t, ":"+nth+"(-n+3) {}", ":"+nth+"(-n+3) {\n}\n", "")
  2703  		expectPrinted(t, ":"+nth+"(-n-3) {}", ":"+nth+"(-n-3) {\n}\n", "")
  2704  		expectPrinted(t, ":"+nth+"( +n + 3 ) {}", ":"+nth+"(n+3) {\n}\n", "")
  2705  		expectPrinted(t, ":"+nth+"( +n - 3 ) {}", ":"+nth+"(n-3) {\n}\n", "")
  2706  		expectPrinted(t, ":"+nth+"( -n + 3 ) {}", ":"+nth+"(-n+3) {\n}\n", "")
  2707  		expectPrinted(t, ":"+nth+"( -n - 3 ) {}", ":"+nth+"(-n-3) {\n}\n", "")
  2708  
  2709  		expectPrinted(t, ":"+nth+"(2n+3) {}", ":"+nth+"(2n+3) {\n}\n", "")
  2710  		expectPrinted(t, ":"+nth+"(2n-3) {}", ":"+nth+"(2n-3) {\n}\n", "")
  2711  		expectPrinted(t, ":"+nth+"(2n +3) {}", ":"+nth+"(2n+3) {\n}\n", "")
  2712  		expectPrinted(t, ":"+nth+"(2n -3) {}", ":"+nth+"(2n-3) {\n}\n", "")
  2713  		expectPrinted(t, ":"+nth+"(2n+ 3) {}", ":"+nth+"(2n+3) {\n}\n", "")
  2714  		expectPrinted(t, ":"+nth+"(2n- 3) {}", ":"+nth+"(2n-3) {\n}\n", "")
  2715  		expectPrinted(t, ":"+nth+"( 2n + 3 ) {}", ":"+nth+"(2n+3) {\n}\n", "")
  2716  		expectPrinted(t, ":"+nth+"( 2n - 3 ) {}", ":"+nth+"(2n-3) {\n}\n", "")
  2717  		expectPrinted(t, ":"+nth+"(+2n+3) {}", ":"+nth+"(2n+3) {\n}\n", "")
  2718  		expectPrinted(t, ":"+nth+"(+2n-3) {}", ":"+nth+"(2n-3) {\n}\n", "")
  2719  		expectPrinted(t, ":"+nth+"(-2n+3) {}", ":"+nth+"(-2n+3) {\n}\n", "")
  2720  		expectPrinted(t, ":"+nth+"(-2n-3) {}", ":"+nth+"(-2n-3) {\n}\n", "")
  2721  		expectPrinted(t, ":"+nth+"( +2n + 3 ) {}", ":"+nth+"(2n+3) {\n}\n", "")
  2722  		expectPrinted(t, ":"+nth+"( +2n - 3 ) {}", ":"+nth+"(2n-3) {\n}\n", "")
  2723  		expectPrinted(t, ":"+nth+"( -2n + 3 ) {}", ":"+nth+"(-2n+3) {\n}\n", "")
  2724  		expectPrinted(t, ":"+nth+"( -2n - 3 ) {}", ":"+nth+"(-2n-3) {\n}\n", "")
  2725  
  2726  		expectPrinted(t, ":"+nth+"(2n of + .foo) {}", ":"+nth+"(2n of + .foo) {\n}\n", "<stdin>: WARNING: Unexpected \"+\"\n")
  2727  		expectPrinted(t, ":"+nth+"(2n of .foo, ~.bar) {}", ":"+nth+"(2n of .foo, ~.bar) {\n}\n", "<stdin>: WARNING: Unexpected \"~\"\n")
  2728  		expectPrinted(t, ":"+nth+"(2n of .foo) {}", ":"+nth+"(2n of .foo) {\n}\n", "")
  2729  		expectPrinted(t, ":"+nth+"(2n of.foo+.bar) {}", ":"+nth+"(2n of .foo + .bar) {\n}\n", "")
  2730  		expectPrinted(t, ":"+nth+"(2n of[href]) {}", ":"+nth+"(2n of [href]) {\n}\n", "")
  2731  		expectPrinted(t, ":"+nth+"(2n of.foo,.bar) {}", ":"+nth+"(2n of .foo, .bar) {\n}\n", "")
  2732  		expectPrinted(t, ":"+nth+"(2n of .foo, .bar) {}", ":"+nth+"(2n of .foo, .bar) {\n}\n", "")
  2733  		expectPrinted(t, ":"+nth+"(2n of .foo , .bar ) {}", ":"+nth+"(2n of .foo, .bar) {\n}\n", "")
  2734  
  2735  		expectPrintedMinify(t, ":"+nth+"(2n of [foo] , [bar] ) {}", ":"+nth+"(2n of[foo],[bar]){}", "")
  2736  		expectPrintedMinify(t, ":"+nth+"(2n of .foo , .bar ) {}", ":"+nth+"(2n of.foo,.bar){}", "")
  2737  		expectPrintedMinify(t, ":"+nth+"(2n of #foo , #bar ) {}", ":"+nth+"(2n of#foo,#bar){}", "")
  2738  		expectPrintedMinify(t, ":"+nth+"(2n of :foo , :bar ) {}", ":"+nth+"(2n of:foo,:bar){}", "")
  2739  		expectPrintedMinify(t, ":"+nth+"(2n of div , span ) {}", ":"+nth+"(2n of div,span){}", "")
  2740  
  2741  		expectPrintedMangle(t, ":"+nth+"(even) { color: red }", ":"+nth+"(2n) {\n  color: red;\n}\n", "")
  2742  		expectPrintedMangle(t, ":"+nth+"(2n+1) { color: red }", ":"+nth+"(odd) {\n  color: red;\n}\n", "")
  2743  		expectPrintedMangle(t, ":"+nth+"(0n) { color: red }", ":"+nth+"(0) {\n  color: red;\n}\n", "")
  2744  		expectPrintedMangle(t, ":"+nth+"(0n+0) { color: red }", ":"+nth+"(0) {\n  color: red;\n}\n", "")
  2745  		expectPrintedMangle(t, ":"+nth+"(1n+0) { color: red }", ":"+nth+"(n) {\n  color: red;\n}\n", "")
  2746  		expectPrintedMangle(t, ":"+nth+"(0n-2) { color: red }", ":"+nth+"(-2) {\n  color: red;\n}\n", "")
  2747  		expectPrintedMangle(t, ":"+nth+"(0n+2) { color: red }", ":"+nth+"(2) {\n  color: red;\n}\n", "")
  2748  	}
  2749  
  2750  	for _, nth := range []string{"nth-of-type", "nth-last-of-type"} {
  2751  		expectPrinted(t, ":"+nth+"(2n of .foo) {}", ":"+nth+"(2n of .foo) {\n}\n",
  2752  			"<stdin>: WARNING: Expected \")\" to go with \"(\"\n<stdin>: NOTE: The unbalanced \"(\" is here:\n")
  2753  		expectPrinted(t, ":"+nth+"(+2n + 1) {}", ":"+nth+"(2n+1) {\n}\n", "")
  2754  	}
  2755  }
  2756  
  2757  func TestComposes(t *testing.T) {
  2758  	expectPrinted(t, ".foo { composes: bar; color: red }", ".foo {\n  composes: bar;\n  color: red;\n}\n", "")
  2759  	expectPrinted(t, ".foo .bar { composes: bar; color: red }", ".foo .bar {\n  composes: bar;\n  color: red;\n}\n", "")
  2760  	expectPrinted(t, ".foo, .bar { composes: bar; color: red }", ".foo,\n.bar {\n  composes: bar;\n  color: red;\n}\n", "")
  2761  	expectPrintedLocal(t, ".foo { composes: bar; color: red }", ".foo {\n  color: red;\n}\n", "")
  2762  	expectPrintedLocal(t, ".foo { composes: bar baz; color: red }", ".foo {\n  color: red;\n}\n", "")
  2763  	expectPrintedLocal(t, ".foo { composes: bar from global; color: red }", ".foo {\n  color: red;\n}\n", "")
  2764  	expectPrintedLocal(t, ".foo { composes: bar from \"file.css\"; color: red }", ".foo {\n  color: red;\n}\n", "")
  2765  	expectPrintedLocal(t, ".foo { composes: bar from url(file.css); color: red }", ".foo {\n  color: red;\n}\n", "")
  2766  	expectPrintedLocal(t, ".foo { & { composes: bar; color: red } }", ".foo {\n  & {\n    color: red;\n  }\n}\n", "")
  2767  	expectPrintedLocal(t, ".foo { :local { composes: bar; color: red } }", ".foo {\n  color: red;\n}\n", "")
  2768  	expectPrintedLocal(t, ".foo { :global { composes: bar; color: red } }", ".foo {\n  color: red;\n}\n", "")
  2769  
  2770  	expectPrinted(t, ".foo, .bar { composes: bar from github }", ".foo,\n.bar {\n  composes: bar from github;\n}\n", "")
  2771  	expectPrintedLocal(t, ".foo { composes: bar from github }", ".foo {\n}\n", "<stdin>: WARNING: \"composes\" declaration uses invalid location \"github\"\n")
  2772  
  2773  	badComposes := "<stdin>: WARNING: \"composes\" only works inside single class selectors\n" +
  2774  		"<stdin>: NOTE: The parent selector is not a single class selector because of the syntax here:\n"
  2775  	expectPrintedLocal(t, "& { composes: bar; color: red }", "& {\n  color: red;\n}\n", badComposes)
  2776  	expectPrintedLocal(t, ".foo& { composes: bar; color: red }", "&.foo {\n  color: red;\n}\n", badComposes)
  2777  	expectPrintedLocal(t, ".foo.bar { composes: bar; color: red }", ".foo.bar {\n  color: red;\n}\n", badComposes)
  2778  	expectPrintedLocal(t, ".foo:hover { composes: bar; color: red }", ".foo:hover {\n  color: red;\n}\n", badComposes)
  2779  	expectPrintedLocal(t, ".foo[href] { composes: bar; color: red }", ".foo[href] {\n  color: red;\n}\n", badComposes)
  2780  	expectPrintedLocal(t, ".foo .bar { composes: bar; color: red }", ".foo .bar {\n  color: red;\n}\n", badComposes)
  2781  	expectPrintedLocal(t, ".foo, div { composes: bar; color: red }", ".foo,\ndiv {\n  color: red;\n}\n", badComposes)
  2782  	expectPrintedLocal(t, ".foo { .bar { composes: foo; color: red } }", ".foo {\n  .bar {\n    color: red;\n  }\n}\n", badComposes)
  2783  }