mitsuhiko / insta

A snapshot testing library for rust
https://insta.rs
Apache License 2.0
2.26k stars 102 forks source link

Total sort order for redactions #587

Open mitsuhiko opened 2 months ago

mitsuhiko commented 2 months ago

Followup to #586 there is another case in the redaction code that is most likely also wrong. It pairs sort_by with unwrap_or.

max-sixty commented 2 months ago

From this code?

#[cfg_attr(docsrs, doc(cfg(feature = "redactions")))]
pub fn sorted_redaction() -> Redaction {
    fn sort(mut value: Content, _path: ContentPath) -> Content {
        match value.resolve_inner_mut() {
            Content::Seq(ref mut val) => {
                val.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal))
            }
            Content::Map(ref mut val) => {
                val.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal))
            }
            Content::Struct(_, ref mut fields)
            | Content::StructVariant(_, _, _, ref mut fields) => {
                fields.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal))
            }
            _ => {}
        }
        value
    }
    dynamic_redaction(sort)
}

I don't feel confident here, but what's the case for this not being a total order? That a.partial_cmp(b) is different from b.partial_cmp(a)? I would have thought it's fine that things are occasionally not comparable and treated as equal...

mitsuhiko commented 2 months ago

It would be for floats containing NaNs in vectors.

max-sixty commented 2 months ago

OK, I had thought those consistently evaluate to Equal given .unwrap_or(std::cmp::Ordering::Equal), but I'm surely missing something