Filterset DSL reference¶
This section contains the full set of operators supported by the filterset DSL.
Basic predicates¶
all()
- Include all tests.
none()
- Include no tests.
test(name-matcher)
- Include all tests matching
name-matcher
. package(name-matcher)
- Include all tests in packages (crates) matching
name-matcher
. deps(name-matcher)
- Include all tests in crates matching
name-matcher
, and all of their (possibly transitive) dependencies. rdeps(name-matcher)
- Include all tests in crates matching
name-matcher
, and all the crates that (possibly transitively) depend onname-matcher
. binary_id(name-matcher)
- Include all tests in binary IDs matching
name-matcher
. Covers all ofpackage()
,kind()
andbinary()
. kind(name-matcher)
- Include all tests in binary kinds matching
name-matcher
. See Binary kinds below. binary(name-matcher)
- Include all tests in binary names matching
name-matcher
. For unit tests, the binary name is the same as the name of the crate. Otherwise, it's the name of the integration test, benchmark, or binary target. platform(host)
orplatform(target)
- Include all tests that are built for the host or target platform, respectively.
Binary exclusions
If a filterset always excludes a particular binary, it will not be run, even to get the list of tests within it. This means that a command like:
cargo nextest list -E 'platform(host)'
will not execute any test binaries built for the target platform.
This is generally what you want, but if you would like to list tests anyway, include a
test()
predicate. For example, to list test binaries for the target platform (using,
for example, a target runner), but skip running them:
cargo nextest list -E 'platform(host) + not test(/.*/)' --verbose
Operators¶
set1 & set2
,set1 and set2
- The intersection of
set1
andset2
. set1 | set2
,set1 + set2
,set1 or set2
- The union of
set1
orset2
. not set
,!set
- Include everything not included in
set
set1 - set2
- Everything in
set1
that isn't inset2
. Equivalent toset1 and not set2
. (set)
- Include everything in
set
.
Operator precedence¶
In order from highest to lowest, or in other words from tightest to loosest binding:
()
not
,!
and
,&
,-
or
,|
,+
Within a precedence group, operators bind from left to right.
Examples
test(a) & test(b) | test(c)
is equivalent to(test(a) & test(b)) | test(c)
.test(a) | test(b) & test(c)
is equivalent totest(a) | (test(b) & test(c))
.test(a) & test(b) - test(c)
is equivalent to(test(a) & test(b)) - test(c)
.not test(a) | test(b)
is equivalent to(not test(a)) | test(b)
.
Binary kinds¶
Accepted by the kind()
operator, these binary kinds match the ones defined by Cargo.
lib
- Unit tests for regular crates, typically in the
src/
directory under#[cfg(test)]
. test
- Integration tests, typically in the
tests/
directory. bench
- Benchmark tests. For example, see Criterion benchmarks.
proc-macro
- Unit tests for proc-macro crates, in the
src/
directory under#[cfg(test)]
. bin
- Tests within
[[bin]]
targets (uncommon). example
- Tests within examples (uncommon).
Name matchers¶
This defines the general syntax for matching against names.
=string
- Equality matcher—match a package or test name that's equal to
string
. ~string
- Contains matcher—match a package or test name containing
string
. /regex/
- Regex matcher—match a package or test name if any part of it matches the regular expression
regex
. To match the entire string against a regular expression, use/^regex$/
. The implementation uses the regex crate. #glob
- Glob matcher—match a package or test name if the full name matches the glob expression
glob
. The implementation uses the globset crate. string
- Default matching strategy for the predicate.
Default matchers¶
For test()
predicates, the default matching strategy is the contains matcher, equivalent to ~string
.
For package-related predicates (package()
, deps()
, and rdeps()
), this is the glob matcher, equivalent to #string
.
For binary-related predicates (binary()
and binary_id()
), this is also the glob matcher.
For kind()
and platform()
, this is the equality matcher, equivalent to =string
.
Warning
If you're constructing an expression string programmatically, always use a prefix to avoid ambiguity.
Escape sequences¶
The equality, contains, and glob matchers can contain escape sequences, preceded by a
backslash (\
).
\n
- line feed
\r
- carriage return
\t
- tab
\\
- backslash
\/
- forward slash
\)
- closing parenthesis
\,
- comma
\u{7FFF}
- 24-bit Unicode character code (up to 6 hex digits)
For the glob matcher, to match against a literal glob metacharacter such as *
or ?
, enclose it in square brackets: [*]
or [?]
.
All other escape sequences are invalid.
The regular expression matcher supports the same escape sequences that the regex crate does. This includes character classes like \d
. Additionally, \/
is interpreted as an escaped /
.
More information¶
This section covers additional information that may be of interest to nextest's developers and curious readers.
Motivation¶
Developer tools often work with some notion of sets, and many of them have grown some kind of domain-specific query language to be able to efficiently specify those sets.
The biggest advantage of a query language is orthogonality: rather than every command having to grow a number of options such as --include
and --exclude
, developers can learn the query language once and use it everywhere.
Design decisions¶
Nextest's filtersets are meant to be specified at the command line as well as in configuration. This led to the following design decisions:
- No quotes: Filtersets do not have embedded quotes. This lets users use either single (
''
) or double quotes (""
) to enclose them on the command line, without having to worry about escaping them. - Minimize nesting of parens: If an expression language uses parentheses or other brackets heavily (e.g. Rust's
cfg()
expressions), getting them wrong can be annoying when trying to write an expression. Text editors typically highlight matching and missing parens, but there's so such immediate feedback on the command line. - Infix operators: Filtersets use infix operators, which are more natural to read and write for most people. (As an alternative, Rust's
cfg()
expressions use the prefix operatorsall()
andany()
). - Operator aliases: Operators are supported as both words (
and
,or
,not
) and symbols (&
,|
,+
,-
,!
), letting users write expressions in the style most natural to them. Filtersets are a small language, so there's no need to be particularly opinionated.