NodeAppender.spec.ts 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. import * as chai from 'chai';
  2. import * as ESTree from 'estree';
  3. import { TStatement } from '../../../src/types/TStatement';
  4. import { IStackTraceAnalyzer } from '../../../src/interfaces/stack-trace-analyzer/IStackTraceAnalyzer';
  5. import { IStackTraceData } from '../../../src/interfaces/stack-trace-analyzer/IStackTraceData';
  6. import { readFileAsString } from '../../helpers/readFileAsString';
  7. import { NodeAppender } from '../../../src/node/NodeAppender';
  8. import { NodeMocks } from '../../mocks/NodeMocks';
  9. import { NodeUtils } from '../../../src/node/NodeUtils';
  10. import { StackTraceAnalyzer } from '../../../src/stack-trace-analyzer/StackTraceAnalyzer';
  11. const assert: any = chai.assert;
  12. describe('NodeAppender', () => {
  13. describe('appendNode (blockScopeNode: TNodeWithBlockStatement[], nodeBodyStatements: TStatement[]): void', () => {
  14. let astTree: ESTree.Program,
  15. expectedAstTree: ESTree.Program,
  16. node: TStatement[];
  17. beforeEach(() => {
  18. node = NodeUtils.convertCodeToStructure(`
  19. var test = 1;
  20. `);
  21. astTree = NodeMocks.getProgramNode(
  22. NodeUtils.convertCodeToStructure(
  23. readFileAsString('./test/fixtures/node-appender/append-node.js')
  24. )
  25. );
  26. expectedAstTree = NodeMocks.getProgramNode(
  27. NodeUtils.convertCodeToStructure(
  28. readFileAsString('./test/fixtures/node-appender/append-node-expected.js')
  29. )
  30. );
  31. NodeUtils.parentize(astTree);
  32. NodeUtils.parentize(expectedAstTree);
  33. NodeAppender.appendNode(astTree, node);
  34. });
  35. it('should append given node to a `BlockStatement` node body', () => {
  36. assert.deepEqual(astTree, expectedAstTree);
  37. });
  38. });
  39. describe('appendNodeToOptimalBlockScope (blockScopeStackTraceData: IStackTraceData[], blockScopeNode: TNodeWithBlockStatement, nodeBodyStatements: TStatement[], index: number = 0): void', () => {
  40. const stackTraceAnalyzer: IStackTraceAnalyzer = new StackTraceAnalyzer();
  41. let astTree: ESTree.Program,
  42. expectedAstTree: ESTree.Program,
  43. node: TStatement[],
  44. stackTraceData: IStackTraceData[];
  45. beforeEach(() => {
  46. node = NodeUtils.convertCodeToStructure(`
  47. var test = 1;
  48. `);
  49. });
  50. it('should append node into first and deepest function call in calls trace - variant #1', () => {
  51. astTree = NodeMocks.getProgramNode(
  52. NodeUtils.convertCodeToStructure(
  53. readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/variant-1.js')
  54. )
  55. );
  56. expectedAstTree = NodeMocks.getProgramNode(
  57. NodeUtils.convertCodeToStructure(
  58. readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/variant-1-expected.js')
  59. )
  60. );
  61. stackTraceData = stackTraceAnalyzer.analyze(astTree.body);
  62. NodeAppender.appendNodeToOptimalBlockScope(stackTraceData, astTree, node);
  63. assert.deepEqual(astTree, expectedAstTree);
  64. });
  65. it('should append node into first and deepest function call in calls trace - variant #2', () => {
  66. astTree = NodeMocks.getProgramNode(
  67. NodeUtils.convertCodeToStructure(
  68. readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/variant-2.js')
  69. )
  70. );
  71. expectedAstTree = NodeMocks.getProgramNode(
  72. NodeUtils.convertCodeToStructure(
  73. readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/variant-2-expected.js')
  74. )
  75. );
  76. stackTraceData = stackTraceAnalyzer.analyze(astTree.body);
  77. NodeAppender.appendNodeToOptimalBlockScope(stackTraceData, astTree, node);
  78. assert.deepEqual(astTree, expectedAstTree);
  79. });
  80. describe('append by specific index', () => {
  81. let astTree: ESTree.Program;
  82. beforeEach(() => {
  83. astTree = NodeMocks.getProgramNode(
  84. NodeUtils.convertCodeToStructure(
  85. readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/by-index.js')
  86. )
  87. );
  88. });
  89. it('should append node into deepest function call by specified index in calls trace - variant #1', () => {
  90. expectedAstTree = NodeMocks.getProgramNode(
  91. NodeUtils.convertCodeToStructure(
  92. readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/by-index-variant-1-expected.js')
  93. )
  94. );
  95. stackTraceData = stackTraceAnalyzer.analyze(astTree.body);
  96. NodeAppender.appendNodeToOptimalBlockScope(stackTraceData, astTree, node, 2);
  97. assert.deepEqual(astTree, expectedAstTree);
  98. });
  99. it('should append node into deepest function call by specified index in calls trace - variant #2', () => {
  100. expectedAstTree = NodeMocks.getProgramNode(
  101. NodeUtils.convertCodeToStructure(
  102. readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/by-index-variant-2-expected.js')
  103. )
  104. );
  105. stackTraceData = stackTraceAnalyzer.analyze(astTree.body);
  106. NodeAppender.appendNodeToOptimalBlockScope(stackTraceData, astTree, node, 1);
  107. assert.deepEqual(astTree, expectedAstTree);
  108. });
  109. it('should append node into deepest function call by specified index in calls trace - variant #3', () => {
  110. astTree = NodeMocks.getProgramNode(
  111. NodeUtils.convertCodeToStructure(
  112. readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/by-index-variant-3.js')
  113. )
  114. );
  115. expectedAstTree = NodeMocks.getProgramNode(
  116. NodeUtils.convertCodeToStructure(
  117. readFileAsString('./test/fixtures/node-appender/append-node-to-optimal-block-scope/by-index-variant-3-expected.js')
  118. )
  119. );
  120. stackTraceData = stackTraceAnalyzer.analyze(astTree.body);
  121. NodeAppender.appendNodeToOptimalBlockScope(
  122. stackTraceData,
  123. astTree,
  124. node,
  125. NodeAppender.getRandomStackTraceIndex(stackTraceData.length)
  126. );
  127. assert.deepEqual(astTree, expectedAstTree);
  128. });
  129. });
  130. });
  131. describe('getRandomStackTraceIndex (stackTraceRootLength: number): number', () => {
  132. it('should returns random index between 0 and stack trace data root length', () => {
  133. let index: number;
  134. for (let i: number = 0; i < 100; i++) {
  135. index = NodeAppender.getRandomStackTraceIndex(100);
  136. assert.isAtLeast(index, 0);
  137. assert.isAtMost(index, 100);
  138. }
  139. });
  140. });
  141. describe('insertNodeAtIndex (blockScopeNode: TNodeWithBlockStatement[], nodeBodyStatements: TStatement[], index: number): void', () => {
  142. let astTree: ESTree.Program,
  143. expectedAstTree: ESTree.Program,
  144. node: TStatement[];
  145. beforeEach(() => {
  146. node = NodeUtils.convertCodeToStructure(`
  147. var test = 1;
  148. `);
  149. astTree = NodeMocks.getProgramNode(
  150. NodeUtils.convertCodeToStructure(
  151. readFileAsString('./test/fixtures/node-appender/insert-node-at-index.js')
  152. )
  153. );
  154. expectedAstTree = NodeMocks.getProgramNode(
  155. NodeUtils.convertCodeToStructure(
  156. readFileAsString('./test/fixtures/node-appender/insert-node-at-index-expected.js')
  157. )
  158. );
  159. NodeUtils.parentize(astTree);
  160. NodeUtils.parentize(expectedAstTree);
  161. NodeAppender.insertNodeAtIndex(astTree, node, 2);
  162. });
  163. it('should insert given node in `BlockStatement` node body at index', () => {
  164. assert.deepEqual(astTree, expectedAstTree);
  165. });
  166. });
  167. describe('prependNode (blockScopeNode: TNodeWithBlockStatement[], nodeBodyStatements: TStatement[]): void', () => {
  168. let astTree: ESTree.Program,
  169. expectedAstTree: ESTree.Program,
  170. node: TStatement[];
  171. beforeEach(() => {
  172. node = NodeUtils.convertCodeToStructure(`
  173. var test = 1;
  174. `);
  175. astTree = NodeMocks.getProgramNode(
  176. NodeUtils.convertCodeToStructure(
  177. readFileAsString('./test/fixtures/node-appender/prepend-node.js')
  178. )
  179. );
  180. expectedAstTree = NodeMocks.getProgramNode(
  181. NodeUtils.convertCodeToStructure(
  182. readFileAsString('./test/fixtures/node-appender/prepend-node-expected.js')
  183. )
  184. );
  185. NodeUtils.parentize(astTree);
  186. NodeUtils.parentize(expectedAstTree);
  187. NodeAppender.prependNode(astTree, node);
  188. });
  189. it('should prepend given node to a `BlockStatement` node body', () => {
  190. assert.deepEqual(astTree, expectedAstTree);
  191. });
  192. });
  193. });