8000 #2784 - adding Myers based diff to rendered string equality assertion failures by dkarlinsky · Pull Request #2923 · zio/zio · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

#2784 - adding Myers based diff to rendered string equality assertion failures #2923

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Mar 3, 2020

Conversation

dkarlinsky
Copy link
Contributor

No description provided.

@dkarlinsky
Copy link
Contributor Author
dkarlinsky commented Feb 17, 2020

@adamgfraser I haven't ironed all the kinks yet but this is an example of diff rendering I currently have:
image
Where the test looks like this:

test("multiline strings not equal") {
   assert("foo bar\nbazz buzzard")(Assertion.equalTo("bar foo\nbazard"))
},

@adamgfraser
Copy link
Contributor

@dkarlinsky Wow! This looks amazing. Will review in detail tomorrow.

@dkarlinsky
Copy link
Contributor Author

@adamgfraser I still have some issues / open questions on how to format multiline diffs, especially when CR/LF char is the only char added/removed...
I'm thinking of perhaps escaping \n and \r in the result but also adding the line break for better human readability...

Copy link
Contributor
@adamgfraser adamgfraser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks really good. A couple of things to think about:

  1. When should we do string diffing? Sometimes I have been annoyed with other test frameworks where I do something like assert("bar")(equalTo("baz")) and get back this detailed diff message where given the size of the strings it is obvious that they are not the same and the diff just clutters things up. Options might be diffing only strings over a certain size, or diffing only when a certain combinator is used assertEqualString. Counterargument would be we should do the same thing for everything.
  2. Can we push more logic out of the DefaultTestReporter? There is a lot going on in that file right now. Would be nice to make it as much a "consumer' of the diffing functionality as possible.

(actual, expected) match {
case (left: Array[_], right: Array[_]) => left.sameElements[Any](right)
case (left, right) => left == right
}
}
assertion.withExpected(Some(expected))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to add the expectation for every equality assertion or only those involving strings? This gets a little to the "when do we want to diff?" question.

Copy link
Contributor Author
@dkarlinsky dkarlinsky Mar 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adamgfraser see my latest commits.
It is still string-only by default, but you can customise it by passing a different Diffing to equalTo

@@ -22,10 +22,11 @@ import scala.io.AnsiColor

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to push more of the logic in this file into the diff package so the test reporter is really just handing over an actual and expected value and getting back what it should render.

Copy link
Contributor Author
@dkarlinsky dkarlinsky Mar 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would love to split DefaultTestReporter into to parts, where one translates test results into a simple (ish) domain model representing notions like assertion failures and diffs but without any markup stuff like lines, offsets and ANSI colors.
This would be useful for JUnitRunner and IDE integration @hmemcpy is working on, I think.
And rendering with colors and offsets would be done by a different class.

But I think this should probably be a separate PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did move FailureRenderer, MessageMarkup and DiffRenderer out into their own files.

@jdegoes
Copy link
Member
jdegoes commented Mar 1, 2020

@dkarlinsky Would love to see this one make it in! You think you'll be able to get back to it sometime soon?

@dkarlinsky
Copy link
Contributor Author

@jdegoes yes, have pushed bunch of commits addressing @adamgfraser 's comments.
Now working on making the CI pass

@adamgfraser
Copy link
Contributor

@dkarlinsky This looks great! It is a big PR and I'm sure there is more follow up we can do, especially around the DefaultTestReporter as you suggested, but I think we could get this in now. My main question at this point is whether we should diff all strings or only strings over a certain size or if you use a combinator that says you want to diff?

@dkarlinsky
Copy link
Contributor Author

@adamgfraser we could make the default Diffing to only apply to strings longer than say 20 characters.
And maybe provide a simple way to construct one with a different limit.
WDYT?

@hmemcpy
Copy link
Contributor
hmemcpy commented Mar 3, 2020

This is great! I started a PR #2975 where I separated the DefaultTestReporter and introduced a base trait TestRenderer to support different outputs. I'm currently on vacation, so I won't be able to proceed with it until next week, so please go ahead and make the changes you need, I'll rework it.

My main need in that PR is to introduce the ability to support a custom renderer via command line arguments, so I can implement one externally for the IntelliJ test runner (without having to reimplement the command line runner logic).

@adamgfraser
Copy link
Contributor

@dkarlinsky That sounds reasonable to me. I don't really have a strong opinion here, I just think it is something we should consider. There is value in having uniformity but at least personally I have been annoyed at times when I am comparing simple strings and get a whole diff from other test frameworks, especially when it is part of a larger test where the difference is the obvious part.

@jdegoes What do you think?

@dkarlinsky
Copy link
Contributor Author

@adamgfraser even if the diff is redundant due to the strings being short, you still also get the message: str1 didn't satisfy equalTo(str2) as before. So you can look at that and ignore the diff.

@adamgfraser
Copy link
Contributor

@dkarlinsky Can you resolve the conflict and then we will merge?

@jdegoes Had an idea that we could look at the percent of differences to the total length of the string, so if the strings are close we show the diff, if they are nothing alike we just show the two strings. That seems pretty good to me but we can follow up on that later.

Copy link
Contributor
@adamgfraser adamgfraser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will merge when it goes green! Great job on this!

@adamgfraser adamgfraser merged commit 511330d into zio:master Mar 3, 2020
@dkarlinsky dkarlinsky deleted the zio-test-differ branch March 3, 2020 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
0