Better diffs with minitest - ruby

I'm looking at my test case results, and it's far to difficult to see where the one small failure in my test is coming from.
I'm dealing with reasonable sized data structures - and I don't want to change the to_s method so that it's slightly better for the minitest diff.
I've looked at the reporters but they don't seem to have anything like what I'm looking for. (I'm using ruby 1.9.3)
Is there any way that minitest or some library for minitest could highlight the part of the string that is different between two results?
Or is there something I'm missing that allows you to visually look at the diff more easily?
Edit: Example
Minitest::Assertion:
--- expected
+++ actual
## -1 +1 ##
-#<struct MyModule::Swipe id=0, lat=37.62996, lng=-122.42115, route=#<struct MyModule::Route id=17, bus_name="test_name", stops=[#<struct MyModule::Stop id=29, name="Cool Stop">]>, date_time="2015-10-29T11:05:02+00:00">
+#<struct MyModule::Swipe id=0, lat=37.62996, lng=-122.42115, route=#<struct MyModule::Route id=17, bus_name="test_name", stops=[#<struct MyModule::Stop id="29", name="Cool Stop">]>, date_time="2015-10-29T11:05:02+00:00">
Instead could show the line, and highlight in another colour the id="29" vs the id=29 only. Minitest seems to show the diff based on the lines printed.

pretty-diff
I had the same problem, and in case of invisible blank characters, this gem is still not good enough for debugging. I end up adding .inspect to both String that I passed to assert_equal in minitest test case.

Related

Writing Capybara expectations to verify phone numbers

I'm using AWS Textract to pull information from PDF documents. After the scanned text is returned from AWS and persisted to a var, I'm doing this:
phone_number = '(555) 123-4567'
scanned_pdf_text.should have_text phone_number
But this fails about 20% of the time because of the non-deterministic way that AWS is returning the scanned PDF text. On occasion, the phone numbers can appear either of these two ways:
(555)123-4567 or (555) 123-4567
Some of this scanned text is very large, and I'd prefer not to go through the exercise of sanitizing the text coming back if I can avoid it (I'm also not good at regex usage). I also think using or logic to handle both cases seems to be a little heavy handed just to check text that is so similar (and clearly near-identical to the human eye).
Is there an rspec matcher that'll allow me to check on this text? I'm also using Capybara.default_normalize_ws = true but that doesn't seem to help in this case.
Assuming scanned_pdf_text is a string and the only differences you're seeing is in spaces then you can just get rid of the spaces and compare
scanned_pdf_text.gsub(/\s+/, '').should eq('(555)123-4567') # exact
scanned_pdf_text.gsub(/\s+/, '').should match('(555)123-4567') # partial
scanned_pdf_text.gsub(/\s+/, '').should have_text('(555)123-4567') # partial

How to show BigDecimal number as human readable when using ActiveSupport::TestCase

When I'm using ActiveSupport::TestCase tests that are failed shows message like this:
2) Failure:
ArrayTest#test_example [/Users/ironsand/dev/my_project/test/core_ext/array_test.rb:6]:
--- expected
+++ actual
## -1 +1 ##
-#<BigDecimal:7fb947c749a0,'0.94E0',9(18)>
+#<BigDecimal:7fb947c7f5a8,'0.95E0',9(45)>
I want to show the value 0.94 instead of <BigDecimal:7fb947c749a0,'0.94E0',9(18)>.
In rails cosole or in pry I'm using awesome_print.
Is there a way to activate awesome_print for result of the test?
I don't insist on using awesome_print, if there is another way to show the number more readable, I gonna happily use it.
You could add a message to to the assert statement
message = "Expected #{expected_number.to_f} but actual number is #{actual_number.to_f}"
assert_equal expected_number, actual_number, message
Also, you didn't ask this, but if you are trying to compare two decimal numbers, you probably want to use assert_in_delta to see that the numbers are close rather than exact.

Is there a ruby gem that does diff between HTML documents?

Doing a diff of two different html documents turns out to be an entirely different problem than simply doing a diff of plain text. For example, if I do a naive LCS diff between:
Google</p>
and
Google</a></p>
the diff result is NOT:
</a>
but
/a></
I've tried most gems out there that claim to be html diff but all of them seem to be just implementing text based LCS diff. Is there any gem that does a diff while taking html tags into account?
Try Samy diffy or rubygems html-diff
After much searching for a gem to do this for me, I discovered that I can simply do a string compare between two parsed Nokogiri documents:
def should_match_html(html_text1, html_text2)
dom1 = Nokogiri::HTML(html_text1)
dom2 = Nokogiri::HTML(html_text2)
dom1.to_s.should == dom2.to_s
end
Then you can simply add this in your spec:
should_match_html expected_html, actual_html
The best part is that the built-in rspec matcher will automatically provide you a line-by-line diff result of the mismatched lines.

Combining RSpec filters?

I've been looking through the docs, but descriptions of how multiple filters work seem to be a bit lacking. Does anyone have a good explanation or source of a good explanation for the behaviour of multiple filters? Does the order they are listed matter? Here's an example of code that might have behaviour other than what one could expect...
Rspec.configure do |c|
this_version = get_version_number.to_sym
c.filter_run :focus=> true
c.filter_run_excluding :limit_to=>true, this_version => false
c.filter_run :new_stuff=>true
c.run_all_when_everything_filtered
end
it "is focused, but not new", :focus
it "is is new", :new_stuff
it "is new and focused", :new_stuff, :focus
it "is focused and new, but limited to a different version", :focus, :limit_to, :correct_version
Experimenting with this, it also seems like multiple arguments on the "filter_run_excluding" line simple act is if you wrote the line multiple times. Is there a way to get it to actually combine the filter checks so that it excludes (or runs, I suppose) only examples that have both the tags listed?
Run multiple filters from the command line with this:
rspec spec --tag my_tag --tag my_second_tag -- tag ~my_third_tag
The ~ will exclude any spec with those tags, so its often useful to do something like
rspec spec --tag ~long_runing

What would be the best way to take a string of html, chop it up, and put each piece into an array?

I have a general idea of how I can do this, but can't pinpoint how exactly to get it done. I am sure it can be done with a regex of some sort. Wondering if anyone here can point me in the right direction.
If I have a string of html such as this
some_html = '<div><b>This is some BOLD text</b></div>'
I want to to divide it into logical pieces, and then put those pieces into an array so I end with a result like this
html_array = ["<div>", "<b>", "This is some BOLD text", "</b>","</div>" ]
Rather than use regex I'd use the nokogiri gem (a gem for parsing html written by Aaron Patterson - contributor to Rails and Ruby). Here's a sample of how to use it:
html_doc = Nokogiri::HTML("<html><body><h1>Mr. Belvedere Fan Club</h1></body></html>")
You can then call html_doc.children to get a nodeset and work your way from there
html_doc.children # returns a nodeset
Use an HTML parser, for instance, Nokogiri. Using SAX you can add tags/elements to the array as events are triggered.
It's not a good idea to try to regex HTML, unless you're planning to treat only a small determined subset of it.
some_html.split(/(<[^>]*>)/).reject{|x| '' == x}

Resources