test: Fix printing bitwise float reprs in error printing

In commit "test: Consolidate `Hexf`, `Hexi`, and the `Hex` trait" we
unintentionally lost the difference between float hex and bitwise hex
formatting; instead, the float hex was getting printed twice. Resolve
this by printing the integer hex whenever the `-` format modifier is
specified.  This also makes things simpler because we no longer need to
keep track of whether an `impl DisplayHex` is a float with `.to_bits()`
available or an integer without it, we can always just try to print both
forms.

As a result, we can use a common error message for all validation
checks.
This commit is contained in:
Trevor Gross
2026-04-19 02:41:56 +00:00
parent 0cc3a7d6fe
commit 996b57d5bc
2 changed files with 74 additions and 50 deletions
@@ -232,19 +232,15 @@ fn validate_int<I, Input>(actual: I, expected: I, input: Input, ctx: &CheckCtx)
None => String::new(),
};
anyhow::ensure!(
result,
"\
\n input: {input:?} {ibits}\
\n expected: {expected:<22?} {expbits}\
\n actual: {actual:<22?} {actbits}\
\n {msg}\
",
actbits = Hex(actual),
expbits = Hex(expected),
ibits = Hex(input),
msg = make_xfail_msg()
);
if !result {
bail!(make_error_message(
input,
expected,
actual,
"",
&make_xfail_msg()
));
}
Ok(())
}
@@ -360,23 +356,7 @@ fn validate_float<F, Input>(actual: F, expected: F, input: Input, ctx: &CheckCtx
}
}
res.with_context(|| {
format!(
"\
\n input: {input:?}\
\n as hex: {ihex}\
\n as bits: {ibits}\
\n expected: {expected:<22?} {exphex} {expbits}\
\n actual: {actual:<22?} {acthex} {actbits}\
",
ihex = Hex(input),
ibits = Hex(input),
exphex = Hex(expected),
expbits = Hex(expected),
actbits = Hex(actual),
acthex = Hex(actual),
)
})
res.with_context(|| make_error_message(input, expected, actual, "", ""))
}
impl_float!(f32, f64);
@@ -397,28 +377,25 @@ impl<Input> CheckOutput<Input> for ($a, $b)
where
Input: Copy + DisplayHex + fmt::Debug,
SpecialCase: MaybeOverride<Input>,
{
{
fn validate<'a>(
self,
expected: Self,
input: Input,
ctx: &CheckCtx,
) -> TestResult {
self.0.validate(expected.0, input, ctx)
self.0
.validate(expected.0, input, ctx)
.and_then(|()| self.1.validate(expected.1, input, ctx))
.with_context(|| format!(
"full context:\
\n input: {input:?} {ibits}\
\n as hex: {ihex}\
\n as bits: {ibits}\
\n expected: {expected:?} {expbits}\
\n actual: {self:?} {actbits}\
",
ihex = Hex(input),
ibits = Hex(input),
expbits = Hex(expected),
actbits = Hex(self),
))
.with_context(|| {
make_error_message(
input,
expected,
self,
"full context:",
"",
)
})
}
}
)*
@@ -459,3 +436,33 @@ fn validate<'a>(
(f128, i32);
(f128, f128);
);
fn make_error_message<I, E, A>(
input: I,
expected: E,
actual: A,
pre_msg: &str,
post_msg: &str,
) -> String
where
I: Copy + fmt::Debug + DisplayHex,
E: Copy + fmt::Debug + DisplayHex,
A: Copy + fmt::Debug + DisplayHex,
{
let pre_pad = if pre_msg.is_empty() { "" } else { "\n " };
let post_pad = if post_msg.is_empty() { "" } else { "\n " };
format!(
"\
{pre_pad}{pre_msg}\
\n input: {input:?}\
\n as hex: {ihex}\
\n as bits: {ihex:-}\
\n expected: {expected:<16?} {exphex} {exphex:-}\
\n actual: {actual:<16?} {acthex} {acthex:-}\
{post_pad}{post_msg}\
",
ihex = Hex(input),
exphex = Hex(expected),
acthex = Hex(actual),
)
}
@@ -378,7 +378,8 @@ pub(super) fn fmt_any_hex<F: Float>(x: &F, f: &mut fmt::Formatter<'_>) -> fmt::R
}
/// Types that can be formatted as hex via `Hex`. For ints we always print with a fixed
/// number of leading zeros. For floats we use the IEEE hex (`%a`) representation.
/// number of leading zeros. For floats we use the IEEE hex (`%a`) representation. The `-`
/// format modifier is used to print the integer hex representation rather than hex float.
pub trait DisplayHex {
#[allow(unused)] // Only used for tests and public test internals
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
@@ -408,7 +409,11 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
impl<F: Float> DisplayHex for F {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt_any_hex(self, f)
if f.sign_minus() {
self.to_bits().fmt(f)
} else {
fmt_any_hex(self, f)
}
}
}
@@ -459,7 +464,9 @@ impl<T1> DisplayHex for (T1,)
T1: Copy + DisplayHex,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({},)", Hex(self.0))
write!(f, "(")?;
self.0.fmt(f)?;
write!(f, ",)")
}
}
@@ -469,7 +476,11 @@ impl<T1, T2> DisplayHex for (T1, T2)
T2: Copy + DisplayHex,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({}, {})", Hex(self.0), Hex(self.1))
write!(f, "(")?;
self.0.fmt(f)?;
write!(f, ", ")?;
self.1.fmt(f)?;
write!(f, ")")
}
}
@@ -480,7 +491,13 @@ impl<T1, T2, T3> DisplayHex for (T1, T2, T3)
T3: Copy + DisplayHex,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({}, {}, {})", Hex(self.0), Hex(self.1), Hex(self.2))
write!(f, "(")?;
self.0.fmt(f)?;
write!(f, ", ")?;
self.1.fmt(f)?;
write!(f, ", ")?;
self.2.fmt(f)?;
write!(f, ")")
}
}
}