-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Filter API pre-filter setup hook. #8142
Changes from 3 commits
1bd8311
0dfb5c5
1464230
784b77b
f052897
6d89fa3
dd507f6
7fa3230
8b34e39
fe25250
4d392ce
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. | ||
|
||
'use strict'; | ||
|
||
const setupData = { | ||
filterText: 'this will return no tests', | ||
}; | ||
|
||
module.exports = function(tests) { | ||
return { | ||
filtered: tests | ||
.filter(t => t.indexOf(setupData.filterText) !== -1) | ||
.map(test => ({test})), | ||
}; | ||
}; | ||
|
||
module.exports.setup = async function() { | ||
await new Promise(resolve => { | ||
setTimeout(() => resolve(), 1000); | ||
}); | ||
setupData.filterText = 'foo'; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ import HasteMap from 'jest-haste-map'; | |
import chalk from 'chalk'; | ||
import rimraf from 'rimraf'; | ||
import exit from 'exit'; | ||
import {Filter} from '../types'; | ||
import createContext from '../lib/create_context'; | ||
import getChangedFilesPromise from '../getChangedFilesPromise'; | ||
import {formatHandleErrors} from '../collectHandles'; | ||
|
@@ -145,6 +146,23 @@ const _run = async ( | |
// as soon as possible, so by the time we need the result it's already there. | ||
const changedFilesPromise = getChangedFilesPromise(globalConfig, configs); | ||
|
||
// Filter may need to do an HTTP call or something similar to setup. | ||
// We will not wait on an async response from this before using the filter. | ||
let filter: Filter | undefined; | ||
if (globalConfig.filter && !globalConfig.skipFilter) { | ||
const rawFilter = require(globalConfig.filter); | ||
let filterSetupPromise: Promise<void> | undefined; | ||
if (rawFilter.setup) { | ||
filterSetupPromise = rawFilter.setup(); | ||
} | ||
filter = async (testPaths: Array<string>) => { | ||
if (filterSetupPromise) { | ||
await filterSetupPromise; | ||
} | ||
return rawFilter(testPaths); | ||
}; | ||
} | ||
|
||
const {contexts, hasteMapInstances} = await buildContextsAndHasteMaps( | ||
configs, | ||
globalConfig, | ||
|
@@ -159,13 +177,15 @@ const _run = async ( | |
globalConfig, | ||
outputStream, | ||
hasteMapInstances, | ||
filter, | ||
) | ||
: await runWithoutWatch( | ||
globalConfig, | ||
contexts, | ||
outputStream, | ||
onComplete, | ||
changedFilesPromise, | ||
filter, | ||
); | ||
}; | ||
|
||
|
@@ -176,17 +196,34 @@ const runWatch = async ( | |
globalConfig: Config.GlobalConfig, | ||
outputStream: NodeJS.WriteStream, | ||
hasteMapInstances: Array<HasteMap>, | ||
filter?: Filter, | ||
) => { | ||
if (hasDeprecationWarnings) { | ||
try { | ||
await handleDeprecationWarnings(outputStream, process.stdin); | ||
return watch(globalConfig, contexts, outputStream, hasteMapInstances); | ||
return watch( | ||
globalConfig, | ||
contexts, | ||
outputStream, | ||
hasteMapInstances, | ||
undefined, | ||
undefined, | ||
filter, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @SimenB we need to convert this to an object finally :D There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree... I'm happy to handle that in a second PR if we want to do it now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Awesome! looks like this won't break public API for |
||
); | ||
} catch (e) { | ||
exit(0); | ||
} | ||
} | ||
|
||
return watch(globalConfig, contexts, outputStream, hasteMapInstances); | ||
return watch( | ||
globalConfig, | ||
contexts, | ||
outputStream, | ||
hasteMapInstances, | ||
undefined, | ||
undefined, | ||
filter, | ||
); | ||
}; | ||
|
||
const runWithoutWatch = async ( | ||
|
@@ -195,6 +232,7 @@ const runWithoutWatch = async ( | |
outputStream: NodeJS.WritableStream, | ||
onComplete: OnCompleteCallback, | ||
changedFilesPromise?: ChangedFilesPromise, | ||
filter?: Filter, | ||
) => { | ||
const startRun = async (): Promise<void | null> => { | ||
if (!globalConfig.listTests) { | ||
|
@@ -209,6 +247,7 @@ const runWithoutWatch = async ( | |
outputStream, | ||
startRun, | ||
testWatcher: new TestWatcher({isWatchMode: false}), | ||
filter, | ||
}); | ||
}; | ||
return startRun(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what happens if this promise rejects before
await filter
inSearchSource
? Will that bubble up as unhandled since no rejection handler has been attached?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could add a
.catch
here and store the rejection in a variable and throw it manually? not sureThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just tested and the filter setup hook being thrown is caught in the same place that the filter itself is called and has all the same behavior as if the filter failed. Which, currently, means the filter is ignored.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
** I meant, not that the filter is ignored, but 0 results are returned.
If/when we add handling for the filter being thrown, the setup hook will be lumped in with it automatically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm adding tests for both filter and setup filter throwing so we at least know the behavior, although when it happens Jest won't run tests (and that's expected).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for feedback; I did find a way to improve the behavior and I wrote tests for both filter and setup filter error code paths.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds great!