Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Needs tests, but would like comments. Launch visual diff tool for comparing registered stub bodies and attempted request #138

Closed
wants to merge 6 commits into from

2 participants

@markburns

I found myself debugging some XML for an external service and found it very difficult doing a spot-the-difference on a huge wall of text.

This will popup opendiff against all the registered stubs and the attempted request.
Tried out and working on my mac.
Apart from tests would you recommend anything else?
Perhaps a better way to configure the diff tool, and make it switchable?
Any other points?

@bblimke
Owner

Hi Mark,

Very cool idea with using the diff tool to spot the differences. It can be very useful in some circumstances.

I'm not sure webmock should depend on any external tools, but I can see you made it configurable, so it's an option.

Maybe it would be better to declare a need to use diff tool as webmock configuration. I.e WebMock.use_diff_tool or something.
Then this could be added temporarily in the test you're trying to debug, instead of enabling it for all test with env variable.
I don't think I would use this functionality for more than one test at once, since I wouldn't know which diff window is from which test.

I'm not sure the diff tool should be initialized within exception constructor. I would rather imagine that the exception is
independent and it has to be intercepted somewhere to initialize the diff tool.

If I have 5 stubs declared, it is going to open 5 windows at once, right? Did you test it with just one registered stub or many?

Bartosz

Hi Bartosz

Thanks for your comments.
I've been using it for a few days now and so far it has saved me a lot of time.
I think it might be nice to configure it for certain headers too.

I.e. in my case only fire up for "application/xml"

It's a pain as it actually opens up windows which block the thread at the moment, so I'd like to tackle that issue too.
And yes it does open up windows for each stub and for each test failure.
It's actually not hard to tell which ones are related because of the visual diffing.
And It's still easier than comparing them in the terminal.

My first attempt was trying to parse and diff the xml tree but this approach is more pragmatic.

I'll take a look at your points and incorporate them and get back to you with an updated pull request.

Owner

Great it works for you. I wonder if it would be as useful for json as it is for xml.

Let me know if you come up with something new.

Cheers.

I should imagine it being as useful for json.
I haven't had any test failures in the json parts of my app, which I think says something.
I prefer using json when I can as it's easier to spot the differences yourself anyway :-)

Another approach which would be less intrusive (but more work), would be to do some nice diffing and colouring in the terminal output.
In fact it might help at the moment just to change from the default red output to different colours for the messages, stubs and output.

Another improvement to the output would be optional Ruby 1.9 hash syntax in the example stubs.

Owner

Have you looked at https://github.com/samg/diffy ? maybe something like that would be useful.

Awesome no I hadn't seen that. Will check it out it looks good.

@markburns

I'm actually going to close this pull request as I've no immediate need to introduce this functionality and so don't intend to put the time in to do the necessary cleanup. I have found that complementing WebMock with https://github.com/myronmarston/vcr solves my issue in a human-friendly way.

I may reopen if I decide to clean up the code. Thanks for the comments.

@markburns markburns closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 11, 2011
  1. @markburns

    Quick hack to see if we can see some diffs of the sent body vs the re…

    markburns authored
    …gistered stub bodies.
    
    Spot the difference with XML is _hard_
  2. @markburns

    incorrect namespacing

    markburns authored
  3. @markburns

    renamed file

    markburns authored
  4. @markburns

    FileUtils instead of Dir

    markburns authored
  5. @markburns

    typo

    markburns authored
  6. @markburns

    use & in diff command

    markburns authored
This page is out of date. Refresh to see the latest.
View
1  lib/webmock.rb
@@ -16,6 +16,7 @@
require 'webmock/http_lib_adapters/typhoeus_hydra_adapter'
require 'webmock/errors'
+require 'webmock/registered_stub_differ'
require 'webmock/util/uri'
require 'webmock/util/headers'
View
4 lib/webmock/errors.rb
@@ -1,7 +1,8 @@
module WebMock
-
class NetConnectNotAllowedError < StandardError
def initialize(request_signature)
+ WebMock::RegisteredStubDiffer.new(request_signature.body) if ENV['show_visual_diffs_for_webmock']
+
text = "Real HTTP connections are disabled. Unregistered request: #{request_signature}"
text << "\n\n"
text << stubbing_instructions(request_signature)
@@ -29,5 +30,4 @@ def stubbing_instructions(request_signature)
text
end
end
-
end
View
55 lib/webmock/registered_stub_differ.rb
@@ -0,0 +1,55 @@
+module WebMock
+ class RegisteredStubDiffer
+ def initialize body
+ if body
+ FileUtils.mkdir_p stub_directory
+
+ save_attempted_file body
+
+ registered = save_registered_stubs
+ registered.each { |r| diff r }
+
+ cleanup registered
+ end
+ end
+
+ private
+
+ def diff registered
+ `#{diff_tool} #{registered} #{attempted_file} &`
+ end
+
+ def attempted_file
+ File.join stub_directory, "attempted_stub.txt"
+ end
+
+ def stub_directory
+ File.join %w(tmp webmock)
+ end
+
+ def cleanup files
+ File.delete attempted_file, *files
+ end
+
+ def save_attempted_file body
+ File.open(attempted_file, "w") { |f| f << body }
+ end
+
+ def save_registered_stubs
+ WebMock::StubRegistry.instance.request_stubs.map.
+ each_with_index do |stub, index|
+ file = "tmp/webmock/registered_stub_#{index}"
+
+ File.open file, "w" do |f|
+ f << stub.request_pattern.body_pattern
+ end
+
+ file
+ end
+ end
+
+ def diff_tool
+ ENV['diff_tool'] || "opendiff"
+ end
+ end
+end
View
4 spec/unit/registered_stub_differ_spec.rb
@@ -0,0 +1,4 @@
+require File.expand_path('spec/spec_helper')
+
+describe WebMock::RegisteredStubDiffer do
+end
Something went wrong with that request. Please try again.