JavascriptParserTests.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. using Jint.Runtime;
  2. namespace Jint.Tests.Parsing;
  3. public class JavascriptParserTests
  4. {
  5. [Fact]
  6. public void ShouldParseThis()
  7. {
  8. var program = new Parser().ParseScript("this");
  9. var body = program.Body;
  10. Assert.Single(body);
  11. Assert.Equal(NodeType.ThisExpression, body.First().As<ExpressionStatement>().Expression.Type);
  12. }
  13. [Fact]
  14. public void ShouldParseNull()
  15. {
  16. var program = new Parser().ParseScript("null");
  17. var body = program.Body;
  18. Assert.Single(body);
  19. Assert.Equal(NodeType.Literal, body.First().As<ExpressionStatement>().Expression.Type);
  20. Assert.Equal(null, body.First().As<ExpressionStatement>().Expression.As<Literal>().Value);
  21. Assert.Equal("null", body.First().As<ExpressionStatement>().Expression.As<Literal>().Raw);
  22. }
  23. [Fact]
  24. public void ShouldParseNumeric()
  25. {
  26. var code = @"
  27. 42
  28. ";
  29. var program = new Parser().ParseScript(code);
  30. var body = program.Body;
  31. Assert.Single(body);
  32. Assert.Equal(NodeType.Literal, body.First().As<ExpressionStatement>().Expression.Type);
  33. Assert.Equal(42d, body.First().As<ExpressionStatement>().Expression.As<Literal>().Value);
  34. Assert.Equal("42", body.First().As<ExpressionStatement>().Expression.As<Literal>().Raw);
  35. }
  36. [Fact]
  37. public void ShouldParseBinaryExpression()
  38. {
  39. BinaryExpression binary;
  40. var program = new Parser().ParseScript("(1 + 2 ) * 3");
  41. var body = program.Body;
  42. Assert.Single(body);
  43. Assert.NotNull(binary = body.First().As<ExpressionStatement>().Expression.As<BinaryExpression>());
  44. Assert.Equal(3d, binary.Right.As<Literal>().Value);
  45. Assert.Equal(Operator.Multiplication, binary.Operator);
  46. Assert.Equal(1d, binary.Left.As<BinaryExpression>().Left.As<Literal>().Value);
  47. Assert.Equal(2d, binary.Left.As<BinaryExpression>().Right.As<Literal>().Value);
  48. Assert.Equal(Operator.Addition, binary.Left.As<BinaryExpression>().Operator);
  49. }
  50. [Theory]
  51. [InlineData(0, "0")]
  52. [InlineData(42, "42")]
  53. [InlineData(0.14, "0.14")]
  54. [InlineData(3.14159, "3.14159")]
  55. [InlineData(6.02214179e+23, "6.02214179e+23")]
  56. [InlineData(1.492417830e-10, "1.492417830e-10")]
  57. [InlineData(0, "0x0")]
  58. [InlineData(0, "0x0;")]
  59. [InlineData(0xabc, "0xabc")]
  60. [InlineData(0xdef, "0xdef")]
  61. [InlineData(0X1A, "0X1A")]
  62. [InlineData(0x10, "0x10")]
  63. [InlineData(0x100, "0x100")]
  64. [InlineData(0X04, "0X04")]
  65. [InlineData(02, "02")]
  66. [InlineData(10, "012")]
  67. [InlineData(10, "0012")]
  68. [InlineData(1.189008226412092e+38, "0x5973772948c653ac1971f1576e03c4d4")]
  69. [InlineData(18446744073709552000d, "0xffffffffffffffff")]
  70. public void ShouldParseNumericLiterals(object expected, string code)
  71. {
  72. Literal literal;
  73. var program = new Parser().ParseScript(code);
  74. var body = program.Body;
  75. Assert.Single(body);
  76. Assert.NotNull(literal = body.First().As<ExpressionStatement>().Expression.As<Literal>());
  77. Assert.Equal(Convert.ToDouble(expected), Convert.ToDouble(literal.Value));
  78. }
  79. [Theory]
  80. [InlineData("Hello", @"'Hello'")]
  81. [InlineData("\n\r\t\v\b\f\\\'\"\0", @"'\n\r\t\v\b\f\\\'\""\0'")]
  82. [InlineData("\u0061", @"'\u0061'")]
  83. [InlineData("\x61", @"'\x61'")]
  84. [InlineData("Hello\nworld", @"'Hello\nworld'")]
  85. [InlineData("Hello\\\nworld", @"'Hello\\\nworld'")]
  86. public void ShouldParseStringLiterals(string expected, string code)
  87. {
  88. Literal literal;
  89. var program = new Parser().ParseScript(code);
  90. var body = program.Body;
  91. Assert.Single(body);
  92. Assert.NotNull(literal = body.First().As<ExpressionStatement>().Expression.As<Literal>());
  93. Assert.Equal(expected, literal.Value);
  94. }
  95. [Theory]
  96. [InlineData(@"{ x
  97. ++y }")]
  98. [InlineData(@"{ x
  99. --y }")]
  100. [InlineData(@"var x /* comment */;
  101. { var x = 14, y = 3
  102. z; }")]
  103. [InlineData(@"while (true) { continue
  104. there; }")]
  105. [InlineData(@"while (true) { continue // Comment
  106. there; }")]
  107. [InlineData(@"while (true) { continue /* Multiline
  108. Comment */there; }")]
  109. [InlineData(@"while (true) { break
  110. there; }")]
  111. [InlineData(@"while (true) { break // Comment
  112. there; }")]
  113. [InlineData(@"while (true) { break /* Multiline
  114. Comment */there; }")]
  115. [InlineData(@"(function(){ return
  116. x; })")]
  117. [InlineData(@"(function(){ return // Comment
  118. x; })")]
  119. [InlineData(@"(function(){ return/* Multiline
  120. Comment */x; })")]
  121. [InlineData(@"{ throw error
  122. error; }")]
  123. [InlineData(@"{ throw error// Comment
  124. error; }")]
  125. [InlineData(@"{ throw error/* Multiline
  126. Comment */error; }")]
  127. public void ShouldInsertSemicolons(string code)
  128. {
  129. new Parser().ParseScript(code);
  130. }
  131. [Fact]
  132. public void ShouldProvideLocationForMultiLinesStringLiterals()
  133. {
  134. const string Code = @"'\
  135. \
  136. '
  137. ";
  138. var program = new Parser().ParseScript(Code);
  139. var expr = program.Body.First().As<ExpressionStatement>().Expression;
  140. Assert.Equal(1, expr.Location.Start.Line);
  141. Assert.Equal(0, expr.Location.Start.Column);
  142. Assert.Equal(3, expr.Location.End.Line);
  143. Assert.Equal(1, expr.Location.End.Column);
  144. }
  145. [Fact]
  146. public void ShouldThrowErrorForInvalidLeftHandOperation()
  147. {
  148. var ex = Assert.Throws<JavaScriptException>(() => new Engine().Execute("~ (WE0=1)--- l('1');"));
  149. Assert.Equal("Invalid left-hand side expression in postfix operation (<anonymous>:1:4)", ex.Message);
  150. }
  151. [Theory]
  152. [InlineData("....")]
  153. [InlineData("while")]
  154. [InlineData("var")]
  155. [InlineData("-.-")]
  156. public void ShouldThrowParseErrorExceptionForInvalidCode(string code)
  157. {
  158. Assert.Throws<SyntaxErrorException>(() => new Parser().ParseScript(code));
  159. }
  160. }