OptionsNormalizer.spec.ts 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. import 'reflect-metadata';
  2. import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers';
  3. import { assert } from 'chai';
  4. import { TInputOptions } from '../../../src/types/options/TInputOptions';
  5. import { IInversifyContainerFacade } from '../../../src/interfaces/container/IInversifyContainerFacade';
  6. import { IOptions } from '../../../src/interfaces/options/IOptions';
  7. import { IOptionsNormalizer } from '../../../src/interfaces/options/IOptionsNormalizer';
  8. import { StringArrayEncoding } from '../../../src/enums/StringArrayEncoding';
  9. import { DEFAULT_PRESET } from '../../../src/options/presets/Default';
  10. import { InversifyContainerFacade } from '../../../src/container/InversifyContainerFacade';
  11. /**
  12. * @param optionsPreset
  13. * @returns {IOptions}
  14. */
  15. function getNormalizedOptions (optionsPreset: TInputOptions): TInputOptions {
  16. const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
  17. inversifyContainerFacade.load('', '', optionsPreset);
  18. const options: IOptions = inversifyContainerFacade
  19. .get<IOptions>(ServiceIdentifiers.IOptions);
  20. const optionsNormalizer: IOptionsNormalizer = inversifyContainerFacade
  21. .get<IOptionsNormalizer>(ServiceIdentifiers.IOptionsNormalizer);
  22. return <TInputOptions>optionsNormalizer.normalize(options);
  23. }
  24. function getDefaultOptions(): TInputOptions {
  25. return {
  26. ...DEFAULT_PRESET,
  27. seed: 1 // set `seed` to the fixed value, to prevent a new seed for the each case
  28. };
  29. }
  30. describe('OptionsNormalizer', () => {
  31. describe('normalize', () => {
  32. let optionsPreset: TInputOptions,
  33. expectedOptionsPreset: TInputOptions;
  34. describe('controlFlowFlatteningThresholdRule', () => {
  35. before(() => {
  36. optionsPreset = getNormalizedOptions({
  37. ...getDefaultOptions(),
  38. controlFlowFlattening: true,
  39. controlFlowFlatteningThreshold: 0
  40. });
  41. expectedOptionsPreset = {
  42. ...getDefaultOptions(),
  43. controlFlowFlattening: false,
  44. controlFlowFlatteningThreshold: 0
  45. };
  46. });
  47. it('should normalize options preset', () => {
  48. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  49. });
  50. });
  51. describe('deadCodeInjectionRule', () => {
  52. before(() => {
  53. optionsPreset = getNormalizedOptions({
  54. ...getDefaultOptions(),
  55. deadCodeInjection: true,
  56. deadCodeInjectionThreshold: 0.4,
  57. stringArray: false,
  58. stringArrayThreshold: 0
  59. });
  60. expectedOptionsPreset = {
  61. ...getDefaultOptions(),
  62. deadCodeInjection: true,
  63. deadCodeInjectionThreshold: 0.4,
  64. stringArray: true,
  65. stringArrayThreshold: 0.75
  66. };
  67. });
  68. it('should normalize options preset', () => {
  69. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  70. });
  71. });
  72. describe('deadCodeInjectionRule', () => {
  73. describe('`stringArrayThreshold` option is empty', () => {
  74. before(() => {
  75. optionsPreset = getNormalizedOptions({
  76. ...getDefaultOptions(),
  77. deadCodeInjection: true,
  78. deadCodeInjectionThreshold: 0.4,
  79. stringArray: false,
  80. stringArrayThreshold: 0
  81. });
  82. expectedOptionsPreset = {
  83. ...getDefaultOptions(),
  84. deadCodeInjection: true,
  85. deadCodeInjectionThreshold: 0.4,
  86. stringArray: true,
  87. stringArrayThreshold: 0.75
  88. };
  89. });
  90. it('should normalize options preset', () => {
  91. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  92. });
  93. });
  94. describe('`stringArrayThreshold` option is not empty', () => {
  95. before(() => {
  96. optionsPreset = getNormalizedOptions({
  97. ...getDefaultOptions(),
  98. deadCodeInjection: true,
  99. deadCodeInjectionThreshold: 0.4,
  100. stringArray: false,
  101. stringArrayThreshold: 0.5
  102. });
  103. expectedOptionsPreset = {
  104. ...getDefaultOptions(),
  105. deadCodeInjection: true,
  106. deadCodeInjectionThreshold: 0.4,
  107. stringArray: true,
  108. stringArrayThreshold: 0.5
  109. };
  110. });
  111. it('should normalize options preset', () => {
  112. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  113. });
  114. });
  115. });
  116. describe('deadCodeInjectionThresholdRule', () => {
  117. before(() => {
  118. optionsPreset = getNormalizedOptions({
  119. ...getDefaultOptions(),
  120. deadCodeInjection: true,
  121. deadCodeInjectionThreshold: 0
  122. });
  123. expectedOptionsPreset = {
  124. ...getDefaultOptions(),
  125. deadCodeInjection: false,
  126. deadCodeInjectionThreshold: 0
  127. };
  128. });
  129. it('should normalize options preset', () => {
  130. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  131. });
  132. });
  133. describe('domainLockRule', () => {
  134. before(() => {
  135. optionsPreset = getNormalizedOptions({
  136. ...getDefaultOptions(),
  137. domainLock: [
  138. '//localhost:9000',
  139. 'https://google.ru/abc?cde=fgh'
  140. ]
  141. });
  142. expectedOptionsPreset = {
  143. ...getDefaultOptions(),
  144. domainLock: [
  145. 'localhost',
  146. 'google.ru'
  147. ]
  148. };
  149. });
  150. it('should normalize options preset', () => {
  151. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  152. });
  153. });
  154. describe('inputFileNameRule', () => {
  155. describe('Variant #1: extension isn\'t set', () => {
  156. before(() => {
  157. optionsPreset = getNormalizedOptions({
  158. ...getDefaultOptions(),
  159. inputFileName: 'foo'
  160. });
  161. expectedOptionsPreset = {
  162. ...getDefaultOptions(),
  163. inputFileName: 'foo.js'
  164. };
  165. });
  166. it('should normalize options preset', () => {
  167. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  168. });
  169. });
  170. describe('Variant #2: extension is set', () => {
  171. before(() => {
  172. optionsPreset = getNormalizedOptions({
  173. ...getDefaultOptions(),
  174. inputFileName: 'foo.js'
  175. });
  176. expectedOptionsPreset = {
  177. ...getDefaultOptions(),
  178. inputFileName: 'foo.js'
  179. };
  180. });
  181. it('should normalize options preset', () => {
  182. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  183. });
  184. });
  185. describe('Variant #3: extension in set with `.map` postfix', () => {
  186. before(() => {
  187. optionsPreset = getNormalizedOptions({
  188. ...getDefaultOptions(),
  189. inputFileName: 'foo.map.js'
  190. });
  191. expectedOptionsPreset = {
  192. ...getDefaultOptions(),
  193. inputFileName: 'foo.map.js'
  194. };
  195. });
  196. it('should normalize options preset', () => {
  197. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  198. });
  199. });
  200. describe('Variant #4: no file name', () => {
  201. before(() => {
  202. optionsPreset = getNormalizedOptions({
  203. ...getDefaultOptions(),
  204. inputFileName: ''
  205. });
  206. expectedOptionsPreset = {
  207. ...getDefaultOptions(),
  208. inputFileName: ''
  209. };
  210. });
  211. it('should normalize options preset', () => {
  212. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  213. });
  214. });
  215. });
  216. describe('seedRule', () => {
  217. describe('Variant #1: seed value is string', () => {
  218. before(() => {
  219. optionsPreset = getNormalizedOptions({
  220. ...getDefaultOptions(),
  221. seed: 'abc'
  222. });
  223. expectedOptionsPreset = {
  224. ...getDefaultOptions(),
  225. seed: 'abc'
  226. };
  227. });
  228. it('should not normalize options preset', () => {
  229. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  230. });
  231. });
  232. describe('Variant #2: seed value is number', () => {
  233. before(() => {
  234. optionsPreset = getNormalizedOptions({
  235. ...getDefaultOptions(),
  236. seed: 123
  237. });
  238. expectedOptionsPreset = {
  239. ...getDefaultOptions(),
  240. seed: 123
  241. };
  242. });
  243. it('should normalize options preset', () => {
  244. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  245. });
  246. });
  247. describe('Variant #3: seed value is `0``', () => {
  248. let seedValue: number;
  249. before(() => {
  250. optionsPreset = getNormalizedOptions({
  251. ...getDefaultOptions(),
  252. seed: 0
  253. });
  254. seedValue = Number(optionsPreset.seed);
  255. });
  256. it('should normalize seed value', () => {
  257. assert.isAtLeast(seedValue, 0);
  258. assert.isBelow(seedValue, 999_999_999);
  259. });
  260. });
  261. });
  262. describe('selfDefendingRule', () => {
  263. before(() => {
  264. optionsPreset = getNormalizedOptions({
  265. ...getDefaultOptions(),
  266. selfDefending: true,
  267. compact: false
  268. });
  269. expectedOptionsPreset = {
  270. ...getDefaultOptions(),
  271. selfDefending: true,
  272. compact: true
  273. };
  274. });
  275. it('should normalize options preset', () => {
  276. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  277. });
  278. });
  279. describe('sourceMapBaseUrlRule', () => {
  280. describe('Variant #1: only source map base url', () => {
  281. before(() => {
  282. optionsPreset = getNormalizedOptions({
  283. ...getDefaultOptions(),
  284. sourceMapBaseUrl: 'http://localhost:9000',
  285. });
  286. expectedOptionsPreset = {
  287. ...getDefaultOptions(),
  288. sourceMapBaseUrl: ''
  289. };
  290. });
  291. it('should normalize options preset', () => {
  292. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  293. });
  294. });
  295. describe('Variant #2: source map base url with source map file name', () => {
  296. before(() => {
  297. optionsPreset = getNormalizedOptions({
  298. ...getDefaultOptions(),
  299. sourceMapBaseUrl: 'http://localhost:9000',
  300. sourceMapFileName: '/outputSourceMapName.map'
  301. });
  302. expectedOptionsPreset = {
  303. ...getDefaultOptions(),
  304. sourceMapBaseUrl: 'http://localhost:9000/',
  305. sourceMapFileName: 'outputSourceMapName.js.map'
  306. };
  307. });
  308. it('should normalize options preset', () => {
  309. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  310. });
  311. });
  312. });
  313. describe('sourceMapFileNameRule', () => {
  314. before(() => {
  315. optionsPreset = getNormalizedOptions({
  316. ...getDefaultOptions(),
  317. sourceMapBaseUrl: 'http://localhost:9000',
  318. sourceMapFileName: '//outputSourceMapName'
  319. });
  320. expectedOptionsPreset = {
  321. ...getDefaultOptions(),
  322. sourceMapBaseUrl: 'http://localhost:9000/',
  323. sourceMapFileName: 'outputSourceMapName.js.map'
  324. };
  325. });
  326. it('should normalize options preset', () => {
  327. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  328. });
  329. });
  330. describe('splitStringsChunkLengthRule', () => {
  331. describe('`splitStringsChunkLengthRule` value is float number', () => {
  332. before(() => {
  333. optionsPreset = getNormalizedOptions({
  334. ...getDefaultOptions(),
  335. splitStrings: true,
  336. splitStringsChunkLength: 5.6
  337. });
  338. expectedOptionsPreset = {
  339. ...getDefaultOptions(),
  340. splitStrings: true,
  341. splitStringsChunkLength: 5
  342. };
  343. });
  344. it('should normalize options preset', () => {
  345. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  346. });
  347. });
  348. });
  349. describe('stringArrayRule', () => {
  350. before(() => {
  351. optionsPreset = getNormalizedOptions({
  352. ...getDefaultOptions(),
  353. stringArray: false,
  354. stringArrayEncoding: StringArrayEncoding.Rc4,
  355. stringArrayThreshold: 0.5,
  356. rotateStringArray: true
  357. });
  358. expectedOptionsPreset = {
  359. ...getDefaultOptions(),
  360. stringArray: false,
  361. stringArrayEncoding: false,
  362. stringArrayThreshold: 0,
  363. rotateStringArray: false
  364. };
  365. });
  366. it('should normalize options preset', () => {
  367. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  368. });
  369. });
  370. describe('stringArrayEncodingRule', () => {
  371. before(() => {
  372. optionsPreset = getNormalizedOptions({
  373. ...getDefaultOptions(),
  374. stringArrayEncoding: true
  375. });
  376. expectedOptionsPreset = {
  377. ...getDefaultOptions(),
  378. stringArrayEncoding: StringArrayEncoding.Base64
  379. };
  380. });
  381. it('should normalize options preset', () => {
  382. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  383. });
  384. });
  385. describe('stringArrayThresholdRule', () => {
  386. before(() => {
  387. optionsPreset = getNormalizedOptions({
  388. ...getDefaultOptions(),
  389. rotateStringArray: true,
  390. stringArray: true,
  391. stringArrayThreshold: 0
  392. });
  393. expectedOptionsPreset = {
  394. ...getDefaultOptions(),
  395. rotateStringArray: false,
  396. stringArray: false,
  397. stringArrayThreshold: 0
  398. };
  399. });
  400. it('should normalize options preset', () => {
  401. assert.deepEqual(optionsPreset, expectedOptionsPreset);
  402. });
  403. });
  404. });
  405. });