NodeAppender.spec.ts 9.9 KB

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