Wrong
Wrong provides a general assert method that takes a predicate block. Assertion failure messages are rich in detail.
Install / Use
/learn @sconover/WrongREADME
"Feels so right, it can't be Wrong"

Maintained by: Alex Chaffee http://alexchaffee.com
Abstract
Wrong provides a simple, general assert method that takes a block, and understands the code inside it, providing verbose failure messages for free.
The Wrong idea is to replace assert_equal and all those countless assert\_this, assert\_that, should\_something library methods which only exist to give a failure message that's not simply "assertion failed". Wrong replaces all of them in one fell swoop, since if you can write it in Ruby, Wrong can make a sensible failure message out of it.
We'd very much appreciate feedback and bug reports. There are plenty of things left to be done to make the results look uniformly clean and beautiful. We want your feedback, and especially to give us cases where either it blows up or the output is ugly or uninformative.
Inspired by assert { 2.0 } but rewritten from scratch. Compatible with Ruby (MRI) 1.8, 1.9, and JRuby 1.5.
Installation
gem install wrong
We have deployed gems for both Ruby and JRuby; if you get dependency issues on your platform, please let us know what Ruby interpreter and version you're using and what errors you get, and we'll try to track it down.
Usage
Wrong provides a simple assert method that takes a block:
require "wrong" # or require "wrong/adapters/rspec" (see below)
include Wrong
assert { 1 == 1 }
==> nil
assert { 2 == 1 }
==> Expected (2 == 1), but 2 is not equal to 1
If your assertion is more than a simple predicate, then Wrong will split it into parts and show you the values of all the relevant subexpressions.
x = 7; y = 10; assert { x == 7 && y == 11 }
==>
Expected ((x == 7) and (y == 11)), but
(x == 7) is true
x is 7
(y == 11) is false
y is 10
--
age = 24
name = "Gaga"
assert { age >= 18 && ["Britney", "Snooki"].include?(name) }
==>
Expected ((age >= 18) and ["Britney", "Snooki"].include?(name)), but
(age >= 18) is true
age is 24
["Britney", "Snooki"].include?(name) is false
name is "Gaga"
And a companion, 'deny':
deny{'abc'.include?('bc')}
==> Didn't expect "abc".include?("bc")
More examples are in the file examples.rb http://github.com/alexch/wrong/blob/master/examples.rb
There's also a spreadsheet showing a translation from Test::Unit and RSpec to Wrong, with notes, at this Google Doc. (Ask alexch@gmail.com if you want editing privileges.)
And don't miss the slideshare presentation.
Helper methods
All these helper methods are provided if you do include Wrong.
rescuing
There's also a convenience method for catching errors:
assert{ rescuing{raise "vanilla"}.message == "chocolate" }
==>
Expected (rescuing { raise("vanilla") }.message == "chocolate"), but
rescuing { raise("vanilla") }.message is "vanilla"
rescuing { raise("vanilla") } is #<RuntimeError: vanilla>
raise("vanilla") raises RuntimeError: vanilla
capturing
And one for capturing output streams:
assert { capturing { puts "hi" } == "hi\n" }
assert { capturing(:stderr) { $stderr.puts "hi" } == "hi\n" }
out, err = capturing(:stdout, :stderr) { ... }
assert { out == "something standard\n" }
assert { err =~ /something erroneous/ }
close_to?
If you want to compare floats, try this:
assert { 5.0.close_to?(5.0001) } # default tolerance = 0.001
assert { 5.0.close_to?(5.1, 0.5) } # optional tolerance parameter
If you don't want close_to? cluttering up Float in your test runs then use include Wrong::Assert instead of include Wrong.
close_to? also works on Times, Dates, and DateTimes. The default tolerance of 1 msec may be too small for you, so you might want to do something like:
assert { user.created_at.close_to?(Time.now, 2) } # or 2.seconds
close_to? also works inside RSpec should statements with the magic be matcher, e.g.
5.should be_close_to(6)
d
We also implement the most amazing debugging method ever, d, which gives you a sort of mini-wrong wherever you want it
, even in production code at runtime:
require 'wrong'
x = 7
d { x } # => prints "x is 7" to the console
d { x * 2 } # => prints "(x * 2) is 14" to the console
d("math is hard") { 2 + 2 } #=> prints "math is hard: (2 + 2) is 4"
d was originally implemented by Rob Sanheim in LogBuddy; as with Assert2 this version is a rewrite and homage. You may also enjoy g by jugyo.
Remember, if you want d to work at runtime (e.g. in a webapp) then you must include Wrong::D inside your app, e.g. in your environment.rb file.
eventually
If you care that something is going to be true soon, but maybe not right now, use eventually.
eventually { night? }
It will keep executing the block, up to 4 times a second, until either
- the block returns true(ish)
- 5 seconds elapse
If the block raises an exception, then eventually will treat that as a false and keep trying. The last time it fails, it'll raise that exception instead of a mere AssertionFailedError. That way, the following are all possible:
eventually { false }
eventually { assert { false } }
eventually { false.should be_true } # in RSpec
and you should get the expected failure after time expires.
You can also send options to eventually as hash parameters.
eventually(:timeout => 10) { false } # keep trying for 10 sec
eventually(:delay => 1) { false } # try every 1.0 sec, not every 0.25 sec
(For now, eventually is in its own module, but you get it when you include Wrong. Maybe it should be in Helpers like the rest?)
Test Framework Adapters
Adapters for various test frameworks sit under wrong/adapters.
Currently we support
- Test::Unit -
require 'wrong/adapters/test_unit' - Minitest -
require 'wrong/adapters/minitest' - RSpec -
require 'wrong/adapters/rspec'(now supports both 1.3 and 2.0)
To use these, put the appropriate require in your helper, after requiring your test framework; it should extend the framework enough that you can use assert { } in your test cases without extra fussing around.
For example:
require "test/unit"
require "wrong/adapters/test_unit"
class PlusTest < Test::Unit::TestCase
def test_adding_two_and_two
assert { 2 + 2 == 4 }
end
end
require "rspec"
require "wrong/adapters/rspec"
describe "plus" do
it "adds two and two" do
assert { 2 + 2 == 4 }
end
end
Piecemeal Usage
We know that sometimes you don't want all the little doodads from a library cluttering up your namespace. If you don't want to do
require 'wrong'
include Wrong
then you can instead require and include just the bits you really want. For example:
require 'wrong/assert'
include Wrong::Assert
will give you the assert and deny methods but not the formatters or rescuing or d or close_to?. And if all you want is d then do:
require 'wrong/d'
include Wrong::D
To summarize: if you do require 'wrong' and include Wrong then you will get the whole ball of wax. Most people will probably want this since it's easier, but there is an alternative, which is to require and include only what you want.
And beware: if you don't require 'wrong', then include Wrong will not do anything at all.
Gotcha: Side Effects Within the Assert Block
Be careful about making calls within the assert block that cause state changes.
@x = 1
def increment
@x += 1
end
assert { increment == 2 }
assert { increment == 2 }
==> Expected (increment == 2), but
increment is 5
The first time increment fires the result is 2. The second time the result is 3, and then Wrong introspects the block to create a good failure message, causing increment to fire a couple more times.
Confusing, we know! A few patient Wrong users have hit this when the assert involves ActiveRecord write methods like #create! and #save.
The fix: introduce a variable:
value = increment
assert { value == 2 }
assert { value == 2 }
Apology
So does the world need another assertion framework? In fact, it does not! We actually believe the world needs fewer assert methods.
The Wrong idea is to replace all those countless assert_this, assert_that, should_something library methods which only exist to give a more useful failure message than "assertion failed". Wrong replaces all of them in one fell swoop, since if you can write it in Ruby, Wrong can make a sensible failure message out of it.
Even the lowly workhorse assert_equal is bloated compared to Wrong: would you rather write this
assert_equal time, money
or this
assert { time == money }
? The Wrong way has the advantage of being plain, transparent Ruby code, not an awkward DSL that moves "equal" out of its natural place between the comparands. Plus, WYSIWYG! You know just from looking at it that "equal" means ==, not eql? or === or =~.
Moreover, much like TDD itself, Wrong encourages you to write cleaner code. If your assertion messages are not clear and "Englishy", then maybe it's time for you to refactor a bit -- extract an informatively named variable or method, maybe push some function onto its natural object a la the Law of Demeter... Also, try not to call any methods with side effects inside an assert. In addition to being bad form, this can cause messed-up failure messages, since the side effects may occur several
