JavascriptParserTests.cs 7.0 KB

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