Skip to content

Commit bd97dc2

Browse files
authored
Merge pull request #265 from oli-obk/disjunctive_filters
Disjunctive filters
2 parents 5b2cb61 + 9fec79c commit bd97dc2

File tree

18 files changed

+109
-56
lines changed

18 files changed

+109
-56
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
### Fixed
13+
14+
### Changed
15+
16+
### Removed
17+
18+
## [0.26.0] - 2024-09-07
19+
20+
### Added
21+
1222
* examples and usage instructions
1323
* `Config::comment_start` field for changing the default comment symbols from `//`
1424

@@ -18,6 +28,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1828

1929
* default comment symbols for `Config::cargo` changed to `#`
2030
* Ctrl+C now prints the summary of the tests that were run before Ctrl+C is pressed
31+
* `//@only-target` and `//@only-host` are now separated from the triple substring by a `:` instead of a `-` and accepts multiple (space separated) filters where just one of them needs to match
32+
* `//@only-64bit` is now `//@only-bitwidth: 64 16` to filter for 64 and 16 bit but not include 32 bit.
2133

2234
### Removed
2335

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ui_test"
3-
version = "0.25.0"
3+
version = "0.26.0"
44
edition = "2021"
55
license = "MIT OR Apache-2.0"
66
description = "A test framework for testing rustc diagnostics output"

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ Any other comments will be ignored, and all `//@` comments must be formatted pre
4545
their command specifies, or the test will fail without even being run.
4646

4747
* `//@ignore-C` avoids running the test when condition `C` is met.
48-
* `C` can be `target-XXX`, which checks whether the target triple contains `XXX`.
49-
* `C` can be `host-XXX`, which checks whether the host triple contains `XXX`.
50-
* `C` can also be one of `64bit`, `32bit` or `16bit`.
48+
* `C` can be `target: XXX YYY`, which checks whether the target triple contains `XXX` or `YYY`.
49+
* `C` can be `host: XXX YYY`, which checks whether the host triple contains `XXX` or `YYY`.
50+
* `C` can also be `bitwidth:` followed by one or more space separated integer size like `64`, `32` or `16`.
5151
* `C` can also be `on-host`, which will only run the test during cross compilation testing.
5252
* `//@only-C` **only** runs the test when condition `C` is met. The conditions are the same as with `ignore`.
5353
* `//@needs-asm-support` **only** runs the test when the target supports `asm!`.

