NodeAppender.spec.ts 9.9 KB

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