github.com/evanw/esbuild@v0.21.4/internal/js_printer/js_printer_test.go (about) 1 package js_printer 2 3 import ( 4 "strings" 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/js_parser" 11 "github.com/evanw/esbuild/internal/logger" 12 "github.com/evanw/esbuild/internal/renamer" 13 "github.com/evanw/esbuild/internal/test" 14 ) 15 16 func expectPrintedCommon(t *testing.T, name string, contents string, expected string, options config.Options) { 17 t.Helper() 18 t.Run(name, func(t *testing.T) { 19 t.Helper() 20 log := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil) 21 tree, ok := js_parser.Parse(log, test.SourceForTest(contents), js_parser.OptionsFromConfig(&options)) 22 msgs := log.Done() 23 text := "" 24 for _, msg := range msgs { 25 text += msg.String(logger.OutputOptions{}, logger.TerminalInfo{}) 26 } 27 test.AssertEqualWithDiff(t, text, "") 28 if !ok { 29 t.Fatal("Parse error") 30 } 31 symbols := ast.NewSymbolMap(1) 32 symbols.SymbolsForSource[0] = tree.Symbols 33 r := renamer.NewNoOpRenamer(symbols) 34 js := Print(tree, symbols, r, Options{ 35 ASCIIOnly: options.ASCIIOnly, 36 MinifySyntax: options.MinifySyntax, 37 MinifyWhitespace: options.MinifyWhitespace, 38 UnsupportedFeatures: options.UnsupportedJSFeatures, 39 }).JS 40 test.AssertEqualWithDiff(t, string(js), expected) 41 }) 42 } 43 44 func expectPrinted(t *testing.T, contents string, expected string) { 45 t.Helper() 46 expectPrintedCommon(t, contents, contents, expected, config.Options{}) 47 } 48 49 func expectPrintedMinify(t *testing.T, contents string, expected string) { 50 t.Helper() 51 expectPrintedCommon(t, contents+" [minified]", contents, expected, config.Options{ 52 MinifyWhitespace: true, 53 }) 54 } 55 56 func expectPrintedMangle(t *testing.T, contents string, expected string) { 57 t.Helper() 58 expectPrintedCommon(t, contents+" [mangled]", contents, expected, config.Options{ 59 MinifySyntax: true, 60 }) 61 } 62 63 func expectPrintedMangleMinify(t *testing.T, contents string, expected string) { 64 t.Helper() 65 expectPrintedCommon(t, contents+" [mangled, minified]", contents, expected, config.Options{ 66 MinifySyntax: true, 67 MinifyWhitespace: true, 68 }) 69 } 70 71 func expectPrintedASCII(t *testing.T, contents string, expected string) { 72 t.Helper() 73 expectPrintedCommon(t, contents+" [ascii]", contents, expected, config.Options{ 74 ASCIIOnly: true, 75 }) 76 } 77 78 func expectPrintedMinifyASCII(t *testing.T, contents string, expected string) { 79 t.Helper() 80 expectPrintedCommon(t, contents+" [ascii]", contents, expected, config.Options{ 81 MinifyWhitespace: true, 82 ASCIIOnly: true, 83 }) 84 } 85 86 func expectPrintedTarget(t *testing.T, esVersion int, contents string, expected string) { 87 t.Helper() 88 expectPrintedCommon(t, contents, contents, expected, config.Options{ 89 UnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{ 90 compat.ES: {Parts: []int{esVersion}}, 91 }), 92 }) 93 } 94 95 func expectPrintedTargetMinify(t *testing.T, esVersion int, contents string, expected string) { 96 t.Helper() 97 expectPrintedCommon(t, contents+" [minified]", contents, expected, config.Options{ 98 UnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{ 99 compat.ES: {Parts: []int{esVersion}}, 100 }), 101 MinifyWhitespace: true, 102 }) 103 } 104 105 func expectPrintedTargetMangle(t *testing.T, esVersion int, contents string, expected string) { 106 t.Helper() 107 expectPrintedCommon(t, contents+" [mangled]", contents, expected, config.Options{ 108 UnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{ 109 compat.ES: {Parts: []int{esVersion}}, 110 }), 111 MinifySyntax: true, 112 }) 113 } 114 115 func expectPrintedTargetASCII(t *testing.T, esVersion int, contents string, expected string) { 116 t.Helper() 117 expectPrintedCommon(t, contents+" [ascii]", contents, expected, config.Options{ 118 UnsupportedJSFeatures: compat.UnsupportedJSFeatures(map[compat.Engine]compat.Semver{ 119 compat.ES: {Parts: []int{esVersion}}, 120 }), 121 ASCIIOnly: true, 122 }) 123 } 124 125 func expectPrintedJSX(t *testing.T, contents string, expected string) { 126 t.Helper() 127 expectPrintedCommon(t, contents, contents, expected, config.Options{ 128 JSX: config.JSXOptions{ 129 Parse: true, 130 Preserve: true, 131 }, 132 }) 133 } 134 135 func expectPrintedJSXASCII(t *testing.T, contents string, expected string) { 136 t.Helper() 137 expectPrintedCommon(t, contents, contents, expected, config.Options{ 138 JSX: config.JSXOptions{ 139 Parse: true, 140 Preserve: true, 141 }, 142 ASCIIOnly: true, 143 }) 144 } 145 146 func expectPrintedJSXMinify(t *testing.T, contents string, expected string) { 147 t.Helper() 148 expectPrintedCommon(t, contents+" [minified]", contents, expected, config.Options{ 149 JSX: config.JSXOptions{ 150 Parse: true, 151 Preserve: true, 152 }, 153 MinifyWhitespace: true, 154 }) 155 } 156 157 func TestNumber(t *testing.T) { 158 // Check "1eN" 159 expectPrinted(t, "x = 1e-100", "x = 1e-100;\n") 160 expectPrinted(t, "x = 1e-4", "x = 1e-4;\n") 161 expectPrinted(t, "x = 1e-3", "x = 1e-3;\n") 162 expectPrinted(t, "x = 1e-2", "x = 0.01;\n") 163 expectPrinted(t, "x = 1e-1", "x = 0.1;\n") 164 expectPrinted(t, "x = 1e0", "x = 1;\n") 165 expectPrinted(t, "x = 1e1", "x = 10;\n") 166 expectPrinted(t, "x = 1e2", "x = 100;\n") 167 expectPrinted(t, "x = 1e3", "x = 1e3;\n") 168 expectPrinted(t, "x = 1e4", "x = 1e4;\n") 169 expectPrinted(t, "x = 1e100", "x = 1e100;\n") 170 expectPrintedMinify(t, "x = 1e-100", "x=1e-100;") 171 expectPrintedMinify(t, "x = 1e-5", "x=1e-5;") 172 expectPrintedMinify(t, "x = 1e-4", "x=1e-4;") 173 expectPrintedMinify(t, "x = 1e-3", "x=.001;") 174 expectPrintedMinify(t, "x = 1e-2", "x=.01;") 175 expectPrintedMinify(t, "x = 1e-1", "x=.1;") 176 expectPrintedMinify(t, "x = 1e0", "x=1;") 177 expectPrintedMinify(t, "x = 1e1", "x=10;") 178 expectPrintedMinify(t, "x = 1e2", "x=100;") 179 expectPrintedMinify(t, "x = 1e3", "x=1e3;") 180 expectPrintedMinify(t, "x = 1e4", "x=1e4;") 181 expectPrintedMinify(t, "x = 1e100", "x=1e100;") 182 183 // Check "12eN" 184 expectPrinted(t, "x = 12e-100", "x = 12e-100;\n") 185 expectPrinted(t, "x = 12e-5", "x = 12e-5;\n") 186 expectPrinted(t, "x = 12e-4", "x = 12e-4;\n") 187 expectPrinted(t, "x = 12e-3", "x = 0.012;\n") 188 expectPrinted(t, "x = 12e-2", "x = 0.12;\n") 189 expectPrinted(t, "x = 12e-1", "x = 1.2;\n") 190 expectPrinted(t, "x = 12e0", "x = 12;\n") 191 expectPrinted(t, "x = 12e1", "x = 120;\n") 192 expectPrinted(t, "x = 12e2", "x = 1200;\n") 193 expectPrinted(t, "x = 12e3", "x = 12e3;\n") 194 expectPrinted(t, "x = 12e4", "x = 12e4;\n") 195 expectPrinted(t, "x = 12e100", "x = 12e100;\n") 196 expectPrintedMinify(t, "x = 12e-100", "x=12e-100;") 197 expectPrintedMinify(t, "x = 12e-6", "x=12e-6;") 198 expectPrintedMinify(t, "x = 12e-5", "x=12e-5;") 199 expectPrintedMinify(t, "x = 12e-4", "x=.0012;") 200 expectPrintedMinify(t, "x = 12e-3", "x=.012;") 201 expectPrintedMinify(t, "x = 12e-2", "x=.12;") 202 expectPrintedMinify(t, "x = 12e-1", "x=1.2;") 203 expectPrintedMinify(t, "x = 12e0", "x=12;") 204 expectPrintedMinify(t, "x = 12e1", "x=120;") 205 expectPrintedMinify(t, "x = 12e2", "x=1200;") 206 expectPrintedMinify(t, "x = 12e3", "x=12e3;") 207 expectPrintedMinify(t, "x = 12e4", "x=12e4;") 208 expectPrintedMinify(t, "x = 12e100", "x=12e100;") 209 210 // Check cases for "A.BeX" => "ABeY" simplification 211 expectPrinted(t, "x = 123456789", "x = 123456789;\n") 212 expectPrinted(t, "x = 1123456789", "x = 1123456789;\n") 213 expectPrinted(t, "x = 10123456789", "x = 10123456789;\n") 214 expectPrinted(t, "x = 100123456789", "x = 100123456789;\n") 215 expectPrinted(t, "x = 1000123456789", "x = 1000123456789;\n") 216 expectPrinted(t, "x = 10000123456789", "x = 10000123456789;\n") 217 expectPrinted(t, "x = 100000123456789", "x = 100000123456789;\n") 218 expectPrinted(t, "x = 1000000123456789", "x = 1000000123456789;\n") 219 expectPrinted(t, "x = 10000000123456789", "x = 10000000123456788;\n") 220 expectPrinted(t, "x = 100000000123456789", "x = 100000000123456780;\n") 221 expectPrinted(t, "x = 1000000000123456789", "x = 1000000000123456800;\n") 222 expectPrinted(t, "x = 10000000000123456789", "x = 10000000000123458e3;\n") 223 expectPrinted(t, "x = 100000000000123456789", "x = 10000000000012345e4;\n") 224 225 // Check numbers around the ends of various integer ranges. These were 226 // crashing in the WebAssembly build due to a bug in the Go runtime. 227 228 // int32 229 expectPrinted(t, "x = 0x7fff_ffff", "x = 2147483647;\n") 230 expectPrinted(t, "x = 0x8000_0000", "x = 2147483648;\n") 231 expectPrinted(t, "x = 0x8000_0001", "x = 2147483649;\n") 232 expectPrinted(t, "x = -0x7fff_ffff", "x = -2147483647;\n") 233 expectPrinted(t, "x = -0x8000_0000", "x = -2147483648;\n") 234 expectPrinted(t, "x = -0x8000_0001", "x = -2147483649;\n") 235 236 // uint32 237 expectPrinted(t, "x = 0xffff_ffff", "x = 4294967295;\n") 238 expectPrinted(t, "x = 0x1_0000_0000", "x = 4294967296;\n") 239 expectPrinted(t, "x = 0x1_0000_0001", "x = 4294967297;\n") 240 expectPrinted(t, "x = -0xffff_ffff", "x = -4294967295;\n") 241 expectPrinted(t, "x = -0x1_0000_0000", "x = -4294967296;\n") 242 expectPrinted(t, "x = -0x1_0000_0001", "x = -4294967297;\n") 243 244 // int64 245 expectPrinted(t, "x = 0x7fff_ffff_ffff_fdff", "x = 9223372036854775e3;\n") 246 expectPrinted(t, "x = 0x8000_0000_0000_0000", "x = 9223372036854776e3;\n") 247 expectPrinted(t, "x = 0x8000_0000_0000_3000", "x = 9223372036854788e3;\n") 248 expectPrinted(t, "x = -0x7fff_ffff_ffff_fdff", "x = -9223372036854775e3;\n") 249 expectPrinted(t, "x = -0x8000_0000_0000_0000", "x = -9223372036854776e3;\n") 250 expectPrinted(t, "x = -0x8000_0000_0000_3000", "x = -9223372036854788e3;\n") 251 252 // uint64 253 expectPrinted(t, "x = 0xffff_ffff_ffff_fbff", "x = 1844674407370955e4;\n") 254 expectPrinted(t, "x = 0x1_0000_0000_0000_0000", "x = 18446744073709552e3;\n") 255 expectPrinted(t, "x = 0x1_0000_0000_0000_1000", "x = 18446744073709556e3;\n") 256 expectPrinted(t, "x = -0xffff_ffff_ffff_fbff", "x = -1844674407370955e4;\n") 257 expectPrinted(t, "x = -0x1_0000_0000_0000_0000", "x = -18446744073709552e3;\n") 258 expectPrinted(t, "x = -0x1_0000_0000_0000_1000", "x = -18446744073709556e3;\n") 259 260 // Check the hex vs. decimal decision boundary when minifying 261 expectPrinted(t, "x = 999999999999", "x = 999999999999;\n") 262 expectPrinted(t, "x = 1000000000001", "x = 1000000000001;\n") 263 expectPrinted(t, "x = 0x0FFF_FFFF_FFFF_FF80", "x = 1152921504606846800;\n") 264 expectPrinted(t, "x = 0x1000_0000_0000_0000", "x = 1152921504606847e3;\n") 265 expectPrinted(t, "x = 0xFFFF_FFFF_FFFF_F000", "x = 18446744073709548e3;\n") 266 expectPrinted(t, "x = 0xFFFF_FFFF_FFFF_F800", "x = 1844674407370955e4;\n") 267 expectPrinted(t, "x = 0xFFFF_FFFF_FFFF_FFFF", "x = 18446744073709552e3;\n") 268 expectPrintedMinify(t, "x = 999999999999", "x=999999999999;") 269 expectPrintedMinify(t, "x = 1000000000001", "x=0xe8d4a51001;") 270 expectPrintedMinify(t, "x = 0x0FFF_FFFF_FFFF_FF80", "x=0xfffffffffffff80;") 271 expectPrintedMinify(t, "x = 0x1000_0000_0000_0000", "x=1152921504606847e3;") 272 expectPrintedMinify(t, "x = 0xFFFF_FFFF_FFFF_F000", "x=0xfffffffffffff000;") 273 expectPrintedMinify(t, "x = 0xFFFF_FFFF_FFFF_F800", "x=1844674407370955e4;") 274 expectPrintedMinify(t, "x = 0xFFFF_FFFF_FFFF_FFFF", "x=18446744073709552e3;") 275 276 // Check printing a space in between a number and a subsequent "." 277 expectPrintedMinify(t, "x = 0.0001 .y", "x=1e-4.y;") 278 expectPrintedMinify(t, "x = 0.001 .y", "x=.001.y;") 279 expectPrintedMinify(t, "x = 0.01 .y", "x=.01.y;") 280 expectPrintedMinify(t, "x = 0.1 .y", "x=.1.y;") 281 expectPrintedMinify(t, "x = 0 .y", "x=0 .y;") 282 expectPrintedMinify(t, "x = 10 .y", "x=10 .y;") 283 expectPrintedMinify(t, "x = 100 .y", "x=100 .y;") 284 expectPrintedMinify(t, "x = 1000 .y", "x=1e3.y;") 285 expectPrintedMinify(t, "x = 12345 .y", "x=12345 .y;") 286 expectPrintedMinify(t, "x = 0xFFFF_0000_FFFF_0000 .y", "x=0xffff0000ffff0000.y;") 287 } 288 289 func TestArray(t *testing.T) { 290 expectPrinted(t, "[]", "[];\n") 291 expectPrinted(t, "[,]", "[,];\n") 292 expectPrinted(t, "[,,]", "[, ,];\n") 293 } 294 295 func TestSplat(t *testing.T) { 296 expectPrinted(t, "[...(a, b)]", "[...(a, b)];\n") 297 expectPrinted(t, "x(...(a, b))", "x(...(a, b));\n") 298 expectPrinted(t, "({...(a, b)})", "({ ...(a, b) });\n") 299 } 300 301 func TestNew(t *testing.T) { 302 expectPrinted(t, "new x", "new x();\n") 303 expectPrinted(t, "new x()", "new x();\n") 304 expectPrinted(t, "new (x)", "new x();\n") 305 expectPrinted(t, "new (x())", "new (x())();\n") 306 expectPrinted(t, "new (new x())", "new new x()();\n") 307 expectPrinted(t, "new (x + x)", "new (x + x)();\n") 308 expectPrinted(t, "(new x)()", "new x()();\n") 309 310 expectPrinted(t, "new foo().bar", "new foo().bar;\n") 311 expectPrinted(t, "new (foo().bar)", "new (foo()).bar();\n") 312 expectPrinted(t, "new (foo()).bar", "new (foo()).bar();\n") 313 expectPrinted(t, "new foo()[bar]", "new foo()[bar];\n") 314 expectPrinted(t, "new (foo()[bar])", "new (foo())[bar]();\n") 315 expectPrinted(t, "new (foo())[bar]", "new (foo())[bar]();\n") 316 317 expectPrinted(t, "new (import('foo').bar)", "new (import(\"foo\")).bar();\n") 318 expectPrinted(t, "new (import('foo')).bar", "new (import(\"foo\")).bar();\n") 319 expectPrinted(t, "new (import('foo')[bar])", "new (import(\"foo\"))[bar]();\n") 320 expectPrinted(t, "new (import('foo'))[bar]", "new (import(\"foo\"))[bar]();\n") 321 322 expectPrintedMinify(t, "new x", "new x;") 323 expectPrintedMinify(t, "new x.y", "new x.y;") 324 expectPrintedMinify(t, "(new x).y", "new x().y;") 325 expectPrintedMinify(t, "new x().y", "new x().y;") 326 expectPrintedMinify(t, "new x() + y", "new x+y;") 327 expectPrintedMinify(t, "new x() ** 2", "new x**2;") 328 329 // Test preservation of Webpack-specific comments 330 expectPrinted(t, "new Worker(// webpackFoo: 1\n // webpackBar: 2\n 'path');", "new Worker(\n // webpackFoo: 1\n // webpackBar: 2\n \"path\"\n);\n") 331 expectPrinted(t, "new Worker(/* webpackFoo: 1 */ /* webpackBar: 2 */ 'path');", "new Worker(\n /* webpackFoo: 1 */\n /* webpackBar: 2 */\n \"path\"\n);\n") 332 expectPrinted(t, "new Worker(\n /* multi\n * line\n * webpackBar: */ 'path');", "new Worker(\n /* multi\n * line\n * webpackBar: */\n \"path\"\n);\n") 333 expectPrinted(t, "new Worker(/* webpackFoo: 1 */ 'path' /* webpackBar:2 */);", "new Worker(\n /* webpackFoo: 1 */\n \"path\"\n /* webpackBar:2 */\n);\n") 334 expectPrinted(t, "new Worker(/* webpackFoo: 1 */ 'path' /* webpackBar:2 */ ,);", "new Worker(\n /* webpackFoo: 1 */\n \"path\"\n);\n") // Not currently handled 335 expectPrinted(t, "new Worker(/* webpackFoo: 1 */ 'path', /* webpackBar:2 */ );", "new Worker(\n /* webpackFoo: 1 */\n \"path\"\n /* webpackBar:2 */\n);\n") 336 expectPrinted(t, "new Worker(new URL('path', /* webpackFoo: these can go anywhere */ import.meta.url))", 337 "new Worker(new URL(\n \"path\",\n /* webpackFoo: these can go anywhere */\n import.meta.url\n));\n") 338 } 339 340 func TestCall(t *testing.T) { 341 expectPrinted(t, "x()()()", "x()()();\n") 342 expectPrinted(t, "x().y()[z]()", "x().y()[z]();\n") 343 expectPrinted(t, "(--x)();", "(--x)();\n") 344 expectPrinted(t, "(x--)();", "(x--)();\n") 345 346 expectPrinted(t, "eval(x)", "eval(x);\n") 347 expectPrinted(t, "eval?.(x)", "eval?.(x);\n") 348 expectPrinted(t, "(eval)(x)", "eval(x);\n") 349 expectPrinted(t, "(eval)?.(x)", "eval?.(x);\n") 350 351 expectPrinted(t, "eval(x, y)", "eval(x, y);\n") 352 expectPrinted(t, "eval?.(x, y)", "eval?.(x, y);\n") 353 expectPrinted(t, "(1, eval)(x)", "(1, eval)(x);\n") 354 expectPrinted(t, "(1, eval)?.(x)", "(1, eval)?.(x);\n") 355 expectPrintedMangle(t, "(1 ? eval : 2)(x)", "(0, eval)(x);\n") 356 expectPrintedMangle(t, "(1 ? eval : 2)?.(x)", "eval?.(x);\n") 357 358 expectPrintedMinify(t, "eval?.(x)", "eval?.(x);") 359 expectPrintedMinify(t, "eval(x,y)", "eval(x,y);") 360 expectPrintedMinify(t, "eval?.(x,y)", "eval?.(x,y);") 361 expectPrintedMinify(t, "(1, eval)(x)", "(1,eval)(x);") 362 expectPrintedMinify(t, "(1, eval)?.(x)", "(1,eval)?.(x);") 363 expectPrintedMangleMinify(t, "(1 ? eval : 2)(x)", "(0,eval)(x);") 364 expectPrintedMangleMinify(t, "(1 ? eval : 2)?.(x)", "eval?.(x);") 365 } 366 367 func TestMember(t *testing.T) { 368 expectPrinted(t, "x.y[z]", "x.y[z];\n") 369 expectPrinted(t, "((x+1).y+1)[z]", "((x + 1).y + 1)[z];\n") 370 } 371 372 func TestComma(t *testing.T) { 373 expectPrinted(t, "1, 2, 3", "1, 2, 3;\n") 374 expectPrinted(t, "(1, 2), 3", "1, 2, 3;\n") 375 expectPrinted(t, "1, (2, 3)", "1, 2, 3;\n") 376 expectPrinted(t, "a ? (b, c) : (d, e)", "a ? (b, c) : (d, e);\n") 377 expectPrinted(t, "let x = (a, b)", "let x = (a, b);\n") 378 expectPrinted(t, "(x = a), b", "x = a, b;\n") 379 expectPrinted(t, "x = (a, b)", "x = (a, b);\n") 380 expectPrinted(t, "x((1, 2))", "x((1, 2));\n") 381 } 382 383 func TestUnary(t *testing.T) { 384 expectPrinted(t, "+(x--)", "+x--;\n") 385 expectPrinted(t, "-(x++)", "-x++;\n") 386 } 387 388 func TestNullish(t *testing.T) { 389 // "??" can't directly contain "||" or "&&" 390 expectPrinted(t, "(a && b) ?? c", "(a && b) ?? c;\n") 391 expectPrinted(t, "(a || b) ?? c", "(a || b) ?? c;\n") 392 expectPrinted(t, "a ?? (b && c)", "a ?? (b && c);\n") 393 expectPrinted(t, "a ?? (b || c)", "a ?? (b || c);\n") 394 395 // "||" and "&&" can't directly contain "??" 396 expectPrinted(t, "a && (b ?? c)", "a && (b ?? c);\n") 397 expectPrinted(t, "a || (b ?? c)", "a || (b ?? c);\n") 398 expectPrinted(t, "(a ?? b) && c", "(a ?? b) && c;\n") 399 expectPrinted(t, "(a ?? b) || c", "(a ?? b) || c;\n") 400 } 401 402 func TestString(t *testing.T) { 403 expectPrinted(t, "let x = ''", "let x = \"\";\n") 404 expectPrinted(t, "let x = '\b'", "let x = \"\\b\";\n") 405 expectPrinted(t, "let x = '\f'", "let x = \"\\f\";\n") 406 expectPrinted(t, "let x = '\t'", "let x = \"\t\";\n") 407 expectPrinted(t, "let x = '\v'", "let x = \"\\v\";\n") 408 expectPrinted(t, "let x = '\\n'", "let x = \"\\n\";\n") 409 expectPrinted(t, "let x = '\\''", "let x = \"'\";\n") 410 expectPrinted(t, "let x = '\\\"'", "let x = '\"';\n") 411 expectPrinted(t, "let x = '\\'\"'", "let x = `'\"`;\n") 412 expectPrinted(t, "let x = '\\\\'", "let x = \"\\\\\";\n") 413 expectPrinted(t, "let x = '\x00'", "let x = \"\\0\";\n") 414 expectPrinted(t, "let x = '\x00!'", "let x = \"\\0!\";\n") 415 expectPrinted(t, "let x = '\x001'", "let x = \"\\x001\";\n") 416 expectPrinted(t, "let x = '\\0'", "let x = \"\\0\";\n") 417 expectPrinted(t, "let x = '\\0!'", "let x = \"\\0!\";\n") 418 expectPrinted(t, "let x = '\x07'", "let x = \"\\x07\";\n") 419 expectPrinted(t, "let x = '\x07!'", "let x = \"\\x07!\";\n") 420 expectPrinted(t, "let x = '\x071'", "let x = \"\\x071\";\n") 421 expectPrinted(t, "let x = '\\7'", "let x = \"\\x07\";\n") 422 expectPrinted(t, "let x = '\\7!'", "let x = \"\\x07!\";\n") 423 expectPrinted(t, "let x = '\\01'", "let x = \"\x01\";\n") 424 expectPrinted(t, "let x = '\x10'", "let x = \"\x10\";\n") 425 expectPrinted(t, "let x = '\\x10'", "let x = \"\x10\";\n") 426 expectPrinted(t, "let x = '\x1B'", "let x = \"\\x1B\";\n") 427 expectPrinted(t, "let x = '\\x1B'", "let x = \"\\x1B\";\n") 428 expectPrinted(t, "let x = '\uABCD'", "let x = \"\uABCD\";\n") 429 expectPrinted(t, "let x = '\\uABCD'", "let x = \"\uABCD\";\n") 430 expectPrinted(t, "let x = '\U000123AB'", "let x = \"\U000123AB\";\n") 431 expectPrinted(t, "let x = '\\u{123AB}'", "let x = \"\U000123AB\";\n") 432 expectPrinted(t, "let x = '\\uD808\\uDFAB'", "let x = \"\U000123AB\";\n") 433 expectPrinted(t, "let x = '\\uD808'", "let x = \"\\uD808\";\n") 434 expectPrinted(t, "let x = '\\uD808X'", "let x = \"\\uD808X\";\n") 435 expectPrinted(t, "let x = '\\uDFAB'", "let x = \"\\uDFAB\";\n") 436 expectPrinted(t, "let x = '\\uDFABX'", "let x = \"\\uDFABX\";\n") 437 438 expectPrinted(t, "let x = '\\x80'", "let x = \"\U00000080\";\n") 439 expectPrinted(t, "let x = '\\xFF'", "let x = \"\U000000FF\";\n") 440 expectPrinted(t, "let x = '\\xF0\\x9F\\x8D\\x95'", "let x = \"\U000000F0\U0000009F\U0000008D\U00000095\";\n") 441 expectPrinted(t, "let x = '\\uD801\\uDC02\\uDC03\\uD804'", "let x = \"\U00010402\\uDC03\\uD804\";\n") 442 } 443 444 func TestTemplate(t *testing.T) { 445 expectPrinted(t, "let x = `\\0`", "let x = `\\0`;\n") 446 expectPrinted(t, "let x = `\\x01`", "let x = `\x01`;\n") 447 expectPrinted(t, "let x = `\\0${0}`", "let x = `\\0${0}`;\n") 448 expectPrinted(t, "let x = `\\x01${0}`", "let x = `\x01${0}`;\n") 449 expectPrinted(t, "let x = `${0}\\0`", "let x = `${0}\\0`;\n") 450 expectPrinted(t, "let x = `${0}\\x01`", "let x = `${0}\x01`;\n") 451 expectPrinted(t, "let x = `${0}\\0${1}`", "let x = `${0}\\0${1}`;\n") 452 expectPrinted(t, "let x = `${0}\\x01${1}`", "let x = `${0}\x01${1}`;\n") 453 454 expectPrinted(t, "let x = String.raw`\\1`", "let x = String.raw`\\1`;\n") 455 expectPrinted(t, "let x = String.raw`\\x01`", "let x = String.raw`\\x01`;\n") 456 expectPrinted(t, "let x = String.raw`\\1${0}`", "let x = String.raw`\\1${0}`;\n") 457 expectPrinted(t, "let x = String.raw`\\x01${0}`", "let x = String.raw`\\x01${0}`;\n") 458 expectPrinted(t, "let x = String.raw`${0}\\1`", "let x = String.raw`${0}\\1`;\n") 459 expectPrinted(t, "let x = String.raw`${0}\\x01`", "let x = String.raw`${0}\\x01`;\n") 460 expectPrinted(t, "let x = String.raw`${0}\\1${1}`", "let x = String.raw`${0}\\1${1}`;\n") 461 expectPrinted(t, "let x = String.raw`${0}\\x01${1}`", "let x = String.raw`${0}\\x01${1}`;\n") 462 463 expectPrinted(t, "let x = `${y}`", "let x = `${y}`;\n") 464 expectPrinted(t, "let x = `$(y)`", "let x = `$(y)`;\n") 465 expectPrinted(t, "let x = `{y}$`", "let x = `{y}$`;\n") 466 expectPrinted(t, "let x = `$}y{`", "let x = `$}y{`;\n") 467 expectPrinted(t, "let x = `\\${y}`", "let x = `\\${y}`;\n") 468 expectPrinted(t, "let x = `$\\{y}`", "let x = `\\${y}`;\n") 469 470 expectPrinted(t, "await tag`x`", "await tag`x`;\n") 471 expectPrinted(t, "await (tag`x`)", "await tag`x`;\n") 472 expectPrinted(t, "(await tag)`x`", "(await tag)`x`;\n") 473 474 expectPrinted(t, "await tag`${x}`", "await tag`${x}`;\n") 475 expectPrinted(t, "await (tag`${x}`)", "await tag`${x}`;\n") 476 expectPrinted(t, "(await tag)`${x}`", "(await tag)`${x}`;\n") 477 478 expectPrinted(t, "new tag`x`", "new tag`x`();\n") 479 expectPrinted(t, "new (tag`x`)", "new tag`x`();\n") 480 expectPrinted(t, "new tag()`x`", "new tag()`x`;\n") 481 expectPrinted(t, "(new tag)`x`", "new tag()`x`;\n") 482 expectPrintedMinify(t, "new tag`x`", "new tag`x`;") 483 expectPrintedMinify(t, "new (tag`x`)", "new tag`x`;") 484 expectPrintedMinify(t, "new tag()`x`", "new tag()`x`;") 485 expectPrintedMinify(t, "(new tag)`x`", "new tag()`x`;") 486 487 expectPrinted(t, "new tag`${x}`", "new tag`${x}`();\n") 488 expectPrinted(t, "new (tag`${x}`)", "new tag`${x}`();\n") 489 expectPrinted(t, "new tag()`${x}`", "new tag()`${x}`;\n") 490 expectPrinted(t, "(new tag)`${x}`", "new tag()`${x}`;\n") 491 expectPrintedMinify(t, "new tag`${x}`", "new tag`${x}`;") 492 expectPrintedMinify(t, "new (tag`${x}`)", "new tag`${x}`;") 493 expectPrintedMinify(t, "new tag()`${x}`", "new tag()`${x}`;") 494 expectPrintedMinify(t, "(new tag)`${x}`", "new tag()`${x}`;") 495 } 496 497 func TestObject(t *testing.T) { 498 expectPrinted(t, "let x = {'(':')'}", "let x = { \"(\": \")\" };\n") 499 expectPrinted(t, "({})", "({});\n") 500 expectPrinted(t, "({}.x)", "({}).x;\n") 501 expectPrinted(t, "({} = {})", "({} = {});\n") 502 expectPrinted(t, "(x, {} = {})", "x, {} = {};\n") 503 expectPrinted(t, "let x = () => ({})", "let x = () => ({});\n") 504 expectPrinted(t, "let x = () => ({}.x)", "let x = () => ({}).x;\n") 505 expectPrinted(t, "let x = () => ({} = {})", "let x = () => ({} = {});\n") 506 expectPrinted(t, "let x = () => (x, {} = {})", "let x = () => (x, {} = {});\n") 507 508 // "{ __proto__: __proto__ }" must not become "{ __proto__ }" 509 expectPrinted(t, "function foo(__proto__) { return { __proto__: __proto__ } }", "function foo(__proto__) {\n return { __proto__: __proto__ };\n}\n") 510 expectPrinted(t, "function foo(__proto__) { return { '__proto__': __proto__ } }", "function foo(__proto__) {\n return { \"__proto__\": __proto__ };\n}\n") 511 expectPrinted(t, "function foo(__proto__) { return { ['__proto__']: __proto__ } }", "function foo(__proto__) {\n return { [\"__proto__\"]: __proto__ };\n}\n") 512 expectPrinted(t, "import { __proto__ } from 'foo'; let foo = () => ({ __proto__: __proto__ })", "import { __proto__ } from \"foo\";\nlet foo = () => ({ __proto__: __proto__ });\n") 513 expectPrinted(t, "import { __proto__ } from 'foo'; let foo = () => ({ '__proto__': __proto__ })", "import { __proto__ } from \"foo\";\nlet foo = () => ({ \"__proto__\": __proto__ });\n") 514 expectPrinted(t, "import { __proto__ } from 'foo'; let foo = () => ({ ['__proto__']: __proto__ })", "import { __proto__ } from \"foo\";\nlet foo = () => ({ [\"__proto__\"]: __proto__ });\n") 515 516 // Don't use ES6+ features (such as a shorthand or computed property name) in ES5 517 expectPrintedTarget(t, 5, "function foo(__proto__) { return { __proto__ } }", "function foo(__proto__) {\n return { __proto__: __proto__ };\n}\n") 518 } 519 520 func TestFor(t *testing.T) { 521 // Make sure "in" expressions are forbidden in the right places 522 expectPrinted(t, "for ((a in b);;);", "for ((a in b); ; ) ;\n") 523 expectPrinted(t, "for (a ? b : (c in d);;);", "for (a ? b : (c in d); ; ) ;\n") 524 expectPrinted(t, "for ((a ? b : c in d).foo;;);", "for ((a ? b : c in d).foo; ; ) ;\n") 525 expectPrinted(t, "for (var x = (a in b);;);", "for (var x = (a in b); ; ) ;\n") 526 expectPrinted(t, "for (x = (a in b);;);", "for (x = (a in b); ; ) ;\n") 527 expectPrinted(t, "for (x == (a in b);;);", "for (x == (a in b); ; ) ;\n") 528 expectPrinted(t, "for (1 * (x == a in b);;);", "for (1 * (x == a in b); ; ) ;\n") 529 expectPrinted(t, "for (a ? b : x = (c in d);;);", "for (a ? b : x = (c in d); ; ) ;\n") 530 expectPrinted(t, "for (var x = y = (a in b);;);", "for (var x = y = (a in b); ; ) ;\n") 531 expectPrinted(t, "for ([a in b];;);", "for ([a in b]; ; ) ;\n") 532 expectPrinted(t, "for (x(a in b);;);", "for (x(a in b); ; ) ;\n") 533 expectPrinted(t, "for (x[a in b];;);", "for (x[a in b]; ; ) ;\n") 534 expectPrinted(t, "for (x?.[a in b];;);", "for (x?.[a in b]; ; ) ;\n") 535 expectPrinted(t, "for ((x => a in b);;);", "for ((x) => (a in b); ; ) ;\n") 536 537 // Make sure for-of loops with commas are wrapped in parentheses 538 expectPrinted(t, "for (let a in b, c);", "for (let a in b, c) ;\n") 539 expectPrinted(t, "for (let a of (b, c));", "for (let a of (b, c)) ;\n") 540 } 541 542 func TestFunction(t *testing.T) { 543 expectPrinted(t, 544 "function foo(a = (b, c), ...d) {}", 545 "function foo(a = (b, c), ...d) {\n}\n") 546 expectPrinted(t, 547 "function foo({[1 + 2]: a = 3} = {[1 + 2]: 3}) {}", 548 "function foo({ [1 + 2]: a = 3 } = { [1 + 2]: 3 }) {\n}\n") 549 expectPrinted(t, 550 "function foo([a = (1, 2), ...[b, ...c]] = [1, [2, 3]]) {}", 551 "function foo([a = (1, 2), ...[b, ...c]] = [1, [2, 3]]) {\n}\n") 552 expectPrinted(t, 553 "function foo([] = []) {}", 554 "function foo([] = []) {\n}\n") 555 expectPrinted(t, 556 "function foo([,] = [,]) {}", 557 "function foo([,] = [,]) {\n}\n") 558 expectPrinted(t, 559 "function foo([,,] = [,,]) {}", 560 "function foo([, ,] = [, ,]) {\n}\n") 561 } 562 563 func TestCommentsAndParentheses(t *testing.T) { 564 expectPrinted(t, "(/* foo */ { x() { foo() } }.x());", "/* foo */\n({ x() {\n foo();\n} }).x();\n") 565 expectPrinted(t, "(/* foo */ function f() { foo(f) }());", "/* foo */\n(function f() {\n foo(f);\n})();\n") 566 expectPrinted(t, "(/* foo */ class x { static y() { foo(x) } }.y());", "/* foo */\n(class x {\n static y() {\n foo(x);\n }\n}).y();\n") 567 expectPrinted(t, "(/* @__PURE__ */ (() => foo())());", "/* @__PURE__ */ (() => foo())();\n") 568 expectPrinted(t, "export default (/* foo */ function f() {});", "export default (\n /* foo */\n function f() {\n }\n);\n") 569 expectPrinted(t, "export default (/* foo */ class x {});", "export default (\n /* foo */\n class x {\n }\n);\n") 570 expectPrinted(t, "x = () => (/* foo */ {});", "x = () => (\n /* foo */\n {}\n);\n") 571 expectPrinted(t, "for ((/* foo */ let).x of y) ;", "for (\n /* foo */\n (let).x of y\n) ;\n") 572 expectPrinted(t, "for (/* foo */ (let).x of y) ;", "for (\n /* foo */\n (let).x of y\n) ;\n") 573 expectPrinted(t, "function *x() { yield (/* foo */ y) }", "function* x() {\n yield (\n /* foo */\n y\n );\n}\n") 574 } 575 576 func TestPureComment(t *testing.T) { 577 expectPrinted(t, 578 "(function() { foo() })", 579 "(function() {\n foo();\n});\n") 580 expectPrinted(t, 581 "(function() { foo() })()", 582 "(function() {\n foo();\n})();\n") 583 expectPrinted(t, 584 "/*@__PURE__*/(function() { foo() })()", 585 "/* @__PURE__ */ (function() {\n foo();\n})();\n") 586 587 expectPrinted(t, 588 "new (function() {})", 589 "new function() {\n}();\n") 590 expectPrinted(t, 591 "new (function() {})()", 592 "new function() {\n}();\n") 593 expectPrinted(t, 594 "/*@__PURE__*/new (function() {})()", 595 "/* @__PURE__ */ new function() {\n}();\n") 596 597 expectPrinted(t, 598 "export default (function() { foo() })", 599 "export default (function() {\n foo();\n});\n") 600 expectPrinted(t, 601 "export default (function() { foo() })()", 602 "export default (function() {\n foo();\n})();\n") 603 expectPrinted(t, 604 "export default /*@__PURE__*/(function() { foo() })()", 605 "export default /* @__PURE__ */ (function() {\n foo();\n})();\n") 606 } 607 608 func TestGenerator(t *testing.T) { 609 expectPrinted(t, 610 "function* foo() {}", 611 "function* foo() {\n}\n") 612 expectPrinted(t, 613 "(function* () {})", 614 "(function* () {\n});\n") 615 expectPrinted(t, 616 "(function* foo() {})", 617 "(function* foo() {\n});\n") 618 619 expectPrinted(t, 620 "class Foo { *foo() {} }", 621 "class Foo {\n *foo() {\n }\n}\n") 622 expectPrinted(t, 623 "class Foo { static *foo() {} }", 624 "class Foo {\n static *foo() {\n }\n}\n") 625 expectPrinted(t, 626 "class Foo { *[foo]() {} }", 627 "class Foo {\n *[foo]() {\n }\n}\n") 628 expectPrinted(t, 629 "class Foo { static *[foo]() {} }", 630 "class Foo {\n static *[foo]() {\n }\n}\n") 631 632 expectPrinted(t, 633 "(class { *foo() {} })", 634 "(class {\n *foo() {\n }\n});\n") 635 expectPrinted(t, 636 "(class { static *foo() {} })", 637 "(class {\n static *foo() {\n }\n});\n") 638 expectPrinted(t, 639 "(class { *[foo]() {} })", 640 "(class {\n *[foo]() {\n }\n});\n") 641 expectPrinted(t, 642 "(class { static *[foo]() {} })", 643 "(class {\n static *[foo]() {\n }\n});\n") 644 } 645 646 func TestArrow(t *testing.T) { 647 expectPrinted(t, "() => {}", "() => {\n};\n") 648 expectPrinted(t, "x => (x, 0)", "(x) => (x, 0);\n") 649 expectPrinted(t, "x => {y}", "(x) => {\n y;\n};\n") 650 expectPrinted(t, 651 "(a = (b, c), ...d) => {}", 652 "(a = (b, c), ...d) => {\n};\n") 653 expectPrinted(t, 654 "({[1 + 2]: a = 3} = {[1 + 2]: 3}) => {}", 655 "({ [1 + 2]: a = 3 } = { [1 + 2]: 3 }) => {\n};\n") 656 expectPrinted(t, 657 "([a = (1, 2), ...[b, ...c]] = [1, [2, 3]]) => {}", 658 "([a = (1, 2), ...[b, ...c]] = [1, [2, 3]]) => {\n};\n") 659 expectPrinted(t, 660 "([] = []) => {}", 661 "([] = []) => {\n};\n") 662 expectPrinted(t, 663 "([,] = [,]) => {}", 664 "([,] = [,]) => {\n};\n") 665 expectPrinted(t, 666 "([,,] = [,,]) => {}", 667 "([, ,] = [, ,]) => {\n};\n") 668 expectPrinted(t, 669 "a = () => {}", 670 "a = () => {\n};\n") 671 expectPrinted(t, 672 "a || (() => {})", 673 "a || (() => {\n});\n") 674 expectPrinted(t, 675 "({a = b, c = d}) => {}", 676 "({ a = b, c = d }) => {\n};\n") 677 expectPrinted(t, 678 "([{a = b, c = d} = {}] = []) => {}", 679 "([{ a = b, c = d } = {}] = []) => {\n};\n") 680 expectPrinted(t, 681 "({a: [b = c] = []} = {}) => {}", 682 "({ a: [b = c] = [] } = {}) => {\n};\n") 683 684 // These are not arrow functions but initially look like one 685 expectPrinted(t, "(a = b, c)", "a = b, c;\n") 686 expectPrinted(t, "([...a = b])", "[...a = b];\n") 687 expectPrinted(t, "([...a, ...b])", "[...a, ...b];\n") 688 expectPrinted(t, "({a: b, c() {}})", "({ a: b, c() {\n} });\n") 689 expectPrinted(t, "({a: b, get c() {}})", "({ a: b, get c() {\n} });\n") 690 expectPrinted(t, "({a: b, set c(x) {}})", "({ a: b, set c(x) {\n} });\n") 691 } 692 693 func TestClass(t *testing.T) { 694 expectPrinted(t, "class Foo extends (a, b) {}", "class Foo extends (a, b) {\n}\n") 695 expectPrinted(t, "class Foo { get foo() {} }", "class Foo {\n get foo() {\n }\n}\n") 696 expectPrinted(t, "class Foo { set foo(x) {} }", "class Foo {\n set foo(x) {\n }\n}\n") 697 expectPrinted(t, "class Foo { static foo() {} }", "class Foo {\n static foo() {\n }\n}\n") 698 expectPrinted(t, "class Foo { static get foo() {} }", "class Foo {\n static get foo() {\n }\n}\n") 699 expectPrinted(t, "class Foo { static set foo(x) {} }", "class Foo {\n static set foo(x) {\n }\n}\n") 700 } 701 702 func TestAutoAccessors(t *testing.T) { 703 expectPrinted(t, "class Foo { accessor x; static accessor y }", "class Foo {\n accessor x;\n static accessor y;\n}\n") 704 expectPrinted(t, "class Foo { accessor [x]; static accessor [y] }", "class Foo {\n accessor [x];\n static accessor [y];\n}\n") 705 expectPrintedMinify(t, "class Foo { accessor x; static accessor y }", "class Foo{accessor x;static accessor y}") 706 expectPrintedMinify(t, "class Foo { accessor [x]; static accessor [y] }", "class Foo{accessor[x];static accessor[y]}") 707 } 708 709 func TestPrivateIdentifiers(t *testing.T) { 710 expectPrinted(t, "class Foo { #foo; foo() { return #foo in this } }", "class Foo {\n #foo;\n foo() {\n return #foo in this;\n }\n}\n") 711 expectPrintedMinify(t, "class Foo { #foo; foo() { return #foo in this } }", "class Foo{#foo;foo(){return#foo in this}}") 712 } 713 714 func TestDecorators(t *testing.T) { 715 example := "class Foo {\n@w\nw; @x x; @a1\n@b1@b2\n@c1@c2@c3\ny = @y1 @y2 class {}; @a1\n@b1@b2\n@c1@c2@c3 z =\n@z1\n@z2\nclass {}}" 716 expectPrinted(t, example, "class Foo {\n @w\n w;\n @x x;\n @a1\n @b1 @b2\n @c1 @c2 @c3\n "+ 717 "y = @y1 @y2 class {\n };\n @a1\n @b1 @b2\n @c1 @c2 @c3 z = @z1 @z2 class {\n };\n}\n") 718 expectPrintedMinify(t, example, "class Foo{@w w;@x x;@a1@b1@b2@c1@c2@c3 y=@y1@y2 class{};@a1@b1@b2@c1@c2@c3 z=@z1@z2 class{}}") 719 } 720 721 func TestImport(t *testing.T) { 722 expectPrinted(t, "import('path');", "import(\"path\");\n") // The semicolon must not be a separate statement 723 724 // Test preservation of Webpack-specific comments 725 expectPrinted(t, "import(// webpackFoo: 1\n // webpackBar: 2\n 'path');", "import(\n // webpackFoo: 1\n // webpackBar: 2\n \"path\"\n);\n") 726 expectPrinted(t, "import(// webpackFoo: 1\n // webpackBar: 2\n 'path', {type: 'module'});", "import(\n // webpackFoo: 1\n // webpackBar: 2\n \"path\",\n { type: \"module\" }\n);\n") 727 expectPrinted(t, "import(/* webpackFoo: 1 */ /* webpackBar: 2 */ 'path');", "import(\n /* webpackFoo: 1 */\n /* webpackBar: 2 */\n \"path\"\n);\n") 728 expectPrinted(t, "import(/* webpackFoo: 1 */ /* webpackBar: 2 */ 'path', {type: 'module'});", "import(\n /* webpackFoo: 1 */\n /* webpackBar: 2 */\n \"path\",\n { type: \"module\" }\n);\n") 729 expectPrinted(t, "import(\n /* multi\n * line\n * webpackBar: */ 'path');", "import(\n /* multi\n * line\n * webpackBar: */\n \"path\"\n);\n") 730 expectPrinted(t, "import(/* webpackFoo: 1 */ 'path' /* webpackBar:2 */);", "import(\n /* webpackFoo: 1 */\n \"path\"\n /* webpackBar:2 */\n);\n") 731 expectPrinted(t, "import(/* webpackFoo: 1 */ 'path' /* webpackBar:2 */ ,);", "import(\n /* webpackFoo: 1 */\n \"path\"\n);\n") // Not currently handled 732 expectPrinted(t, "import(/* webpackFoo: 1 */ 'path', /* webpackBar:2 */ );", "import(\n /* webpackFoo: 1 */\n \"path\"\n /* webpackBar:2 */\n);\n") 733 expectPrinted(t, "import(/* webpackFoo: 1 */ 'path', { type: 'module' } /* webpackBar:2 */ );", "import(\n /* webpackFoo: 1 */\n \"path\",\n { type: \"module\" }\n /* webpackBar:2 */\n);\n") 734 expectPrinted(t, "import(new URL('path', /* webpackFoo: these can go anywhere */ import.meta.url))", 735 "import(new URL(\n \"path\",\n /* webpackFoo: these can go anywhere */\n import.meta.url\n));\n") 736 } 737 738 func TestExportDefault(t *testing.T) { 739 expectPrinted(t, "export default function() {}", "export default function() {\n}\n") 740 expectPrinted(t, "export default function foo() {}", "export default function foo() {\n}\n") 741 expectPrinted(t, "export default async function() {}", "export default async function() {\n}\n") 742 expectPrinted(t, "export default async function foo() {}", "export default async function foo() {\n}\n") 743 expectPrinted(t, "export default class {}", "export default class {\n}\n") 744 expectPrinted(t, "export default class foo {}", "export default class foo {\n}\n") 745 746 expectPrinted(t, "export default (function() {})", "export default (function() {\n});\n") 747 expectPrinted(t, "export default (function foo() {})", "export default (function foo() {\n});\n") 748 expectPrinted(t, "export default (async function() {})", "export default (async function() {\n});\n") 749 expectPrinted(t, "export default (async function foo() {})", "export default (async function foo() {\n});\n") 750 expectPrinted(t, "export default (class {})", "export default (class {\n});\n") 751 expectPrinted(t, "export default (class foo {})", "export default (class foo {\n});\n") 752 753 expectPrinted(t, "export default (function() {}.toString())", "export default (function() {\n}).toString();\n") 754 expectPrinted(t, "export default (function foo() {}.toString())", "export default (function foo() {\n}).toString();\n") 755 expectPrinted(t, "export default (async function() {}.toString())", "export default (async function() {\n}).toString();\n") 756 expectPrinted(t, "export default (async function foo() {}.toString())", "export default (async function foo() {\n}).toString();\n") 757 expectPrinted(t, "export default (class {}.toString())", "export default (class {\n}).toString();\n") 758 expectPrinted(t, "export default (class foo {}.toString())", "export default (class foo {\n}).toString();\n") 759 760 expectPrintedMinify(t, "export default function() {}", "export default function(){}") 761 expectPrintedMinify(t, "export default function foo() {}", "export default function foo(){}") 762 expectPrintedMinify(t, "export default async function() {}", "export default async function(){}") 763 expectPrintedMinify(t, "export default async function foo() {}", "export default async function foo(){}") 764 expectPrintedMinify(t, "export default class {}", "export default class{}") 765 expectPrintedMinify(t, "export default class foo {}", "export default class foo{}") 766 } 767 768 func TestWhitespace(t *testing.T) { 769 expectPrinted(t, "- -x", "- -x;\n") 770 expectPrinted(t, "+ -x", "+-x;\n") 771 expectPrinted(t, "- +x", "-+x;\n") 772 expectPrinted(t, "+ +x", "+ +x;\n") 773 expectPrinted(t, "- --x", "- --x;\n") 774 expectPrinted(t, "+ --x", "+--x;\n") 775 expectPrinted(t, "- ++x", "-++x;\n") 776 expectPrinted(t, "+ ++x", "+ ++x;\n") 777 778 expectPrintedMinify(t, "- -x", "- -x;") 779 expectPrintedMinify(t, "+ -x", "+-x;") 780 expectPrintedMinify(t, "- +x", "-+x;") 781 expectPrintedMinify(t, "+ +x", "+ +x;") 782 expectPrintedMinify(t, "- --x", "- --x;") 783 expectPrintedMinify(t, "+ --x", "+--x;") 784 expectPrintedMinify(t, "- ++x", "-++x;") 785 expectPrintedMinify(t, "+ ++x", "+ ++x;") 786 787 expectPrintedMinify(t, "x - --y", "x- --y;") 788 expectPrintedMinify(t, "x + --y", "x+--y;") 789 expectPrintedMinify(t, "x - ++y", "x-++y;") 790 expectPrintedMinify(t, "x + ++y", "x+ ++y;") 791 792 expectPrintedMinify(t, "x-- > y", "x-- >y;") 793 expectPrintedMinify(t, "x < !--y", "x<! --y;") 794 expectPrintedMinify(t, "x > !--y", "x>!--y;") 795 expectPrintedMinify(t, "!--y", "!--y;") 796 797 expectPrintedMinify(t, "1 + -0", "1+-0;") 798 expectPrintedMinify(t, "1 - -0", "1- -0;") 799 expectPrintedMinify(t, "1 + -Infinity", "1+-Infinity;") 800 expectPrintedMinify(t, "1 - -Infinity", "1- -Infinity;") 801 802 expectPrintedMinify(t, "/x/ / /y/", "/x// /y/;") 803 expectPrintedMinify(t, "/x/ + Foo", "/x/+Foo;") 804 expectPrintedMinify(t, "/x/ instanceof Foo", "/x/ instanceof Foo;") 805 expectPrintedMinify(t, "[x] instanceof Foo", "[x]instanceof Foo;") 806 807 expectPrintedMinify(t, "throw x", "throw x;") 808 expectPrintedMinify(t, "throw typeof x", "throw typeof x;") 809 expectPrintedMinify(t, "throw delete x", "throw delete x;") 810 expectPrintedMinify(t, "throw function(){}", "throw function(){};") 811 812 expectPrintedMinify(t, "x in function(){}", "x in function(){};") 813 expectPrintedMinify(t, "x instanceof function(){}", "x instanceof function(){};") 814 expectPrintedMinify(t, "π in function(){}", "π in function(){};") 815 expectPrintedMinify(t, "π instanceof function(){}", "π instanceof function(){};") 816 817 expectPrintedMinify(t, "()=>({})", "()=>({});") 818 expectPrintedMinify(t, "()=>({}[1])", "()=>({})[1];") 819 expectPrintedMinify(t, "()=>({}+0)", "()=>\"[object Object]0\";") 820 expectPrintedMinify(t, "()=>function(){}", "()=>function(){};") 821 822 expectPrintedMinify(t, "(function(){})", "(function(){});") 823 expectPrintedMinify(t, "(class{})", "(class{});") 824 expectPrintedMinify(t, "({})", "({});") 825 } 826 827 func TestMangle(t *testing.T) { 828 expectPrintedMangle(t, "let x = '\\n'", "let x = `\n`;\n") 829 expectPrintedMangle(t, "let x = `\n`", "let x = `\n`;\n") 830 expectPrintedMangle(t, "let x = '\\n${}'", "let x = \"\\n${}\";\n") 831 expectPrintedMangle(t, "let x = `\n\\${}`", "let x = \"\\n${}\";\n") 832 expectPrintedMangle(t, "let x = `\n\\${}${y}\\${}`", "let x = `\n\\${}${y}\\${}`;\n") 833 } 834 835 func TestMinify(t *testing.T) { 836 expectPrintedMinify(t, "0.1", ".1;") 837 expectPrintedMinify(t, "1.2", "1.2;") 838 839 expectPrintedMinify(t, "() => {}", "()=>{};") 840 expectPrintedMinify(t, "(a) => {}", "a=>{};") 841 expectPrintedMinify(t, "(...a) => {}", "(...a)=>{};") 842 expectPrintedMinify(t, "(a = 0) => {}", "(a=0)=>{};") 843 expectPrintedMinify(t, "(a, b) => {}", "(a,b)=>{};") 844 845 expectPrinted(t, "true ** 2", "true ** 2;\n") 846 expectPrinted(t, "false ** 2", "false ** 2;\n") 847 expectPrintedMinify(t, "true ** 2", "true**2;") 848 expectPrintedMinify(t, "false ** 2", "false**2;") 849 expectPrintedMangle(t, "true ** 2", "(!0) ** 2;\n") 850 expectPrintedMangle(t, "false ** 2", "(!1) ** 2;\n") 851 852 expectPrintedMinify(t, "import a from 'path'", "import a from\"path\";") 853 expectPrintedMinify(t, "import * as ns from 'path'", "import*as ns from\"path\";") 854 expectPrintedMinify(t, "import {a, b as c} from 'path'", "import{a,b as c}from\"path\";") 855 expectPrintedMinify(t, "import {a, ' ' as c} from 'path'", "import{a,\" \"as c}from\"path\";") 856 857 expectPrintedMinify(t, "export * as ns from 'path'", "export*as ns from\"path\";") 858 expectPrintedMinify(t, "export * as ' ' from 'path'", "export*as\" \"from\"path\";") 859 expectPrintedMinify(t, "export {a, b as c} from 'path'", "export{a,b as c}from\"path\";") 860 expectPrintedMinify(t, "export {' ', '-' as ';'} from 'path'", "export{\" \",\"-\"as\";\"}from\"path\";") 861 expectPrintedMinify(t, "let a, b; export {a, b as c}", "let a,b;export{a,b as c};") 862 expectPrintedMinify(t, "let a, b; export {a, b as ' '}", "let a,b;export{a,b as\" \"};") 863 864 // Print some strings using template literals when minifying 865 expectPrinted(t, "x = '\\n'", "x = \"\\n\";\n") 866 expectPrintedMangle(t, "x = '\\n'", "x = `\n`;\n") 867 expectPrintedMangle(t, "x = {'\\n': 0}", "x = { \"\\n\": 0 };\n") 868 expectPrintedMangle(t, "x = class{'\\n' = 0}", "x = class {\n \"\\n\" = 0;\n};\n") 869 expectPrintedMangle(t, "class Foo{'\\n' = 0}", "class Foo {\n \"\\n\" = 0;\n}\n") 870 871 // Special identifiers must not be minified 872 expectPrintedMinify(t, "exports", "exports;") 873 expectPrintedMinify(t, "require", "require;") 874 expectPrintedMinify(t, "module", "module;") 875 876 // Comment statements must not affect their surroundings when minified 877 expectPrintedMinify(t, "//!single\nthrow 1 + 2", "//!single\nthrow 1+2;") 878 expectPrintedMinify(t, "/*!multi-\nline*/\nthrow 1 + 2", "/*!multi-\nline*/throw 1+2;") 879 } 880 881 func TestES5(t *testing.T) { 882 expectPrintedTargetMangle(t, 5, "foo('a\\n\\n\\nb')", "foo(\"a\\n\\n\\nb\");\n") 883 expectPrintedTargetMangle(t, 2015, "foo('a\\n\\n\\nb')", "foo(`a\n\n\nb`);\n") 884 885 expectPrintedTarget(t, 5, "foo({a, b})", "foo({ a: a, b: b });\n") 886 expectPrintedTarget(t, 2015, "foo({a, b})", "foo({ a, b });\n") 887 888 expectPrintedTarget(t, 5, "x => x", "(function(x) {\n return x;\n});\n") 889 expectPrintedTarget(t, 2015, "x => x", "(x) => x;\n") 890 891 expectPrintedTarget(t, 5, "() => {}", "(function() {\n});\n") 892 expectPrintedTarget(t, 2015, "() => {}", "() => {\n};\n") 893 894 expectPrintedTargetMinify(t, 5, "x => x", "(function(x){return x});") 895 expectPrintedTargetMinify(t, 2015, "x => x", "x=>x;") 896 897 expectPrintedTargetMinify(t, 5, "() => {}", "(function(){});") 898 expectPrintedTargetMinify(t, 2015, "() => {}", "()=>{};") 899 } 900 901 func TestASCIIOnly(t *testing.T) { 902 expectPrinted(t, "let π = 'π'", "let π = \"π\";\n") 903 expectPrinted(t, "let π_ = 'π'", "let π_ = \"π\";\n") 904 expectPrinted(t, "let _π = 'π'", "let _π = \"π\";\n") 905 expectPrintedASCII(t, "let π = 'π'", "let \\u03C0 = \"\\u03C0\";\n") 906 expectPrintedASCII(t, "let π_ = 'π'", "let \\u03C0_ = \"\\u03C0\";\n") 907 expectPrintedASCII(t, "let _π = 'π'", "let _\\u03C0 = \"\\u03C0\";\n") 908 909 expectPrinted(t, "let 貓 = '🐈'", "let 貓 = \"🐈\";\n") 910 expectPrinted(t, "let 貓abc = '🐈'", "let 貓abc = \"🐈\";\n") 911 expectPrinted(t, "let abc貓 = '🐈'", "let abc貓 = \"🐈\";\n") 912 expectPrintedASCII(t, "let 貓 = '🐈'", "let \\u8C93 = \"\\u{1F408}\";\n") 913 expectPrintedASCII(t, "let 貓abc = '🐈'", "let \\u8C93abc = \"\\u{1F408}\";\n") 914 expectPrintedASCII(t, "let abc貓 = '🐈'", "let abc\\u8C93 = \"\\u{1F408}\";\n") 915 916 // Test a character outside the BMP 917 expectPrinted(t, "var 𐀀", "var 𐀀;\n") 918 expectPrinted(t, "var \\u{10000}", "var 𐀀;\n") 919 expectPrintedASCII(t, "var 𐀀", "var \\u{10000};\n") 920 expectPrintedASCII(t, "var \\u{10000}", "var \\u{10000};\n") 921 expectPrintedTargetASCII(t, 2015, "'𐀀'", "\"\\u{10000}\";\n") 922 expectPrintedTargetASCII(t, 5, "'𐀀'", "\"\\uD800\\uDC00\";\n") 923 expectPrintedTargetASCII(t, 2015, "x.𐀀", "x[\"\\u{10000}\"];\n") 924 expectPrintedTargetASCII(t, 5, "x.𐀀", "x[\"\\uD800\\uDC00\"];\n") 925 926 // Escapes should use consistent case 927 expectPrintedASCII(t, "var \\u{100a} = {\\u100A: '\\u100A'}", "var \\u100A = { \\u100A: \"\\u100A\" };\n") 928 expectPrintedASCII(t, "var \\u{1000a} = {\\u{1000A}: '\\u{1000A}'}", "var \\u{1000A} = { \"\\u{1000A}\": \"\\u{1000A}\" };\n") 929 930 // These characters should always be escaped 931 expectPrinted(t, "let x = '\u2028'", "let x = \"\\u2028\";\n") 932 expectPrinted(t, "let x = '\u2029'", "let x = \"\\u2029\";\n") 933 expectPrinted(t, "let x = '\uFEFF'", "let x = \"\\uFEFF\";\n") 934 935 // There should still be a space before "extends" 936 expectPrintedASCII(t, "class 𐀀 extends π {}", "class \\u{10000} extends \\u03C0 {\n}\n") 937 expectPrintedASCII(t, "(class 𐀀 extends π {})", "(class \\u{10000} extends \\u03C0 {\n});\n") 938 expectPrintedMinifyASCII(t, "class 𐀀 extends π {}", "class \\u{10000} extends \\u03C0{}") 939 expectPrintedMinifyASCII(t, "(class 𐀀 extends π {})", "(class \\u{10000} extends \\u03C0{});") 940 } 941 942 func TestJSX(t *testing.T) { 943 expectPrintedJSX(t, "<a/>", "<a />;\n") 944 expectPrintedJSX(t, "<A/>", "<A />;\n") 945 expectPrintedJSX(t, "<a.b/>", "<a.b />;\n") 946 expectPrintedJSX(t, "<A.B/>", "<A.B />;\n") 947 expectPrintedJSX(t, "<a-b/>", "<a-b />;\n") 948 expectPrintedJSX(t, "<a:b/>", "<a:b />;\n") 949 expectPrintedJSX(t, "<a></a>", "<a />;\n") 950 expectPrintedJSX(t, "<a b></a>", "<a b />;\n") 951 952 expectPrintedJSX(t, "<a b={true}></a>", "<a b={true} />;\n") 953 expectPrintedJSX(t, "<a b='x'></a>", "<a b='x' />;\n") 954 expectPrintedJSX(t, "<a b=\"x\"></a>", "<a b=\"x\" />;\n") 955 expectPrintedJSX(t, "<a b={'x'}></a>", "<a b={\"x\"} />;\n") 956 expectPrintedJSX(t, "<a b={`'`}></a>", "<a b={`'`} />;\n") 957 expectPrintedJSX(t, "<a b={`\"`}></a>", "<a b={`\"`} />;\n") 958 expectPrintedJSX(t, "<a b={`'\"`}></a>", "<a b={`'\"`} />;\n") 959 expectPrintedJSX(t, "<a b=\""\"></a>", "<a b=\""\" />;\n") 960 expectPrintedJSX(t, "<a b=\"&\"></a>", "<a b=\"&\" />;\n") 961 962 expectPrintedJSX(t, "<a>x</a>", "<a>x</a>;\n") 963 expectPrintedJSX(t, "<a>x\ny</a>", "<a>x\ny</a>;\n") 964 expectPrintedJSX(t, "<a>{'x'}{'y'}</a>", "<a>{\"x\"}{\"y\"}</a>;\n") 965 expectPrintedJSX(t, "<a> x</a>", "<a> x</a>;\n") 966 expectPrintedJSX(t, "<a>x </a>", "<a>x </a>;\n") 967 expectPrintedJSX(t, "<a> </a>", "<a> </a>;\n") 968 expectPrintedJSX(t, "<a>&</a>", "<a>&</a>;\n") 969 expectPrintedJSX(t, "<a><</a>", "<a><</a>;\n") 970 expectPrintedJSX(t, "<a>></a>", "<a>></a>;\n") 971 expectPrintedJSX(t, "<a>{</a>", "<a>{</a>;\n") 972 expectPrintedJSX(t, "<a>}</a>", "<a>}</a>;\n") 973 974 expectPrintedJSX(t, "<a><x/></a>", "<a><x /></a>;\n") 975 expectPrintedJSX(t, "<a><x/><y/></a>", "<a><x /><y /></a>;\n") 976 expectPrintedJSX(t, "<a>b<c/>d</a>", "<a>b<c />d</a>;\n") 977 978 expectPrintedJSX(t, "<></>", "<></>;\n") 979 expectPrintedJSX(t, "<>x<y/>z</>", "<>x<y />z</>;\n") 980 981 // JSX elements as JSX attribute values 982 expectPrintedJSX(t, "<a b=<c/>/>", "<a b=<c /> />;\n") 983 expectPrintedJSX(t, "<a b=<>c</>/>", "<a b=<>c</> />;\n") 984 expectPrintedJSX(t, "<a b=<>{c}</>/>", "<a b=<>{c}</> />;\n") 985 expectPrintedJSX(t, "<a b={<c/>}/>", "<a b={<c />} />;\n") 986 expectPrintedJSX(t, "<a b={<>c</>}/>", "<a b={<>c</>} />;\n") 987 expectPrintedJSX(t, "<a b={<>{c}</>}/>", "<a b={<>{c}</>} />;\n") 988 989 // These can't be escaped because JSX lacks a syntax for escapes 990 expectPrintedJSXASCII(t, "<π/>", "<π />;\n") 991 expectPrintedJSXASCII(t, "<π.𐀀/>", "<π.𐀀 />;\n") 992 expectPrintedJSXASCII(t, "<𐀀.π/>", "<𐀀.π />;\n") 993 expectPrintedJSXASCII(t, "<π>x</π>", "<π>x</π>;\n") 994 expectPrintedJSXASCII(t, "<𐀀>x</𐀀>", "<𐀀>x</𐀀>;\n") 995 expectPrintedJSXASCII(t, "<a π/>", "<a π />;\n") 996 expectPrintedJSXASCII(t, "<a 𐀀/>", "<a 𐀀 />;\n") 997 998 // JSX text is deliberately not printed as ASCII when JSX preservation is 999 // enabled. This is because: 1000 // 1001 // a) The JSX specification doesn't say how JSX text is supposed to be interpreted 1002 // b) Enabling JSX preservation means that JSX will be transformed again anyway 1003 // c) People do very weird/custom things with JSX that "preserve" shouldn't break 1004 // 1005 // See also: https://github.com/evanw/esbuild/issues/3605 1006 expectPrintedJSXASCII(t, "<a b='π'/>", "<a b='π' />;\n") 1007 expectPrintedJSXASCII(t, "<a b='𐀀'/>", "<a b='𐀀' />;\n") 1008 expectPrintedJSXASCII(t, "<a>π</a>", "<a>π</a>;\n") 1009 expectPrintedJSXASCII(t, "<a>𐀀</a>", "<a>𐀀</a>;\n") 1010 1011 expectPrintedJSXMinify(t, "<a b c={x,y} d='true'/>", "<a b c={(x,y)}d='true'/>;") 1012 expectPrintedJSXMinify(t, "<a><b/><c/></a>", "<a><b/><c/></a>;") 1013 expectPrintedJSXMinify(t, "<a> x <b/> y </a>", "<a> x <b/> y </a>;") 1014 expectPrintedJSXMinify(t, "<a>{' x '}{'<b/>'}{' y '}</a>", "<a>{\" x \"}{\"<b/>\"}{\" y \"}</a>;") 1015 } 1016 1017 func TestJSXSingleLine(t *testing.T) { 1018 expectPrintedJSX(t, "<x/>", "<x />;\n") 1019 expectPrintedJSX(t, "<x y/>", "<x y />;\n") 1020 expectPrintedJSX(t, "<x\n/>", "<x />;\n") 1021 expectPrintedJSX(t, "<x\ny/>", "<x\n y\n/>;\n") 1022 expectPrintedJSX(t, "<x y\n/>", "<x\n y\n/>;\n") 1023 expectPrintedJSX(t, "<x\n{...y}/>", "<x\n {...y}\n/>;\n") 1024 1025 expectPrintedJSXMinify(t, "<x/>", "<x/>;") 1026 expectPrintedJSXMinify(t, "<x y/>", "<x y/>;") 1027 expectPrintedJSXMinify(t, "<x\n/>", "<x/>;") 1028 expectPrintedJSXMinify(t, "<x\ny/>", "<x y/>;") 1029 expectPrintedJSXMinify(t, "<x y\n/>", "<x y/>;") 1030 expectPrintedJSXMinify(t, "<x\n{...y}/>", "<x{...y}/>;") 1031 } 1032 1033 func TestAvoidSlashScript(t *testing.T) { 1034 // Positive cases 1035 expectPrinted(t, "x = '</script'", "x = \"<\\/script\";\n") 1036 expectPrinted(t, "x = `</script`", "x = `<\\/script`;\n") 1037 expectPrinted(t, "x = `</SCRIPT`", "x = `<\\/SCRIPT`;\n") 1038 expectPrinted(t, "x = `</ScRiPt`", "x = `<\\/ScRiPt`;\n") 1039 expectPrinted(t, "x = `</script${y}`", "x = `<\\/script${y}`;\n") 1040 expectPrinted(t, "x = `${y}</script`", "x = `${y}<\\/script`;\n") 1041 expectPrintedMinify(t, "x = 1 < /script/.exec(y).length", "x=1< /script/.exec(y).length;") 1042 expectPrintedMinify(t, "x = 1 < /SCRIPT/.exec(y).length", "x=1< /SCRIPT/.exec(y).length;") 1043 expectPrintedMinify(t, "x = 1 < /ScRiPt/.exec(y).length", "x=1< /ScRiPt/.exec(y).length;") 1044 expectPrintedMinify(t, "x = 1 << /script/.exec(y).length", "x=1<< /script/.exec(y).length;") 1045 expectPrinted(t, "//! </script\n//! >/script\n//! /script", "//! <\\/script\n//! >/script\n//! /script\n") 1046 expectPrinted(t, "//! </SCRIPT\n//! >/SCRIPT\n//! /SCRIPT", "//! <\\/SCRIPT\n//! >/SCRIPT\n//! /SCRIPT\n") 1047 expectPrinted(t, "//! </ScRiPt\n//! >/ScRiPt\n//! /ScRiPt", "//! <\\/ScRiPt\n//! >/ScRiPt\n//! /ScRiPt\n") 1048 expectPrinted(t, "/*! </script \n </script */", "/*! <\\/script \n <\\/script */\n") 1049 expectPrinted(t, "/*! </SCRIPT \n </SCRIPT */", "/*! <\\/SCRIPT \n <\\/SCRIPT */\n") 1050 expectPrinted(t, "/*! </ScRiPt \n </ScRiPt */", "/*! <\\/ScRiPt \n <\\/ScRiPt */\n") 1051 expectPrinted(t, "String.raw`</script`", 1052 "import { __template } from \"<runtime>\";\nvar _a;\nString.raw(_a || (_a = __template([\"<\\/script\"])));\n") 1053 expectPrinted(t, "String.raw`</script${a}`", 1054 "import { __template } from \"<runtime>\";\nvar _a;\nString.raw(_a || (_a = __template([\"<\\/script\", \"\"])), a);\n") 1055 expectPrinted(t, "String.raw`${a}</script`", 1056 "import { __template } from \"<runtime>\";\nvar _a;\nString.raw(_a || (_a = __template([\"\", \"<\\/script\"])), a);\n") 1057 expectPrinted(t, "String.raw`</SCRIPT`", 1058 "import { __template } from \"<runtime>\";\nvar _a;\nString.raw(_a || (_a = __template([\"<\\/SCRIPT\"])));\n") 1059 expectPrinted(t, "String.raw`</ScRiPt`", 1060 "import { __template } from \"<runtime>\";\nvar _a;\nString.raw(_a || (_a = __template([\"<\\/ScRiPt\"])));\n") 1061 1062 // Negative cases 1063 expectPrinted(t, "x = '</'", "x = \"</\";\n") 1064 expectPrinted(t, "x = '</ script'", "x = \"</ script\";\n") 1065 expectPrinted(t, "x = '< /script'", "x = \"< /script\";\n") 1066 expectPrinted(t, "x = '/script>'", "x = \"/script>\";\n") 1067 expectPrinted(t, "x = '<script>'", "x = \"<script>\";\n") 1068 expectPrintedMinify(t, "x = 1 < / script/.exec(y).length", "x=1</ script/.exec(y).length;") 1069 expectPrintedMinify(t, "x = 1 << / script/.exec(y).length", "x=1<</ script/.exec(y).length;") 1070 } 1071 1072 func TestInfinity(t *testing.T) { 1073 expectPrinted(t, "x = Infinity", "x = Infinity;\n") 1074 expectPrinted(t, "x = -Infinity", "x = -Infinity;\n") 1075 expectPrinted(t, "x = (Infinity).toString", "x = Infinity.toString;\n") 1076 expectPrinted(t, "x = (-Infinity).toString", "x = (-Infinity).toString;\n") 1077 expectPrinted(t, "x = (Infinity) ** 2", "x = Infinity ** 2;\n") 1078 expectPrinted(t, "x = (-Infinity) ** 2", "x = (-Infinity) ** 2;\n") 1079 expectPrinted(t, "x = ~Infinity", "x = ~Infinity;\n") 1080 expectPrinted(t, "x = ~-Infinity", "x = ~-Infinity;\n") 1081 expectPrinted(t, "x = Infinity * y", "x = Infinity * y;\n") 1082 expectPrinted(t, "x = Infinity / y", "x = Infinity / y;\n") 1083 expectPrinted(t, "x = y * Infinity", "x = y * Infinity;\n") 1084 expectPrinted(t, "x = y / Infinity", "x = y / Infinity;\n") 1085 expectPrinted(t, "throw Infinity", "throw Infinity;\n") 1086 1087 expectPrintedMinify(t, "x = Infinity", "x=Infinity;") 1088 expectPrintedMinify(t, "x = -Infinity", "x=-Infinity;") 1089 expectPrintedMinify(t, "x = (Infinity).toString", "x=Infinity.toString;") 1090 expectPrintedMinify(t, "x = (-Infinity).toString", "x=(-Infinity).toString;") 1091 expectPrintedMinify(t, "x = (Infinity) ** 2", "x=Infinity**2;") 1092 expectPrintedMinify(t, "x = (-Infinity) ** 2", "x=(-Infinity)**2;") 1093 expectPrintedMinify(t, "x = ~Infinity", "x=~Infinity;") 1094 expectPrintedMinify(t, "x = ~-Infinity", "x=~-Infinity;") 1095 expectPrintedMinify(t, "x = Infinity * y", "x=Infinity*y;") 1096 expectPrintedMinify(t, "x = Infinity / y", "x=Infinity/y;") 1097 expectPrintedMinify(t, "x = y * Infinity", "x=y*Infinity;") 1098 expectPrintedMinify(t, "x = y / Infinity", "x=y/Infinity;") 1099 expectPrintedMinify(t, "throw Infinity", "throw Infinity;") 1100 1101 expectPrintedMangle(t, "x = Infinity", "x = 1 / 0;\n") 1102 expectPrintedMangle(t, "x = -Infinity", "x = -1 / 0;\n") 1103 expectPrintedMangle(t, "x = (Infinity).toString", "x = (1 / 0).toString;\n") 1104 expectPrintedMangle(t, "x = (-Infinity).toString", "x = (-1 / 0).toString;\n") 1105 expectPrintedMangle(t, "x = Infinity ** 2", "x = (1 / 0) ** 2;\n") 1106 expectPrintedMangle(t, "x = (-Infinity) ** 2", "x = (-1 / 0) ** 2;\n") 1107 expectPrintedMangle(t, "x = Infinity * y", "x = 1 / 0 * y;\n") 1108 expectPrintedMangle(t, "x = Infinity / y", "x = 1 / 0 / y;\n") 1109 expectPrintedMangle(t, "x = y * Infinity", "x = y * (1 / 0);\n") 1110 expectPrintedMangle(t, "x = y / Infinity", "x = y / (1 / 0);\n") 1111 expectPrintedMangle(t, "throw Infinity", "throw 1 / 0;\n") 1112 1113 expectPrintedMangleMinify(t, "x = Infinity", "x=1/0;") 1114 expectPrintedMangleMinify(t, "x = -Infinity", "x=-1/0;") 1115 expectPrintedMangleMinify(t, "x = (Infinity).toString", "x=(1/0).toString;") 1116 expectPrintedMangleMinify(t, "x = (-Infinity).toString", "x=(-1/0).toString;") 1117 expectPrintedMangleMinify(t, "x = Infinity ** 2", "x=(1/0)**2;") 1118 expectPrintedMangleMinify(t, "x = (-Infinity) ** 2", "x=(-1/0)**2;") 1119 expectPrintedMangleMinify(t, "x = Infinity * y", "x=1/0*y;") 1120 expectPrintedMangleMinify(t, "x = Infinity / y", "x=1/0/y;") 1121 expectPrintedMangleMinify(t, "x = y * Infinity", "x=y*(1/0);") 1122 expectPrintedMangleMinify(t, "x = y / Infinity", "x=y/(1/0);") 1123 expectPrintedMangleMinify(t, "throw Infinity", "throw 1/0;") 1124 } 1125 1126 func TestBinaryOperatorVisitor(t *testing.T) { 1127 // Make sure the inner "/*b*/" comment doesn't disappear due to weird binary visitor stuff 1128 expectPrintedMangle(t, "x = (0, /*a*/ (0, /*b*/ (0, /*c*/ 1 == 2) + 3) * 4)", "x = /*a*/\n/*b*/\n(/*c*/\n!1 + 3) * 4;\n") 1129 1130 // Make sure deeply-nested ASTs don't cause a stack overflow 1131 x := "x = f()" + strings.Repeat(" || f()", 10_000) + ";\n" 1132 expectPrinted(t, x, x) 1133 } 1134 1135 // See: https://github.com/tc39/proposal-explicit-resource-management 1136 func TestUsing(t *testing.T) { 1137 expectPrinted(t, "using x = y", "using x = y;\n") 1138 expectPrinted(t, "using x = y, z = _", "using x = y, z = _;\n") 1139 expectPrintedMinify(t, "using x = y", "using x=y;") 1140 expectPrintedMinify(t, "using x = y, z = _", "using x=y,z=_;") 1141 1142 expectPrinted(t, "await using x = y", "await using x = y;\n") 1143 expectPrinted(t, "await using x = y, z = _", "await using x = y, z = _;\n") 1144 expectPrintedMinify(t, "await using x = y", "await using x=y;") 1145 expectPrintedMinify(t, "await using x = y, z = _", "await using x=y,z=_;") 1146 }