sconover / wrong

Wrong provides a general assert method that takes a predicate block. Assertion failure messages are rich in detail.
MIT License
434 stars 31 forks source link

Doesn't work with enumerables #11

Closed bradphelan closed 13 years ago

bradphelan commented 13 years ago

a = [1,2,3,4]

assert{a.all?{|i| i<4}}

Wrong::Assert::AssertionFailedError: Expected a.all? { |i| (i < 4) }, but
    i raises NameError: undefined local variable or method `i' for main:Object

    from /Users/bradphelan/.rvm/gems/ruby-1.9.2-p180/gems/wrong-0.5.4/lib/wrong/assert.rb:72:in `aver'
    from /Users/bradphelan/.rvm/gems/ruby-1.9.2-p180/gems/wrong-0.5.4/lib/wrong/assert.rb:34:in `assert'
    from (irb):12
    from /Users/bradphelan/.rvm/rubies/ruby-1.9.2-p180/bin/irb:16:in `<main>'

also

 assert{a.all?{|i| i<4}==true}
Wrong::Assert::AssertionFailedError: Expected a.all? { |i| (i < 4) }, but
    i raises NameError: undefined local variable or method `i' for main:Object

    from /Users/bradphelan/.rvm/gems/ruby-1.9.2-p180/gems/wrong-0.5.4/lib/wrong/assert.rb:72:in `aver'
    from /Users/bradphelan/.rvm/gems/ruby-1.9.2-p180/gems/wrong-0.5.4/lib/wrong/assert.rb:34:in `assert'
    from (irb):12
    from /Users/bradphelan/.rvm/rubies/ruby-1.9.2-p180/bin/irb:16:in `<main>'
alexch commented 13 years ago

To clarify, the error is that the failure message is misleading. But it is correctly noting that the block returns false, since the final pass through the iterator is false (4 < 4).

It's not clear to me what a better behavior would be. Wrong has already told you that

a.all? { |i| (i < 4) }

is false, and when it tries to break that down further into parts, it can't get very far since i really is undefined unless you're in the middle of a call to all?.

You should probably rewrite your test like this:

    a = [1,2,3,4]
    a.each {|i| assert {i < 4}}

which gives

Wrong::Assert::AssertionFailedError: Expected (i < 4), but
    i is 4
bradphelan commented 13 years ago

Ok I think I understand what it is doing but I suggest that the parser should try and recognize cases it can't handle and just be nice about it and leave off the backtrace of the "but" section.

bradphelan commented 13 years ago

though in this case you could do some analysis and guess that the object of the comparison was 'a' not 'i'. Not sure how complex a heuristic you would need for that though.

alexch commented 13 years ago

Not sure how complex a heuristic you would need for that though

patches welcome :-)

alexch commented 13 years ago

I added this case to the readme as an example of misleading detail messages.