JavascriptParserTests.cs 6.7 KB

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