JavaScriptObfuscatorCLI.spec.ts 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. import * as fs from 'fs';
  2. import * as mkdirp from 'mkdirp';
  3. import * as path from 'path';
  4. import * as rimraf from 'rimraf';
  5. import * as sinon from 'sinon';
  6. import { assert } from 'chai';
  7. import { StdoutWriteMock } from '../../mocks/StdoutWriteMock';
  8. import { JavaScriptObfuscatorCLI } from '../../../src/JavaScriptObfuscatorCLIFacade';
  9. describe('JavaScriptObfuscatorCLI', function (): void {
  10. this.timeout(100000);
  11. const expectedError: RegExp = /Given input path must be a valid/;
  12. const fixturesDirName: string = 'test/fixtures';
  13. const fixtureFileName: string = 'sample.js';
  14. const fixtureFilePath: string = `${fixturesDirName}/${fixtureFileName}`;
  15. const outputDirName: string = 'test/tmp';
  16. const outputFileName: string = 'sample-obfuscated.js';
  17. const outputFilePath: string = `${outputDirName}/${outputFileName}`;
  18. const configDirName: string = 'test/fixtures';
  19. const configFileName: string = 'config.js';
  20. const configFilePath: string = `${configDirName}/${configFileName}`;
  21. describe('run', () => {
  22. before(() => {
  23. mkdirp.sync(outputDirName);
  24. });
  25. describe('Variant #1: obfuscation of single file', () => {
  26. describe('`--output` option is set', () => {
  27. let isFileExist: boolean;
  28. before(() => {
  29. JavaScriptObfuscatorCLI.obfuscate([
  30. 'node',
  31. 'javascript-obfuscator',
  32. fixtureFilePath,
  33. '--output',
  34. outputFilePath,
  35. '--compact',
  36. 'true',
  37. '--self-defending',
  38. '0'
  39. ]);
  40. isFileExist = fs.existsSync(outputFilePath);
  41. });
  42. it('should create file with obfuscated code in `--output` directory', () => {
  43. assert.equal(isFileExist, true);
  44. });
  45. after(() => {
  46. fs.unlinkSync(outputFilePath);
  47. });
  48. });
  49. describe('`--output` option isn\'t set', () => {
  50. describe('Variant #1: default behaviour', () => {
  51. let outputFixturesFilePath: string,
  52. isFileExist: boolean;
  53. before(() => {
  54. outputFixturesFilePath = `${fixturesDirName}/${outputFileName}`;
  55. JavaScriptObfuscatorCLI.obfuscate([
  56. 'node',
  57. 'javascript-obfuscator',
  58. fixtureFilePath
  59. ]);
  60. isFileExist = fs.existsSync(outputFixturesFilePath);
  61. });
  62. it(`should create file \`${outputFileName}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
  63. assert.equal(isFileExist, true);
  64. });
  65. after(() => {
  66. fs.unlinkSync(outputFixturesFilePath);
  67. });
  68. });
  69. describe('Variant #2: invalid input file path', () => {
  70. let testFunc: () => void;
  71. before(() => {
  72. testFunc = () => JavaScriptObfuscatorCLI.obfuscate([
  73. 'node',
  74. 'javascript-obfuscator',
  75. 'wrong/file/path'
  76. ]);
  77. });
  78. it(`should throw an error`, () => {
  79. assert.throws(testFunc, expectedError);
  80. });
  81. });
  82. describe('Variant #3: input file extension isn\'t `.js`', () => {
  83. const expectedError: RegExp = /Given input path must be a valid/;
  84. const outputFileName: string = 'sample-obfuscated.ts';
  85. const outputFilePath: string = `${outputDirName}/${outputFileName}`;
  86. let testFunc: () => void;
  87. before(() => {
  88. fs.writeFileSync(outputFilePath, 'data');
  89. testFunc = () => JavaScriptObfuscatorCLI.obfuscate([
  90. 'node',
  91. 'javascript-obfuscator',
  92. outputFilePath
  93. ]);
  94. });
  95. it(`should throw an error`, () => {
  96. assert.throws(testFunc, expectedError);
  97. });
  98. after(() => {
  99. fs.unlinkSync(outputFilePath);
  100. });
  101. });
  102. });
  103. describe('--exclude option', () => {
  104. describe('Variant #1: --exclude option is pointed on different file', () => {
  105. let isFileExist: boolean;
  106. before(() => {
  107. JavaScriptObfuscatorCLI.obfuscate([
  108. 'node',
  109. 'javascript-obfuscator',
  110. fixtureFilePath,
  111. '--output',
  112. outputFilePath,
  113. '--exclude',
  114. '**/foo.js'
  115. ]);
  116. isFileExist = fs.existsSync(outputFilePath);
  117. });
  118. it('should create file with obfuscated code in `--output` directory', () => {
  119. assert.equal(isFileExist, true);
  120. });
  121. });
  122. describe('Variant #2: --exclude option is pointed on input file', () => {
  123. let testFunc: () => void;
  124. before(() => {
  125. testFunc = () => JavaScriptObfuscatorCLI.obfuscate([
  126. 'node',
  127. 'javascript-obfuscator',
  128. fixtureFilePath,
  129. '--output',
  130. outputFilePath,
  131. '--exclude',
  132. '**/sample.js'
  133. ]);
  134. });
  135. it('should throw an error', () => {
  136. assert.throws(testFunc, expectedError);
  137. });
  138. after(() => {
  139. fs.unlinkSync(outputFilePath);
  140. });
  141. });
  142. });
  143. });
  144. describe('Variant #2: obfuscation of directory', () => {
  145. describe(`Variant #1: default behaviour`, () => {
  146. const directoryPath: string = `${fixturesDirName}/directory-obfuscation`;
  147. const outputFileName1: string = 'foo-obfuscated.js';
  148. const outputFileName2: string = 'bar-obfuscated.js';
  149. const outputFileName3: string = 'baz-obfuscated.js';
  150. const readFileEncoding: string = 'utf8';
  151. const regExp1: RegExp = /^var *a1_0x(\w){4,6} *= *0x1;$/;
  152. const regExp2: RegExp = /^var *a0_0x(\w){4,6} *= *0x2;$/;
  153. let outputFixturesFilePath1: string,
  154. outputFixturesFilePath2: string,
  155. outputFixturesFilePath3: string,
  156. isFileExist1: boolean,
  157. isFileExist2: boolean,
  158. isFileExist3: boolean,
  159. fileContent1: string,
  160. fileContent2: string;
  161. before(() => {
  162. outputFixturesFilePath1 = `${directoryPath}/${outputFileName1}`;
  163. outputFixturesFilePath2 = `${directoryPath}/${outputFileName2}`;
  164. outputFixturesFilePath3 = `${directoryPath}/${outputFileName3}`;
  165. JavaScriptObfuscatorCLI.obfuscate([
  166. 'node',
  167. 'javascript-obfuscator',
  168. directoryPath,
  169. '--rename-globals',
  170. 'true'
  171. ]);
  172. isFileExist1 = fs.existsSync(outputFixturesFilePath1);
  173. isFileExist2 = fs.existsSync(outputFixturesFilePath2);
  174. isFileExist3 = fs.existsSync(outputFixturesFilePath3);
  175. fileContent1 = fs.readFileSync(outputFixturesFilePath1, readFileEncoding);
  176. fileContent2 = fs.readFileSync(outputFixturesFilePath2, readFileEncoding);
  177. });
  178. it(`should create file \`${outputFileName1}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
  179. assert.equal(isFileExist1, true);
  180. });
  181. it(`should create file \`${outputFileName2}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
  182. assert.equal(isFileExist2, true);
  183. });
  184. it(`shouldn't create file \`${outputFileName3}\` in \`${fixturesDirName}\` directory`, () => {
  185. assert.equal(isFileExist3, false);
  186. });
  187. it(`match #1: should create file with obfuscated code with prefixed identifier`, () => {
  188. assert.match(fileContent1, regExp1);
  189. });
  190. it(`match #2: should create file with obfuscated code with prefixed identifier`, () => {
  191. assert.match(fileContent2, regExp2);
  192. });
  193. after(() => {
  194. rimraf.sync(outputFixturesFilePath1);
  195. rimraf.sync(outputFixturesFilePath2);
  196. });
  197. });
  198. describe('Variant #2: obfuscation of directory with `identifiersPrefix` option value', () => {
  199. const directoryPath: string = `${fixturesDirName}/directory-obfuscation`;
  200. const identifiersPrefix: string = 'foo';
  201. const outputFileName1: string = 'foo-obfuscated.js';
  202. const outputFileName2: string = 'bar-obfuscated.js';
  203. const readFileEncoding: string = 'utf8';
  204. const regExp1: RegExp = /^var *foo1_0x(\w){4,6} *= *0x1;$/;
  205. const regExp2: RegExp = /^var *foo0_0x(\w){4,6} *= *0x2;$/;
  206. let outputFixturesFilePath1: string,
  207. outputFixturesFilePath2: string,
  208. isFileExist1: boolean,
  209. isFileExist2: boolean,
  210. fileContent1: string,
  211. fileContent2: string;
  212. before(() => {
  213. outputFixturesFilePath1 = `${directoryPath}/${outputFileName1}`;
  214. outputFixturesFilePath2 = `${directoryPath}/${outputFileName2}`;
  215. JavaScriptObfuscatorCLI.obfuscate([
  216. 'node',
  217. 'javascript-obfuscator',
  218. directoryPath,
  219. '--identifiers-prefix',
  220. identifiersPrefix,
  221. '--rename-globals',
  222. 'true'
  223. ]);
  224. isFileExist1 = fs.existsSync(outputFixturesFilePath1);
  225. isFileExist2 = fs.existsSync(outputFixturesFilePath2);
  226. fileContent1 = fs.readFileSync(outputFixturesFilePath1, readFileEncoding);
  227. fileContent2 = fs.readFileSync(outputFixturesFilePath2, readFileEncoding);
  228. });
  229. it(`should create file \`${outputFileName1}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
  230. assert.equal(isFileExist1, true);
  231. });
  232. it(`should create file \`${outputFileName2}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
  233. assert.equal(isFileExist2, true);
  234. });
  235. it(`match #1: should create file with obfuscated code with prefixed identifier`, () => {
  236. assert.match(fileContent1, regExp1);
  237. });
  238. it(`match #2: should create file with obfuscated code with prefixed identifier`, () => {
  239. assert.match(fileContent2, regExp2);
  240. });
  241. after(() => {
  242. rimraf.sync(outputFixturesFilePath1);
  243. rimraf.sync(outputFixturesFilePath2);
  244. });
  245. });
  246. describe('Variant #3: obfuscation of directory with `output` option', () => {
  247. const directoryPath: string = `${fixturesDirName}/directory-obfuscation`;
  248. const outputDirectoryName: string = 'obfuscated';
  249. const outputDirectoryPath: string = `${directoryPath}/${outputDirectoryName}`;
  250. const outputFileName1: string = 'foo.js';
  251. const outputFileName2: string = 'bar.js';
  252. const outputFileName3: string = 'baz.js';
  253. let outputFixturesFilePath1: string,
  254. outputFixturesFilePath2: string,
  255. outputFixturesFilePath3: string,
  256. isFileExist1: boolean,
  257. isFileExist2: boolean,
  258. isFileExist3: boolean;
  259. before(() => {
  260. outputFixturesFilePath1 = `${outputDirectoryPath}/${directoryPath}/${outputFileName1}`;
  261. outputFixturesFilePath2 = `${outputDirectoryPath}/${directoryPath}/${outputFileName2}`;
  262. outputFixturesFilePath3 = `${outputDirectoryPath}/${directoryPath}/${outputFileName3}`;
  263. JavaScriptObfuscatorCLI.obfuscate([
  264. 'node',
  265. 'javascript-obfuscator',
  266. directoryPath,
  267. '--output',
  268. outputDirectoryPath
  269. ]);
  270. isFileExist1 = fs.existsSync(outputFixturesFilePath1);
  271. isFileExist2 = fs.existsSync(outputFixturesFilePath2);
  272. isFileExist3 = fs.existsSync(outputFixturesFilePath3);
  273. });
  274. it(
  275. `should create file \`${outputFileName1}\` with obfuscated code in ` +
  276. `\`${fixturesDirName}/${outputDirectoryName}\` directory`,
  277. () => {
  278. assert.equal(isFileExist1, true);
  279. }
  280. );
  281. it(
  282. `should create file \`${outputFileName2}\` with obfuscated code in ` +
  283. `\`${fixturesDirName}/${outputDirectoryName}\` directory`,
  284. () => {
  285. assert.equal(isFileExist2, true);
  286. }
  287. );
  288. it(
  289. `shouldn't create file \`${outputFileName3}\` in ` +
  290. `\`${fixturesDirName}/${outputDirectoryName}\` directory`,
  291. () => {
  292. assert.equal(isFileExist3, false);
  293. }
  294. );
  295. after(() => {
  296. rimraf.sync(outputDirectoryPath);
  297. });
  298. });
  299. describe('Variant #4: --exclude option', () => {
  300. describe('Variant #1: --exclude option is pointed on different file', () => {
  301. const directoryPath: string = `${fixturesDirName}/directory-obfuscation`;
  302. const outputFileName1: string = 'foo-obfuscated.js';
  303. const outputFileName2: string = 'bar-obfuscated.js';
  304. const outputFileName3: string = 'baz-obfuscated.js';
  305. const readFileEncoding: string = 'utf8';
  306. const regExp1: RegExp = /^var *a1_0x(\w){4,6} *= *0x1;$/;
  307. const regExp2: RegExp = /^var *a0_0x(\w){4,6} *= *0x2;$/;
  308. let outputFixturesFilePath1: string,
  309. outputFixturesFilePath2: string,
  310. outputFixturesFilePath3: string,
  311. isFileExist1: boolean,
  312. isFileExist2: boolean,
  313. isFileExist3: boolean,
  314. fileContent1: string,
  315. fileContent2: string;
  316. before(() => {
  317. outputFixturesFilePath1 = `${directoryPath}/${outputFileName1}`;
  318. outputFixturesFilePath2 = `${directoryPath}/${outputFileName2}`;
  319. outputFixturesFilePath3 = `${directoryPath}/${outputFileName3}`;
  320. JavaScriptObfuscatorCLI.obfuscate([
  321. 'node',
  322. 'javascript-obfuscator',
  323. directoryPath,
  324. '--exclude',
  325. '**/bark.js',
  326. '--rename-globals',
  327. 'true'
  328. ]);
  329. isFileExist1 = fs.existsSync(outputFixturesFilePath1);
  330. isFileExist2 = fs.existsSync(outputFixturesFilePath2);
  331. isFileExist3 = fs.existsSync(outputFixturesFilePath3);
  332. fileContent1 = fs.readFileSync(outputFixturesFilePath1, readFileEncoding);
  333. fileContent2 = fs.readFileSync(outputFixturesFilePath2, readFileEncoding);
  334. });
  335. it(`should create file \`${outputFileName1}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
  336. assert.equal(isFileExist1, true);
  337. });
  338. it(`should create file \`${outputFileName2}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
  339. assert.equal(isFileExist2, true);
  340. });
  341. it(`shouldn't create file \`${outputFileName3}\` in \`${fixturesDirName}\` directory`, () => {
  342. assert.equal(isFileExist3, false);
  343. });
  344. it(`match #1: should create file with obfuscated code with prefixed identifier`, () => {
  345. assert.match(fileContent1, regExp1);
  346. });
  347. it(`match #2: should create file with obfuscated code with prefixed identifier`, () => {
  348. assert.match(fileContent2, regExp2);
  349. });
  350. after(() => {
  351. rimraf.sync(outputFixturesFilePath1);
  352. rimraf.sync(outputFixturesFilePath2);
  353. });
  354. });
  355. describe('Variant #2: --exclude option is pointed on file under obfuscating directory', () => {
  356. const directoryPath: string = `${fixturesDirName}/directory-obfuscation`;
  357. const outputFileName1: string = 'foo-obfuscated.js';
  358. const outputFileName2: string = 'bar-obfuscated.js';
  359. const outputFileName3: string = 'baz-obfuscated.js';
  360. const readFileEncoding: string = 'utf8';
  361. const regExp1: RegExp = /^var *a0_0x(\w){4,6} *= *0x2;$/;
  362. let outputFixturesFilePath1: string,
  363. outputFixturesFilePath2: string,
  364. outputFixturesFilePath3: string,
  365. isFileExist1: boolean,
  366. isFileExist2: boolean,
  367. isFileExist3: boolean,
  368. fileContent1: string;
  369. before(() => {
  370. outputFixturesFilePath1 = `${directoryPath}/${outputFileName1}`;
  371. outputFixturesFilePath2 = `${directoryPath}/${outputFileName2}`;
  372. outputFixturesFilePath3 = `${directoryPath}/${outputFileName3}`;
  373. JavaScriptObfuscatorCLI.obfuscate([
  374. 'node',
  375. 'javascript-obfuscator',
  376. directoryPath,
  377. '--exclude',
  378. '**/foo.js',
  379. '--rename-globals',
  380. 'true'
  381. ]);
  382. isFileExist1 = fs.existsSync(outputFixturesFilePath1);
  383. isFileExist2 = fs.existsSync(outputFixturesFilePath2);
  384. isFileExist3 = fs.existsSync(outputFixturesFilePath3);
  385. fileContent1 = fs.readFileSync(outputFixturesFilePath2, readFileEncoding);
  386. });
  387. it(`shouldn't create file \`${outputFileName1}\` in \`${fixturesDirName}\` directory`, () => {
  388. assert.equal(isFileExist1, false);
  389. });
  390. it(`should create file \`${outputFileName2}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
  391. assert.equal(isFileExist2, true);
  392. });
  393. it(`shouldn't create file \`${outputFileName3}\` in \`${fixturesDirName}\` directory`, () => {
  394. assert.equal(isFileExist3, false);
  395. });
  396. it(`match #1: should create file with obfuscated code with prefixed identifier`, () => {
  397. assert.match(fileContent1, regExp1);
  398. });
  399. after(() => {
  400. rimraf.sync(outputFixturesFilePath1);
  401. rimraf.sync(outputFixturesFilePath2);
  402. });
  403. });
  404. });
  405. });
  406. describe('`--sourceMap` option is set', () => {
  407. const outputSourceMapPath: string = `${outputFilePath}.map`;
  408. describe('Variant #1: `--sourceMapMode` option value is `separate`', () => {
  409. describe('Variant #1: default behaviour', () => {
  410. const expectedSourceMapSourceName: string = path.basename(fixtureFileName);
  411. let isFileExist: boolean,
  412. sourceMapObject: any;
  413. before(() => {
  414. JavaScriptObfuscatorCLI.obfuscate([
  415. 'node',
  416. 'javascript-obfuscator',
  417. fixtureFilePath,
  418. '--output',
  419. outputFilePath,
  420. '--compact',
  421. 'true',
  422. '--self-defending',
  423. '0',
  424. '--source-map',
  425. 'true'
  426. ]);
  427. try {
  428. const content: string = fs.readFileSync(outputSourceMapPath, { encoding: 'utf8' });
  429. isFileExist = true;
  430. sourceMapObject = JSON.parse(content);
  431. } catch (e) {
  432. isFileExist = false;
  433. }
  434. });
  435. it('should create file with source map in the same directory as output file', () => {
  436. assert.equal(isFileExist, true);
  437. });
  438. it('source map from created file should contains property `version`', () => {
  439. assert.property(sourceMapObject, 'version');
  440. });
  441. it('source map from created file should contains property `sources`', () => {
  442. assert.property(sourceMapObject, 'sources');
  443. });
  444. it('source map source should has correct name', () => {
  445. assert.equal(sourceMapObject.sources[0], expectedSourceMapSourceName);
  446. });
  447. it('source map from created file should contains property `names`', () => {
  448. assert.property(sourceMapObject, 'names');
  449. });
  450. after(() => {
  451. rimraf.sync(outputFilePath);
  452. rimraf.sync(outputSourceMapPath);
  453. });
  454. });
  455. describe('Variant #2: `sourceMapBaseUrl` option is set', () => {
  456. const expectedSourceMapSourceName: string = path.basename(fixtureFileName);
  457. let isFileExist: boolean,
  458. sourceMapObject: any;
  459. before(() => {
  460. JavaScriptObfuscatorCLI.obfuscate([
  461. 'node',
  462. 'javascript-obfuscator',
  463. fixtureFilePath,
  464. '--output',
  465. outputFilePath,
  466. '--compact',
  467. 'true',
  468. '--self-defending',
  469. '0',
  470. '--source-map',
  471. 'true',
  472. '--source-map-base-url',
  473. 'http://localhost:9000/'
  474. ]);
  475. try {
  476. const content: string = fs.readFileSync(outputSourceMapPath, { encoding: 'utf8' });
  477. isFileExist = true;
  478. sourceMapObject = JSON.parse(content);
  479. } catch (e) {
  480. isFileExist = false;
  481. }
  482. });
  483. it('should create file with source map in the same directory as output file', () => {
  484. assert.equal(isFileExist, true);
  485. });
  486. it('source map from created file should contains property `version`', () => {
  487. assert.property(sourceMapObject, 'version');
  488. });
  489. it('source map from created file should contains property `sources`', () => {
  490. assert.property(sourceMapObject, 'sources');
  491. });
  492. it('source map source should has correct name', () => {
  493. assert.equal(sourceMapObject.sources[0], expectedSourceMapSourceName);
  494. });
  495. it('source map from created file should contains property `names`', () => {
  496. assert.property(sourceMapObject, 'names');
  497. });
  498. after(() => {
  499. fs.unlinkSync(outputFilePath);
  500. fs.unlinkSync(outputSourceMapPath);
  501. });
  502. });
  503. describe('Variant #3: `--sourceMapFileName` option is set', () => {
  504. const expectedSourceMapSourceName: string = path.basename(fixtureFileName);
  505. const sourceMapFileName: string = 'test';
  506. const sourceMapFilePath: string = `${sourceMapFileName}.js.map`;
  507. const outputSourceMapFilePath: string = `${outputDirName}/${sourceMapFilePath}`;
  508. let isFileExist: boolean,
  509. sourceMapObject: any;
  510. before(() => {
  511. JavaScriptObfuscatorCLI.obfuscate([
  512. 'node',
  513. 'javascript-obfuscator',
  514. fixtureFilePath,
  515. '--output',
  516. outputFilePath,
  517. '--compact',
  518. 'true',
  519. '--self-defending',
  520. '0',
  521. '--source-map',
  522. 'true',
  523. '--source-map-file-name',
  524. sourceMapFileName
  525. ]);
  526. try {
  527. const content: string = fs.readFileSync(outputSourceMapFilePath, { encoding: 'utf8' });
  528. isFileExist = true;
  529. sourceMapObject = JSON.parse(content);
  530. } catch (e) {
  531. isFileExist = false;
  532. }
  533. });
  534. it('should create source map file with given name in the same directory as output file', () => {
  535. assert.equal(isFileExist, true);
  536. });
  537. it('source map from created file should contains property `version`', () => {
  538. assert.property(sourceMapObject, 'version');
  539. });
  540. it('source map from created file should contains property `sources`', () => {
  541. assert.property(sourceMapObject, 'sources');
  542. });
  543. it('source map source should has correct name', () => {
  544. assert.equal(sourceMapObject.sources[0], expectedSourceMapSourceName);
  545. });
  546. it('source map from created file should contains property `names`', () => {
  547. assert.property(sourceMapObject, 'names');
  548. });
  549. after(() => {
  550. fs.unlinkSync(outputFilePath);
  551. fs.unlinkSync(outputSourceMapFilePath);
  552. });
  553. });
  554. });
  555. describe('Variant #2: `--sourceMapMode` option is `inline`', () => {
  556. let isFileExist: boolean;
  557. before(() => {
  558. JavaScriptObfuscatorCLI.obfuscate([
  559. 'node',
  560. 'javascript-obfuscator',
  561. fixtureFilePath,
  562. '--output',
  563. outputFilePath,
  564. '--compact',
  565. 'true',
  566. '--self-defending',
  567. '0',
  568. '--source-map',
  569. 'true',
  570. '--source-map-mode',
  571. 'inline'
  572. ]);
  573. isFileExist = fs.existsSync(outputSourceMapPath);
  574. });
  575. it('shouldn\'t create file with source map', () => {
  576. assert.equal(isFileExist, false);
  577. });
  578. after(() => {
  579. fs.unlinkSync(outputFilePath);
  580. });
  581. });
  582. });
  583. describe('help output', () => {
  584. let callback: sinon.SinonSpy<any, void>,
  585. stdoutWriteMock: StdoutWriteMock;
  586. beforeEach(() => {
  587. callback = sinon.spy(console, 'log');
  588. stdoutWriteMock = new StdoutWriteMock(process.stdout.write);
  589. });
  590. describe('`--help` option is set', () => {
  591. let isConsoleLogCalled: boolean;
  592. beforeEach(() => {
  593. stdoutWriteMock.mute();
  594. JavaScriptObfuscatorCLI.obfuscate([
  595. 'node',
  596. 'javascript-obfuscator',
  597. fixtureFilePath,
  598. '--help'
  599. ]);
  600. stdoutWriteMock.restore();
  601. isConsoleLogCalled = callback.called;
  602. });
  603. it('should print `console.log` help', () => {
  604. assert.equal(isConsoleLogCalled, true);
  605. });
  606. });
  607. describe('no arguments passed', () => {
  608. let isConsoleLogCalled: boolean;
  609. beforeEach(() => {
  610. stdoutWriteMock.mute();
  611. JavaScriptObfuscatorCLI.obfuscate([
  612. 'node',
  613. 'javascript-obfuscator'
  614. ]);
  615. stdoutWriteMock.restore();
  616. isConsoleLogCalled = callback.called;
  617. });
  618. it('should print `console.log` help', () => {
  619. assert.equal(isConsoleLogCalled, true);
  620. });
  621. });
  622. afterEach(() => {
  623. callback.restore();
  624. });
  625. });
  626. describe('`--config` option is set', () => {
  627. const outputSourceMapPath: string = `${outputFilePath}.map`;
  628. let isFileExist: boolean,
  629. sourceMapObject: any;
  630. before(() => {
  631. JavaScriptObfuscatorCLI.obfuscate([
  632. 'node',
  633. 'javascript-obfuscator',
  634. fixtureFilePath,
  635. '--output',
  636. outputFilePath,
  637. '--config',
  638. configFilePath
  639. ]);
  640. try {
  641. const content: string = fs.readFileSync(outputSourceMapPath, {encoding: 'utf8'});
  642. isFileExist = true;
  643. sourceMapObject = JSON.parse(content);
  644. } catch (e) {
  645. isFileExist = false;
  646. }
  647. });
  648. it('should create file with source map in the same directory as output file', () => {
  649. assert.equal(isFileExist, true);
  650. });
  651. it('source map from created file should contains property `version`', () => {
  652. assert.property(sourceMapObject, 'version');
  653. });
  654. it('source map from created file should contains property `sources`', () => {
  655. assert.property(sourceMapObject, 'sources');
  656. });
  657. it('source map from created file should contains property `names`', () => {
  658. assert.property(sourceMapObject, 'names');
  659. });
  660. after(() => {
  661. fs.unlinkSync(outputFilePath);
  662. fs.unlinkSync(outputSourceMapPath);
  663. });
  664. });
  665. describe('`--config` option is set but overridden by CLI option', () => {
  666. const outputSourceMapPath: string = `${outputFilePath}.map`;
  667. let isFileExist: boolean;
  668. before(() => {
  669. JavaScriptObfuscatorCLI.obfuscate([
  670. 'node',
  671. 'javascript-obfuscator',
  672. fixtureFilePath,
  673. '--output',
  674. outputFilePath,
  675. '--config',
  676. configFilePath,
  677. '--source-map',
  678. 'false',
  679. ]);
  680. try {
  681. fs.readFileSync(outputSourceMapPath, {encoding: 'utf8'});
  682. isFileExist = true;
  683. } catch (e) {
  684. isFileExist = false;
  685. }
  686. });
  687. it('should create file without source map in the same directory as output file', () => {
  688. assert.equal(isFileExist, false);
  689. });
  690. after(() => {
  691. fs.unlinkSync(outputFilePath);
  692. });
  693. });
  694. after(() => {
  695. rimraf.sync(outputDirName);
  696. });
  697. });
  698. });