github.com/evanw/esbuild@v0.21.4/internal/css_printer/css_printer_test.go (about) 1 package css_printer 2 3 import ( 4 "testing" 5 6 "github.com/evanw/esbuild/internal/ast" 7 "github.com/evanw/esbuild/internal/config" 8 "github.com/evanw/esbuild/internal/css_parser" 9 "github.com/evanw/esbuild/internal/logger" 10 "github.com/evanw/esbuild/internal/test" 11 ) 12 13 func expectPrintedCommon(t *testing.T, name string, contents string, expected string, options Options) { 14 t.Helper() 15 t.Run(name, func(t *testing.T) { 16 t.Helper() 17 log := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil) 18 tree := css_parser.Parse(log, test.SourceForTest(contents), css_parser.OptionsFromConfig(config.LoaderCSS, &config.Options{ 19 MinifyWhitespace: options.MinifyWhitespace, 20 })) 21 msgs := log.Done() 22 text := "" 23 for _, msg := range msgs { 24 if msg.Kind == logger.Error { 25 text += msg.String(logger.OutputOptions{}, logger.TerminalInfo{}) 26 } 27 } 28 test.AssertEqualWithDiff(t, text, "") 29 symbols := ast.NewSymbolMap(1) 30 symbols.SymbolsForSource[0] = tree.Symbols 31 result := Print(tree, symbols, options) 32 test.AssertEqualWithDiff(t, string(result.CSS), expected) 33 }) 34 } 35 36 func expectPrinted(t *testing.T, contents string, expected string) { 37 t.Helper() 38 expectPrintedCommon(t, contents, contents, expected, Options{}) 39 } 40 41 func expectPrintedMinify(t *testing.T, contents string, expected string) { 42 t.Helper() 43 expectPrintedCommon(t, contents+" [minified]", contents, expected, Options{ 44 MinifyWhitespace: true, 45 }) 46 } 47 48 func expectPrintedASCII(t *testing.T, contents string, expected string) { 49 t.Helper() 50 expectPrintedCommon(t, contents+" [ascii]", contents, expected, Options{ 51 ASCIIOnly: true, 52 }) 53 } 54 55 func expectPrintedString(t *testing.T, stringValue string, expected string) { 56 t.Helper() 57 t.Run(stringValue, func(t *testing.T) { 58 t.Helper() 59 p := printer{} 60 p.printQuoted(stringValue, 0) 61 test.AssertEqualWithDiff(t, string(p.css), expected) 62 }) 63 } 64 65 func TestStringQuote(t *testing.T) { 66 expectPrintedString(t, "", "\"\"") 67 expectPrintedString(t, "foo", "\"foo\"") 68 expectPrintedString(t, "f\"o", "'f\"o'") 69 expectPrintedString(t, "f'\"'o", "\"f'\\\"'o\"") 70 expectPrintedString(t, "f\"'\"o", "'f\"\\'\"o'") 71 expectPrintedString(t, "f\\o", "\"f\\\\o\"") 72 expectPrintedString(t, "f\ro", "\"f\\do\"") 73 expectPrintedString(t, "f\no", "\"f\\ao\"") 74 expectPrintedString(t, "f\fo", "\"f\\co\"") 75 expectPrintedString(t, "f\r\no", "\"f\\d\\ao\"") 76 expectPrintedString(t, "f\r0", "\"f\\d 0\"") 77 expectPrintedString(t, "f\n0", "\"f\\a 0\"") 78 expectPrintedString(t, "f\n ", "\"f\\a \"") 79 expectPrintedString(t, "f\n\t", "\"f\\a \t\"") 80 expectPrintedString(t, "f\nf", "\"f\\a f\"") 81 expectPrintedString(t, "f\nF", "\"f\\a F\"") 82 expectPrintedString(t, "f\ng", "\"f\\ag\"") 83 expectPrintedString(t, "f\nG", "\"f\\aG\"") 84 expectPrintedString(t, "f\x01o", "\"f\x01o\"") 85 expectPrintedString(t, "f\to", "\"f\to\"") 86 87 expectPrintedString(t, "</script>", "\"</script>\"") 88 expectPrintedString(t, "</style>", "\"<\\/style>\"") 89 expectPrintedString(t, "</style", "\"<\\/style\"") 90 expectPrintedString(t, "</STYLE", "\"<\\/STYLE\"") 91 expectPrintedString(t, "</StYlE", "\"<\\/StYlE\"") 92 expectPrintedString(t, ">/style", "\">/style\"") 93 expectPrintedString(t, ">/STYLE", "\">/STYLE\"") 94 expectPrintedString(t, ">/StYlE", "\">/StYlE\"") 95 } 96 97 func TestURLQuote(t *testing.T) { 98 expectPrinted(t, "* { background: url('foo') }", "* {\n background: url(foo);\n}\n") 99 expectPrinted(t, "* { background: url('f o') }", "* {\n background: url(f\\ o);\n}\n") 100 expectPrinted(t, "* { background: url('f o') }", "* {\n background: url(\"f o\");\n}\n") 101 expectPrinted(t, "* { background: url('foo)') }", "* {\n background: url(foo\\));\n}\n") 102 expectPrinted(t, "* { background: url('(foo') }", "* {\n background: url(\\(foo);\n}\n") 103 expectPrinted(t, "* { background: url('(foo)') }", "* {\n background: url(\"(foo)\");\n}\n") 104 expectPrinted(t, "* { background: url('\"foo\"') }", "* {\n background: url('\"foo\"');\n}\n") 105 } 106 107 func TestImportant(t *testing.T) { 108 expectPrinted(t, "a { b: c!important }", "a {\n b: c !important;\n}\n") 109 expectPrinted(t, "a { b: c!important; }", "a {\n b: c !important;\n}\n") 110 expectPrinted(t, "a { b: c! important }", "a {\n b: c !important;\n}\n") 111 expectPrinted(t, "a { b: c! important; }", "a {\n b: c !important;\n}\n") 112 expectPrinted(t, "a { b: c ! important }", "a {\n b: c !important;\n}\n") 113 expectPrinted(t, "a { b: c ! important; }", "a {\n b: c !important;\n}\n") 114 expectPrinted(t, "a { b: c !IMPORTANT; }", "a {\n b: c !important;\n}\n") 115 expectPrinted(t, "a { b: c !ImPoRtAnT; }", "a {\n b: c !important;\n}\n") 116 expectPrintedMinify(t, "a { b: c !important }", "a{b:c!important}") 117 } 118 119 func TestSelector(t *testing.T) { 120 expectPrintedMinify(t, "a + b c > d ~ e{}", "a+b c>d~e{}") 121 122 expectPrinted(t, ":unknown( x (a+b), 'c' ) {}", ":unknown(x (a+b), \"c\") {\n}\n") 123 expectPrinted(t, ":unknown( x (a-b), 'c' ) {}", ":unknown(x (a-b), \"c\") {\n}\n") 124 expectPrinted(t, ":unknown( x (a,b), 'c' ) {}", ":unknown(x (a, b), \"c\") {\n}\n") 125 expectPrinted(t, ":unknown( x ( a + b ), 'c' ) {}", ":unknown(x (a + b), \"c\") {\n}\n") 126 expectPrinted(t, ":unknown( x ( a - b ), 'c' ) {}", ":unknown(x (a - b), \"c\") {\n}\n") 127 expectPrinted(t, ":unknown( x ( a , b ), 'c' ) {}", ":unknown(x (a, b), \"c\") {\n}\n") 128 129 expectPrintedMinify(t, ":unknown( x (a+b), 'c' ) {}", ":unknown(x (a+b),\"c\"){}") 130 expectPrintedMinify(t, ":unknown( x (a-b), 'c' ) {}", ":unknown(x (a-b),\"c\"){}") 131 expectPrintedMinify(t, ":unknown( x (a,b), 'c' ) {}", ":unknown(x (a,b),\"c\"){}") 132 expectPrintedMinify(t, ":unknown( x ( a + b ), 'c' ) {}", ":unknown(x (a + b),\"c\"){}") 133 expectPrintedMinify(t, ":unknown( x ( a - b ), 'c' ) {}", ":unknown(x (a - b),\"c\"){}") 134 expectPrintedMinify(t, ":unknown( x ( a , b ), 'c' ) {}", ":unknown(x (a,b),\"c\"){}") 135 136 // ":foo()" is a parse error, but should ideally still be preserved so they don't accidentally become valid 137 expectPrinted(t, ":is {}", ":is {\n}\n") 138 expectPrinted(t, ":is() {}", ":is() {\n}\n") 139 expectPrinted(t, ":hover {}", ":hover {\n}\n") 140 expectPrinted(t, ":hover() {}", ":hover() {\n}\n") 141 expectPrintedMinify(t, ":is {}", ":is{}") 142 expectPrintedMinify(t, ":is() {}", ":is(){}") 143 expectPrintedMinify(t, ":hover {}", ":hover{}") 144 expectPrintedMinify(t, ":hover() {}", ":hover(){}") 145 } 146 147 func TestNestedSelector(t *testing.T) { 148 expectPrintedMinify(t, "a { &b {} }", "a{&b{}}") 149 expectPrintedMinify(t, "a { & b {} }", "a{& b{}}") 150 expectPrintedMinify(t, "a { & :b {} }", "a{& :b{}}") 151 expectPrintedMinify(t, "& a & b & c {}", "& a & b & c{}") 152 } 153 154 func TestBadQualifiedRules(t *testing.T) { 155 expectPrinted(t, ";", "; {\n}\n") 156 expectPrinted(t, "$bad: rule;", "$bad: rule; {\n}\n") 157 expectPrinted(t, "a {}; b {};", "a {\n}\n; b {\n}\n; {\n}\n") 158 expectPrinted(t, "a { div.major { color: blue } color: red }", "a {\n div.major {\n color: blue;\n }\n color: red;\n}\n") 159 expectPrinted(t, "a { div:hover { color: blue } color: red }", "a {\n div:hover {\n color: blue;\n }\n color: red;\n}\n") 160 expectPrinted(t, "a { div:hover { color: blue }; color: red }", "a {\n div:hover {\n color: blue;\n }\n color: red;\n}\n") 161 162 expectPrinted(t, "$bad{ color: red }", "$bad {\n color: red;\n}\n") 163 expectPrinted(t, "$bad { color: red }", "$bad {\n color: red;\n}\n") 164 expectPrinted(t, "$bad foo{ color: red }", "$bad foo {\n color: red;\n}\n") 165 expectPrinted(t, "$bad foo { color: red }", "$bad foo {\n color: red;\n}\n") 166 167 expectPrintedMinify(t, "$bad{ color: red }", "$bad{color:red}") 168 expectPrintedMinify(t, "$bad { color: red }", "$bad{color:red}") 169 expectPrintedMinify(t, "$bad foo{ color: red }", "$bad foo{color:red}") 170 expectPrintedMinify(t, "$bad foo { color: red }", "$bad foo{color:red}") 171 } 172 173 func TestDeclaration(t *testing.T) { 174 expectPrinted(t, "* { unknown: x (a+b) }", "* {\n unknown: x (a+b);\n}\n") 175 expectPrinted(t, "* { unknown: x (a-b) }", "* {\n unknown: x (a-b);\n}\n") 176 expectPrinted(t, "* { unknown: x (a,b) }", "* {\n unknown: x (a, b);\n}\n") 177 expectPrinted(t, "* { unknown: x ( a + b ) }", "* {\n unknown: x (a + b);\n}\n") 178 expectPrinted(t, "* { unknown: x ( a - b ) }", "* {\n unknown: x (a - b);\n}\n") 179 expectPrinted(t, "* { unknown: x ( a , b ) }", "* {\n unknown: x (a, b);\n}\n") 180 181 expectPrintedMinify(t, "* { unknown: x (a+b) }", "*{unknown:x (a+b)}") 182 expectPrintedMinify(t, "* { unknown: x (a-b) }", "*{unknown:x (a-b)}") 183 expectPrintedMinify(t, "* { unknown: x (a,b) }", "*{unknown:x (a,b)}") 184 expectPrintedMinify(t, "* { unknown: x ( a + b ) }", "*{unknown:x (a + b)}") 185 expectPrintedMinify(t, "* { unknown: x ( a - b ) }", "*{unknown:x (a - b)}") 186 expectPrintedMinify(t, "* { unknown: x ( a , b ) }", "*{unknown:x (a,b)}") 187 188 // Pretty-print long lists in declarations 189 expectPrinted(t, "a { b: c, d }", "a {\n b: c, d;\n}\n") 190 expectPrinted(t, "a { b: c, (d, e) }", "a {\n b: c, (d, e);\n}\n") 191 expectPrinted(t, "a { b: c, d, e }", "a {\n b:\n c,\n d,\n e;\n}\n") 192 expectPrinted(t, "a { b: c, (d, e), f }", "a {\n b:\n c,\n (d, e),\n f;\n}\n") 193 194 expectPrintedMinify(t, "a { b: c, d }", "a{b:c,d}") 195 expectPrintedMinify(t, "a { b: c, (d, e) }", "a{b:c,(d,e)}") 196 expectPrintedMinify(t, "a { b: c, d, e }", "a{b:c,d,e}") 197 expectPrintedMinify(t, "a { b: c, (d, e), f }", "a{b:c,(d,e),f}") 198 } 199 200 func TestVerbatimWhitespace(t *testing.T) { 201 expectPrinted(t, "*{--x:}", "* {\n --x:;\n}\n") 202 expectPrinted(t, "*{--x: }", "* {\n --x: ;\n}\n") 203 expectPrinted(t, "* { --x:; }", "* {\n --x:;\n}\n") 204 expectPrinted(t, "* { --x: ; }", "* {\n --x: ;\n}\n") 205 206 expectPrintedMinify(t, "*{--x:}", "*{--x:}") 207 expectPrintedMinify(t, "*{--x: }", "*{--x: }") 208 expectPrintedMinify(t, "* { --x:; }", "*{--x:}") 209 expectPrintedMinify(t, "* { --x: ; }", "*{--x: }") 210 211 expectPrinted(t, "*{--x:!important}", "* {\n --x:!important;\n}\n") 212 expectPrinted(t, "*{--x: !important}", "* {\n --x: !important;\n}\n") 213 expectPrinted(t, "*{ --x:!important }", "* {\n --x:!important;\n}\n") 214 expectPrinted(t, "*{ --x: !important }", "* {\n --x: !important;\n}\n") 215 expectPrinted(t, "* { --x:!important; }", "* {\n --x:!important;\n}\n") 216 expectPrinted(t, "* { --x: !important; }", "* {\n --x: !important;\n}\n") 217 expectPrinted(t, "* { --x:! important ; }", "* {\n --x:!important;\n}\n") 218 expectPrinted(t, "* { --x: ! important ; }", "* {\n --x: !important;\n}\n") 219 220 expectPrintedMinify(t, "*{--x:!important}", "*{--x:!important}") 221 expectPrintedMinify(t, "*{--x: !important}", "*{--x: !important}") 222 expectPrintedMinify(t, "*{ --x:!important }", "*{--x:!important}") 223 expectPrintedMinify(t, "*{ --x: !important }", "*{--x: !important}") 224 expectPrintedMinify(t, "* { --x:!important; }", "*{--x:!important}") 225 expectPrintedMinify(t, "* { --x: !important; }", "*{--x: !important}") 226 expectPrintedMinify(t, "* { --x:! important ; }", "*{--x:!important}") 227 expectPrintedMinify(t, "* { --x: ! important ; }", "*{--x: !important}") 228 229 expectPrinted(t, "* { --x:y; }", "* {\n --x:y;\n}\n") 230 expectPrinted(t, "* { --x: y; }", "* {\n --x: y;\n}\n") 231 expectPrinted(t, "* { --x:y ; }", "* {\n --x:y ;\n}\n") 232 expectPrinted(t, "* { --x:y, ; }", "* {\n --x:y, ;\n}\n") 233 expectPrinted(t, "* { --x: var(y,); }", "* {\n --x: var(y,);\n}\n") 234 expectPrinted(t, "* { --x: var(y, ); }", "* {\n --x: var(y, );\n}\n") 235 236 expectPrintedMinify(t, "* { --x:y; }", "*{--x:y}") 237 expectPrintedMinify(t, "* { --x: y; }", "*{--x: y}") 238 expectPrintedMinify(t, "* { --x:y ; }", "*{--x:y }") 239 expectPrintedMinify(t, "* { --x:y, ; }", "*{--x:y, }") 240 expectPrintedMinify(t, "* { --x: var(y,); }", "*{--x: var(y,)}") 241 expectPrintedMinify(t, "* { --x: var(y, ); }", "*{--x: var(y, )}") 242 243 expectPrinted(t, "* { --x:(y); }", "* {\n --x:(y);\n}\n") 244 expectPrinted(t, "* { --x:(y) ; }", "* {\n --x:(y) ;\n}\n") 245 expectPrinted(t, "* { --x: (y); }", "* {\n --x: (y);\n}\n") 246 expectPrinted(t, "* { --x:(y ); }", "* {\n --x:(y );\n}\n") 247 expectPrinted(t, "* { --x:( y); }", "* {\n --x:( y);\n}\n") 248 249 expectPrintedMinify(t, "* { --x:(y); }", "*{--x:(y)}") 250 expectPrintedMinify(t, "* { --x:(y) ; }", "*{--x:(y) }") 251 expectPrintedMinify(t, "* { --x: (y); }", "*{--x: (y)}") 252 expectPrintedMinify(t, "* { --x:(y ); }", "*{--x:(y )}") 253 expectPrintedMinify(t, "* { --x:( y); }", "*{--x:( y)}") 254 255 expectPrinted(t, "* { --x:f(y); }", "* {\n --x:f(y);\n}\n") 256 expectPrinted(t, "* { --x:f(y) ; }", "* {\n --x:f(y) ;\n}\n") 257 expectPrinted(t, "* { --x: f(y); }", "* {\n --x: f(y);\n}\n") 258 expectPrinted(t, "* { --x:f(y ); }", "* {\n --x:f(y );\n}\n") 259 expectPrinted(t, "* { --x:f( y); }", "* {\n --x:f( y);\n}\n") 260 261 expectPrintedMinify(t, "* { --x:f(y); }", "*{--x:f(y)}") 262 expectPrintedMinify(t, "* { --x:f(y) ; }", "*{--x:f(y) }") 263 expectPrintedMinify(t, "* { --x: f(y); }", "*{--x: f(y)}") 264 expectPrintedMinify(t, "* { --x:f(y ); }", "*{--x:f(y )}") 265 expectPrintedMinify(t, "* { --x:f( y); }", "*{--x:f( y)}") 266 267 expectPrinted(t, "* { --x:[y]; }", "* {\n --x:[y];\n}\n") 268 expectPrinted(t, "* { --x:[y] ; }", "* {\n --x:[y] ;\n}\n") 269 expectPrinted(t, "* { --x: [y]; }", "* {\n --x: [y];\n}\n") 270 expectPrinted(t, "* { --x:[y ]; }", "* {\n --x:[y ];\n}\n") 271 expectPrinted(t, "* { --x:[ y]; }", "* {\n --x:[ y];\n}\n") 272 273 expectPrintedMinify(t, "* { --x:[y]; }", "*{--x:[y]}") 274 expectPrintedMinify(t, "* { --x:[y] ; }", "*{--x:[y] }") 275 expectPrintedMinify(t, "* { --x: [y]; }", "*{--x: [y]}") 276 expectPrintedMinify(t, "* { --x:[y ]; }", "*{--x:[y ]}") 277 expectPrintedMinify(t, "* { --x:[ y]; }", "*{--x:[ y]}") 278 279 // Note: These cases now behave like qualified rules 280 expectPrinted(t, "* { --x:{y}; }", "* {\n --x: {\n y;\n }\n}\n") 281 expectPrinted(t, "* { --x:{y} ; }", "* {\n --x: {\n y;\n }\n}\n") 282 expectPrinted(t, "* { --x: {y}; }", "* {\n --x: {\n y;\n }\n}\n") 283 expectPrinted(t, "* { --x:{y }; }", "* {\n --x: {\n y;\n }\n}\n") 284 expectPrinted(t, "* { --x:{ y}; }", "* {\n --x: {\n y;\n }\n}\n") 285 286 // Note: These cases now behave like qualified rules 287 expectPrintedMinify(t, "* { --x:{y}; }", "*{--x:{y}}") 288 expectPrintedMinify(t, "* { --x:{y} ; }", "*{--x:{y}}") 289 expectPrintedMinify(t, "* { --x: {y}; }", "*{--x:{y}}") 290 expectPrintedMinify(t, "* { --x:{y }; }", "*{--x:{y}}") 291 expectPrintedMinify(t, "* { --x:{ y}; }", "*{--x:{y}}") 292 293 expectPrintedMinify(t, "@supports ( --x : y , z ) { a { color: red; } }", "@supports ( --x : y , z ){a{color:red}}") 294 expectPrintedMinify(t, "@supports ( --x : ) { a { color: red; } }", "@supports ( --x : ){a{color:red}}") 295 expectPrintedMinify(t, "@supports (--x: ) { a { color: red; } }", "@supports (--x: ){a{color:red}}") 296 expectPrintedMinify(t, "@supports ( --x y , z ) { a { color: red; } }", "@supports (--x y,z){a{color:red}}") 297 expectPrintedMinify(t, "@supports ( --x ) { a { color: red; } }", "@supports (--x){a{color:red}}") 298 expectPrintedMinify(t, "@supports ( ) { a { color: red; } }", "@supports (){a{color:red}}") 299 expectPrintedMinify(t, "@supports ( . --x : y , z ) { a { color: red; } }", "@supports (. --x : y,z){a{color:red}}") 300 } 301 302 func TestAtRule(t *testing.T) { 303 expectPrintedMinify(t, "@unknown;", "@unknown;") 304 expectPrintedMinify(t, "@unknown x;", "@unknown x;") 305 expectPrintedMinify(t, "@unknown{}", "@unknown{}") 306 expectPrintedMinify(t, "@unknown{\na: b;\nc: d;\n}", "@unknown{a: b; c: d;}") 307 308 expectPrinted(t, "@unknown x{}", "@unknown x {}\n") 309 expectPrinted(t, "@unknown x {}", "@unknown x {}\n") 310 expectPrintedMinify(t, "@unknown x{}", "@unknown x{}") 311 expectPrintedMinify(t, "@unknown x {}", "@unknown x{}") 312 313 expectPrinted(t, "@unknown x ( a + b ) ;", "@unknown x (a + b);\n") 314 expectPrinted(t, "@unknown x ( a - b ) ;", "@unknown x (a - b);\n") 315 expectPrinted(t, "@unknown x ( a , b ) ;", "@unknown x (a, b);\n") 316 expectPrintedMinify(t, "@unknown x ( a + b ) ;", "@unknown x (a + b);") 317 expectPrintedMinify(t, "@unknown x ( a - b ) ;", "@unknown x (a - b);") 318 expectPrintedMinify(t, "@unknown x ( a , b ) ;", "@unknown x (a,b);") 319 } 320 321 func TestAtCharset(t *testing.T) { 322 expectPrinted(t, "@charset \"UTF-8\";", "@charset \"UTF-8\";\n") 323 expectPrintedMinify(t, "@charset \"UTF-8\";", "@charset \"UTF-8\";") 324 } 325 326 func TestAtImport(t *testing.T) { 327 expectPrinted(t, "@import\"foo.css\";", "@import \"foo.css\";\n") 328 expectPrinted(t, "@import \"foo.css\";", "@import \"foo.css\";\n") 329 expectPrinted(t, "@import url(foo.css);", "@import \"foo.css\";\n") 330 expectPrinted(t, "@import url(\"foo.css\");", "@import \"foo.css\";\n") 331 expectPrinted(t, "@import url(\"foo.css\") print;", "@import \"foo.css\" print;\n") 332 333 expectPrintedMinify(t, "@import\"foo.css\";", "@import\"foo.css\";") 334 expectPrintedMinify(t, "@import \"foo.css\";", "@import\"foo.css\";") 335 expectPrintedMinify(t, "@import url(foo.css);", "@import\"foo.css\";") 336 expectPrintedMinify(t, "@import url(\"foo.css\");", "@import\"foo.css\";") 337 expectPrintedMinify(t, "@import url(\"foo.css\") print;", "@import\"foo.css\"print;") 338 } 339 340 func TestAtKeyframes(t *testing.T) { 341 expectPrintedMinify(t, "@keyframes name { 0%, 50% { color: red } 25%, 75% { color: blue } }", 342 "@keyframes name{0%,50%{color:red}25%,75%{color:blue}}") 343 expectPrintedMinify(t, "@keyframes name { from { color: red } to { color: blue } }", 344 "@keyframes name{from{color:red}to{color:blue}}") 345 } 346 347 func TestAtMedia(t *testing.T) { 348 expectPrinted(t, "@media screen { div { color: red } }", "@media screen {\n div {\n color: red;\n }\n}\n") 349 expectPrinted(t, "@media screen{div{color:red}}", "@media screen {\n div {\n color: red;\n }\n}\n") 350 expectPrintedMinify(t, "@media screen { div { color: red } }", "@media screen{div{color:red}}") 351 expectPrintedMinify(t, "@media screen{div{color:red}}", "@media screen{div{color:red}}") 352 } 353 354 func TestAtFontFace(t *testing.T) { 355 expectPrinted(t, "@font-face { font-family: 'Open Sans'; src: url('OpenSans.woff') format('woff') }", 356 "@font-face {\n font-family: \"Open Sans\";\n src: url(OpenSans.woff) format(\"woff\");\n}\n") 357 expectPrintedMinify(t, "@font-face { font-family: 'Open Sans'; src: url('OpenSans.woff') format('woff') }", 358 "@font-face{font-family:\"Open Sans\";src:url(OpenSans.woff) format(\"woff\")}") 359 } 360 361 func TestAtPage(t *testing.T) { 362 expectPrinted(t, "@page { margin: 1cm }", "@page {\n margin: 1cm;\n}\n") 363 expectPrinted(t, "@page :first { margin: 1cm }", "@page :first {\n margin: 1cm;\n}\n") 364 expectPrintedMinify(t, "@page { margin: 1cm }", "@page{margin:1cm}") 365 expectPrintedMinify(t, "@page :first { margin: 1cm }", "@page :first{margin:1cm}") 366 } 367 368 func TestMsGridColumnsWhitespace(t *testing.T) { 369 // Must not insert a space between the "]" and the "(" 370 expectPrinted(t, "div { -ms-grid-columns: (1fr)[3] }", "div {\n -ms-grid-columns: (1fr)[3];\n}\n") 371 expectPrinted(t, "div { -ms-grid-columns: 1fr (20px 1fr)[3] }", "div {\n -ms-grid-columns: 1fr (20px 1fr)[3];\n}\n") 372 expectPrintedMinify(t, "div { -ms-grid-columns: (1fr)[3] }", "div{-ms-grid-columns:(1fr)[3]}") 373 expectPrintedMinify(t, "div { -ms-grid-columns: 1fr (20px 1fr)[3] }", "div{-ms-grid-columns:1fr (20px 1fr)[3]}") 374 } 375 376 func TestASCII(t *testing.T) { 377 expectPrintedASCII(t, "* { background: url(🐈) }", "* {\n background: url(\\1f408);\n}\n") 378 expectPrintedASCII(t, "* { background: url(🐈6) }", "* {\n background: url(\\1f408 6);\n}\n") 379 expectPrintedASCII(t, "* { background: url('🐈') }", "* {\n background: url(\\1f408);\n}\n") 380 expectPrintedASCII(t, "* { background: url('🐈6') }", "* {\n background: url(\\1f408 6);\n}\n") 381 expectPrintedASCII(t, "* { background: url('(🐈)') }", "* {\n background: url(\"(\\1f408)\");\n}\n") 382 expectPrintedASCII(t, "* { background: url('(🐈6)') }", "* {\n background: url(\"(\\1f408 6)\");\n}\n") 383 384 expectPrintedASCII(t, "div { 🐈: 🐈('🐈') }", "div {\n \\1f408: \\1f408(\"\\1f408\");\n}\n") 385 expectPrintedASCII(t, "div { 🐈 : 🐈 ('🐈 ') }", "div {\n \\1f408: \\1f408 (\"\\1f408 \");\n}\n") 386 expectPrintedASCII(t, "div { 🐈6: 🐈6('🐈6') }", "div {\n \\1f408 6: \\1f408 6(\"\\1f408 6\");\n}\n") 387 388 expectPrintedASCII(t, "@🐈;", "@\\1f408;\n") 389 expectPrintedASCII(t, "@🐈 {}", "@\\1f408 {}\n") 390 expectPrintedASCII(t, "@🐈 x {}", "@\\1f408 x {}\n") 391 392 expectPrintedASCII(t, "#🐈#x {}", "#\\1f408#x {\n}\n") 393 expectPrintedASCII(t, "#🐈 #x {}", "#\\1f408 #x {\n}\n") 394 expectPrintedASCII(t, "#🐈::x {}", "#\\1f408::x {\n}\n") 395 expectPrintedASCII(t, "#🐈 ::x {}", "#\\1f408 ::x {\n}\n") 396 397 expectPrintedASCII(t, ".🐈.x {}", ".\\1f408.x {\n}\n") 398 expectPrintedASCII(t, ".🐈 .x {}", ".\\1f408 .x {\n}\n") 399 expectPrintedASCII(t, ".🐈::x {}", ".\\1f408::x {\n}\n") 400 expectPrintedASCII(t, ".🐈 ::x {}", ".\\1f408 ::x {\n}\n") 401 402 expectPrintedASCII(t, "🐈|🐈.x {}", "\\1f408|\\1f408.x {\n}\n") 403 expectPrintedASCII(t, "🐈|🐈 .x {}", "\\1f408|\\1f408 .x {\n}\n") 404 expectPrintedASCII(t, "🐈|🐈::x {}", "\\1f408|\\1f408::x {\n}\n") 405 expectPrintedASCII(t, "🐈|🐈 ::x {}", "\\1f408|\\1f408 ::x {\n}\n") 406 407 expectPrintedASCII(t, "::🐈:x {}", "::\\1f408:x {\n}\n") 408 expectPrintedASCII(t, "::🐈 :x {}", "::\\1f408 :x {\n}\n") 409 410 expectPrintedASCII(t, "[🐈] {}", "[\\1f408] {\n}\n") 411 expectPrintedASCII(t, "[🐈=🐈] {}", "[\\1f408=\\1f408] {\n}\n") 412 expectPrintedASCII(t, "[🐈|🐈=🐈] {}", "[\\1f408|\\1f408=\\1f408] {\n}\n") 413 414 // A space must be consumed after an escaped code point even with six digits 415 expectPrintedASCII(t, ".\\10FFF abc:after { content: '\\10FFF abc' }", ".\\10fff abc:after {\n content: \"\\10fff abc\";\n}\n") 416 expectPrintedASCII(t, ".\U00010FFFabc:after { content: '\U00010FFFabc' }", ".\\10fff abc:after {\n content: \"\\10fff abc\";\n}\n") 417 expectPrintedASCII(t, ".\\10FFFFabc:after { content: '\\10FFFFabc' }", ".\\10ffffabc:after {\n content: \"\\10ffffabc\";\n}\n") 418 expectPrintedASCII(t, ".\\10FFFF abc:after { content: '\\10FFFF abc' }", ".\\10ffffabc:after {\n content: \"\\10ffffabc\";\n}\n") 419 expectPrintedASCII(t, ".\U0010FFFFabc:after { content: '\U0010FFFFabc' }", ".\\10ffffabc:after {\n content: \"\\10ffffabc\";\n}\n") 420 421 // This character should always be escaped 422 expectPrinted(t, ".\\FEFF:after { content: '\uFEFF' }", ".\\feff:after {\n content: \"\\feff\";\n}\n") 423 }