| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590 | import * as fs from 'fs';import * as mkdirp from 'mkdirp';import * as rimraf from 'rimraf';import { assert } from 'chai';import * as sinon from 'sinon';import { IFileData } from '../../../../src/interfaces/cli/IFileData';import { SourceCodeReader } from '../../../../src/cli/utils/SourceCodeReader';describe('SourceCodeReader', () => {    const expectedError: RegExp = /Given input path must be a valid/;    const fileContent: string = 'test';    const tmpDirectoryPath: string = 'test/tmp';    before(() => {        mkdirp.sync(tmpDirectoryPath);    });    describe('readSourceCode', () => {        describe('Variant #1: input path is a file path', () => {            describe('Variant #1: `inputPath` is a valid path', () => {                const tmpFileName: string = 'test.js';                const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;                const expectedFilesData: IFileData[] = [{                    content: fileContent,                    filePath: inputPath                }];                let filesData: IFileData[];                before(() => {                    fs.writeFileSync(inputPath, fileContent);                    filesData = new SourceCodeReader(inputPath, {}).readSourceCode();                });                it('should return valid files data', () => {                    assert.deepEqual(filesData, expectedFilesData);                });                after(() => {                    fs.unlinkSync(inputPath);                });            });            describe('Variant #2: `inputPath` is not a valid path', () => {                const tmpFileName: string = 'test.js';                const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;                let testFunc: () => void;                before(() => {                    testFunc = () => new SourceCodeReader(inputPath, {}).readSourceCode();                });                it('should throw an error if `inputPath` is not a valid path', () => {                    assert.throws(testFunc, expectedError);                });            });            describe('Variant #3: `inputPath` has invalid extension', () => {                const tmpFileName: string = 'test.ts';                const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;                let testFunc: () => void;                before(() => {                    fs.writeFileSync(inputPath, fileContent);                    testFunc = () => new SourceCodeReader(inputPath, {}).readSourceCode();                });                it('should throw an error if `inputPath` has invalid extension', () => {                    assert.throws(testFunc, expectedError);                });                after(() => {                    fs.unlinkSync(inputPath);                });            });            describe('Variant #4: `exclude` option', () => {                describe('Variant #1: `inputPath` isn\'t excluded path', () => {                    const tmpFileName: string = 'test.js';                    const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;                    const expectedFilesData: IFileData[] = [{                        content: fileContent,                        filePath: inputPath                    }];                    let filesData: IFileData[];                    before(() => {                        fs.writeFileSync(inputPath, fileContent);                        filesData = new SourceCodeReader(                            inputPath,                            {                                exclude: ['**/foo.js']                            }                        ).readSourceCode();                    });                    it('should return valid files data', () => {                        assert.deepEqual(filesData, expectedFilesData);                    });                    after(() => {                        fs.unlinkSync(inputPath);                    });                });                describe('Variant #2: `inputPath` is excluded path', () => {                    describe('Variant #1: exclude by `glob` pattern', () => {                        const tmpFileName: string = 'test.js';                        const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;                        let testFunc: () => void;                        before(() => {                            fs.writeFileSync(inputPath, fileContent);                            testFunc = () => new SourceCodeReader(                                inputPath,                                {                                    exclude: [`**/${tmpFileName}`]                                }                            ).readSourceCode();                        });                        it('should throw an error if `inputPath` is the excluded file path', () => {                            assert.throws(testFunc, expectedError);                        });                        after(() => {                            fs.unlinkSync(inputPath);                        });                    });                    describe('Variant #2: exclude by file name', () => {                        const tmpFileName: string = 'test.js';                        const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;                        let testFunc: () => void;                        before(() => {                            fs.writeFileSync(inputPath, fileContent);                            testFunc = () => new SourceCodeReader(                                inputPath,                                {                                    exclude: [tmpFileName]                                }                            ).readSourceCode();                        });                        it('should throw an error if `inputPath` is the excluded file path', () => {                            assert.throws(testFunc, expectedError);                        });                        after(() => {                            fs.unlinkSync(inputPath);                        });                    });                    describe('Variant #3: exclude by file path', () => {                        const tmpFileName: string = 'test.js';                        const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;                        let testFunc: () => void;                        before(() => {                            fs.writeFileSync(inputPath, fileContent);                            testFunc = () => new SourceCodeReader(                                inputPath,                                {                                    exclude: [inputPath]                                }                            ).readSourceCode();                        });                        it('should throw an error if `inputPath` is the excluded file path', () => {                            assert.throws(testFunc, expectedError);                        });                        after(() => {                            fs.unlinkSync(inputPath);                        });                    });                });            });        });        describe('Variant #2: input path is a directory path', () => {            describe('Variant #1: `inputPath` is a valid path', () => {                const tmpFileName1: string = 'foo.js';                const tmpFileName2: string = 'bar.js';                const tmpFileName3: string = 'baz.png';                const tmpFileName4: string = 'bark-obfuscated.js';                const filePath1: string = `${tmpDirectoryPath}/${tmpFileName1}`;                const filePath2: string = `${tmpDirectoryPath}/${tmpFileName2}`;                const filePath3: string = `${tmpDirectoryPath}/${tmpFileName3}`;                const filePath4: string = `${tmpDirectoryPath}/${tmpFileName4}`;                const expectedResult: IFileData[] = [                    {                        filePath: filePath2,                        content: fileContent                    },                    {                        filePath: filePath1,                        content: fileContent                    }                ];                let result: IFileData[];                before(() => {                    fs.writeFileSync(filePath1, fileContent);                    fs.writeFileSync(filePath2, fileContent);                    fs.writeFileSync(filePath3, fileContent);                    fs.writeFileSync(filePath4, fileContent);                    result = new SourceCodeReader(tmpDirectoryPath, {}).readSourceCode();                });                it('should return files data', () => {                    assert.deepEqual(result, expectedResult);                });                after(() => {                    fs.unlinkSync(filePath1);                    fs.unlinkSync(filePath2);                    fs.unlinkSync(filePath3);                    fs.unlinkSync(filePath4);                });            });            describe('Variant #2: `inputPath` is not a valid path', () => {                const inputPath: string = 'abc';                let testFunc: () => void;                before(() => {                    testFunc = () => new SourceCodeReader(inputPath, {}).readSourceCode();                });                it('should throw an error if `inputPath` is not a valid path', () => {                    assert.throws(testFunc, expectedError);                });            });            describe('Variant #3: `inputPath` is a directory with sub-directories', () => {                const parentDirectoryName1: string = 'parent1';                const parentDirectoryName2: string = 'parent';                const parentDirectoryPath1: string = `${tmpDirectoryPath}/${parentDirectoryName1}`;                const parentDirectoryPath2: string = `${tmpDirectoryPath}/${parentDirectoryName2}`;                const tmpFileName1: string = 'foo.js';                const tmpFileName2: string = 'bar.js';                const tmpFileName3: string = 'baz.js';                const tmpFileName4: string = 'bark.js';                const filePath1: string = `${tmpDirectoryPath}/${tmpFileName1}`;                const filePath2: string = `${tmpDirectoryPath}/${tmpFileName2}`;                const filePath3: string = `${parentDirectoryPath1}/${tmpFileName3}`;                const filePath4: string = `${parentDirectoryPath2}/${tmpFileName4}`;                const expectedResult: IFileData[] = [                    {                        filePath: filePath2,                        content: fileContent                    },                    {                        filePath: filePath1,                        content: fileContent                    },                    {                        filePath: filePath4,                        content: fileContent                    },                    {                        filePath: filePath3,                        content: fileContent                    }                ];                let result: IFileData[];                before(() => {                    mkdirp.sync(parentDirectoryPath1);                    mkdirp.sync(parentDirectoryPath2);                    fs.writeFileSync(filePath1, fileContent);                    fs.writeFileSync(filePath2, fileContent);                    fs.writeFileSync(filePath3, fileContent);                    fs.writeFileSync(filePath4, fileContent);                    result = new SourceCodeReader(tmpDirectoryPath, {}).readSourceCode();                });                it('should return files data', () => {                    assert.deepEqual(result, expectedResult);                });                after(() => {                    fs.unlinkSync(filePath1);                    fs.unlinkSync(filePath2);                    fs.unlinkSync(filePath3);                    fs.unlinkSync(filePath4);                    rimraf.sync(parentDirectoryPath1);                    rimraf.sync(parentDirectoryPath2);                });            });            describe('Variant #4: `exclude` option', () => {                describe('Variant #1: `inputPath` isn\'t excluded path', () => {                    const tmpFileName1: string = 'foo.js';                    const tmpFileName2: string = 'bar.js';                    const tmpFileName3: string = 'baz.png';                    const tmpFileName4: string = 'bark-obfuscated.js';                    const filePath1: string = `${tmpDirectoryPath}/${tmpFileName1}`;                    const filePath2: string = `${tmpDirectoryPath}/${tmpFileName2}`;                    const filePath3: string = `${tmpDirectoryPath}/${tmpFileName3}`;                    const filePath4: string = `${tmpDirectoryPath}/${tmpFileName4}`;                    const expectedResult: IFileData[] = [                        {                            filePath: filePath2,                            content: fileContent                        },                        {                            filePath: filePath1,                            content: fileContent                        }                    ];                    let result: IFileData[];                    before(() => {                        fs.writeFileSync(filePath1, fileContent);                        fs.writeFileSync(filePath2, fileContent);                        fs.writeFileSync(filePath3, fileContent);                        fs.writeFileSync(filePath4, fileContent);                        result = new SourceCodeReader(                            tmpDirectoryPath,                            {                                exclude: ['**/hawk.js']                            }                        ).readSourceCode();                    });                    it('should return files data', () => {                        assert.deepEqual(result, expectedResult);                    });                    after(() => {                        fs.unlinkSync(filePath1);                        fs.unlinkSync(filePath2);                        fs.unlinkSync(filePath3);                        fs.unlinkSync(filePath4);                    });                });                describe('Variant #2: `inputPath` is excluded path', () => {                    describe('Variant #1: exclude by `glob` pattern', () => {                        const tmpFileName1: string = 'foo.js';                        const tmpFileName2: string = 'bar.js';                        const tmpFileName3: string = 'baz.js';                        const tmpFileName4: string = 'bark.js';                        const filePath1: string = `${tmpDirectoryPath}/${tmpFileName1}`;                        const filePath2: string = `${tmpDirectoryPath}/${tmpFileName2}`;                        const filePath3: string = `${tmpDirectoryPath}/${tmpFileName3}`;                        const filePath4: string = `${tmpDirectoryPath}/${tmpFileName4}`;                        const expectedResult: IFileData[] = [                            {                                filePath: filePath3,                                content: fileContent                            },                            {                                filePath: filePath1,                                content: fileContent                            }                        ];                        let result: IFileData[];                        before(() => {                            fs.writeFileSync(filePath1, fileContent);                            fs.writeFileSync(filePath2, fileContent);                            fs.writeFileSync(filePath3, fileContent);                            fs.writeFileSync(filePath4, fileContent);                            result = new SourceCodeReader(                                tmpDirectoryPath,                                {                                    exclude: [                                        `**/${tmpFileName2}`,                                        `**/${tmpFileName4}`                                    ]                                }                            ).readSourceCode();                        });                        it('should return files data', () => {                            assert.deepEqual(result, expectedResult);                        });                        after(() => {                            fs.unlinkSync(filePath1);                            fs.unlinkSync(filePath2);                            fs.unlinkSync(filePath3);                            fs.unlinkSync(filePath4);                        });                    });                    describe('Variant #2: exclude by file name', () => {                        const tmpFileName1: string = 'foo.js';                        const tmpFileName2: string = 'bar.js';                        const tmpFileName3: string = 'baz.js';                        const tmpFileName4: string = 'bark.js';                        const filePath1: string = `${tmpDirectoryPath}/${tmpFileName1}`;                        const filePath2: string = `${tmpDirectoryPath}/${tmpFileName2}`;                        const filePath3: string = `${tmpDirectoryPath}/${tmpFileName3}`;                        const filePath4: string = `${tmpDirectoryPath}/${tmpFileName4}`;                        const expectedResult: IFileData[] = [                            {                                filePath: filePath3,                                content: fileContent                            },                            {                                filePath: filePath1,                                content: fileContent                            }                        ];                        let result: IFileData[];                        before(() => {                            fs.writeFileSync(filePath1, fileContent);                            fs.writeFileSync(filePath2, fileContent);                            fs.writeFileSync(filePath3, fileContent);                            fs.writeFileSync(filePath4, fileContent);                            result = new SourceCodeReader(                                tmpDirectoryPath,                                {                                    exclude: [                                        tmpFileName2,                                        tmpFileName4                                    ]                                }                            ).readSourceCode();                        });                        it('should return files data', () => {                            assert.deepEqual(result, expectedResult);                        });                        after(() => {                            fs.unlinkSync(filePath1);                            fs.unlinkSync(filePath2);                            fs.unlinkSync(filePath3);                            fs.unlinkSync(filePath4);                        });                    });                    describe('Variant #3: exclude by file path', () => {                        const tmpFileName1: string = 'foo.js';                        const tmpFileName2: string = 'bar.js';                        const tmpFileName3: string = 'baz.js';                        const tmpFileName4: string = 'bark.js';                        const filePath1: string = `${tmpDirectoryPath}/${tmpFileName1}`;                        const filePath2: string = `${tmpDirectoryPath}/${tmpFileName2}`;                        const filePath3: string = `${tmpDirectoryPath}/${tmpFileName3}`;                        const filePath4: string = `${tmpDirectoryPath}/${tmpFileName4}`;                        const expectedResult: IFileData[] = [                            {                                filePath: filePath3,                                content: fileContent                            },                            {                                filePath: filePath1,                                content: fileContent                            }                        ];                        let result: IFileData[];                        before(() => {                            fs.writeFileSync(filePath1, fileContent);                            fs.writeFileSync(filePath2, fileContent);                            fs.writeFileSync(filePath3, fileContent);                            fs.writeFileSync(filePath4, fileContent);                            result = new SourceCodeReader(                                tmpDirectoryPath,                                {                                    exclude: [                                        filePath2,                                        filePath4                                    ]                                }                            ).readSourceCode();                        });                        it('should return files data', () => {                            assert.deepEqual(result, expectedResult);                        });                        after(() => {                            fs.unlinkSync(filePath1);                            fs.unlinkSync(filePath2);                            fs.unlinkSync(filePath3);                            fs.unlinkSync(filePath4);                        });                    });                    describe('Variant #4: exclude whole directory', () => {                        const tmpFileName1: string = 'foo.js';                        const tmpFileName2: string = 'bar.js';                        const tmpFileName3: string = 'baz.js';                        const tmpFileName4: string = 'bark.js';                        const filePath1: string = `${tmpDirectoryPath}/${tmpFileName1}`;                        const filePath2: string = `${tmpDirectoryPath}/${tmpFileName2}`;                        const filePath3: string = `${tmpDirectoryPath}/${tmpFileName3}`;                        const filePath4: string = `${tmpDirectoryPath}/${tmpFileName4}`;                        let testFunc: () => void;                        before(() => {                            fs.writeFileSync(filePath1, fileContent);                            fs.writeFileSync(filePath2, fileContent);                            fs.writeFileSync(filePath3, fileContent);                            fs.writeFileSync(filePath4, fileContent);                            testFunc = () => new SourceCodeReader(                                tmpDirectoryPath,                                {                                    exclude: [tmpDirectoryPath]                                }                            ).readSourceCode();                        });                        it('should return files data', () => {                            assert.throws(testFunc, expectedError);                        });                        after(() => {                            fs.unlinkSync(filePath1);                            fs.unlinkSync(filePath2);                            fs.unlinkSync(filePath3);                            fs.unlinkSync(filePath4);                        });                    });                });            });        });        describe('Variant #3: logging', () => {            const tmpFileName: string = 'test.js';            const inputPath: string = `${tmpDirectoryPath}/${tmpFileName}`;            const expectedConsoleLogCallResult: boolean = true;            const expectedLoggingMessage: string = `[javascript-obfuscator-cli] Obfuscating file: ${inputPath}...`;            let consoleLogSpy: sinon.SinonSpy<any, void>,                consoleLogCallResult: boolean,                loggingMessageResult: string;            before(() => {                consoleLogSpy = sinon.spy(console, 'log');                fs.writeFileSync(inputPath, fileContent);                new SourceCodeReader(inputPath, {}).readSourceCode();                consoleLogCallResult = consoleLogSpy.called;                loggingMessageResult = consoleLogSpy.getCall(0).args[0];            });            it('should call `console.log`', () => {                assert.equal(consoleLogCallResult, expectedConsoleLogCallResult);            });            it('should log file name to the console', () => {                assert.include(loggingMessageResult, expectedLoggingMessage);            });            after(() => {                consoleLogSpy.restore();                fs.unlinkSync(inputPath);            });        });    });    after(() => {        rimraf.sync(tmpDirectoryPath);    });});
 |