-
-
Notifications
You must be signed in to change notification settings - Fork 359
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
Use the differ to print diffs when args are mismatched between expectations and calls #751
Conversation
end | ||
|
||
def diff_message(expected_args, actual_args) | ||
RSpec::Support::Differ.new(:color => true).diff(actual_args, expected_args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Colour shouldn't be on by default, and having it based off the configuration would simply the spec below too :p
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed...rspec-expectations exposes a color
config option if rspec-core isn't loaded, and otherwise simply delegates to rspec-core's config if it is:
Looks fairly simple, nice :) |
Can't this use the
Hmmm...I'd have to see example output from the different options before forming an opinion. Overall, I'd say I'd err on the side of only adding diffing to places where it definitely makes sense; we can always add additional diffing later in the future. |
I'm gonna be trying to finish this off over the coming weekend \o/ |
I think you also need to add |
Yep, if we're using the differ from support. |
I added some specs with output. @myronmarston @JonRowe got thoughts? |
Looks good to me, except it doesn't seem to work on |
1.8.7 is ordering the hashes differently. I'll take a look at it when I get the chance. |
It's moaning about objects too isn't it? Also on |
|
||
def diff_message(expected_args, actual_args) | ||
formatted_expected_args = expected_args.map do |x| | ||
if x.respond_to?(:description) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking respond_to?(:description)
is problematic because it could be something like a BlogPost
AR instance that has a description
attribute which is a blank string or nil...we can't count on it being a matcher in that case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should also check if it's a matcher using Support.is_a_matcher?
:
I can't get this to fail locally on 1.8.7 |
Yolo pushed a fix. |
Hey it passed! |
1.8.7 doesn't like your last commit again :/ |
I had a look locally but I didn't get anywhere concrete. Going to try again tomorrow. |
@myronmarston good point. I'll do that :) |
I'm having some trouble debugging this 1.8.7 failure but I'm going to give it another stab on my upcoming holiday (first one in 9 months I am so excite) |
@@ -257,7 +257,7 @@ def @double.method_with_default_argument(arg={}); end | |||
expect { | |||
@double.method_with_default_argument(nil) | |||
verify @double | |||
}.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :method_with_default_argument with unexpected arguments\n expected: ({})\n got: (nil)") | |||
}.to raise_error(RSpec::Mocks::MockExpectationError, "Double \"test double\" received :method_with_default_argument with unexpected arguments\n expected: ({})\n got: (nil) \e[0m\n\e[0m\e[34m@@ -1,2 +1,2 @@\n\e[0m\e[31m-[{}]\n\e[0m\e[32m+[nil]\n\e[0m") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The diff isn't really the point in this spec, so I'd prefer it not leak into the expectation here as it's brittle. Instead, you can pass a_string_starting_with(...)
as the string arg and only include the part of the failure message that was there before.
I kicked the build and left a couple comments. |
@samphippen where are you at on this? My 3.1 blog post is almost ready... |
@myronmarston I'm gonna get this done today whilst travelling to berlin. |
c51b2f7
to
7e1a938
Compare
Gonna have to fix a bunch of rubocop violations now that I've merged master into this. |
I can't reproduce this jruby failure locally, can anyone take a look at it? |
@@ -226,7 +245,7 @@ def arg_list(*args) | |||
end | |||
|
|||
def arg_has_valid_description(arg) | |||
return false unless arg.respond_to?(:description) | |||
return false unless RSpec::Support.is_a_matcher?(arg) | |||
|
|||
!arg.description.nil? && !arg.description.empty? | |||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The !arg.description.nil? && !arg.description.empty?
logic is no longer necessary -- it was an earlier attempt to deal with non-matcher args that responded to description
, but now that we check if it's a matcher we don't need that logic anymore. I'd just remove the arg_has_valid_description
method altogether and replace it with a call to RSpec::Support.is_a_matcher?
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I just remembered that description
is an optional part of the rspec matcher interface, so a valid matcher may not respond to description
. Thus, I think we actually do need to keep this method (although, it should be renamed to have a ?
on the end...), and its logic should be:
RSpec::Support.is_a_matcher?(arg) && arg.respond_to?(:description)
Your diff_message
method above should then use this method as well.
I've been slowly addressing the feedback. I need to do one more pass and get it mergable but then it should be fine. I'll aim to have it all done this weekend. As a note: I think from now on I'd always prefer in-pull request feedback because github does not collapse commit feedback even if it's been addressed. |
@samphippen it does, but only if the previous 5 (from memory) lines have changed |
I'm sorry I haven't gotten to this recently. Some things have gone a little awry at my company and it's keeping me very occupied. If someone else wants to punt this over the finish line, go for it. I'll get to this as soon as I can. |
@myronmarston it looks like github has collapsed all of your feedback. Can you check this over once more (please leave comments on the PR itself and not the commits). I'm also going to look into this JRuby failure. |
This fixes #685. It means that we only print descriptions in errors for matcher objects and not for user objects.
ed4f247
to
2d7b8a7
Compare
|
||
* Print diffs when arguments in mock expectations are mismatched. | ||
(Sam Phippen, #751) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're changelog entry is in the 3.1.2 section. It should go in the 3.2.0 section.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also I think you fixed #685, right? That probably warrants a call-out in the changelog as well.
Gonna push to get this done on sunday. |
2d7b8a7
to
29ee51d
Compare
@myronmarston how's this looking? |
"unexpected arguments\n expected: #{expected_args}\n" \ | ||
" got: #{actual_args}" | ||
diff = diff_message(expectation.expected_args, args) | ||
message = "#{intro} received #{expectation.message.inspect} #{unexpected_arguments_message(expected_args, actual_args)}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you split these lines up again? We're looking to reduce our line length, not increase it :P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. Not a merge blocker though.
Looks good to me although I'd like to split the lines up to help reduce our overall length. |
Thanks, @samphippen! As @JonRowe said it would be good to re-split the lines to keep new or recently edited code under 80 chars as that's where we'd like to get eventually. Not a merge blocker, though, so I'm going to merge and maybe you can follow up by splitting those lines in a separate tiny PR. |
Use the differ to print diffs when args are mismatched between expectations and calls
Thanks for this @samphippen, @myronmarston, @JonRowe! |
Related #434. This uses the differ that is now in RSpec support to
perform argument diffing when arguments don't match.
Things worth noting/still to do:
and the any arguments matcher, at the moment something like this:
gets printed, and that's obviously not great.
potentially multiple calls. I think the best thing to do would be to
would be to only diff if there's one call. (@myronmarston maybe has thoughts?)
There's some refactoring that could be done here but I want to finish
implementing the "similar args" implementation before I do that so that
I'm sure that I'm refactoring the right thing.
Also: needs more specs.