diff --git a/index.js b/index.js index f751cef..880f1f0 100644 --- a/index.js +++ b/index.js @@ -60,7 +60,7 @@ const defaultOptions = { }, } -const getBrowserifyOptions = (entry, userBrowserifyOptions = {}, typescriptPath = null) => { +const getBrowserifyOptions = async (entry, userBrowserifyOptions = {}, typescriptPath = null) => { let browserifyOptions = cloneDeep(defaultOptions.browserifyOptions) // allow user to override default options @@ -82,6 +82,16 @@ const getBrowserifyOptions = (entry, userBrowserifyOptions = {}, typescriptPath }) if (typescriptPath) { + if (typeof typescriptPath !== 'string') { + throw new Error(`The 'typescript' option must be a string. You passed: ${typescriptPath}`) + } + + const pathExists = await fs.pathExists(typescriptPath) + + if (!pathExists) { + throw new Error(`The 'typescript' option must be a valid path to your TypeScript installation. We could not find anything at the following path: ${typescriptPath}`) + } + const transform = browserifyOptions.transform const hasTsifyTransform = transform.some(([name]) => name.includes('tsify')) const hastsifyPlugin = browserifyOptions.plugin.includes('tsify') @@ -135,7 +145,7 @@ const preprocessor = (options = {}) => { // when running in the GUI, it will likely get called multiple times // with the same filePath, as the user could re-run the tests, causing // the supported file and spec file to be requested again - return (file) => { + return async (file) => { const filePath = file.filePath debug('get:', filePath) @@ -157,7 +167,7 @@ const preprocessor = (options = {}) => { debug('input:', filePath) debug('output:', outputPath) - const browserifyOptions = getBrowserifyOptions(filePath, options.browserifyOptions, options.typescript) + const browserifyOptions = await getBrowserifyOptions(filePath, options.browserifyOptions, options.typescript) const watchifyOptions = Object.assign({}, defaultOptions.watchifyOptions, options.watchifyOptions) const bundler = browserify(browserifyOptions) diff --git a/test/unit/index_spec.js b/test/unit/index_spec.js index be99068..5b729f5 100644 --- a/test/unit/index_spec.js +++ b/test/unit/index_spec.js @@ -424,23 +424,55 @@ describe('browserify preprocessor', function () { }) }) - describe('when typescript path and tsify are given together', function () { - it('throws error when it is a plugin', function () { + describe('validation', function () { + const shouldntResolve = () => { + throw new Error('Should error, should not resolve') + } + + it('throws error when typescript path is not a string', function () { + this.options.typescript = true + + return this.run() + .then(shouldntResolve) + .catch((err) => { + expect(err.message).to.equal(`The 'typescript' option must be a string. You passed: true`) + }) + }) + + it('throws error when nothing exists at typescript path', function () { + this.options.typescript = '/nothing/here' + + return this.run() + .then(shouldntResolve) + .catch((err) => { + expect(err.message).to.equal(`The 'typescript' option must be a valid path to your TypeScript installation. We could not find anything at the following path: /nothing/here`) + }) + }) + + it('throws error when typescript path and tsify plugin are specified', function () { this.options.browserifyOptions = { plugin: ['tsify'], } - expect(this.run).to.throw('This may cause conflicts') + return this.run() + .then(shouldntResolve) + .catch((err) => { + expect(err.message).to.include('This may cause conflicts') + }) }) - it('throws error when it is a transform', function () { + it('throws error when typescript path and tsify transform are specified', function () { this.options.browserifyOptions = { transform: [ ['path/to/tsify', {}], ], } - expect(this.run).to.throw('This may cause conflicts') + return this.run() + .then(shouldntResolve) + .catch((err) => { + expect(err.message).to.include('This may cause conflicts') + }) }) }) })