StringArrayStorageAnalyzer.spec.ts 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. import 'reflect-metadata';
  2. import { assert } from 'chai';
  3. import * as ESTree from 'estree';
  4. import { ServiceIdentifiers } from '../../../../src/container/ServiceIdentifiers';
  5. import { TInputOptions } from '../../../../src/types/options/TInputOptions';
  6. import { IInversifyContainerFacade } from '../../../../src/interfaces/container/IInversifyContainerFacade';
  7. import { IStringArrayStorageAnalyzer } from '../../../../src/interfaces/analyzers/string-array-storage-analyzer/IStringArrayStorageAnalyzer';
  8. import { IStringArrayStorageItemData } from '../../../../src/interfaces/storages/string-array-storage/IStringArrayStorageItem';
  9. import { InversifyContainerFacade } from '../../../../src/container/InversifyContainerFacade';
  10. import { NodeFactory } from '../../../../src/node/NodeFactory';
  11. import { NodeMetadata } from '../../../../src/node/NodeMetadata';
  12. const getStringArrayStorageAnalyzer = (options: TInputOptions): IStringArrayStorageAnalyzer => {
  13. const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
  14. inversifyContainerFacade.load('', '', options);
  15. return inversifyContainerFacade.get<IStringArrayStorageAnalyzer>(ServiceIdentifiers.IStringArrayStorageAnalyzer);
  16. };
  17. describe('StringArrayStorageAnalyzer', () => {
  18. let stringArrayStorageAnalyzer: IStringArrayStorageAnalyzer;
  19. describe('analyze', () => {
  20. describe('Base analyze of the AST tree', () => {
  21. const literalNode1: ESTree.Literal = NodeFactory.literalNode('foo');
  22. const literalNode2: ESTree.Literal = NodeFactory.literalNode('bar');
  23. const literalNode3: ESTree.Literal = NodeFactory.literalNode('baz');
  24. const expectedStringArrayStorageItemData1: IStringArrayStorageItemData = {
  25. encodedValue: 'foo',
  26. decodeKey: null,
  27. index: 0,
  28. value: 'foo'
  29. };
  30. const expectedStringArrayStorageItemData2: IStringArrayStorageItemData = {
  31. encodedValue: 'bar',
  32. decodeKey: null,
  33. index: 1,
  34. value: 'bar'
  35. };
  36. const expectedStringArrayStorageItemData3: undefined = undefined;
  37. let stringArrayStorageItemData1: IStringArrayStorageItemData | undefined;
  38. let stringArrayStorageItemData2: IStringArrayStorageItemData | undefined;
  39. let stringArrayStorageItemData3: IStringArrayStorageItemData | undefined;
  40. before(() => {
  41. stringArrayStorageAnalyzer = getStringArrayStorageAnalyzer({
  42. stringArrayThreshold: 1
  43. });
  44. const astTree: ESTree.Program = NodeFactory.programNode([
  45. NodeFactory.expressionStatementNode(literalNode1),
  46. NodeFactory.expressionStatementNode(literalNode2)
  47. ]);
  48. stringArrayStorageAnalyzer.analyze(astTree);
  49. stringArrayStorageItemData1 = stringArrayStorageAnalyzer.getItemDataForLiteralNode(literalNode1);
  50. stringArrayStorageItemData2 = stringArrayStorageAnalyzer.getItemDataForLiteralNode(literalNode2);
  51. stringArrayStorageItemData3 = stringArrayStorageAnalyzer.getItemDataForLiteralNode(literalNode3);
  52. });
  53. it('Variant #1: should return correct string array storage item data for literal node #1', () => {
  54. assert.deepEqual(stringArrayStorageItemData1, expectedStringArrayStorageItemData1);
  55. });
  56. it('Variant #2: should return correct string array storage item data for literal node #1', () => {
  57. assert.deepEqual(stringArrayStorageItemData2, expectedStringArrayStorageItemData2);
  58. });
  59. it('Variant #3: should return correct string array storage item data for literal node #1', () => {
  60. assert.deepEqual(stringArrayStorageItemData3, expectedStringArrayStorageItemData3);
  61. });
  62. });
  63. describe('Base analyze of the AST tree with string literal nodes with values shorter than allowed length', () => {
  64. const literalNode1: ESTree.Literal = NodeFactory.literalNode('foo');
  65. const literalNode2: ESTree.Literal = NodeFactory.literalNode('ba');
  66. const expectedStringArrayStorageItemData1: IStringArrayStorageItemData = {
  67. encodedValue: 'foo',
  68. decodeKey: null,
  69. index: 0,
  70. value: 'foo'
  71. };
  72. const expectedStringArrayStorageItemData2: undefined = undefined;
  73. let stringArrayStorageItemData1: IStringArrayStorageItemData | undefined;
  74. let stringArrayStorageItemData2: IStringArrayStorageItemData | undefined;
  75. before(() => {
  76. stringArrayStorageAnalyzer = getStringArrayStorageAnalyzer({
  77. stringArrayThreshold: 1
  78. });
  79. const astTree: ESTree.Program = NodeFactory.programNode([
  80. NodeFactory.expressionStatementNode(literalNode1),
  81. NodeFactory.expressionStatementNode(literalNode2)
  82. ]);
  83. stringArrayStorageAnalyzer.analyze(astTree);
  84. stringArrayStorageItemData1 = stringArrayStorageAnalyzer.getItemDataForLiteralNode(literalNode1);
  85. stringArrayStorageItemData2 = stringArrayStorageAnalyzer.getItemDataForLiteralNode(literalNode2);
  86. });
  87. it('Variant #1: should return correct string array storage item data for literal node #1', () => {
  88. assert.deepEqual(stringArrayStorageItemData1, expectedStringArrayStorageItemData1);
  89. });
  90. it('Variant #2: should return correct string array storage item data for literal node #1', () => {
  91. assert.deepEqual(stringArrayStorageItemData2, expectedStringArrayStorageItemData2);
  92. });
  93. });
  94. describe('Base analyze of the AST tree with number literal nodes', () => {
  95. const literalNode1: ESTree.Literal = NodeFactory.literalNode('foo');
  96. const literalNode2: ESTree.Literal = NodeFactory.literalNode(1);
  97. const expectedStringArrayStorageItemData1: IStringArrayStorageItemData = {
  98. encodedValue: 'foo',
  99. decodeKey: null,
  100. index: 0,
  101. value: 'foo'
  102. };
  103. const expectedStringArrayStorageItemData2: undefined = undefined;
  104. let stringArrayStorageItemData1: IStringArrayStorageItemData | undefined;
  105. let stringArrayStorageItemData2: IStringArrayStorageItemData | undefined;
  106. before(() => {
  107. stringArrayStorageAnalyzer = getStringArrayStorageAnalyzer({
  108. stringArrayThreshold: 1
  109. });
  110. const astTree: ESTree.Program = NodeFactory.programNode([
  111. NodeFactory.expressionStatementNode(literalNode1),
  112. NodeFactory.expressionStatementNode(literalNode2)
  113. ]);
  114. stringArrayStorageAnalyzer.analyze(astTree);
  115. stringArrayStorageItemData1 = stringArrayStorageAnalyzer.getItemDataForLiteralNode(literalNode1);
  116. stringArrayStorageItemData2 = stringArrayStorageAnalyzer.getItemDataForLiteralNode(literalNode2);
  117. });
  118. it('Variant #1: should return correct string array storage item data for literal node #1', () => {
  119. assert.deepEqual(stringArrayStorageItemData1, expectedStringArrayStorageItemData1);
  120. });
  121. it('Variant #2: should return correct string array storage item data for literal node #1', () => {
  122. assert.deepEqual(stringArrayStorageItemData2, expectedStringArrayStorageItemData2);
  123. });
  124. });
  125. describe('Analyzes of the AST tree with prohibited string literal nodes', () => {
  126. const literalNode1: ESTree.Literal = NodeFactory.literalNode('foo');
  127. const literalNode2: ESTree.Literal = NodeFactory.literalNode('bar');
  128. const expectedStringArrayStorageItemData1: IStringArrayStorageItemData = {
  129. encodedValue: 'foo',
  130. decodeKey: null,
  131. index: 0,
  132. value: 'foo'
  133. };
  134. const expectedStringArrayStorageItemData2: undefined = undefined;
  135. let stringArrayStorageItemData1: IStringArrayStorageItemData | undefined;
  136. let stringArrayStorageItemData2: IStringArrayStorageItemData | undefined;
  137. before(() => {
  138. stringArrayStorageAnalyzer = getStringArrayStorageAnalyzer({
  139. stringArrayThreshold: 1
  140. });
  141. const astTree: ESTree.Program = NodeFactory.programNode([
  142. NodeFactory.expressionStatementNode(literalNode1),
  143. NodeFactory.variableDeclarationNode([
  144. NodeFactory.variableDeclaratorNode(
  145. NodeFactory.identifierNode('bar'),
  146. NodeFactory.objectExpressionNode([
  147. NodeFactory.propertyNode(
  148. literalNode2,
  149. NodeFactory.literalNode(1)
  150. )
  151. ])
  152. )
  153. ])
  154. ]);
  155. stringArrayStorageAnalyzer.analyze(astTree);
  156. stringArrayStorageItemData1 = stringArrayStorageAnalyzer.getItemDataForLiteralNode(literalNode1);
  157. stringArrayStorageItemData2 = stringArrayStorageAnalyzer.getItemDataForLiteralNode(literalNode2);
  158. });
  159. it('Variant #1: should return correct string array storage item data for literal node #1', () => {
  160. assert.deepEqual(stringArrayStorageItemData1, expectedStringArrayStorageItemData1);
  161. });
  162. it('Variant #2: should return correct string array storage item data for literal node #1', () => {
  163. assert.deepEqual(stringArrayStorageItemData2, expectedStringArrayStorageItemData2);
  164. });
  165. });
  166. describe('Analyzes of the AST tree with ignored nodes', () => {
  167. const literalNode1: ESTree.Literal = NodeFactory.literalNode('foo');
  168. const literalNode2: ESTree.Literal = NodeFactory.literalNode('bar');
  169. NodeMetadata.set(literalNode2, {ignoredNode: true});
  170. const expectedStringArrayStorageItemData1: IStringArrayStorageItemData = {
  171. encodedValue: 'foo',
  172. decodeKey: null,
  173. index: 0,
  174. value: 'foo'
  175. };
  176. const expectedStringArrayStorageItemData2: undefined = undefined;
  177. let stringArrayStorageItemData1: IStringArrayStorageItemData | undefined;
  178. let stringArrayStorageItemData2: IStringArrayStorageItemData | undefined;
  179. before(() => {
  180. stringArrayStorageAnalyzer = getStringArrayStorageAnalyzer({
  181. stringArrayThreshold: 1
  182. });
  183. const astTree: ESTree.Program = NodeFactory.programNode([
  184. NodeFactory.expressionStatementNode(literalNode1),
  185. NodeFactory.expressionStatementNode(literalNode2)
  186. ]);
  187. stringArrayStorageAnalyzer.analyze(astTree);
  188. stringArrayStorageItemData1 = stringArrayStorageAnalyzer.getItemDataForLiteralNode(literalNode1);
  189. stringArrayStorageItemData2 = stringArrayStorageAnalyzer.getItemDataForLiteralNode(literalNode2);
  190. });
  191. it('Variant #1: should return correct string array storage item data for literal node #1', () => {
  192. assert.deepEqual(stringArrayStorageItemData1, expectedStringArrayStorageItemData1);
  193. });
  194. it('Variant #2: should return correct string array storage item data for literal node #1', () => {
  195. assert.deepEqual(stringArrayStorageItemData2, expectedStringArrayStorageItemData2);
  196. });
  197. });
  198. /**
  199. * This test covers rare case when with random value inside `shouldAddValueToStringArray` was `0`
  200. * that trigger positive check for method.
  201. *
  202. * As fix i added check of `this.options.stringArray` option value
  203. */
  204. describe('Analyzes of the AST tree with disabled string array', () => {
  205. const literalNode1: ESTree.Literal = NodeFactory.literalNode('foo');
  206. const literalNode2: ESTree.Literal = NodeFactory.literalNode('bar');
  207. const expectedStringArrayStorageItemData1: undefined = undefined;
  208. const expectedStringArrayStorageItemData2: undefined = undefined;
  209. let stringArrayStorageItemData1: IStringArrayStorageItemData | undefined;
  210. let stringArrayStorageItemData2: IStringArrayStorageItemData | undefined;
  211. before(() => {
  212. stringArrayStorageAnalyzer = getStringArrayStorageAnalyzer({
  213. stringArray: false,
  214. stringArrayThreshold: 1
  215. });
  216. (<any>stringArrayStorageAnalyzer).options.stringArrayThreshold = 1;
  217. const astTree: ESTree.Program = NodeFactory.programNode([
  218. NodeFactory.expressionStatementNode(literalNode1),
  219. NodeFactory.expressionStatementNode(literalNode2)
  220. ]);
  221. stringArrayStorageAnalyzer.analyze(astTree);
  222. stringArrayStorageItemData1 = stringArrayStorageAnalyzer.getItemDataForLiteralNode(literalNode1);
  223. stringArrayStorageItemData2 = stringArrayStorageAnalyzer.getItemDataForLiteralNode(literalNode2);
  224. });
  225. it('Variant #1: should return correct string array storage item data for literal node #1', () => {
  226. assert.deepEqual(stringArrayStorageItemData1, expectedStringArrayStorageItemData1);
  227. });
  228. it('Variant #2: should return correct string array storage item data for literal node #1', () => {
  229. assert.deepEqual(stringArrayStorageItemData2, expectedStringArrayStorageItemData2);
  230. });
  231. });
  232. describe('Analyzes of the AST tree with string array threshold', () => {
  233. describe('Threshold value: 0', () => {
  234. const literalNode1: ESTree.Literal = NodeFactory.literalNode('foo');
  235. const literalNode2: ESTree.Literal = NodeFactory.literalNode('bar');
  236. const expectedStringArrayStorageItemData1: undefined = undefined;
  237. const expectedStringArrayStorageItemData2: undefined = undefined;
  238. let stringArrayStorageItemData1: IStringArrayStorageItemData | undefined;
  239. let stringArrayStorageItemData2: IStringArrayStorageItemData | undefined;
  240. before(() => {
  241. stringArrayStorageAnalyzer = getStringArrayStorageAnalyzer({
  242. stringArrayThreshold: 0
  243. });
  244. const astTree: ESTree.Program = NodeFactory.programNode([
  245. NodeFactory.expressionStatementNode(literalNode1),
  246. NodeFactory.expressionStatementNode(literalNode2)
  247. ]);
  248. stringArrayStorageAnalyzer.analyze(astTree);
  249. stringArrayStorageItemData1 = stringArrayStorageAnalyzer.getItemDataForLiteralNode(literalNode1);
  250. stringArrayStorageItemData2 = stringArrayStorageAnalyzer.getItemDataForLiteralNode(literalNode2);
  251. });
  252. it('Variant #1: should return correct string array storage item data for literal node #1', () => {
  253. assert.deepEqual(stringArrayStorageItemData1, expectedStringArrayStorageItemData1);
  254. });
  255. it('Variant #2: should return correct string array storage item data for literal node #1', () => {
  256. assert.deepEqual(stringArrayStorageItemData2, expectedStringArrayStorageItemData2);
  257. });
  258. });
  259. describe('Threshold value: 0.5', () => {
  260. const literalNode1: ESTree.Literal = NodeFactory.literalNode('foo');
  261. const literalNode2: ESTree.Literal = NodeFactory.literalNode('bar');
  262. const expectedStringArrayStorageItemData1: undefined = undefined;
  263. const expectedStringArrayStorageItemData2: IStringArrayStorageItemData = {
  264. encodedValue: 'bar',
  265. decodeKey: null,
  266. index: 0,
  267. value: 'bar'
  268. };
  269. let stringArrayStorageItemData1: IStringArrayStorageItemData | undefined;
  270. let stringArrayStorageItemData2: IStringArrayStorageItemData | undefined;
  271. before(() => {
  272. stringArrayStorageAnalyzer = getStringArrayStorageAnalyzer({
  273. stringArrayThreshold: 0.5,
  274. seed: 1
  275. });
  276. const astTree: ESTree.Program = NodeFactory.programNode([
  277. NodeFactory.expressionStatementNode(literalNode1),
  278. NodeFactory.expressionStatementNode(literalNode2)
  279. ]);
  280. stringArrayStorageAnalyzer.analyze(astTree);
  281. stringArrayStorageItemData1 = stringArrayStorageAnalyzer.getItemDataForLiteralNode(literalNode1);
  282. stringArrayStorageItemData2 = stringArrayStorageAnalyzer.getItemDataForLiteralNode(literalNode2);
  283. });
  284. it('Variant #1: should return correct string array storage item data for literal node #1', () => {
  285. assert.deepEqual(stringArrayStorageItemData1, expectedStringArrayStorageItemData1);
  286. });
  287. it('Variant #2: should return correct string array storage item data for literal node #2', () => {
  288. assert.deepEqual(stringArrayStorageItemData2, expectedStringArrayStorageItemData2);
  289. });
  290. });
  291. });
  292. });
  293. });