JavascriptParserTests.cs 6.6 KB

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