diff --git a/test/integration/helpers.js b/test/integration/helpers.js index 705bdba3..b913acff 100644 --- a/test/integration/helpers.js +++ b/test/integration/helpers.js @@ -2,16 +2,27 @@ var fs = require('fs'); var path = require('path'); var webpack = require('webpack'); var ForkTsCheckerWebpackPlugin = require('../../lib/index'); -var IncrementalChecker = require('../../lib/IncrementalChecker') - .IncrementalChecker; -var NormalizedMessageFactories = require('../../lib/NormalizedMessageFactories'); +var RpcProvider = require('worker-rpc').RpcProvider; var webpackMajorVersion = require('./webpackVersion')(); var VueLoaderPlugin = webpackMajorVersion >= 4 ? require('vue-loader/lib/plugin') : undefined; -exports.createVueCompiler = function(options) { +const rpcMethods = { + checker_nextIteration: 'checker_nextIteration', + checker_getKnownFileNames: 'checker_getKnownFileNames', + checker_getSourceFile: 'checker_getSourceFile', + checker_getSyntacticDiagnostics: 'checker_getSyntacticDiagnostics' +}; + +exports.createVueCompiler = async function(options) { var plugin = new ForkTsCheckerWebpackPlugin({ ...options, silent: true }); + plugin.nodeArgs = [ + `--require`, + `${path.resolve(__dirname, './mocks/IncrementalCheckerWithRpc.js')}`, + `--require`, + `${path.resolve(__dirname, './mocks/ApiIncrementalCheckerWithRpc.js')}` + ]; var compiler = webpack({ ...(webpackMajorVersion >= 4 ? { mode: 'development' } : {}), @@ -57,27 +68,10 @@ exports.createVueCompiler = function(options) { 'syntacticError.ts': path.resolve(compiler.context, 'src/syntacticError.ts') }; - var checker = new IncrementalChecker( - require('typescript'), - NormalizedMessageFactories.makeCreateNormalizedMessageFromDiagnostic( - require('typescript') - ), - NormalizedMessageFactories.makeCreateNormalizedMessageFromRuleFailure, - plugin.tsconfigPath, - {}, - path.resolve(__dirname, './vue'), - plugin.tslintPath || false, - plugin.tslintAutoFix || false, - [compiler.context], - ForkTsCheckerWebpackPlugin.ONE_CPU, - 1, - plugin.checkSyntacticErrors, - plugin.vue - ); - - checker.nextIteration(); + plugin.spawnService(); + await plugin.serviceRpc.rpc(rpcMethods.checker_nextIteration); - return { plugin, compiler, files, checker }; + return { plugin, compiler, files }; }; exports.createCompiler = function( @@ -194,3 +188,14 @@ exports.expectedErrorCodes = { expectedSyntacticErrorCode: 'TS1005', expectedSemanticErrorCode: 'TS2322' }; + +exports.rpcMethods = rpcMethods; + +let rpc; +exports.getRpcProvider = () => { + if (!rpc) { + rpc = new RpcProvider(message => process.send(message)); + process.on('message', message => rpc.dispatch(message)); + } + return rpc; +}; diff --git a/test/integration/incrementalApi.spec.js b/test/integration/incrementalApi.spec.js index e5456c9b..6835d643 100644 --- a/test/integration/incrementalApi.spec.js +++ b/test/integration/incrementalApi.spec.js @@ -88,31 +88,32 @@ describe('[INTEGRATION] specific tests for useTypescriptIncrementalApi: true', f }); it('should get syntactic diagnostics from Vue program', function(callback) { - var { compiler } = createVueCompiler({ checkSyntacticErrors: true }); - - compiler.run(function(error, stats) { - const syntacticErrorFoundInStats = stats.compilation.errors.some(error => - error.rawMessage.includes( - helpers.expectedErrorCodes.expectedSyntacticErrorCode - ) - ); - expect(syntacticErrorFoundInStats).to.be.true; - callback(); - }); + createVueCompiler({ checkSyntacticErrors: true }).then(({ compiler }) => + compiler.run(function(error, stats) { + const syntacticErrorFoundInStats = stats.compilation.errors.some( + error => + error.rawMessage.includes( + helpers.expectedErrorCodes.expectedSyntacticErrorCode + ) + ); + expect(syntacticErrorFoundInStats).to.be.true; + callback(); + }) + ); }); it('should not find syntactic errors in Vue program when checkSyntacticErrors is false', function(callback) { - var { compiler } = createVueCompiler({ checkSyntacticErrors: false }); - - compiler.run(function(error, stats) { - const syntacticErrorNotFoundInStats = stats.compilation.errors.every( - error => - !error.rawMessage.includes( - helpers.expectedErrorCodes.expectedSyntacticErrorCode - ) - ); - expect(syntacticErrorNotFoundInStats).to.be.true; - callback(); - }); + createVueCompiler({ checkSyntacticErrors: false }).then(({ compiler }) => + compiler.run(function(error, stats) { + const syntacticErrorNotFoundInStats = stats.compilation.errors.every( + error => + !error.rawMessage.includes( + helpers.expectedErrorCodes.expectedSyntacticErrorCode + ) + ); + expect(syntacticErrorNotFoundInStats).to.be.true; + callback(); + }) + ); }); }); diff --git a/test/integration/mocks/ApiIncrementalCheckerWithRpc.js b/test/integration/mocks/ApiIncrementalCheckerWithRpc.js new file mode 100644 index 00000000..7802fbc7 --- /dev/null +++ b/test/integration/mocks/ApiIncrementalCheckerWithRpc.js @@ -0,0 +1,57 @@ +const mock = require('mock-require'); + +const origImport = require('../../../lib/ApiIncrementalChecker'); +const { rpcMethods, getRpcProvider } = require('../helpers'); + +mock('../../../lib/ApiIncrementalChecker', { + ApiIncrementalChecker: class extends origImport.ApiIncrementalChecker { + constructor(...args) { + super(...args); + + const rpc = getRpcProvider(); + + const awaitInit = async () => { + if (!this.tsIncrementalCompiler.lastProcessing) { + await this.tsIncrementalCompiler.processChanges(); + } else { + await this.tsIncrementalCompiler.lastProcessing; + } + }; + + rpc.registerRpcHandler(rpcMethods.checker_nextIteration, () => { + return this.nextIteration(); + }); + + rpc.registerRpcHandler(rpcMethods.checker_getKnownFileNames, async () => { + await awaitInit(); + return Array.from(this.tsIncrementalCompiler.getAllKnownFiles()); + }); + + rpc.registerRpcHandler( + rpcMethods.checker_getSourceFile, + async fileName => { + await awaitInit(); + const result = this.tsIncrementalCompiler + .getProgram() + .getSourceFile(fileName); + return !result ? undefined : { text: result.text }; + } + ); + + rpc.registerRpcHandler( + rpcMethods.checker_getSyntacticDiagnostics, + async () => { + await awaitInit(); + const result = this.tsIncrementalCompiler + .getProgram() + .getSyntacticDiagnostics(); + return result.map(({ start, length, file }) => ({ + start, + length, + file: { text: file.text } + })); + } + ); + } + } +}); diff --git a/test/integration/mocks/IncrementalCheckerWithRpc.js b/test/integration/mocks/IncrementalCheckerWithRpc.js new file mode 100644 index 00000000..652a29af --- /dev/null +++ b/test/integration/mocks/IncrementalCheckerWithRpc.js @@ -0,0 +1,37 @@ +const mock = require('mock-require'); + +const origImport = require('../../../lib/IncrementalChecker'); + +const { rpcMethods, getRpcProvider } = require('../helpers'); + +mock('../../../lib/IncrementalChecker', { + IncrementalChecker: class extends origImport.IncrementalChecker { + constructor(...args) { + super(...args); + + const rpc = getRpcProvider(); + + rpc.registerRpcHandler(rpcMethods.checker_nextIteration, () => { + return this.nextIteration(); + }); + + rpc.registerRpcHandler(rpcMethods.checker_getKnownFileNames, () => { + return this.programConfig.fileNames; + }); + + rpc.registerRpcHandler(rpcMethods.checker_getSourceFile, fileName => { + const result = this.program.getSourceFile(fileName); + return !result ? undefined : { text: result.text }; + }); + + rpc.registerRpcHandler(rpcMethods.checker_getSyntacticDiagnostics, () => { + const result = this.program.getSyntacticDiagnostics(); + return result.map(({ start, length, file }) => ({ + start, + length, + file: { text: file.text } + })); + }); + } + } +}); diff --git a/test/integration/vue.spec.js b/test/integration/vue.spec.js index f00e6a1b..c9fb4e3d 100644 --- a/test/integration/vue.spec.js +++ b/test/integration/vue.spec.js @@ -2,273 +2,312 @@ var describe = require('mocha').describe; var it = require('mocha').it; var expect = require('chai').expect; var path = require('path'); -var process = require('process'); var unixify = require('unixify'); var helpers = require('./helpers'); -describe('[INTEGRATION] vue', function() { - this.timeout(60000); - process.setMaxListeners(0); - var files; - var compiler; - var checker; - - function createCompiler(options) { - var vueCompiler = helpers.createVueCompiler(options); - files = vueCompiler.files; - compiler = vueCompiler.compiler; - checker = vueCompiler.checker; - } - - it('should create a Vue program config if vue=true', function() { - createCompiler({ vue: true }); - - var fileFound; - var fileWeWant = unixify(files['example.vue']); - fileFound = checker.programConfig.fileNames.some( - filename => unixify(filename) === fileWeWant - ); - expect(fileFound).to.be.true; - - fileWeWant = unixify(files['syntacticError.ts']); - fileFound = checker.programConfig.fileNames.some( - filename => unixify(filename) === fileWeWant - ); - expect(fileFound).to.be.true; - }); - - it('should not create a Vue program config if vue=false', function() { - createCompiler(); - - var fileFound; - var fileWeWant = unixify(files['example.vue']); - - fileFound = checker.programConfig.fileNames.some( - filename => unixify(filename) === fileWeWant - ); - expect(fileFound).to.be.false; - - fileWeWant = unixify(files['syntacticError.ts']); - fileFound = checker.programConfig.fileNames.some( - filename => unixify(filename) === fileWeWant - ); - expect(fileFound).to.be.true; - }); - - it('should create a Vue program if vue=true', function() { - createCompiler({ vue: true }); - - var source; - - source = checker.program.getSourceFile(files['example.vue']); - expect(source).to.not.be.undefined; - - source = checker.program.getSourceFile(files['syntacticError.ts']); - expect(source).to.not.be.undefined; - }); - - it('should not create a Vue program if vue=false', function() { - createCompiler(); - - var source; - - source = checker.program.getSourceFile(files['example.vue']); - expect(source).to.be.undefined; - - source = checker.program.getSourceFile(files['syntacticError.ts']); - expect(source).to.not.be.undefined; - }); - - it('should get syntactic diagnostics from Vue program', function() { - createCompiler({ tslint: true, vue: true }); - - const diagnostics = checker.program.getSyntacticDiagnostics(); - expect(diagnostics.length).to.be.equal(1); - }); - - it('should not find syntactic errors when checkSyntacticErrors is false', function(callback) { - createCompiler({ tslint: true, vue: true }); - - compiler.run(function(error, stats) { - const syntacticErrorNotFoundInStats = stats.compilation.errors.every( - error => - !error.rawMessage.includes( - helpers.expectedErrorCodes.expectedSyntacticErrorCode - ) - ); - expect(syntacticErrorNotFoundInStats).to.be.true; - callback(); - }); - }); +describe.skip( + '[INTEGRATION] vue tests - useTypescriptIncrementalApi: true', + makeCommonTests(true) +); +describe( + '[INTEGRATION] vue tests - useTypescriptIncrementalApi: false', + makeCommonTests(false) +); + +function makeCommonTests(useTypescriptIncrementalApi) { + return function() { + this.timeout(60000); + require('events').EventEmitter.defaultMaxListeners = 100; + var files; + var compiler; + var rpc; + + const getKnownFileNames = () => + rpc.rpc(helpers.rpcMethods.checker_getKnownFileNames); + const getSourceFile = fileName => + rpc.rpc(helpers.rpcMethods.checker_getSourceFile, fileName); + const getSyntacticDiagnostics = () => + rpc.rpc(helpers.rpcMethods.checker_getSyntacticDiagnostics); + + async function createCompiler(options) { + options = options || {}; + options.useTypescriptIncrementalApi = useTypescriptIncrementalApi; + var vueCompiler = await helpers.createVueCompiler(options); + files = vueCompiler.files; + compiler = vueCompiler.compiler; + rpc = vueCompiler.plugin.serviceRpc; + } - it('should find syntactic errors when checkSyntacticErrors is true', function(callback) { - createCompiler({ tslint: true, vue: true, checkSyntacticErrors: true }); + it('should create a Vue program config if vue=true', async function() { + await createCompiler({ vue: true }); - compiler.run(function(error, stats) { - const syntacticErrorFoundInStats = stats.compilation.errors.some(error => - error.rawMessage.includes( - helpers.expectedErrorCodes.expectedSyntacticErrorCode - ) - ); - expect(syntacticErrorFoundInStats).to.be.true; - callback(); - }); - }); + const fileNames = await getKnownFileNames(); - it('should not report no-consecutive-blank-lines tslint rule', function(callback) { - createCompiler({ tslint: true, vue: true }); + var fileFound; + var fileWeWant = unixify(files['example.vue']); + fileFound = fileNames.some(filename => unixify(filename) === fileWeWant); + expect(fileFound).to.be.true; - compiler.run(function(error, stats) { - stats.compilation.warnings.forEach(function(warning) { - expect(warning.rawMessage).to.not.match(/no-consecutive-blank-lines/); - }); - callback(); + fileWeWant = unixify(files['syntacticError.ts']); + fileFound = fileNames.some(filename => unixify(filename) === fileWeWant); + expect(fileFound).to.be.true; }); - }); - it('should resolve src attribute but not report not found error', function(callback) { - createCompiler({ vue: true, tsconfig: 'tsconfig-attrs.json' }); + it('should not create a Vue program config if vue=false', async function() { + await createCompiler(); - compiler.run(function(error, stats) { - const errors = stats.compilation.errors; - expect(errors.length).to.be.equal(1); - expect(errors[0].file).to.match( - /test\/integration\/vue\/src\/attrs\/test.ts$/ - ); - callback(); + const fileNames = await getKnownFileNames(); + + var fileFound; + var fileWeWant = unixify(files['example.vue']); + + fileFound = fileNames.some(filename => unixify(filename) === fileWeWant); + expect(fileFound).to.be.false; + + fileWeWant = unixify(files['syntacticError.ts']); + fileFound = fileNames.some(filename => unixify(filename) === fileWeWant); + expect(fileFound).to.be.true; }); - }); - - [ - 'example-ts.vue', - 'example-tsx.vue', - 'example-js.vue', - 'example-jsx.vue', - 'example-nolang.vue' - ].forEach(fileName => { - it('should be able to extract script from ' + fileName, function() { - createCompiler({ vue: true, tsconfig: 'tsconfig-langs.json' }); - var sourceFilePath = path.resolve( - compiler.context, - 'src/langs/' + fileName - ); - var source = checker.program.getSourceFile(sourceFilePath); + + it('should create a Vue program if vue=true', async function() { + await createCompiler({ vue: true }); + + var source; + + source = await getSourceFile(files['example.vue']); + expect(source).to.not.be.undefined; + + source = await getSourceFile(files['syntacticError.ts']); expect(source).to.not.be.undefined; - // remove padding lines - var text = source.text.replace(/^\s*\/\/.*$\r*\n/gm, '').trim(); - expect(text.startsWith('/* OK */')).to.be.true; - }); - }); - - function groupByFileName(errors) { - var ret = { - 'example-ts.vue': [], - 'example-tsx.vue': [], - 'example-js.vue': [], - 'example-jsx.vue': [], - 'example-nolang.vue': [] - }; - for (var error of errors) { - ret[path.basename(error.file)].push(error); - } - return ret; - } - - describe('should be able to compile *.vue with each lang', function() { - var errors; - before(function(callback) { - createCompiler({ vue: true, tsconfig: 'tsconfig-langs.json' }); - compiler.run(function(error, stats) { - errors = groupByFileName(stats.compilation.errors); - callback(); - }); - }); - it('lang=ts', function() { - expect(errors['example-ts.vue'].length).to.be.equal(0); - }); - it('lang=tsx', function() { - expect(errors['example-tsx.vue'].length).to.be.equal(0); - }); - it('lang=js', function() { - expect(errors['example-js.vue'].length).to.be.equal(0); - }); - it('lang=jsx', function() { - expect(errors['example-jsx.vue'].length).to.be.equal(0); }); - it('no lang', function() { - expect(errors['example-nolang.vue'].length).to.be.equal(0); + + it('should not create a Vue program if vue=false', async function() { + await createCompiler(); + + var source; + + source = await getSourceFile(files['example.vue']); + expect(source).to.be.undefined; + + source = await getSourceFile(files['syntacticError.ts']); + expect(source).to.not.be.undefined; }); - }); - - describe('should be able to detect errors in *.vue', function() { - var errors; - before(function(callback) { - // tsconfig-langs-strict.json === tsconfig-langs.json + noUnusedLocals - createCompiler({ vue: true, tsconfig: 'tsconfig-langs-strict.json' }); - compiler.run(function(error, stats) { - errors = groupByFileName(stats.compilation.errors); - callback(); - }); + + it('should get syntactic diagnostics from Vue program', async function() { + await createCompiler({ tslint: true, vue: true }); + + const diagnostics = await getSyntacticDiagnostics(); + expect(diagnostics.length).to.be.equal(1); }); - it('lang=ts', function() { - expect(errors['example-ts.vue'].length).to.be.equal(1); - expect(errors['example-ts.vue'][0].rawMessage).to.match( - /'a' is declared but/ + + it('should not find syntactic errors when checkSyntacticErrors is false', function(callback) { + createCompiler({ tslint: true, vue: true }).then(() => + compiler.run(function(error, stats) { + const syntacticErrorNotFoundInStats = stats.compilation.errors.every( + error => + !error.rawMessage.includes( + helpers.expectedErrorCodes.expectedSyntacticErrorCode + ) + ); + expect(syntacticErrorNotFoundInStats).to.be.true; + callback(); + }) ); }); - it('lang=tsx', function() { - expect(errors['example-tsx.vue'].length).to.be.equal(1); - expect(errors['example-tsx.vue'][0].rawMessage).to.match( - /'a' is declared but/ + + it('should find syntactic errors when checkSyntacticErrors is true', function(callback) { + createCompiler({ + tslint: true, + vue: true, + checkSyntacticErrors: true + }).then(() => + compiler.run(function(error, stats) { + const syntacticErrorFoundInStats = stats.compilation.errors.some( + error => + error.rawMessage.includes( + helpers.expectedErrorCodes.expectedSyntacticErrorCode + ) + ); + expect(syntacticErrorFoundInStats).to.be.true; + callback(); + }) ); }); - it('lang=js', function() { - expect(errors['example-js.vue'].length).to.be.equal(0); - }); - it('lang=jsx', function() { - expect(errors['example-jsx.vue'].length).to.be.equal(0); + + it('should not report no-consecutive-blank-lines tslint rule', function(callback) { + createCompiler({ tslint: true, vue: true }).then(() => + compiler.run(function(error, stats) { + stats.compilation.warnings.forEach(function(warning) { + expect(warning.rawMessage).to.not.match( + /no-consecutive-blank-lines/ + ); + }); + callback(); + }) + ); }); - it('no lang', function() { - expect(errors['example-nolang.vue'].length).to.be.equal(0); + + it('should resolve src attribute but not report not found error', function(callback) { + createCompiler({ vue: true, tsconfig: 'tsconfig-attrs.json' }).then(() => + compiler.run(function(error, stats) { + const errors = stats.compilation.errors; + expect(errors.length).to.be.equal(1); + expect(errors[0].file).to.match( + /test\/integration\/vue\/src\/attrs\/test.ts$/ + ); + callback(); + }) + ); }); - }); - - describe('should resolve *.vue in the same way as TypeScript', function() { - var errors; - before(function(callback) { - createCompiler({ vue: true, tsconfig: 'tsconfig-imports.json' }); - compiler.run(function(error, stats) { - errors = stats.compilation.errors; - callback(); + + [ + 'example-ts.vue', + 'example-tsx.vue', + 'example-js.vue', + 'example-jsx.vue', + 'example-nolang.vue' + ].forEach(fileName => { + it('should be able to extract script from ' + fileName, async function() { + await createCompiler({ vue: true, tsconfig: 'tsconfig-langs.json' }); + var sourceFilePath = path.resolve( + compiler.context, + 'src/langs/' + fileName + ); + var source = await getSourceFile(sourceFilePath); + expect(source).to.not.be.undefined; + // remove padding lines + var text = source.text.replace(/^\s*\/\/.*$\r*\n/gm, '').trim(); + expect(text.startsWith('/* OK */')).to.be.true; }); }); - it('should be able to import by relative path', function() { - expect( - errors.filter(e => e.rawMessage.indexOf('./Component1.vue') >= 0).length - ).to.be.equal(0); - }); - it('should be able to import by path from baseUrl', function() { - expect( - errors.filter(e => e.rawMessage.indexOf('imports/Component2.vue') >= 0) - .length - ).to.be.equal(0); - }); - it('should be able to import by compilerOptions.paths setting', function() { - expect( - errors.filter(e => e.rawMessage.indexOf('@/Component3.vue') >= 0).length - ).to.be.equal(0); + function groupByFileName(errors) { + var ret = { + 'example-ts.vue': [], + 'example-tsx.vue': [], + 'example-js.vue': [], + 'example-jsx.vue': [], + 'example-nolang.vue': [], + 'example-ts-with-errors.vue': [] + }; + for (var error of errors) { + ret[path.basename(error.file)].push(error); + } + return ret; + } + + describe('should be able to compile *.vue with each lang', function() { + var errors; + before(function(callback) { + createCompiler({ vue: true, tsconfig: 'tsconfig-langs.json' }).then( + () => + compiler.run(function(error, stats) { + errors = groupByFileName(stats.compilation.errors); + callback(); + }) + ); + }); + it('lang=ts', function() { + expect(errors['example-ts.vue'].length).to.be.equal(0); + }); + it('lang=tsx', function() { + expect(errors['example-tsx.vue'].length).to.be.equal(0); + }); + it('lang=js', function() { + expect(errors['example-js.vue'].length).to.be.equal(0); + }); + it('lang=jsx', function() { + expect(errors['example-jsx.vue'].length).to.be.equal(0); + }); + it('no lang', function() { + expect(errors['example-nolang.vue'].length).to.be.equal(0); + }); + it('counter check - invalid code produces errors', function() { + expect(errors['example-ts-with-errors.vue'].length).to.be.greaterThan( + 0 + ); + }); }); - it('should be able to import by compilerOptions.paths setting (by array)', function() { - expect( - errors.filter(e => e.rawMessage.indexOf('foo/Foo1.vue') >= 0).length - ).to.be.equal(0); - expect( - errors.filter(e => e.rawMessage.indexOf('foo/Foo2.vue') >= 0).length - ).to.be.equal(0); + + describe('should be able to detect errors in *.vue', function() { + var errors; + before(function(callback) { + // tsconfig-langs-strict.json === tsconfig-langs.json + noUnusedLocals + createCompiler({ + vue: true, + tsconfig: 'tsconfig-langs-strict.json' + }).then(() => + compiler.run(function(error, stats) { + errors = groupByFileName(stats.compilation.errors); + callback(); + }) + ); + }); + it('lang=ts', function() { + expect(errors['example-ts.vue'].length).to.be.equal(1); + expect(errors['example-ts.vue'][0].rawMessage).to.match( + /'a' is declared but/ + ); + }); + it('lang=tsx', function() { + expect(errors['example-tsx.vue'].length).to.be.equal(1); + expect(errors['example-tsx.vue'][0].rawMessage).to.match( + /'a' is declared but/ + ); + }); + it('lang=js', function() { + expect(errors['example-js.vue'].length).to.be.equal(0); + }); + it('lang=jsx', function() { + expect(errors['example-jsx.vue'].length).to.be.equal(0); + }); + it('no lang', function() { + expect(errors['example-nolang.vue'].length).to.be.equal(0); + }); }); - it('should not report any compilation errors', function() { - expect(errors.length).to.be.equal(0); + + describe('should resolve *.vue in the same way as TypeScript', function() { + var errors; + before(function(callback) { + createCompiler({ vue: true, tsconfig: 'tsconfig-imports.json' }).then( + () => + compiler.run(function(error, stats) { + errors = stats.compilation.errors; + callback(); + }) + ); + }); + + it('should be able to import by relative path', function() { + expect( + errors.filter(e => e.rawMessage.indexOf('./Component1.vue') >= 0) + .length + ).to.be.equal(0); + }); + it('should be able to import by path from baseUrl', function() { + expect( + errors.filter( + e => e.rawMessage.indexOf('imports/Component2.vue') >= 0 + ).length + ).to.be.equal(0); + }); + it('should be able to import by compilerOptions.paths setting', function() { + expect( + errors.filter(e => e.rawMessage.indexOf('@/Component3.vue') >= 0) + .length + ).to.be.equal(0); + }); + it('should be able to import by compilerOptions.paths setting (by array)', function() { + expect( + errors.filter(e => e.rawMessage.indexOf('foo/Foo1.vue') >= 0).length + ).to.be.equal(0); + expect( + errors.filter(e => e.rawMessage.indexOf('foo/Foo2.vue') >= 0).length + ).to.be.equal(0); + }); + it('counter check - should report report one generic compilation error', function() { + expect(errors.length).to.be.equal(1); + }); }); - }); -}); + }; +} diff --git a/test/integration/vue/src/imports/Test.vue b/test/integration/vue/src/imports/Test.vue index dcda44db..ec8214df 100644 --- a/test/integration/vue/src/imports/Test.vue +++ b/test/integration/vue/src/imports/Test.vue @@ -24,5 +24,8 @@ export default { Foo2 } }; + +// we want there to be at least one error to make sure errors are thrown at all +const x: string = 1; diff --git a/test/integration/vue/src/langs/example-ts-with-errors.vue b/test/integration/vue/src/langs/example-ts-with-errors.vue new file mode 100644 index 00000000..9912fb15 --- /dev/null +++ b/test/integration/vue/src/langs/example-ts-with-errors.vue @@ -0,0 +1,8 @@ + + + + diff --git a/test/integration/vue/tsconfig-imports.json b/test/integration/vue/tsconfig-imports.json index 65fce0e2..c4205687 100644 --- a/test/integration/vue/tsconfig-imports.json +++ b/test/integration/vue/tsconfig-imports.json @@ -1,20 +1,13 @@ { "compilerOptions": { - "baseUrl": "./src", - "moduleResolution": "node", - "paths": { - "@/*": ["imports/*"], - "foo/*": [ - "imports/foo1/*", - "imports/foo2/*" - ] - }, - "lib": ["es2016", "dom"] + "baseUrl": "./src", + "moduleResolution": "node", + "paths": { + "@/*": ["imports/*"], + "foo/*": ["imports/foo1/*", "imports/foo2/*"] + }, + "lib": ["es2016", "dom"] }, - "include": [ - "imports/Test.vue" - ], - "exclude": [ - "node_modules" - ] + "include": ["src/imports/Test.vue"], + "exclude": ["node_modules"] }