github.com/evanw/esbuild@v0.21.4/internal/js_lexer/js_lexer_test.go (about)

     1  package js_lexer
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"strings"
     7  	"testing"
     8  	"unicode/utf8"
     9  
    10  	"github.com/evanw/esbuild/internal/config"
    11  	"github.com/evanw/esbuild/internal/helpers"
    12  	"github.com/evanw/esbuild/internal/logger"
    13  	"github.com/evanw/esbuild/internal/test"
    14  )
    15  
    16  func assertEqualStrings(t *testing.T, a string, b string) {
    17  	t.Helper()
    18  	pretty := func(text string) string {
    19  		builder := strings.Builder{}
    20  		builder.WriteRune('"')
    21  		i := 0
    22  		for i < len(text) {
    23  			c, width := utf8.DecodeRuneInString(text[i:])
    24  			builder.WriteString(fmt.Sprintf("\\u{%X}", c))
    25  			i += width
    26  		}
    27  		builder.WriteRune('"')
    28  		return builder.String()
    29  	}
    30  	if a != b {
    31  		t.Fatalf("%s != %s", pretty(a), pretty(b))
    32  	}
    33  }
    34  
    35  func lexToken(t *testing.T, contents string) T {
    36  	log := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)
    37  	lexer := NewLexer(log, test.SourceForTest(contents), config.TSOptions{})
    38  	return lexer.Token
    39  }
    40  
    41  func expectLexerError(t *testing.T, contents string, expected string) {
    42  	t.Helper()
    43  	t.Run(contents, func(t *testing.T) {
    44  		t.Helper()
    45  		log := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)
    46  		func() {
    47  			defer func() {
    48  				r := recover()
    49  				if _, isLexerPanic := r.(LexerPanic); r != nil && !isLexerPanic {
    50  					panic(r)
    51  				}
    52  			}()
    53  			NewLexer(log, test.SourceForTest(contents), config.TSOptions{})
    54  		}()
    55  		msgs := log.Done()
    56  		text := ""
    57  		for _, msg := range msgs {
    58  			text += msg.String(logger.OutputOptions{}, logger.TerminalInfo{})
    59  		}
    60  		test.AssertEqual(t, text, expected)
    61  	})
    62  }
    63  
    64  func TestComment(t *testing.T) {
    65  	expectLexerError(t, "/*", "<stdin>: ERROR: Expected \"*/\" to terminate multi-line comment\n<stdin>: NOTE: The multi-line comment starts here:\n")
    66  	expectLexerError(t, "/*/", "<stdin>: ERROR: Expected \"*/\" to terminate multi-line comment\n<stdin>: NOTE: The multi-line comment starts here:\n")
    67  	expectLexerError(t, "/**/", "")
    68  	expectLexerError(t, "//", "")
    69  }
    70  
    71  func expectHashbang(t *testing.T, contents string, expected string) {
    72  	t.Helper()
    73  	t.Run(contents, func(t *testing.T) {
    74  		t.Helper()
    75  		log := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)
    76  		lexer := func() Lexer {
    77  			defer func() {
    78  				r := recover()
    79  				if _, isLexerPanic := r.(LexerPanic); r != nil && !isLexerPanic {
    80  					panic(r)
    81  				}
    82  			}()
    83  			return NewLexer(log, test.SourceForTest(contents), config.TSOptions{})
    84  		}()
    85  		msgs := log.Done()
    86  		test.AssertEqual(t, len(msgs), 0)
    87  		test.AssertEqual(t, lexer.Token, THashbang)
    88  		test.AssertEqual(t, lexer.Identifier.String, expected)
    89  	})
    90  }
    91  
    92  func TestHashbang(t *testing.T) {
    93  	expectHashbang(t, "#!/usr/bin/env node", "#!/usr/bin/env node")
    94  	expectHashbang(t, "#!/usr/bin/env node\n", "#!/usr/bin/env node")
    95  	expectHashbang(t, "#!/usr/bin/env node\nlet x", "#!/usr/bin/env node")
    96  	expectLexerError(t, " #!/usr/bin/env node", "<stdin>: ERROR: Syntax error \"!\"\n")
    97  }
    98  
    99  func expectIdentifier(t *testing.T, contents string, expected string) {
   100  	t.Helper()
   101  	t.Run(contents, func(t *testing.T) {
   102  		t.Helper()
   103  		log := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)
   104  		lexer := func() Lexer {
   105  			defer func() {
   106  				r := recover()
   107  				if _, isLexerPanic := r.(LexerPanic); r != nil && !isLexerPanic {
   108  					panic(r)
   109  				}
   110  			}()
   111  			return NewLexer(log, test.SourceForTest(contents), config.TSOptions{})
   112  		}()
   113  		msgs := log.Done()
   114  		test.AssertEqual(t, len(msgs), 0)
   115  		test.AssertEqual(t, lexer.Token, TIdentifier)
   116  		test.AssertEqual(t, lexer.Identifier.String, expected)
   117  	})
   118  }
   119  
   120  func TestIdentifier(t *testing.T) {
   121  	expectIdentifier(t, "_", "_")
   122  	expectIdentifier(t, "$", "$")
   123  	expectIdentifier(t, "test", "test")
   124  	expectIdentifier(t, "t\\u0065st", "test")
   125  	expectIdentifier(t, "t\\u{65}st", "test")
   126  
   127  	expectLexerError(t, "t\\u.", "<stdin>: ERROR: Syntax error \".\"\n")
   128  	expectLexerError(t, "t\\u0.", "<stdin>: ERROR: Syntax error \".\"\n")
   129  	expectLexerError(t, "t\\u00.", "<stdin>: ERROR: Syntax error \".\"\n")
   130  	expectLexerError(t, "t\\u006.", "<stdin>: ERROR: Syntax error \".\"\n")
   131  	expectLexerError(t, "t\\u{.", "<stdin>: ERROR: Syntax error \".\"\n")
   132  	expectLexerError(t, "t\\u{0.", "<stdin>: ERROR: Syntax error \".\"\n")
   133  
   134  	expectIdentifier(t, "a\u200C", "a\u200C")
   135  	expectIdentifier(t, "a\u200D", "a\u200D")
   136  	expectIdentifier(t, "a\u200Cb", "a\u200Cb")
   137  	expectIdentifier(t, "a\u200Db", "a\u200Db")
   138  }
   139  
   140  func expectNumber(t *testing.T, contents string, expected float64) {
   141  	t.Helper()
   142  	t.Run(contents, func(t *testing.T) {
   143  		t.Helper()
   144  		log := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)
   145  		lexer := func() Lexer {
   146  			defer func() {
   147  				r := recover()
   148  				if _, isLexerPanic := r.(LexerPanic); r != nil && !isLexerPanic {
   149  					panic(r)
   150  				}
   151  			}()
   152  			return NewLexer(log, test.SourceForTest(contents), config.TSOptions{})
   153  		}()
   154  		msgs := log.Done()
   155  		test.AssertEqual(t, len(msgs), 0)
   156  		test.AssertEqual(t, lexer.Token, TNumericLiteral)
   157  		test.AssertEqual(t, lexer.Number, expected)
   158  	})
   159  }
   160  
   161  func TestNumericLiteral(t *testing.T) {
   162  	expectNumber(t, "0", 0.0)
   163  	expectNumber(t, "000", 0.0)
   164  	expectNumber(t, "010", 8.0)
   165  	expectNumber(t, "123", 123.0)
   166  	expectNumber(t, "987", 987.0)
   167  	expectNumber(t, "0000", 0.0)
   168  	expectNumber(t, "0123", 83.0)
   169  	expectNumber(t, "0123.4567", 83.0)
   170  	expectNumber(t, "0987", 987.0)
   171  	expectNumber(t, "0987.6543", 987.6543)
   172  	expectNumber(t, "01289", 1289.0)
   173  	expectNumber(t, "01289.345", 1289.0)
   174  	expectNumber(t, "999999999", 999999999.0)
   175  	expectNumber(t, "9999999999", 9999999999.0)
   176  	expectNumber(t, "99999999999", 99999999999.0)
   177  	expectNumber(t, "123456789123456789", 123456789123456780.0)
   178  	expectNumber(t, "123456789123456789"+strings.Repeat("0", 128), 1.2345678912345679e+145)
   179  
   180  	expectNumber(t, "0b00101", 5.0)
   181  	expectNumber(t, "0B00101", 5.0)
   182  	expectNumber(t, "0b1011101011101011101011101011101011101", 100352251741.0)
   183  	expectNumber(t, "0B1011101011101011101011101011101011101", 100352251741.0)
   184  	expectLexerError(t, "0b", "<stdin>: ERROR: Unexpected end of file\n")
   185  	expectLexerError(t, "0B", "<stdin>: ERROR: Unexpected end of file\n")
   186  	expectLexerError(t, "0b012", "<stdin>: ERROR: Syntax error \"2\"\n")
   187  	expectLexerError(t, "0b018", "<stdin>: ERROR: Syntax error \"8\"\n")
   188  	expectLexerError(t, "0b01a", "<stdin>: ERROR: Syntax error \"a\"\n")
   189  	expectLexerError(t, "0b01A", "<stdin>: ERROR: Syntax error \"A\"\n")
   190  
   191  	expectNumber(t, "0o12345", 5349.0)
   192  	expectNumber(t, "0O12345", 5349.0)
   193  	expectNumber(t, "0o1234567654321", 89755965649.0)
   194  	expectNumber(t, "0O1234567654321", 89755965649.0)
   195  	expectLexerError(t, "0o", "<stdin>: ERROR: Unexpected end of file\n")
   196  	expectLexerError(t, "0O", "<stdin>: ERROR: Unexpected end of file\n")
   197  	expectLexerError(t, "0o018", "<stdin>: ERROR: Syntax error \"8\"\n")
   198  	expectLexerError(t, "0o01a", "<stdin>: ERROR: Syntax error \"a\"\n")
   199  	expectLexerError(t, "0o01A", "<stdin>: ERROR: Syntax error \"A\"\n")
   200  
   201  	expectNumber(t, "0x12345678", float64(0x12345678))
   202  	expectNumber(t, "0xFEDCBA987", float64(0xFEDCBA987))
   203  	expectNumber(t, "0x000012345678", float64(0x12345678))
   204  	expectNumber(t, "0x123456781234", float64(0x123456781234))
   205  	expectLexerError(t, "0x", "<stdin>: ERROR: Unexpected end of file\n")
   206  	expectLexerError(t, "0X", "<stdin>: ERROR: Unexpected end of file\n")
   207  	expectLexerError(t, "0xGFEDCBA", "<stdin>: ERROR: Syntax error \"G\"\n")
   208  	expectLexerError(t, "0xABCDEFG", "<stdin>: ERROR: Syntax error \"G\"\n")
   209  
   210  	expectNumber(t, "123.", 123.0)
   211  	expectNumber(t, ".0123", 0.0123)
   212  	expectNumber(t, "0.0123", 0.0123)
   213  	expectNumber(t, "2.2250738585072014e-308", 2.2250738585072014e-308)
   214  	expectNumber(t, "1.7976931348623157e+308", 1.7976931348623157e+308)
   215  
   216  	// Underflow
   217  	expectNumber(t, "4.9406564584124654417656879286822e-324", 5e-324)
   218  	expectNumber(t, "5e-324", 5e-324)
   219  	expectNumber(t, "1e-325", 0.0)
   220  
   221  	// Overflow
   222  	expectNumber(t, "1.797693134862315708145274237317e+308", 1.7976931348623157e+308)
   223  	expectNumber(t, "1.797693134862315808e+308", math.Inf(1))
   224  	expectNumber(t, "1e+309", math.Inf(1))
   225  
   226  	// int32
   227  	expectNumber(t, "0x7fff_ffff", 2147483647.0)
   228  	expectNumber(t, "0x8000_0000", 2147483648.0)
   229  	expectNumber(t, "0x8000_0001", 2147483649.0)
   230  
   231  	// uint32
   232  	expectNumber(t, "0xffff_ffff", 4294967295.0)
   233  	expectNumber(t, "0x1_0000_0000", 4294967296.0)
   234  	expectNumber(t, "0x1_0000_0001", 4294967297.0)
   235  
   236  	// int64
   237  	expectNumber(t, "0x7fff_ffff_ffff_fdff", 9223372036854774784)
   238  	expectNumber(t, "0x8000_0000_0000_0000", 9.223372036854776e+18)
   239  	expectNumber(t, "0x8000_0000_0000_3000", 9.223372036854788e+18)
   240  
   241  	// uint64
   242  	expectNumber(t, "0xffff_ffff_ffff_fbff", 1.844674407370955e+19)
   243  	expectNumber(t, "0x1_0000_0000_0000_0000", 1.8446744073709552e+19)
   244  	expectNumber(t, "0x1_0000_0000_0000_1000", 1.8446744073709556e+19)
   245  
   246  	expectNumber(t, "1.", 1.0)
   247  	expectNumber(t, ".1", 0.1)
   248  	expectNumber(t, "1.1", 1.1)
   249  	expectNumber(t, "1e1", 10.0)
   250  	expectNumber(t, "1e+1", 10.0)
   251  	expectNumber(t, "1e-1", 0.1)
   252  	expectNumber(t, ".1e1", 1.0)
   253  	expectNumber(t, ".1e+1", 1.0)
   254  	expectNumber(t, ".1e-1", 0.01)
   255  	expectNumber(t, "1.e1", 10.0)
   256  	expectNumber(t, "1.e+1", 10.0)
   257  	expectNumber(t, "1.e-1", 0.1)
   258  	expectNumber(t, "1.1e1", 11.0)
   259  	expectNumber(t, "1.1e+1", 11.0)
   260  	expectNumber(t, "1.1e-1", 0.11)
   261  
   262  	expectLexerError(t, "1e", "<stdin>: ERROR: Unexpected end of file\n")
   263  	expectLexerError(t, ".1e", "<stdin>: ERROR: Unexpected end of file\n")
   264  	expectLexerError(t, "1.e", "<stdin>: ERROR: Unexpected end of file\n")
   265  	expectLexerError(t, "1.1e", "<stdin>: ERROR: Unexpected end of file\n")
   266  	expectLexerError(t, "1e+", "<stdin>: ERROR: Unexpected end of file\n")
   267  	expectLexerError(t, ".1e+", "<stdin>: ERROR: Unexpected end of file\n")
   268  	expectLexerError(t, "1.e+", "<stdin>: ERROR: Unexpected end of file\n")
   269  	expectLexerError(t, "1.1e+", "<stdin>: ERROR: Unexpected end of file\n")
   270  	expectLexerError(t, "1e-", "<stdin>: ERROR: Unexpected end of file\n")
   271  	expectLexerError(t, ".1e-", "<stdin>: ERROR: Unexpected end of file\n")
   272  	expectLexerError(t, "1.e-", "<stdin>: ERROR: Unexpected end of file\n")
   273  	expectLexerError(t, "1.1e-", "<stdin>: ERROR: Unexpected end of file\n")
   274  	expectLexerError(t, "1e+-1", "<stdin>: ERROR: Syntax error \"-\"\n")
   275  	expectLexerError(t, "1e-+1", "<stdin>: ERROR: Syntax error \"+\"\n")
   276  
   277  	expectLexerError(t, "1z", "<stdin>: ERROR: Syntax error \"z\"\n")
   278  	expectLexerError(t, "1.z", "<stdin>: ERROR: Syntax error \"z\"\n")
   279  	expectLexerError(t, "1.0f", "<stdin>: ERROR: Syntax error \"f\"\n")
   280  	expectLexerError(t, "0b1z", "<stdin>: ERROR: Syntax error \"z\"\n")
   281  	expectLexerError(t, "0o1z", "<stdin>: ERROR: Syntax error \"z\"\n")
   282  	expectLexerError(t, "0x1z", "<stdin>: ERROR: Syntax error \"z\"\n")
   283  	expectLexerError(t, "1e1z", "<stdin>: ERROR: Syntax error \"z\"\n")
   284  
   285  	expectNumber(t, "1_2_3", 123)
   286  	expectNumber(t, ".1_2", 0.12)
   287  	expectNumber(t, "1_2.3_4", 12.34)
   288  	expectNumber(t, "1e2_3", 1e23)
   289  	expectNumber(t, "1_2e3_4", 12e34)
   290  	expectNumber(t, "1_2.3_4e5_6", 12.34e56)
   291  	expectNumber(t, "0b1_0", 2)
   292  	expectNumber(t, "0B1_0", 2)
   293  	expectNumber(t, "0o1_2", 10)
   294  	expectNumber(t, "0O1_2", 10)
   295  	expectNumber(t, "0x1_2", 0x12)
   296  	expectNumber(t, "0X1_2", 0x12)
   297  	expectNumber(t, "08.0_1", 8.01)
   298  	expectNumber(t, "09.0_1", 9.01)
   299  
   300  	expectLexerError(t, "0_0", "<stdin>: ERROR: Syntax error \"_\"\n")
   301  	expectLexerError(t, "0_1", "<stdin>: ERROR: Syntax error \"_\"\n")
   302  	expectLexerError(t, "0_7", "<stdin>: ERROR: Syntax error \"_\"\n")
   303  	expectLexerError(t, "0_8", "<stdin>: ERROR: Syntax error \"_\"\n")
   304  	expectLexerError(t, "0_9", "<stdin>: ERROR: Syntax error \"_\"\n")
   305  	expectLexerError(t, "00_0", "<stdin>: ERROR: Syntax error \"_\"\n")
   306  	expectLexerError(t, "01_0", "<stdin>: ERROR: Syntax error \"_\"\n")
   307  	expectLexerError(t, "07_0", "<stdin>: ERROR: Syntax error \"_\"\n")
   308  	expectLexerError(t, "08_0", "<stdin>: ERROR: Syntax error \"_\"\n")
   309  	expectLexerError(t, "09_0", "<stdin>: ERROR: Syntax error \"_\"\n")
   310  	expectLexerError(t, "08_0.1", "<stdin>: ERROR: Syntax error \"_\"\n")
   311  	expectLexerError(t, "09_0.1", "<stdin>: ERROR: Syntax error \"_\"\n")
   312  
   313  	expectLexerError(t, "1__2", "<stdin>: ERROR: Syntax error \"_\"\n")
   314  	expectLexerError(t, ".1__2", "<stdin>: ERROR: Syntax error \"_\"\n")
   315  	expectLexerError(t, "1e2__3", "<stdin>: ERROR: Syntax error \"_\"\n")
   316  	expectLexerError(t, "0b1__0", "<stdin>: ERROR: Syntax error \"_\"\n")
   317  	expectLexerError(t, "0B1__0", "<stdin>: ERROR: Syntax error \"_\"\n")
   318  	expectLexerError(t, "0o1__2", "<stdin>: ERROR: Syntax error \"_\"\n")
   319  	expectLexerError(t, "0O1__2", "<stdin>: ERROR: Syntax error \"_\"\n")
   320  	expectLexerError(t, "0x1__2", "<stdin>: ERROR: Syntax error \"_\"\n")
   321  	expectLexerError(t, "0X1__2", "<stdin>: ERROR: Syntax error \"_\"\n")
   322  
   323  	expectLexerError(t, "1_", "<stdin>: ERROR: Syntax error \"_\"\n")
   324  	expectLexerError(t, "1._", "<stdin>: ERROR: Syntax error \"_\"\n")
   325  	expectLexerError(t, "1_.", "<stdin>: ERROR: Syntax error \"_\"\n")
   326  	expectLexerError(t, ".1_", "<stdin>: ERROR: Syntax error \"_\"\n")
   327  	expectLexerError(t, "1e_", "<stdin>: ERROR: Syntax error \"_\"\n")
   328  	expectLexerError(t, "1e1_", "<stdin>: ERROR: Syntax error \"_\"\n")
   329  	expectLexerError(t, "1_e1", "<stdin>: ERROR: Syntax error \"_\"\n")
   330  	expectLexerError(t, ".1_e1", "<stdin>: ERROR: Syntax error \"_\"\n")
   331  	expectLexerError(t, "1._2", "<stdin>: ERROR: Syntax error \"_\"\n")
   332  	expectLexerError(t, "1_.2", "<stdin>: ERROR: Syntax error \"_\"\n")
   333  	expectLexerError(t, "0b_1", "<stdin>: ERROR: Syntax error \"_\"\n")
   334  	expectLexerError(t, "0B_1", "<stdin>: ERROR: Syntax error \"_\"\n")
   335  	expectLexerError(t, "0o_1", "<stdin>: ERROR: Syntax error \"_\"\n")
   336  	expectLexerError(t, "0O_1", "<stdin>: ERROR: Syntax error \"_\"\n")
   337  	expectLexerError(t, "0x_1", "<stdin>: ERROR: Syntax error \"_\"\n")
   338  	expectLexerError(t, "0X_1", "<stdin>: ERROR: Syntax error \"_\"\n")
   339  	expectLexerError(t, "0b1_", "<stdin>: ERROR: Syntax error \"_\"\n")
   340  	expectLexerError(t, "0B1_", "<stdin>: ERROR: Syntax error \"_\"\n")
   341  	expectLexerError(t, "0o1_", "<stdin>: ERROR: Syntax error \"_\"\n")
   342  	expectLexerError(t, "0O1_", "<stdin>: ERROR: Syntax error \"_\"\n")
   343  	expectLexerError(t, "0x1_", "<stdin>: ERROR: Syntax error \"_\"\n")
   344  	expectLexerError(t, "0X1_", "<stdin>: ERROR: Syntax error \"_\"\n")
   345  }
   346  
   347  func expectBigInteger(t *testing.T, contents string, expected string) {
   348  	t.Helper()
   349  	t.Run(contents, func(t *testing.T) {
   350  		t.Helper()
   351  		log := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)
   352  		lexer := func() Lexer {
   353  			defer func() {
   354  				r := recover()
   355  				if _, isLexerPanic := r.(LexerPanic); r != nil && !isLexerPanic {
   356  					panic(r)
   357  				}
   358  			}()
   359  			return NewLexer(log, test.SourceForTest(contents), config.TSOptions{})
   360  		}()
   361  		msgs := log.Done()
   362  		test.AssertEqual(t, len(msgs), 0)
   363  		test.AssertEqual(t, lexer.Token, TBigIntegerLiteral)
   364  		test.AssertEqual(t, lexer.Identifier.String, expected)
   365  	})
   366  }
   367  
   368  func TestBigIntegerLiteral(t *testing.T) {
   369  	expectBigInteger(t, "0n", "0")
   370  	expectBigInteger(t, "123n", "123")
   371  	expectBigInteger(t, "9007199254740993n", "9007199254740993") // This can't fit in a float64
   372  
   373  	expectBigInteger(t, "0b00101n", "0b00101")
   374  	expectBigInteger(t, "0B00101n", "0B00101")
   375  	expectBigInteger(t, "0b1011101011101011101011101011101011101n", "0b1011101011101011101011101011101011101")
   376  	expectBigInteger(t, "0B1011101011101011101011101011101011101n", "0B1011101011101011101011101011101011101")
   377  
   378  	expectBigInteger(t, "0o12345n", "0o12345")
   379  	expectBigInteger(t, "0O12345n", "0O12345")
   380  	expectBigInteger(t, "0o1234567654321n", "0o1234567654321")
   381  	expectBigInteger(t, "0O1234567654321n", "0O1234567654321")
   382  
   383  	expectBigInteger(t, "0x12345678n", "0x12345678")
   384  	expectBigInteger(t, "0xFEDCBA987n", "0xFEDCBA987")
   385  	expectBigInteger(t, "0x000012345678n", "0x000012345678")
   386  	expectBigInteger(t, "0x123456781234n", "0x123456781234")
   387  
   388  	expectBigInteger(t, "1_2_3n", "123")
   389  	expectBigInteger(t, "0b1_0_1n", "0b101")
   390  	expectBigInteger(t, "0o1_2_3n", "0o123")
   391  	expectBigInteger(t, "0x1_2_3n", "0x123")
   392  
   393  	expectLexerError(t, "1e2n", "<stdin>: ERROR: Syntax error \"n\"\n")
   394  	expectLexerError(t, "1.0n", "<stdin>: ERROR: Syntax error \"n\"\n")
   395  	expectLexerError(t, ".1n", "<stdin>: ERROR: Syntax error \"n\"\n")
   396  	expectLexerError(t, "000n", "<stdin>: ERROR: Syntax error \"n\"\n")
   397  	expectLexerError(t, "0123n", "<stdin>: ERROR: Syntax error \"n\"\n")
   398  	expectLexerError(t, "089n", "<stdin>: ERROR: Syntax error \"n\"\n")
   399  	expectLexerError(t, "0_1n", "<stdin>: ERROR: Syntax error \"_\"\n")
   400  }
   401  
   402  func expectString(t *testing.T, contents string, expected string) {
   403  	t.Helper()
   404  	t.Run(contents, func(t *testing.T) {
   405  		t.Helper()
   406  		log := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)
   407  		lexer := func() Lexer {
   408  			defer func() {
   409  				r := recover()
   410  				if _, isLexerPanic := r.(LexerPanic); r != nil && !isLexerPanic {
   411  					panic(r)
   412  				}
   413  			}()
   414  			return NewLexer(log, test.SourceForTest(contents), config.TSOptions{})
   415  		}()
   416  		text := lexer.StringLiteral()
   417  		msgs := log.Done()
   418  		test.AssertEqual(t, len(msgs), 0)
   419  		test.AssertEqual(t, lexer.Token, TStringLiteral)
   420  		assertEqualStrings(t, helpers.UTF16ToString(text), expected)
   421  	})
   422  }
   423  
   424  func expectLexerErrorString(t *testing.T, contents string, expected string) {
   425  	t.Helper()
   426  	t.Run(contents, func(t *testing.T) {
   427  		t.Helper()
   428  		log := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug, nil)
   429  		func() {
   430  			defer func() {
   431  				r := recover()
   432  				if _, isLexerPanic := r.(LexerPanic); r != nil && !isLexerPanic {
   433  					panic(r)
   434  				}
   435  			}()
   436  			lexer := NewLexer(log, test.SourceForTest(contents), config.TSOptions{})
   437  			lexer.StringLiteral()
   438  		}()
   439  		msgs := log.Done()
   440  		text := ""
   441  		for _, msg := range msgs {
   442  			text += msg.String(logger.OutputOptions{}, logger.TerminalInfo{})
   443  		}
   444  		test.AssertEqual(t, text, expected)
   445  	})
   446  }
   447  
   448  func TestStringLiteral(t *testing.T) {
   449  	expectString(t, "''", "")
   450  	expectString(t, "'123'", "123")
   451  
   452  	expectString(t, "'\"'", "\"")
   453  	expectString(t, "'\\''", "'")
   454  	expectString(t, "'\\\"'", "\"")
   455  	expectString(t, "'\\\\'", "\\")
   456  	expectString(t, "'\\a'", "a")
   457  	expectString(t, "'\\b'", "\b")
   458  	expectString(t, "'\\f'", "\f")
   459  	expectString(t, "'\\n'", "\n")
   460  	expectString(t, "'\\r'", "\r")
   461  	expectString(t, "'\\t'", "\t")
   462  	expectString(t, "'\\v'", "\v")
   463  
   464  	expectString(t, "'\\0'", "\000")
   465  	expectString(t, "'\\1'", "\001")
   466  	expectString(t, "'\\2'", "\002")
   467  	expectString(t, "'\\3'", "\003")
   468  	expectString(t, "'\\4'", "\004")
   469  	expectString(t, "'\\5'", "\005")
   470  	expectString(t, "'\\6'", "\006")
   471  	expectString(t, "'\\7'", "\007")
   472  
   473  	expectString(t, "'\\000'", "\000")
   474  	expectString(t, "'\\001'", "\001")
   475  	expectString(t, "'\\002'", "\002")
   476  	expectString(t, "'\\003'", "\003")
   477  	expectString(t, "'\\004'", "\004")
   478  	expectString(t, "'\\005'", "\005")
   479  	expectString(t, "'\\006'", "\006")
   480  	expectString(t, "'\\007'", "\007")
   481  
   482  	expectString(t, "'\\000'", "\000")
   483  	expectString(t, "'\\100'", "\100")
   484  	expectString(t, "'\\200'", "\u0080")
   485  	expectString(t, "'\\300'", "\u00C0")
   486  	expectString(t, "'\\377'", "\u00FF")
   487  	expectString(t, "'\\378'", "\0378")
   488  	expectString(t, "'\\400'", "\0400")
   489  	expectString(t, "'\\500'", "\0500")
   490  	expectString(t, "'\\600'", "\0600")
   491  	expectString(t, "'\\700'", "\0700")
   492  
   493  	expectString(t, "'\\x00'", "\x00")
   494  	expectString(t, "'\\X11'", "X11")
   495  	expectString(t, "'\\x71'", "\x71")
   496  	expectString(t, "'\\x7f'", "\x7f")
   497  	expectString(t, "'\\x7F'", "\x7F")
   498  
   499  	expectString(t, "'\\u0000'", "\u0000")
   500  	expectString(t, "'\\ucafe\\uCAFE\\u7FFF'", "\ucafe\uCAFE\u7FFF")
   501  	expectString(t, "'\\uD800'", "\xED\xA0\x80")
   502  	expectString(t, "'\\uDC00'", "\xED\xB0\x80")
   503  	expectString(t, "'\\U0000'", "U0000")
   504  
   505  	expectString(t, "'\\u{100000}'", "\U00100000")
   506  	expectString(t, "'\\u{10FFFF}'", "\U0010FFFF")
   507  	expectLexerErrorString(t, "'\\u{110000}'", "<stdin>: ERROR: Unicode escape sequence is out of range\n")
   508  	expectLexerErrorString(t, "'\\u{FFFFFFFF}'", "<stdin>: ERROR: Unicode escape sequence is out of range\n")
   509  
   510  	// Line continuation
   511  	expectLexerErrorString(t, "'\n'", "<stdin>: ERROR: Unterminated string literal\n")
   512  	expectLexerErrorString(t, "'\r'", "<stdin>: ERROR: Unterminated string literal\n")
   513  	expectLexerErrorString(t, "\"\n\"", "<stdin>: ERROR: Unterminated string literal\n")
   514  	expectLexerErrorString(t, "\"\r\"", "<stdin>: ERROR: Unterminated string literal\n")
   515  
   516  	expectString(t, "'\u2028'", "\u2028")
   517  	expectString(t, "'\u2029'", "\u2029")
   518  	expectString(t, "\"\u2028\"", "\u2028")
   519  	expectString(t, "\"\u2029\"", "\u2029")
   520  
   521  	expectString(t, "'1\\\r2'", "12")
   522  	expectString(t, "'1\\\n2'", "12")
   523  	expectString(t, "'1\\\r\n2'", "12")
   524  	expectString(t, "'1\\\u20282'", "12")
   525  	expectString(t, "'1\\\u20292'", "12")
   526  	expectLexerErrorString(t, "'1\\\n\r2'", "<stdin>: ERROR: Unterminated string literal\n")
   527  
   528  	expectLexerErrorString(t, "\"'", "<stdin>: ERROR: Unterminated string literal\n")
   529  	expectLexerErrorString(t, "'\"", "<stdin>: ERROR: Unterminated string literal\n")
   530  	expectLexerErrorString(t, "'\\", "<stdin>: ERROR: Unterminated string literal\n")
   531  	expectLexerErrorString(t, "'\\'", "<stdin>: ERROR: Unterminated string literal\n")
   532  
   533  	expectLexerErrorString(t, "'\\x", "<stdin>: ERROR: Unterminated string literal\n")
   534  	expectLexerErrorString(t, "'\\x'", "<stdin>: ERROR: Syntax error \"'\"\n")
   535  	expectLexerErrorString(t, "'\\xG'", "<stdin>: ERROR: Syntax error \"G\"\n")
   536  	expectLexerErrorString(t, "'\\xF'", "<stdin>: ERROR: Syntax error \"'\"\n")
   537  	expectLexerErrorString(t, "'\\xFG'", "<stdin>: ERROR: Syntax error \"G\"\n")
   538  
   539  	expectLexerErrorString(t, "'\\u", "<stdin>: ERROR: Unterminated string literal\n")
   540  	expectLexerErrorString(t, "'\\u'", "<stdin>: ERROR: Syntax error \"'\"\n")
   541  	expectLexerErrorString(t, "'\\u0'", "<stdin>: ERROR: Syntax error \"'\"\n")
   542  	expectLexerErrorString(t, "'\\u00'", "<stdin>: ERROR: Syntax error \"'\"\n")
   543  	expectLexerErrorString(t, "'\\u000'", "<stdin>: ERROR: Syntax error \"'\"\n")
   544  }
   545  
   546  func TestTokens(t *testing.T) {
   547  	expected := []struct {
   548  		contents string
   549  		token    T
   550  	}{
   551  		{"", TEndOfFile},
   552  		{"\x00", TSyntaxError},
   553  
   554  		// "#!/usr/bin/env node"
   555  		{"#!", THashbang},
   556  
   557  		// Punctuation
   558  		{"(", TOpenParen},
   559  		{")", TCloseParen},
   560  		{"[", TOpenBracket},
   561  		{"]", TCloseBracket},
   562  		{"{", TOpenBrace},
   563  		{"}", TCloseBrace},
   564  
   565  		// Reserved words
   566  		{"break", TBreak},
   567  		{"case", TCase},
   568  		{"catch", TCatch},
   569  		{"class", TClass},
   570  		{"const", TConst},
   571  		{"continue", TContinue},
   572  		{"debugger", TDebugger},
   573  		{"default", TDefault},
   574  		{"delete", TDelete},
   575  		{"do", TDo},
   576  		{"else", TElse},
   577  		{"enum", TEnum},
   578  		{"export", TExport},
   579  		{"extends", TExtends},
   580  		{"false", TFalse},
   581  		{"finally", TFinally},
   582  		{"for", TFor},
   583  		{"function", TFunction},
   584  		{"if", TIf},
   585  		{"import", TImport},
   586  		{"in", TIn},
   587  		{"instanceof", TInstanceof},
   588  		{"new", TNew},
   589  		{"null", TNull},
   590  		{"return", TReturn},
   591  		{"super", TSuper},
   592  		{"switch", TSwitch},
   593  		{"this", TThis},
   594  		{"throw", TThrow},
   595  		{"true", TTrue},
   596  		{"try", TTry},
   597  		{"typeof", TTypeof},
   598  		{"var", TVar},
   599  		{"void", TVoid},
   600  		{"while", TWhile},
   601  		{"with", TWith},
   602  	}
   603  
   604  	for _, it := range expected {
   605  		contents := it.contents
   606  		token := it.token
   607  		t.Run(contents, func(t *testing.T) {
   608  			test.AssertEqual(t, lexToken(t, contents), token)
   609  		})
   610  	}
   611  }