-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
feat(cli): Support specifying a line number when filtering tests #6411
feat(cli): Support specifying a line number when filtering tests #6411
Conversation
✅ Deploy Preview for vitest-dev ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
Vitest has specs that describe the test behaviour: vitest/packages/vitest/src/node/core.ts Line 1083 in 83638eb
I would prefer if we passed down locations there to keep the scope clean and avoid polluting the config. |
As far as I can tell, I went with this approach as it is more similar to how |
We don't need to collect tests for this to work, spec defines what tests to run. This is the perfect place to tell Vitest to limit what test functions to run.
I know. This doesn't really explain why it should follow the same implementation. You can keep the filtering in the test like it is, but change how the values are passed down from the main process. |
I might be missing something. What kind of information do I have access to in a spec? How would I access the line numbers of a test? I see |
Spec is a specification, it doesn't have any information about the test or a file. It tells what file to run and how to run it.
Maybe you can populate the provided context somehow or inject the config value, that's up to you, but the processing should happen there. |
Do you mean that the issue at hand is not filtering inside
Is the issue that we should provide each worker with only the values that are relevant values to its files (unlike |
Yes. The
Yes, that's the idea. |
Yeah, that makes sense. I'll take a shot at it. |
I gave it a try. See 76bd921. Previous code will be removed of course. In I thought it would be a good idea to include the files with the location in the same object, instead of having them in their own attribute in the config and then matching based on the path or something. But I ended up having to modify types everywhere to get this to work. I had to modify Much of the code in this commit is hacked together, but I had to get something that somewhat works, sometimes, just to see if I'm on the right track. Would appreciate inputs on this before I commit to making more changes. |
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.
The general direction seems fine to me, but there are some changes that we cannot make because it would be a breaking change. Unless you want to have this merged in a year,
One thing I shouldn't be doing is parsing the filters in vitest/packages/vitest/src/node/cli/cac.ts Line 265 in 76bd921
If I were to do the parsing inside How about Instead of using an incompatible type like
This has been labelled a "nice to have", but I'm not sure I'll be here in a year :) |
I guess that would work but I don't understand why you need this if you will still parse it inside, right? |
I Forgot to add the declaration of export interface FileSpec {
file: string
testLocations: number[] | undefined
} The intention of this is to pass both the filepath and the |
Cleaned up a bit
I hope I'm in the right direction. Thank you for you time @sheremet-va! |
a4c4a04
to
83e103e
Compare
squashed and rebased. Should be up to date with main, will check it later. For now, I've added an error |
beba5a5
to
c7831bf
Compare
@sheremet-va Should be good, if you can take a look. Thanks you! |
There are issues in CI it seems. Something with benchmarking? |
Aha, thought it had to do with stuff not related to me, will look into it. |
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.
Looks good! We need more tests, all the tests now are using list
command
@@ -282,6 +331,53 @@ export function formatCollectedAsString(files: File[]) { | |||
}).flat() | |||
} | |||
|
|||
export function parseFilter(filter: string): Filter { |
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.
It doesn't seem like these two functions belong here because they are not used for the CLI specifically. Maybe create a separate file for them?
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 do you think of vitest/src/node/filter.ts
?
packages/vitest/src/node/core.ts
Outdated
const dir = this.config.dir || this.config.root | ||
const parsedFilters = filters.map(f => parseFilter(f)) | ||
const testLocations = groupFilters(parsedFilters.map( | ||
f => ({ ...f, filename: resolve(dir, f.filename) }), |
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 wonder if it makes sense to validate that the path exists. Filters can be anything, you can provide a part of the file
I think we should throw an error if:
- There is a location in filters
- File is resolved with
process.cwd(), file
, notroot
(because filters are provides via a CLI normally) - File doesn't exist, or it's not a file at all (a directory for example)
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.
Interesting.
What came to mind is to limit matching to full filename, instead of part of it, in order not to match multiple files at the same time. Does that sound right to you?
Note that I'm passing the filters as is (before resolving) to project.globTestFiles
, and then I narrow the matching for filters with location specified. Later at line 1143, I'm skipping over reporting errors for filters that don't have location specified.
For now I'm just reporting error and continuing. Now that I'm thinking about it, this has weird behavior for example pnpm exec vitest basic.test.ts:3
would report an error about "not finding the file", but will run the tests anyways.
It seems I might be able to fix this by only resolving filters with test location and then passing on to project.globTestFiles
, does that sound right to you?
Good point on resolving with process.cwd()
.
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 don't know if I follow what you want to do instead of what I proposed. Maybe you can build a prototype?
e505eeb
to
7a53882
Compare
7a53882
to
2d727fd
Compare
For the failing build, seems like it is caused by import of |
@@ -1,3 +1,4 @@ | |||
import type { FileSpec } from '@vitest/runner/types/runner' |
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.
@vitest/runner/types/runner
doesn't exist when built. you need to expose it in @vitest/runner
I don't know how this got over here.
- rebase issues
In `globTestSpecs`, test locations are matched with their test file by full path (`globTestFiles` returns full path). I think we should keep it this way because:(A) matching multiple files doesn't make much sense -- for example, `fileA.test.ts` might have test at line 21, but `fileB.test.ts` won't; and (B) this feature will be used in command line mostly, where entering full path is easy with autocomplete. Issue arises when location filter (let's say `file`) doesn't match a file by full path. Previously, I thought about dropping files `fileA.test.ts` and `fileB.test.ts`, and running the rest of the files but implementing this doesn't seem straightforward to me. For now, I'll be throwing error.
- Previous implementation failed on windows (drive letter detected as range location `D:/...`) - Add related test cases too
- Modify test case to use a file that doesn't exist instead
8a266d4
to
beed808
Compare
Thank you for keeping this PR up-to-date! |
Anytime! Was quite challenging (and fun) working on this, although I got busy with some stuff throughout. I hope I have the chance to contribute again. |
Description
closes #5445.
Added a function to parse filters into
{ filename, lineNumber? }
. The function attempts to parse each filter with the format<filename>:<line_number>
. If succssful,lineNumber
is set, and we have a "location filter", otherwise line number is not set and the filter is treated as a regular filter.Added
locationFilters
toUserConfig
and toVitestRunnerConfig
.Note that the we only store filters that have
lineNumber
, in order to use them ininterpretTaskModes
.The parsing is done in
cac.ts:start
because that's the place where we have access to both the options and filters.I think I know where to do stuff for the most part, but I need help with some stuff:
I'm not sure how to report errors in case the user included a range instead of a line number.
I'm not happy with my use of
Required
inRequired<Filter[]>
, but I'm not sure what would be a better way to do it.I think we should match filename strictly when location filter is provided, but I'm not sure how to. Should I be using something similar to
WorkspaceProject.filterFiles()
?As for printing an error when the user provides a wrong line number, it's a bit tough withinterpretTaskModes
being a recursive a function. What I have in mind is to keep track of all the filters and wether it was matched or not, and print out errors once we've been through all the tests.The part I'm having an issue with is where to keep track of that. That would involve major changes to howinterpretTaskModes
is written. I could move theSee 36c88e9
Please don't delete this checklist! Before submitting the PR, please make sure you do the following:
pnpm-lock.yaml
unless you introduce a new test example.Tests
pnpm test:ci
.Documentation
pnpm run docs
command.Changesets
feat:
,fix:
,perf:
,docs:
, orchore:
.