From 586d820ad2426039ff7328a61443d2a82dfd1a69 Mon Sep 17 00:00:00 2001 From: Mark Wubben Date: Sun, 2 Feb 2020 16:59:40 +0100 Subject: [PATCH] Improve integration with AVA Have the watcher ignore changes to the original TypeScript source files. This way, the watcher will only react to changes to the TypeScript build output. Allow the watcher to resolve the rewritten path of a test file, so it can track it as a dependency of the original TypeScript source file. This way, when the build output changes, the watcher knows to re-run the original test file. Update file patterns to ignore *.d.ts files, as well as any files in the build output. Updated the ignored-by-watcher patterns to ignore source map files from the build output. Fixes #10, #7, #9. --- index.js | 52 +++++++++++++++++++++--- test/protocol-ava-3.2.js | 43 ++++++++++++++++++++ test/snapshots/protocol-ava-3.2.js.md | 21 ++++++++++ test/snapshots/protocol-ava-3.2.js.snap | Bin 0 -> 296 bytes 4 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 test/protocol-ava-3.2.js create mode 100644 test/snapshots/protocol-ava-3.2.js.md create mode 100644 test/snapshots/protocol-ava-3.2.js.snap diff --git a/index.js b/index.js index 98c9adc..5d0cd1e 100644 --- a/index.js +++ b/index.js @@ -24,7 +24,7 @@ function isValidRewritePaths(rewritePaths) { } module.exports = ({negotiateProtocol}) => { - const protocol = negotiateProtocol(['ava-3'], {version: pkg.version}); + const protocol = negotiateProtocol(['ava-3.2', 'ava-3'], {version: pkg.version}); if (protocol === null) { return; } @@ -47,22 +47,62 @@ module.exports = ({negotiateProtocol}) => { const { extensions = ['ts'], - rewritePaths + rewritePaths: relativeRewritePaths } = config; + const rewritePaths = Object.entries(relativeRewritePaths).map(([from, to]) => [ + path.join(protocol.projectDir, from), + path.join(protocol.projectDir, to) + ]); + const testFileExtension = new RegExp(`\\.(${extensions.map(ext => escapeStringRegexp(ext)).join('|')})$`); + return { async compile() { return { extensions: extensions.slice(), - rewritePaths: Object.entries(rewritePaths).map(([from, to]) => [ - path.join(protocol.projectDir, from), - path.join(protocol.projectDir, to) - ]) + rewritePaths: rewritePaths.slice() }; }, get extensions() { return extensions.slice(); + }, + + ignoreChange(filePath) { + if (!testFileExtension.test(filePath)) { + return false; + } + + return rewritePaths.some(([from]) => filePath.startsWith(from)); + }, + + resolveTestFile(testfile) { + if (!testFileExtension.test(testfile)) { + return testfile; + } + + const rewrite = rewritePaths.find(([from]) => testfile.startsWith(from)); + if (rewrite === undefined) { + return testfile; + } + + const [from, to] = rewrite; + // TODO: Support JSX preserve mode — https://www.typescriptlang.org/docs/handbook/jsx.html + return `${to}${testfile.slice(from.length)}`.replace(testFileExtension, '.js'); + }, + + updateGlobs({filePatterns, ignoredByWatcherPatterns}) { + return { + filePatterns: [ + ...filePatterns, + '!**/*.d.ts', + ...Object.values(relativeRewritePaths).map(to => `!${to}**`) + ], + ignoredByWatcherPatterns: [ + ...ignoredByWatcherPatterns, + ...Object.values(relativeRewritePaths).map(to => `${to}**/*.js.map`) + ] + }; } }; }, diff --git a/test/protocol-ava-3.2.js b/test/protocol-ava-3.2.js new file mode 100644 index 0000000..8400002 --- /dev/null +++ b/test/protocol-ava-3.2.js @@ -0,0 +1,43 @@ +const path = require('path'); +const test = require('ava'); +const pkg = require('../package.json'); +const makeProvider = require('..'); + +const withProvider = (t, run) => run(t, makeProvider({ + negotiateProtocol(identifiers, {version}) { + t.true(identifiers.includes('ava-3.2')); + t.is(version, pkg.version); + return { + ava: {version: '3.2.0'}, + identifier: 'ava-3.2', + normalizeGlobPatterns: patterns => patterns, + async findFiles({patterns}) { + return patterns.map(file => path.join(__dirname, file)); + }, + projectDir: __dirname + }; + } +})); + +test('negotiates ava-3.2 protocol', withProvider, t => t.plan(2)); + +test('main() ignoreChange()', withProvider, (t, provider) => { + const main = provider.main({config: {rewritePaths: {'src/': 'build/'}}}); + t.true(main.ignoreChange(path.join(__dirname, 'src/foo.ts'))); + t.false(main.ignoreChange(path.join(__dirname, 'build/foo.js'))); +}); + +test('main() resolveTestfile()', withProvider, (t, provider) => { + const main = provider.main({config: {rewritePaths: {'src/': 'build/'}}}); + t.is(main.resolveTestFile(path.join(__dirname, 'src/foo.ts')), path.join(__dirname, 'build/foo.js')); + t.is(main.resolveTestFile(path.join(__dirname, 'build/foo.js')), path.join(__dirname, 'build/foo.js')); + t.is(main.resolveTestFile(path.join(__dirname, 'foo/bar.ts')), path.join(__dirname, 'foo/bar.ts')); +}); + +test('main() updateGlobs()', withProvider, (t, provider) => { + const main = provider.main({config: {rewritePaths: {'src/': 'build/'}}}); + t.snapshot(main.updateGlobs({ + filePatterns: ['src/test.ts'], + ignoredByWatcherPatterns: ['assets/**'] + })); +}); diff --git a/test/snapshots/protocol-ava-3.2.js.md b/test/snapshots/protocol-ava-3.2.js.md new file mode 100644 index 0000000..121606e --- /dev/null +++ b/test/snapshots/protocol-ava-3.2.js.md @@ -0,0 +1,21 @@ +# Snapshot report for `test/protocol-ava-3.2.js` + +The actual snapshot is saved in `protocol-ava-3.2.js.snap`. + +Generated by [AVA](https://avajs.dev). + +## main() updateGlobs() + +> Snapshot 1 + + { + filePatterns: [ + 'src/test.ts', + '!**/*.d.ts', + '!build/**', + ], + ignoredByWatcherPatterns: [ + 'assets/**', + 'build/**/*.js.map', + ], + } diff --git a/test/snapshots/protocol-ava-3.2.js.snap b/test/snapshots/protocol-ava-3.2.js.snap new file mode 100644 index 0000000000000000000000000000000000000000..d5b6a0d95e73ce9b91665eedfe98971e388572e1 GIT binary patch literal 296 zcmV+@0oVRPRzVJu00000000A1 zU|?WiWRNW1&RF-Nsp5?!+Y^b*wxx^=AW#IPm>Jl?Y(@@7W+NbN0mNZIEX>Fz$jIiO zl$DxX!pI0`3J3@=F!C}mGBGgnF)}s)6^bx2Gcd9WGV-Kl=A;HBmXxFx)Bxj@+AyjfOvRnhIyaU8Pz&fCovpN!?T3TR(na~a9Oe`)=Ehz@eqZum*(+M;?t5`2Lu>b(aq}^7M0RRBxhj_;T literal 0 HcmV?d00001