Skip to content

Commit

Permalink
Merge pull request #259 from epage/fixes
Browse files Browse the repository at this point in the history
fix(snap): Ignore noise in svg comparisons / diff
  • Loading branch information
epage authored Feb 21, 2024
2 parents 17b4655 + c08882a commit 99fc297
Show file tree
Hide file tree
Showing 5 changed files with 305 additions and 11 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/snapbox/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ anstream = { version = "0.6.7", optional = true }
document-features = { version = "0.2.6", optional = true }

serde_json = { version = "1.0.85", optional = true}
anstyle-svg = { version = "0.1.0", optional = true }
anstyle-svg = { version = "0.1.1", optional = true }

[target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.52.0", features = ["Win32_Foundation"], optional = true }
Expand Down
52 changes: 49 additions & 3 deletions crates/snapbox/src/data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ pub struct Data {
source: Option<DataSource>,
}

#[derive(Clone, Debug, PartialEq, Eq)]
enum DataInner {
#[derive(Clone, Debug)]
pub(crate) enum DataInner {
Error(crate::Error),
Binary(Vec<u8>),
Text(String),
Expand Down Expand Up @@ -367,6 +367,18 @@ impl Data {
DataInner::TermSvg(_) => DataFormat::TermSvg,
}
}

pub(crate) fn relevant(&self) -> Option<&str> {
match &self.inner {
DataInner::Error(_) => None,
DataInner::Binary(_) => None,
DataInner::Text(_) => None,
#[cfg(feature = "json")]
DataInner::Json(_) => None,
#[cfg(feature = "term-svg")]
DataInner::TermSvg(data) => text_elem(data),
}
}
}

impl From<DataInner> for Data {
Expand Down Expand Up @@ -394,10 +406,44 @@ impl std::fmt::Display for Data {

impl PartialEq for Data {
fn eq(&self, other: &Data) -> bool {
self.inner == other.inner
match (&self.inner, &other.inner) {
(DataInner::Error(left), DataInner::Error(right)) => left == right,
(DataInner::Binary(left), DataInner::Binary(right)) => left == right,
(DataInner::Text(left), DataInner::Text(right)) => left == right,
#[cfg(feature = "json")]
(DataInner::Json(left), DataInner::Json(right)) => left == right,
#[cfg(feature = "term-svg")]
(DataInner::TermSvg(left), DataInner::TermSvg(right)) => {
// HACK: avoid including `width` and `height` in the comparison
let left = text_elem(left.as_str());
let right = text_elem(right.as_str());
left == right
}
(_, _) => false,
}
}
}

#[cfg(feature = "term-svg")]
fn text_elem(svg: &str) -> Option<&str> {
let open_elem_start_idx = svg.find("<text")?;
_ = svg[open_elem_start_idx..].find('>')?;
let open_elem_line_start_idx = svg[..open_elem_start_idx]
.rfind('\n')
.map(|idx| idx + 1)
.unwrap_or(svg.len());

let close_elem = "</text>";
let close_elem_start_idx = svg.rfind(close_elem).unwrap_or(svg.len());
let close_elem_line_end_idx = svg[close_elem_start_idx..]
.find('\n')
.map(|idx| idx + close_elem_start_idx + 1)
.unwrap_or(svg.len());

let body = &svg[open_elem_line_start_idx..close_elem_line_end_idx];
Some(body)
}

impl Eq for Data {}

impl Default for Data {
Expand Down
134 changes: 134 additions & 0 deletions crates/snapbox/src/data/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,74 @@ use serde_json::json;

use super::*;

#[test]
#[cfg(feature = "term-svg")]
fn term_svg_eq() {
let left = Data::from(DataInner::TermSvg(
"
irrelevant
<text>relevant
</text>
irrelevant"
.to_owned(),
));
let right = Data::from(DataInner::TermSvg(
"
irrelevant
<text>relevant
</text>
irrelevant"
.to_owned(),
));
assert_eq!(left, right);

let left = Data::from(DataInner::TermSvg(
"
irrelevant 1
<text>relevant
</text>
irrelevant 1"
.to_owned(),
));
let right = Data::from(DataInner::TermSvg(
"
irrelevant 2
<text>relevant
</text>
irrelevant 2"
.to_owned(),
));
assert_eq!(left, right);
}

#[test]
#[cfg(feature = "term-svg")]
fn term_svg_ne() {
let left = Data::from(DataInner::TermSvg(
"
irrelevant 1
<text>relevant 1
</text>
irrelevant 1"
.to_owned(),
));
let right = Data::from(DataInner::TermSvg(
"
irrelevant 2
<text>relevant 2
</text>
irrelevant 2"
.to_owned(),
));
assert_ne!(left, right);
}

// Tests for checking to_bytes and render produce the same results
#[test]
fn text_to_bytes_render() {
Expand Down Expand Up @@ -492,3 +560,69 @@ fn json_normalize_wildcard_array_middle_last_early_return() {
assert_eq!(act, actual);
}
}

#[cfg(feature = "term-svg")]
mod text_elem {
use super::super::*;

#[test]
fn empty() {
let input = "";
let expected = None;
let actual = text_elem(input);
assert_eq!(expected, actual);
}

#[test]
fn no_open_tag() {
let input = "hello
</text>
world!";
let expected = None;
let actual = text_elem(input);
assert_eq!(expected, actual);
}

#[test]
fn unclosed_open_text() {
let input = "
Hello
<text
world!";
let expected = None;
let actual = text_elem(input);
assert_eq!(expected, actual);
}

#[test]
fn capture_one() {
let input = "
Hello
<text>
world
</text>
Oh";
let expected = Some(
"<text>
world
</text>
",
);
let actual = text_elem(input);
assert_eq!(expected, actual);
}

#[test]
fn no_end_tag() {
let input = "
Hello
<text>
world";
let expected = Some(
"<text>
world",
);
let actual = text_elem(input);
assert_eq!(expected, actual);
}
}
Loading

0 comments on commit 99fc297

Please sign in to comment.