ErrorTests.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. using Esprima;
  2. using Jint.Runtime;
  3. using System;
  4. using System.Collections.Generic;
  5. using Xunit;
  6. namespace Jint.Tests.Runtime
  7. {
  8. public class ErrorTests
  9. {
  10. [Fact]
  11. public void CanReturnCorrectErrorMessageAndLocation1()
  12. {
  13. var script = @"
  14. var a = {};
  15. var b = a.user.name;
  16. ";
  17. var engine = new Engine();
  18. var e = Assert.Throws<JavaScriptException>(() => engine.Execute(script));
  19. Assert.Equal("Cannot read property 'name' of undefined", e.Message);
  20. Assert.Equal(4, e.Location.Start.Line);
  21. Assert.Equal(8, e.Location.Start.Column);
  22. }
  23. [Fact]
  24. public void CanReturnCorrectErrorMessageAndLocation1WithoutReferencedName()
  25. {
  26. var script = @"
  27. var c = a(b().Length);
  28. ";
  29. var engine = new Engine();
  30. engine.SetValue("a", new Action<string>((a) =>
  31. {
  32. }));
  33. engine.SetValue("b", new Func<string>(() =>
  34. {
  35. return null;
  36. }));
  37. var e = Assert.Throws<JavaScriptException>(() => engine.Execute(script));
  38. Assert.Equal("Cannot read property 'Length' of null", e.Message);
  39. Assert.Equal(2, e.Location.Start.Line);
  40. Assert.Equal(10, e.Location.Start.Column);
  41. }
  42. [Fact]
  43. public void CanReturnCorrectErrorMessageAndLocation2()
  44. {
  45. var script = @"
  46. test();
  47. ";
  48. var engine = new Engine();
  49. var e = Assert.Throws<JavaScriptException>(() => engine.Execute(script));
  50. Assert.Equal("test is not defined", e.Message);
  51. Assert.Equal(2, e.Location.Start.Line);
  52. Assert.Equal(1, e.Location.Start.Column);
  53. }
  54. [Fact]
  55. public void CanProduceCorrectStackTrace()
  56. {
  57. var engine = new Engine(options => options.LimitRecursion(1000));
  58. engine.Execute(@"var a = function(v) {
  59. return v.xxx.yyy;
  60. }
  61. var b = function(v) {
  62. return a(v);
  63. }", new ParserOptions("custom.js") { Loc = true });
  64. var e = Assert.Throws<JavaScriptException>(() => engine.Execute("var x = b(7);", new ParserOptions("main.js") { Loc = true } ));
  65. Assert.Equal("Cannot read property 'yyy' of undefined", e.Message);
  66. Assert.Equal(2, e.Location.Start.Line);
  67. Assert.Equal(8, e.Location.Start.Column);
  68. Assert.Equal("custom.js", e.Location.Source);
  69. var stack = e.CallStack;
  70. Assert.Equal(@" at a(v) @ custom.js 8:6
  71. at b(7) @ main.js 8:1
  72. ".Replace("\r\n", "\n"), stack.Replace("\r\n", "\n"));
  73. }
  74. private class Folder
  75. {
  76. public Folder Parent { get; set; }
  77. public string Name { get; set; }
  78. }
  79. [Fact]
  80. public void CallStackBuildingShouldSkipResolvingFromEngine()
  81. {
  82. var engine = new Engine(o => o.LimitRecursion(200));
  83. var recordedFolderTraversalOrder = new List<string>();
  84. engine.SetValue("log", new Action<object>(o => recordedFolderTraversalOrder.Add(o.ToString())));
  85. var folder = new Folder
  86. {
  87. Name = "SubFolder2",
  88. Parent = new Folder
  89. {
  90. Name = "SubFolder1",
  91. Parent = new Folder
  92. {
  93. Name = "Root", Parent = null,
  94. }
  95. }
  96. };
  97. engine.SetValue("folder", folder);
  98. var javaScriptException = Assert.Throws<JavaScriptException>(() =>
  99. engine.Execute(@"
  100. var Test = {
  101. recursive: function(folderInstance) {
  102. // Enabling the guard here corrects the problem, but hides the hard fault
  103. // if (folderInstance==null) return null;
  104. log(folderInstance.Name);
  105. if (folderInstance==null) return null;
  106. return this.recursive(folderInstance.parent);
  107. }
  108. }
  109. Test.recursive(folder);"
  110. ));
  111. Assert.Equal("Cannot read property 'Name' of null", javaScriptException.Message);
  112. Assert.Equal(@" at recursive(folderInstance.parent) @ 31:8
  113. at recursive(folderInstance.parent) @ 31:8
  114. at recursive(folderInstance.parent) @ 31:8
  115. at recursive(folder) @ 16:12
  116. ", javaScriptException.CallStack);
  117. var expected = new List<string>
  118. {
  119. "SubFolder2", "SubFolder1", "Root"
  120. };
  121. Assert.Equal(expected, recordedFolderTraversalOrder);
  122. }
  123. }
  124. }