JavaScriptObfuscatorCLI.spec.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. import * as fs from 'fs';
  2. import * as mkdirp from 'mkdirp';
  3. import * as sinon from 'sinon';
  4. import { assert } from 'chai';
  5. import { StdoutWriteMock } from '../../mocks/StdoutWriteMock';
  6. import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscator';
  7. describe('JavaScriptObfuscatorCLI', function (): void {
  8. this.timeout(100000);
  9. const fixturesDirName: string = 'test/fixtures';
  10. const fixtureFileName: string = 'sample.js';
  11. const fixtureFilePath: string = `${fixturesDirName}/${fixtureFileName}`;
  12. const outputDirName: string = 'test/tmp';
  13. const outputFileName: string = 'sample-obfuscated.js';
  14. const outputFilePath: string = `${outputDirName}/${outputFileName}`;
  15. describe('run (): void', () => {
  16. before(() => {
  17. mkdirp.sync(outputDirName);
  18. });
  19. describe('`--output` option is set', () => {
  20. let isFileExist: boolean;
  21. before(() => {
  22. JavaScriptObfuscator.runCLI([
  23. 'node',
  24. 'javascript-obfuscator',
  25. fixtureFilePath,
  26. '--output',
  27. outputFilePath,
  28. '--compact',
  29. 'true',
  30. '--selfDefending',
  31. '0'
  32. ]);
  33. isFileExist = fs.existsSync(outputFilePath);
  34. });
  35. it('should create file with obfuscated code in `--output` directory', () => {
  36. assert.equal(isFileExist, true);
  37. });
  38. after(() => {
  39. fs.unlinkSync(outputFilePath);
  40. });
  41. });
  42. describe('`--output` option isn\'t set', () => {
  43. describe('variant #1: default behaviour', () => {
  44. let outputFixturesFilePath: string,
  45. isFileExist: boolean;
  46. before(() => {
  47. outputFixturesFilePath = `${fixturesDirName}/${outputFileName}`;
  48. JavaScriptObfuscator.runCLI([
  49. 'node',
  50. 'javascript-obfuscator',
  51. fixtureFilePath
  52. ]);
  53. isFileExist = fs.existsSync(outputFixturesFilePath);
  54. });
  55. it(`should create file \`${outputFileName}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => {
  56. assert.equal(isFileExist, true);
  57. });
  58. after(() => {
  59. fs.unlinkSync(outputFixturesFilePath);
  60. });
  61. });
  62. describe('variant #2: invalid input file path', () => {
  63. const expectedError: ReferenceErrorConstructor = ReferenceError;
  64. let testFunc: () => void;
  65. before(() => {
  66. testFunc = () => JavaScriptObfuscator.runCLI([
  67. 'node',
  68. 'javascript-obfuscator',
  69. 'wrong/file/path'
  70. ]);
  71. });
  72. it(`should throw an error`, () => {
  73. assert.throws(testFunc, expectedError);
  74. });
  75. });
  76. describe('variant #3: input file extension isn\'t `.js`', () => {
  77. const expectedError: ReferenceErrorConstructor = ReferenceError;
  78. const outputFileName: string = 'sample-obfuscated.ts';
  79. const outputFilePath: string = `${outputDirName}/${outputFileName}`;
  80. let testFunc: () => void;
  81. before(() => {
  82. fs.writeFileSync(outputFilePath, 'data');
  83. testFunc = () => JavaScriptObfuscator.runCLI([
  84. 'node',
  85. 'javascript-obfuscator',
  86. outputFilePath
  87. ]);
  88. });
  89. it(`should throw an error`, () => {
  90. assert.throws(testFunc, expectedError);
  91. });
  92. after(() => {
  93. fs.unlinkSync(outputFilePath);
  94. });
  95. });
  96. });
  97. describe('`--sourceMap` option is set', () => {
  98. const outputSourceMapPath: string = `${outputFilePath}.map`;
  99. describe('variant #1: `--sourceMapMode` option value is `separate`', () => {
  100. describe('variant #1: default behaviour', () => {
  101. let isFileExist: boolean,
  102. sourceMapObject: any;
  103. before(() => {
  104. JavaScriptObfuscator.runCLI([
  105. 'node',
  106. 'javascript-obfuscator',
  107. fixtureFilePath,
  108. '--output',
  109. outputFilePath,
  110. '--compact',
  111. 'true',
  112. '--selfDefending',
  113. '0',
  114. '--sourceMap',
  115. 'true'
  116. ]);
  117. try {
  118. const content: string = fs.readFileSync(outputSourceMapPath, { encoding: 'utf8' });
  119. isFileExist = true;
  120. sourceMapObject = JSON.parse(content);
  121. } catch (e) {
  122. isFileExist = false;
  123. }
  124. });
  125. it('should create file with source map in the same directory as output file', () => {
  126. assert.equal(isFileExist, true);
  127. });
  128. it('source map from created file should contains property `version`', () => {
  129. assert.property(sourceMapObject, 'version');
  130. });
  131. it('source map from created file should contains property `sources`', () => {
  132. assert.property(sourceMapObject, 'sources');
  133. });
  134. it('source map from created file should contains property `names`', () => {
  135. assert.property(sourceMapObject, 'names');
  136. });
  137. after(() => {
  138. fs.unlinkSync(outputFilePath);
  139. fs.unlinkSync(outputSourceMapPath);
  140. });
  141. });
  142. describe('variant #2: `sourceMapBaseUrl` option is set', () => {
  143. let isFileExist: boolean,
  144. sourceMapObject: any;
  145. before(() => {
  146. JavaScriptObfuscator.runCLI([
  147. 'node',
  148. 'javascript-obfuscator',
  149. fixtureFilePath,
  150. '--output',
  151. outputFilePath,
  152. '--compact',
  153. 'true',
  154. '--selfDefending',
  155. '0',
  156. '--sourceMap',
  157. 'true',
  158. '--sourceMapBaseUrl',
  159. 'http://localhost:9000/'
  160. ]);
  161. try {
  162. const content: string = fs.readFileSync(outputSourceMapPath, { encoding: 'utf8' });
  163. isFileExist = true;
  164. sourceMapObject = JSON.parse(content);
  165. } catch (e) {
  166. isFileExist = false;
  167. }
  168. });
  169. it('should create file with source map in the same directory as output file', () => {
  170. assert.equal(isFileExist, true);
  171. });
  172. it('source map from created file should contains property `version`', () => {
  173. assert.property(sourceMapObject, 'version');
  174. });
  175. it('source map from created file should contains property `sources`', () => {
  176. assert.property(sourceMapObject, 'sources');
  177. });
  178. it('source map from created file should contains property `names`', () => {
  179. assert.property(sourceMapObject, 'names');
  180. });
  181. after(() => {
  182. fs.unlinkSync(outputFilePath);
  183. fs.unlinkSync(outputSourceMapPath);
  184. });
  185. });
  186. describe('variant #3: `--sourceMapFileName` option is set', () => {
  187. const sourceMapFileName: string = 'test';
  188. const sourceMapFilePath: string = `${sourceMapFileName}.js.map`;
  189. const outputSourceMapFilePath: string = `${outputDirName}/${sourceMapFilePath}`;
  190. let isFileExist: boolean,
  191. sourceMapObject: any;
  192. before(() => {
  193. JavaScriptObfuscator.runCLI([
  194. 'node',
  195. 'javascript-obfuscator',
  196. fixtureFilePath,
  197. '--output',
  198. outputFilePath,
  199. '--compact',
  200. 'true',
  201. '--selfDefending',
  202. '0',
  203. '--sourceMap',
  204. 'true',
  205. '--sourceMapFileName',
  206. sourceMapFileName
  207. ]);
  208. try {
  209. const content: string = fs.readFileSync(outputSourceMapFilePath, { encoding: 'utf8' });
  210. isFileExist = true;
  211. sourceMapObject = JSON.parse(content);
  212. } catch (e) {
  213. isFileExist = false;
  214. }
  215. });
  216. it('should create source map file with given name in the same directory as output file', () => {
  217. assert.equal(isFileExist, true);
  218. });
  219. it('source map from created file should contains property `version`', () => {
  220. assert.property(sourceMapObject, 'version');
  221. });
  222. it('source map from created file should contains property `sources`', () => {
  223. assert.property(sourceMapObject, 'sources');
  224. });
  225. it('source map from created file should contains property `names`', () => {
  226. assert.property(sourceMapObject, 'names');
  227. });
  228. after(() => {
  229. fs.unlinkSync(outputFilePath);
  230. fs.unlinkSync(outputSourceMapFilePath);
  231. });
  232. });
  233. });
  234. describe('variant #2: `--sourceMapMode` option is `inline`', () => {
  235. let isFileExist: boolean;
  236. before(() => {
  237. JavaScriptObfuscator.runCLI([
  238. 'node',
  239. 'javascript-obfuscator',
  240. fixtureFilePath,
  241. '--output',
  242. outputFilePath,
  243. '--compact',
  244. 'true',
  245. '--selfDefending',
  246. '0',
  247. '--sourceMap',
  248. 'true',
  249. '--sourceMapMode',
  250. 'inline'
  251. ]);
  252. isFileExist = fs.existsSync(outputSourceMapPath);
  253. });
  254. it('shouldn\'t create file with source map', () => {
  255. assert.equal(isFileExist, false);
  256. });
  257. after(() => {
  258. fs.unlinkSync(outputFilePath);
  259. });
  260. });
  261. });
  262. describe('help output', () => {
  263. let callback: sinon.SinonSpy,
  264. stdoutWriteMock: StdoutWriteMock;
  265. beforeEach(() => {
  266. callback = sinon.spy(console, 'log');
  267. stdoutWriteMock = new StdoutWriteMock(process.stdout.write);
  268. });
  269. describe('`--help` option is set', () => {
  270. let isConsoleLogCalled: boolean;
  271. beforeEach(() => {
  272. stdoutWriteMock.mute();
  273. JavaScriptObfuscator.runCLI([
  274. 'node',
  275. 'javascript-obfuscator',
  276. fixtureFilePath,
  277. '--help'
  278. ]);
  279. stdoutWriteMock.restore();
  280. isConsoleLogCalled = callback.called;
  281. });
  282. it('should print `console.log` help', () => {
  283. assert.equal(isConsoleLogCalled, true);
  284. });
  285. });
  286. describe('no arguments passed', () => {
  287. let isConsoleLogCalled: boolean;
  288. beforeEach(() => {
  289. stdoutWriteMock.mute();
  290. JavaScriptObfuscator.runCLI([
  291. 'node',
  292. 'javascript-obfuscator'
  293. ]);
  294. stdoutWriteMock.restore();
  295. isConsoleLogCalled = callback.called;
  296. });
  297. it('should print `console.log` help', () => {
  298. assert.equal(isConsoleLogCalled, true);
  299. });
  300. });
  301. afterEach(() => {
  302. callback.restore();
  303. });
  304. });
  305. after(() => {
  306. fs.rmdirSync(outputDirName);
  307. });
  308. });
  309. });