JavascriptParserTests.cs 7.2 KB

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