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 }