src/config.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -386,9 +386,9 @@ impl Config {
386386
pub(crate) fn test_condition(&self, condition: &Condition) -> bool {
387387
let target = self.target.as_ref().unwrap();
388388
match condition {
389-
Condition::Bitwidth(bits) => self.get_pointer_width() == *bits,
390-
Condition::Target(t) => target.contains(t),
391-
Condition::Host(t) => self.host.as_ref().unwrap().contains(t),
389+
Condition::Bitwidth(bits) => bits.iter().any(|bits| self.get_pointer_width() == *bits),
390+
Condition::Target(t) => t.iter().any(|t| target.contains(t)),
391+
Condition::Host(t) => t.iter().any(|t| self.host.as_ref().unwrap().contains(t)),
392392
Condition::OnHost => self.host_matches_target(),
393393
}
394394
}

src/parser.rs

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -226,12 +226,12 @@ impl<T> std::ops::DerefMut for CommentParser<T> {
226226
/// The conditions used for "ignore" and "only" filters.
227227
#[derive(Debug, Clone)]
228228
pub enum Condition {
229-
/// The given string must appear in the host triple.
230-
Host(String),
231-
/// The given string must appear in the target triple.
232-
Target(String),
233-
/// Tests that the bitwidth is the given one.
234-
Bitwidth(u8),
229+
/// One of the given strings must appear in the host triple.
230+
Host(Vec<String>),
231+
/// One of the given string must appear in the target triple.
232+
Target(Vec<String>),
233+
/// Tests that the bitwidth is one of the given ones.
234+
Bitwidth(Vec<u8>),
235235
/// Tests that the target is the host.
236236
OnHost,
237237
}
@@ -262,22 +262,19 @@ pub(crate) struct ErrorMatch {
262262
}
263263

264264
impl Condition {
265-
fn parse(c: &str) -> std::result::Result<Self, String> {
266-
if c == "on-host" {
267-
Ok(Condition::OnHost)
268-
} else if let Some(bits) = c.strip_suffix("bit") {
269-
let bits: u8 = bits.parse().map_err(|_err| {
270-
format!("invalid ignore/only filter ending in 'bit': {c:?} is not a valid bitwdith")
271-
})?;
272-
Ok(Condition::Bitwidth(bits))
273-
} else if let Some(triple_substr) = c.strip_prefix("target-") {
274-
Ok(Condition::Target(triple_substr.to_owned()))
275-
} else if let Some(triple_substr) = c.strip_prefix("host-") {
276-
Ok(Condition::Host(triple_substr.to_owned()))
277-
} else {
278-
Err(format!(
279-
"`{c}` is not a valid condition, expected `on-host`, /[0-9]+bit/, /host-.*/, or /target-.*/"
280-
))
265+
fn parse(c: &str, args: &str) -> std::result::Result<Self, String> {
266+
let args = args.split_whitespace();
267+
match c {
268+
"on-host" => Ok(Condition::OnHost),
269+
"bitwidth" => {
270+
let bits = args.map(|arg| arg.parse::<u8>().map_err(|_err| {
271+
format!("invalid ignore/only filter ending in 'bit': {c:?} is not a valid bitwdith")
272+
})).collect::<Result<Vec<_>, _>>()?;
273+
Ok(Condition::Bitwidth(bits))
274+
}
275+
"target" => Ok(Condition::Target(args.map(|arg|arg.to_owned()).collect())),
276+
"host" => Ok(Condition::Host(args.map(|arg|arg.to_owned()).collect())),
277+
_ => Err(format!("`{c}` is not a valid condition, expected `on-host`, /[0-9]+bit/, /host-.*/, or /target-.*/")),
281278
}
282279
}
283280
}
@@ -769,17 +766,20 @@ impl CommentParser<&mut Revisioned> {
769766
fn parse_command(&mut self, command: Spanned<&str>, args: Spanned<&str>) {
770767
if let Some(command_handler) = self.commands.get(*command) {
771768
command_handler(self, args, command.span());
772-
} else if let Some(s) = command.strip_prefix("ignore-") {
773-
// args are ignored (can be used as comment)
774-
match Condition::parse(*s) {
775-
Ok(cond) => self.ignore.push(cond),
776-
Err(msg) => self.error(s.span(), msg),
777-
}
778-
} else if let Some(s) = command.strip_prefix("only-") {
769+
} else if let Some(rest) = command
770+
.strip_prefix("ignore-")
771+
.or_else(|| command.strip_prefix("only-"))
772+
{
779773
// args are ignored (can be used as comment)
780-
match Condition::parse(*s) {
781-
Ok(cond) => self.only.push(cond),
782-
Err(msg) => self.error(s.span(), msg),
774+
match Condition::parse(*rest, *args) {
775+
Ok(cond) => {
776+
if command.starts_with("ignore") {
777+
self.ignore.push(cond)
778+
} else {
779+
self.only.push(cond)
780+
}
781+
}
782+
Err(msg) => self.error(rest.span(), msg),
783783
}
784784
} else {
785785
let best_match = self

src/parser/tests.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ use std::mem;
238238

239239
#[test]
240240
fn parse_x86_64() {
241-
let s = r"//@ only-target-x86_64-unknown-linux";
241+
let s = r"//@ only-target:x86_64-unknown-linux";
242242
let comments = Comments::parse(
243243
Spanned::new(
244244
s.as_bytes(),
@@ -255,7 +255,31 @@ fn parse_x86_64() {
255255
let revisioned = &comments.revisioned[&vec![]];
256256
assert_eq!(revisioned.only.len(), 1);
257257
match &revisioned.only[0] {
258-
Condition::Target(t) => assert_eq!(t, "x86_64-unknown-linux"),
258+
Condition::Target(t) => assert_eq!(t, &["x86_64-unknown-linux"]),
259+
_ => unreachable!(),
260+
}
261+
}
262+
263+
#[test]
264+
fn parse_two_only_filters() {
265+
let s = r"//@only-target: hello world";
266+
let comments = Comments::parse(
267+
Spanned::new(
268+
s.as_bytes(),
269+
Span {
270+
file: PathBuf::new(),
271+
bytes: 0..s.len(),
272+
},
273+
),
274+
&Config::rustc(""),
275+
)
276+
.unwrap();
277+
println!("parsed comments: {:#?}", comments);
278+
assert_eq!(comments.revisioned.len(), 1);
279+
let revisioned = &comments.revisioned[&vec![]];
280+
assert_eq!(revisioned.only.len(), 1);
281+
match &revisioned.only[0] {
282+
Condition::Target(t) => assert_eq!(t, &["hello", "world"]),
259283
_ => unreachable!(),
260284
}
261285
}

tests/integrations/basic-bin/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/integrations/basic-fail-mode/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/integrations/basic-fail/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)