djanowski/cutest — pull request #20 by moonglum (2014-11-28 15:11:33+00:00)
Title: Custom Assertion Messages

This pull request adds the possibility to add custom assertion messages when using assert. This allows to give better feedback when running a test suite. A simple example for that might be the following:

```ruby
test "failed custom assertion" do
assert(string.empty?, "not empty")
end
```

This gives better feedback, because it gives a **reason for the failure**.

It also makes the step to a custom assertion very easy when we find that we need this kind of assertion multiple times:

```ruby
def assert_empty(string)
assert(string.empty?, "not empty")
end

test "failed custom assertion" do
assert_empty "foo"
end
```

# Background

This arose from a discussion with @tonchis. We talked about his [assert-url](https://github.com/tonchis/assert-url) library. He told me that his library is agnostic of test frameworks, and he explained to me how he managed to do that. It has a drawback though: As it doesn't use `fluke` and `success`, it can't do the same kind of reporting that a built-in or cutest-specific `assert_*` can do (e.g. put a dot onto the command line when it succeeds). And it can't use fluke and success, because this is very specific to cutest. So we discussed the following:

```
[13:33:47]	My gut reaction would say that if you write a lib that's providing assert_* methods there's one thing you can assume: The person that is using your lib uses assert_* methods (so not Rspec's expect for example).
[13:34:02]	So I guess it would be save to assume that there's a `assert` method available?
[13:34:09]	it's a reasonable assumption, yes
[13:35:04]	So if your lib can break everything down to an `assert` it would be fine, right? In the sense of `assert` can be used as the building block for all assertions
[13:35:40]	also true
[13:35:42]	But the problem I see here is that cutest doesn't offer an 'explanation string' in its assert as many frameworks do
[13:36:00]	yeap
[13:36:04]	assert false, "EXPLAIN EXPLAIN"
[13:36:33]	that's useful, may be you can propose it to jano and see what he thinks of it
[13:36:58]	it wouldn't be hard to implement either, I think
```

# Example for custom assertions with the "new assert"

@tonchis' [assert_schema_equal](https://github.com/tonchis/assert-url/blob/master/lib/assert_url.rb#L16-20):

```ruby
def assert_scheme_equal(expected, value)
value = urify(value).scheme

assert(expected.to_s == value, "Expected #{value} to have the following scheme: #{expected}"
end
```

In my opinion: Better error reporting with the same amount of understandable code.

# Impact

* Add optional message argument to assert
* Reimplemented assert_equal and assert_raise with assert
* Totally backwards compatible as the new argument is optional
* Adds little to no complexity, and even removes two lines of code
* Introduces a way to add custom assertions in a straight forward way (without using fluke and success)