CallStackTests.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. using Jint.Runtime.Debugger;
  2. using Xunit;
  3. namespace Jint.Tests.Runtime.Debugger
  4. {
  5. public class CallStackTests
  6. {
  7. [Fact]
  8. public void NamesRegularFunction()
  9. {
  10. var engine = new Engine(options => options
  11. .DebugMode()
  12. .DebuggerStatementHandling(DebuggerStatementHandling.Script));
  13. bool didBreak = false;
  14. engine.Break += (sender, info) =>
  15. {
  16. didBreak = true;
  17. Assert.Equal("regularFunction", info.CallStack.Peek());
  18. return StepMode.None;
  19. };
  20. engine.Execute(
  21. @"function regularFunction() { debugger; }
  22. regularFunction()");
  23. Assert.True(didBreak);
  24. }
  25. [Fact]
  26. public void NamesFunctionExpression()
  27. {
  28. var engine = new Engine(options => options
  29. .DebugMode()
  30. .DebuggerStatementHandling(DebuggerStatementHandling.Script));
  31. bool didBreak = false;
  32. engine.Break += (sender, info) =>
  33. {
  34. didBreak = true;
  35. Assert.Equal("functionExpression", info.CallStack.Peek());
  36. return StepMode.None;
  37. };
  38. engine.Execute(
  39. @"const functionExpression = function() { debugger; }
  40. functionExpression()");
  41. Assert.True(didBreak);
  42. }
  43. [Fact]
  44. public void NamesNamedFunctionExpression()
  45. {
  46. var engine = new Engine(options => options
  47. .DebugMode()
  48. .DebuggerStatementHandling(DebuggerStatementHandling.Script));
  49. bool didBreak = false;
  50. engine.Break += (sender, info) =>
  51. {
  52. didBreak = true;
  53. Assert.Equal("namedFunction", info.CallStack.Peek());
  54. return StepMode.None;
  55. };
  56. engine.Execute(
  57. @"const functionExpression = function namedFunction() { debugger; }
  58. functionExpression()");
  59. Assert.True(didBreak);
  60. }
  61. [Fact]
  62. public void NamesArrowFunction()
  63. {
  64. var engine = new Engine(options => options
  65. .DebugMode()
  66. .DebuggerStatementHandling(DebuggerStatementHandling.Script));
  67. bool didBreak = false;
  68. engine.Break += (sender, info) =>
  69. {
  70. didBreak = true;
  71. Assert.Equal("arrowFunction", info.CallStack.Peek());
  72. return StepMode.None;
  73. };
  74. engine.Execute(
  75. @"const arrowFunction = () => { debugger; }
  76. arrowFunction()");
  77. Assert.True(didBreak);
  78. }
  79. [Fact]
  80. public void NamesNewFunction()
  81. {
  82. var engine = new Engine(options => options
  83. .DebugMode()
  84. .DebuggerStatementHandling(DebuggerStatementHandling.Script));
  85. bool didBreak = false;
  86. engine.Break += (sender, info) =>
  87. {
  88. didBreak = true;
  89. // Ideally, this should be "(anonymous)", but FunctionConstructor sets the "anonymous" name.
  90. Assert.Equal("anonymous", info.CallStack.Peek());
  91. return StepMode.None;
  92. };
  93. engine.Execute(
  94. @"const newFunction = new Function('debugger;');
  95. newFunction()");
  96. Assert.True(didBreak);
  97. }
  98. [Fact]
  99. public void NamesMemberFunction()
  100. {
  101. var engine = new Engine(options => options
  102. .DebugMode()
  103. .DebuggerStatementHandling(DebuggerStatementHandling.Script));
  104. bool didBreak = false;
  105. engine.Break += (sender, info) =>
  106. {
  107. didBreak = true;
  108. Assert.Equal("memberFunction", info.CallStack.Peek());
  109. return StepMode.None;
  110. };
  111. engine.Execute(
  112. @"const obj = { memberFunction() { debugger; } };
  113. obj.memberFunction()");
  114. Assert.True(didBreak);
  115. }
  116. [Fact]
  117. public void NamesAnonymousFunction()
  118. {
  119. var engine = new Engine(options => options
  120. .DebugMode()
  121. .DebuggerStatementHandling(DebuggerStatementHandling.Script));
  122. bool didBreak = false;
  123. engine.Break += (sender, info) =>
  124. {
  125. didBreak = true;
  126. Assert.Equal("(anonymous)", info.CallStack.Peek());
  127. return StepMode.None;
  128. };
  129. engine.Execute(
  130. @"(function()
  131. {
  132. debugger;
  133. }());");
  134. Assert.True(didBreak);
  135. }
  136. [Fact(Skip = "Debugger has no accessor awareness yet")]
  137. public void NamesGetAccessor()
  138. {
  139. var engine = new Engine(options => options
  140. .DebugMode()
  141. .DebuggerStatementHandling(DebuggerStatementHandling.Script));
  142. bool didBreak = false;
  143. engine.Break += (sender, info) =>
  144. {
  145. didBreak = true;
  146. Assert.Equal("get accessor", info.CallStack.Peek());
  147. return StepMode.None;
  148. };
  149. engine.Execute(
  150. @"
  151. const obj = {
  152. get accessor()
  153. {
  154. debugger;
  155. return 'test';
  156. }
  157. };
  158. const x = obj.accessor;");
  159. Assert.True(didBreak);
  160. }
  161. [Fact(Skip = "Debugger has no accessor awareness yet")]
  162. public void NamesSetAccessor()
  163. {
  164. var engine = new Engine(options => options
  165. .DebugMode()
  166. .DebuggerStatementHandling(DebuggerStatementHandling.Script));
  167. bool didBreak = false;
  168. engine.Break += (sender, info) =>
  169. {
  170. didBreak = true;
  171. Assert.Equal("set accessor", info.CallStack.Peek());
  172. return StepMode.None;
  173. };
  174. engine.Execute(
  175. @"
  176. const obj = {
  177. set accessor(value)
  178. {
  179. debugger;
  180. this.value = value;
  181. }
  182. };
  183. obj.accessor = 42;");
  184. Assert.True(didBreak);
  185. }
  186. }
  187. }