NodeUtils.spec.ts 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. import { IBlockStatementNode } from "../src/interfaces/nodes/IBlockStatementNode";
  2. import { IIdentifierNode } from "../src/interfaces/nodes/IIdentifierNode";
  3. import { ILiteralNode } from "../src/interfaces/nodes/ILiteralNode";
  4. import { IProgramNode } from "../src/interfaces/nodes/IProgramNode";
  5. import { NodeType } from "../src/enums/NodeType";
  6. import { NodeUtils } from '../src/NodeUtils';
  7. import {IFunctionDeclarationNode} from "../src/interfaces/nodes/IFunctionDeclarationNode";
  8. let assert: any = require('chai').assert;
  9. describe('NodeUtils', () => {
  10. describe('addXVerbatimPropertyToLiterals (node: INode): void', () => {
  11. let node: any;
  12. beforeEach(() => {
  13. node = {
  14. type: NodeType.Literal,
  15. value: 'string',
  16. raw: `'string'`
  17. };
  18. NodeUtils.addXVerbatimPropertyToLiterals(node)
  19. });
  20. it('should add `x-verbatim-property` to `Literal` node', () => {
  21. assert.deepEqual(node, {
  22. type: NodeType.Literal,
  23. value: 'string',
  24. raw: `'string'`,
  25. 'x-verbatim-property': `'string'`
  26. });
  27. });
  28. });
  29. describe('appendNode (blockScopeBody: INode[], node: INode): void', () => {
  30. let blockStatementNode: IBlockStatementNode,
  31. identifierNode: IIdentifierNode;
  32. beforeEach(() => {
  33. blockStatementNode = {
  34. type: NodeType.Literal,
  35. body: []
  36. };
  37. identifierNode = {
  38. type: NodeType.Identifier,
  39. name: 'identifier'
  40. };
  41. NodeUtils.appendNode(blockStatementNode.body, identifierNode)
  42. });
  43. it('should append given node to a `BlockStatement` node body', () => {
  44. assert.deepEqual(blockStatementNode, {
  45. type: NodeType.Literal,
  46. body: [identifierNode]
  47. });
  48. });
  49. });
  50. describe('getBlockStatementNodeByIndex (node: INode, index: number = 0): INode', () => {
  51. let blockStatementNode: IBlockStatementNode,
  52. identifierNode: IIdentifierNode,
  53. literalNode: ILiteralNode;
  54. beforeEach(() => {
  55. identifierNode = {
  56. type: NodeType.Identifier,
  57. name: 'identifier'
  58. };
  59. literalNode = {
  60. type: NodeType.Literal,
  61. value: 'string',
  62. raw: `'string'`,
  63. 'x-verbatim-property': `'string'`
  64. };
  65. blockStatementNode = {
  66. type: NodeType.BlockStatement,
  67. body: [
  68. identifierNode,
  69. literalNode
  70. ]
  71. };
  72. });
  73. it('should return block-statement child node of given node if that node has block-statement', () => {
  74. assert.deepEqual(NodeUtils.getBlockStatementNodeByIndex(blockStatementNode), identifierNode);
  75. assert.deepEqual(NodeUtils.getBlockStatementNodeByIndex(blockStatementNode, 1), literalNode);
  76. });
  77. it('should throw a `ReferenceError` if index is out of boundaries', () => {
  78. assert.throws(function () {
  79. return NodeUtils.getBlockStatementNodeByIndex(blockStatementNode, 2);
  80. }, ReferenceError);
  81. });
  82. it('should throw a `TypeError` if node has not block-statement', () => {
  83. assert.throws(function () {
  84. NodeUtils.getBlockStatementNodeByIndex(identifierNode, 1)
  85. }, TypeError);
  86. });
  87. });
  88. describe('getBlockScopeOfNode (node: INode, depth: number = 0): TNodeWithBlockStatement', () => {
  89. let blockStatementNode: IBlockStatementNode,
  90. identifierNode: IIdentifierNode,
  91. functionDeclarationNode: IFunctionDeclarationNode,
  92. literalNode: ILiteralNode,
  93. programNode: IProgramNode;
  94. beforeEach(() => {
  95. identifierNode = {
  96. type: NodeType.Identifier,
  97. name: 'identifier',
  98. };
  99. literalNode = {
  100. type: NodeType.Literal,
  101. value: 'string',
  102. raw: `'string'`,
  103. 'x-verbatim-property': `'string'`
  104. };
  105. blockStatementNode = {
  106. type: NodeType.BlockStatement,
  107. body: [
  108. identifierNode,
  109. literalNode
  110. ]
  111. };
  112. functionDeclarationNode = {
  113. type: NodeType.FunctionDeclaration,
  114. id: {
  115. type: NodeType.Identifier,
  116. name: 'test'
  117. },
  118. params: [],
  119. body: blockStatementNode,
  120. generator: false,
  121. expression: false
  122. };
  123. programNode = {
  124. type: NodeType.Program,
  125. body: [functionDeclarationNode]
  126. };
  127. programNode['parentNode'] = programNode;
  128. functionDeclarationNode['parentNode'] = programNode;
  129. blockStatementNode['parentNode'] = functionDeclarationNode;
  130. identifierNode['parentNode'] = blockStatementNode;
  131. literalNode['parentNode'] = blockStatementNode;
  132. });
  133. it('should return block-scope node for given node', () => {
  134. assert.deepEqual(NodeUtils.getBlockScopeOfNode(identifierNode), blockStatementNode);
  135. assert.deepEqual(NodeUtils.getBlockScopeOfNode(identifierNode, 1), programNode);
  136. assert.deepEqual(NodeUtils.getBlockScopeOfNode(functionDeclarationNode), programNode);
  137. assert.deepEqual(NodeUtils.getBlockScopeOfNode(programNode), programNode);
  138. });
  139. });
  140. describe('insertNodeAtIndex (blockScopeBody: INode[], node: INode, index: number): void', () => {
  141. let blockStatementNode: IBlockStatementNode,
  142. expectedBlockStatementNode: IBlockStatementNode,
  143. identifierNode: IIdentifierNode,
  144. literalNode: ILiteralNode;
  145. beforeEach(() => {
  146. identifierNode = {
  147. type: NodeType.Identifier,
  148. name: 'identifier'
  149. };
  150. literalNode = {
  151. type: NodeType.Literal,
  152. value: 'string',
  153. raw: `'string'`,
  154. 'x-verbatim-property': `'string'`
  155. };
  156. blockStatementNode = {
  157. type: NodeType.BlockStatement,
  158. body: [
  159. identifierNode
  160. ]
  161. };
  162. expectedBlockStatementNode = Object.assign({}, blockStatementNode);
  163. expectedBlockStatementNode['body'].push(literalNode);
  164. NodeUtils.insertNodeAtIndex(blockStatementNode.body, literalNode, 1);
  165. });
  166. it('should insert given node in block-scope body at index', () => {
  167. assert.deepEqual(blockStatementNode, expectedBlockStatementNode);
  168. });
  169. });
  170. describe('parentize (node: INode): void', () => {
  171. let blockStatementNode: IBlockStatementNode,
  172. identifierNode: IIdentifierNode,
  173. literalNode: ILiteralNode,
  174. programNode: IProgramNode;
  175. beforeEach(() => {
  176. identifierNode = {
  177. type: NodeType.Identifier,
  178. name: 'identifier'
  179. };
  180. literalNode = {
  181. type: NodeType.Literal,
  182. value: 'string',
  183. raw: `'string'`,
  184. 'x-verbatim-property': `'string'`
  185. };
  186. blockStatementNode = {
  187. type: NodeType.BlockStatement,
  188. body: [
  189. identifierNode,
  190. literalNode
  191. ]
  192. };
  193. programNode = {
  194. type: NodeType.Program,
  195. body: [blockStatementNode]
  196. };
  197. NodeUtils.parentize(blockStatementNode);
  198. });
  199. it('should parentize given AST-tree', () => {
  200. assert.deepEqual(blockStatementNode['parentNode'], programNode);
  201. assert.deepEqual(identifierNode['parentNode'], blockStatementNode);
  202. assert.deepEqual(literalNode['parentNode'], blockStatementNode);
  203. });
  204. });
  205. describe('prependNode (blockScopeBody: INode[], node: INode): void', () => {
  206. let blockStatementNode: IBlockStatementNode,
  207. expectedBlockStatementNode: IBlockStatementNode,
  208. identifierNode: IIdentifierNode,
  209. literalNode: ILiteralNode;
  210. beforeEach(() => {
  211. identifierNode = {
  212. type: NodeType.Identifier,
  213. name: 'identifier'
  214. };
  215. literalNode = {
  216. type: NodeType.Literal,
  217. value: 'string',
  218. raw: `'string'`,
  219. 'x-verbatim-property': `'string'`
  220. };
  221. blockStatementNode = {
  222. type: NodeType.Literal,
  223. body: [identifierNode]
  224. };
  225. expectedBlockStatementNode = Object.assign({}, blockStatementNode);
  226. expectedBlockStatementNode['body'].unshift(literalNode);
  227. NodeUtils.prependNode(blockStatementNode.body, literalNode)
  228. });
  229. it('should prepend given node to a `BlockStatement` node body', () => {
  230. assert.deepEqual(blockStatementNode, expectedBlockStatementNode);
  231. });
  232. });
  233. });