EngineTests.ScriptPreparation.cs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. using System.Text.RegularExpressions;
  2. using Esprima.Ast;
  3. using Jint.Native;
  4. using Jint.Runtime.Interpreter;
  5. using Jint.Runtime.Interpreter.Expressions;
  6. using Jint.Runtime.Interpreter.Statements;
  7. namespace Jint.Tests.Runtime;
  8. public partial class EngineTests
  9. {
  10. [Fact]
  11. public void ScriptPreparationAcceptsReturnOutsideOfFunctions()
  12. {
  13. var preparedScript = Engine.PrepareScript("return 1;");
  14. Assert.IsType<ReturnStatement>(preparedScript.Body[0]);
  15. }
  16. [Fact]
  17. public void CanPreCompileRegex()
  18. {
  19. var script = Engine.PrepareScript("var x = /[cgt]/ig; var y = /[cgt]/ig; 'g'.match(x).length;");
  20. var declaration = Assert.IsType<VariableDeclaration>(script.Body[0]);
  21. var init = Assert.IsType<RegExpLiteral>(declaration.Declarations[0].Init);
  22. var regex = Assert.IsType<Regex>(init.AssociatedData);
  23. Assert.Equal("[cgt]", regex.ToString());
  24. Assert.Equal(RegexOptions.Compiled, regex.Options & RegexOptions.Compiled);
  25. Assert.Equal(1, _engine.Evaluate(script));
  26. }
  27. [Fact]
  28. public void ScriptPreparationFoldsConstants()
  29. {
  30. var preparedScript = Engine.PrepareScript("return 1 + 2;");
  31. var returnStatement = Assert.IsType<ReturnStatement>(preparedScript.Body[0]);
  32. var constant = Assert.IsType<JintConstantExpression>(returnStatement.Argument?.AssociatedData);
  33. Assert.Equal(3, constant.GetValue(null!));
  34. Assert.Equal(3, _engine.Evaluate(preparedScript));
  35. }
  36. [Fact]
  37. public void ScriptPreparationOptimizesNegatingUnaryExpression()
  38. {
  39. var preparedScript = Engine.PrepareScript("-1");
  40. var expression = Assert.IsType<ExpressionStatement>(preparedScript.Body[0]);
  41. var unaryExpression = Assert.IsType<UnaryExpression>(expression.Expression);
  42. var constant = Assert.IsType<JintConstantExpression>(unaryExpression.AssociatedData);
  43. Assert.Equal(-1, constant.GetValue(null!));
  44. Assert.Equal(-1, _engine.Evaluate(preparedScript));
  45. }
  46. [Fact]
  47. public void ScriptPreparationOptimizesConstantReturn()
  48. {
  49. var preparedScript = Engine.PrepareScript("return false;");
  50. var statement = Assert.IsType<ReturnStatement>(preparedScript.Body[0]);
  51. var returnStatement = Assert.IsType<ConstantStatement>(statement.AssociatedData);
  52. var builtStatement = JintStatement.Build(statement);
  53. Assert.Same(returnStatement, builtStatement);
  54. var result = builtStatement.Execute(new EvaluationContext(_engine)).Value;
  55. Assert.Equal(JsBoolean.False, result);
  56. }
  57. [Fact]
  58. public void CompiledRegexShouldProduceSameResultAsNonCompiled()
  59. {
  60. const string Script = """JSON.stringify(/(.*?)a(?!(a+)b\2c)\2(.*)/.exec("baaabaac"))""";
  61. var nonCompiled = _engine.Evaluate(Script);
  62. var compiled = _engine.Evaluate(Engine.PrepareScript(Script));
  63. Assert.Equal(nonCompiled, compiled);
  64. }
  65. }