Skip to content
Browse files

Documentation fixes for yard compliance

* CHANGELOG using markdown (yay!). Doesn't look so stupid anymore
* Removed hash-links from README
* Broke out assertion definitions into their own header
* Fixed yard warnings

[ci skip]
  • Loading branch information...
1 parent 3fcc7f1 commit 9ea2edd5a37cdfed0e9eab1064115d053e422e03 @gus gus committed Mar 20, 2012
Showing with 567 additions and 467 deletions.
  1. +282 −247 CHANGELOG
  2. +282 −217 README.markdown
  3. +1 −1 lib/riot/message.rb
  4. +1 −1 lib/riot/reporter.rb
  5. +1 −1 lib/riot/situation.rb
View
529 CHANGELOG
@@ -1,328 +1,363 @@
-== 0.12.5
+# @markup markdown
-==== Remove doc for some deprecated macros: not, exists, any [charlietanskley]
+# 0.12.5
-==== Deprecate two more macros [charlietanskley]
+* Remove doc for some deprecated macros: not, exists, any [charlietanskley]
+* Deprecate two more macros [charlietanskley]
+* make riot run -w clean. None of those pesky warnings [achiu]
+* Use #inspect for printing arguments in error results [Mon-Ouie]
+* Move BlankSlate into Riot namespace [Mon-Ouie]
+* Setting options in a sub-context don't leak back into the parent context [skade]
+* Remove deprecated `not!` macro [charlietanksley]
+* Fix all warnings so riot runs `-w` clean
-==== make riot run -w clean. None of those pesky warnings [achiu]
+# 0.12.4
-==== Use #inspect for printing arguments in error results [Mon-Ouie]
-
-==== Move BlankSlate into Riot namespace [Mon-Ouie]
-
-==== Setting options in a sub-context don't leak back into the parent context [skade]
-
-==== Remove deprecated `not!` macro [charlietanksley]
-
-==== Fix all warnings so riot runs `-w` clean
-
-== 0.12.4
-
-==== Adding Riot.plain! option for not printing output in color [c00lryguy,
+* Adding Riot.plain! option for not printing output in color [c00lryguy,
jaknowlden]
-== 0.12.3
+# 0.12.3
-==== Going nuts with context helpers: should_not, asserts/denies_topic arguments [achiu]
+* Going nuts with context helpers: should_not, asserts/denies_topic arguments [achiu]
This works now: `should_not("do something")` as an alias for `denies`
You can now pass arguments to `asserts`, `denies`, `should`, and `should_not`.
- context "Playing with hashes" do
- setup do
- { "foo" => "bar" }
- end
+```
+context "Playing with hashes" do
+ setup do
+ { "foo" => "bar" }
+ end
- asserts(:[], "foo").equals("bar")
- should(:[], "foo").equals("bar")
- denies(:[], "foo").equals("goo")
- should_not(:[], "foo").equals("goo")
- end # Playing with hashes
+ asserts(:[], "foo").equals("bar")
+ should(:[], "foo").equals("bar")
+ denies(:[], "foo").equals("goo")
+ should_not(:[], "foo").equals("goo")
+end # Playing with hashes
+```
-==== Exit gracefully if a child process exited with failing status [timgaleckas]
+* Exit gracefully if a child process exited with failing status [timgaleckas]
No tests will run in this situation.
-==== No status displayed if no tests run [timgaleckas]
-
-==== Adding a `denies_topic` macro to Context [Mon-Ouie]
+* No status displayed if no tests run [timgaleckas]
+* Adding a `denies_topic` macro to Context [Mon-Ouie]
-== 0.12.2
+# 0.12.2
-==== RDoc'ed the hell out of everything [jaknowlden]
+* RDoc'ed the hell out of everything [jaknowlden]
+* Deprecating the not! assertion macro. It may just be gone by 0.13.0 [jaknowlden]
+* Remove ANSI-color dependency [achiu]
+* Switch from Jeweler to Bundler [achiu]
+* Add PrettyDotMatrixReporter [achiu]
-==== Deprecating the not! assertion macro. It may just be gone by 0.13.0 [jaknowlden]
+# 0.12.1
-==== Remove ANSI-color dependency [achiu]
+* Error reporting now filters the backtrace to include only meaningful line items. [mbriggs]
+* Added ability to pass method arguments to asserts. [sirupsen]
-==== Switch from Jeweler to Bundler [achiu]
+# 0.12.0
-==== Add PrettyDotMatrixReporter [achiu]
+* Negative tests are finally here! Added support for `denies` and adjusted macros to care about it with `devaluate`. [jaknowlden, achiu]
-== 0.12.1
+```
+denies("my name") { "Rumplestiltzkin" }.equals("Henry")
+```
-==== Error reporting now filters the backtrace to include only meaningful line items. [mbriggs]
+# 0.11.4
-==== Added ability to pass method arguments to asserts. [sirupsen]
-
-== 0.12.0
-
-==== Negative tests are finally here! Added support for `denies` and adjusted macros to care about it with `devaluate`. [jaknowlden, achiu]
-
- denies("my name") { "Rumplestiltzkin" }.equals("Henry")
-
-== 0.11.4
-
-==== [skade] Passing Proc's instead of lambdas to `instance_eval` to comply with ruby 1.9.2.
-
-==== [nu7hatch] Added `describe` alias for `context` for easier rspec porting. Useful at the top level and within a context.
+* [skade] Passing Proc's instead of lambdas to `instance_eval` to comply with ruby 1.9.2.
+* [nu7hatch] Added `describe` alias for `context` for easier rspec porting. Useful at the top level and within a context.
Who can argue with porting from rspec to riot? Not me.
- describe "My thing" do
- asserts(:size).equals(:small)
- end # My thing
+```
+describe "My thing" do
+ asserts(:size).equals(:small)
+end # My thing
+```
The following also works:
- context "Another thing is"
- describe "my" do
- asserts_topic.equals("marshmallow") # this test will fail ... because it will ... because it's wrong
- end # my
- end # Another thing is
+```
+context "Another thing is"
+ describe "my" do
+ asserts_topic.equals("marshmallow") # this test will fail ... because it will ... because it's wrong
+ end # my
+end # Another thing is
+```
-== 0.11.3
+# 0.11.3
-==== [jaknowlden] Modified `matches` assertion macro to treat actual as a string before executing regular expression comparison.
+* [jaknowlden] Modified `matches` assertion macro to treat actual as a string before executing regular expression comparison.
- asserts("a number") { 42 }.matches(/\d+/)
- # same as
- asserts("a number as string") { "42" }.matches(/\d+/)
+```
+asserts("a number") { 42 }.matches(/\d+/)
+# same as
+asserts("a number as string") { "42" }.matches(/\d+/)
+```
-== 0.11.2
+# 0.11.2
-==== [jaknowlden] [ISSUE] Options were not nesting. Now fixed.
+* [jaknowlden] [ISSUE] Options were not nesting. Now fixed.
-== 0.11.1
+# 0.11.1
-==== [jaknowlden] Middleware can now acts more like you would expect. Middleware now know the next neighbor in the chain and can do stuff to the context before and after the user-defined context is prepared. Removes support for the handle? method. Now we act more like a Rack app.
+* [jaknowlden] Middleware can now acts more like you would expect. Middleware now know the next neighbor in the chain and can do stuff to the context before and after the user-defined context is prepared. Removes support for the handle? method. Now we act more like a Rack app.
- class MyMiddleware < Riot::ContextMiddleware
- register
-
- def call(context)
- context.setup { "fooberries" }
+```
+class MyMiddleware < Riot::ContextMiddleware
+ register
+
+ def call(context)
+ context.setup { "fooberries" }
- middleware.call(context)
+ middleware.call(context)
- context.hookup { "furberries" } if context.option(:barns)
- end
- end
+ context.hookup { "furberries" } if context.option(:barns)
+ end
+end
+```
-== 0.11.0
+# 0.11.0
-==== [jaknowlden] Added option to Context#setup which puts the specific setup block at the beginning of the setups to be called for a context. Also useful for middlewares.
+* [jaknowlden] Added option to Context#setup which puts the specific setup block at the beginning of the setups to be called for a context. Also useful for middlewares.
- context "Foo" do
- setup { puts "called second" }
- setup { puts "called third" }
- setup(true) { puts "called first" }
- end # Foo
+```
+context "Foo" do
+ setup { puts "called second" }
+ setup { puts "called third" }
+ setup(true) { puts "called first" }
+end # Foo
+```
-==== [jaknowlden] Added idea of options for a context. This is another feature picked up from riot-rails work.
+* [jaknowlden] Added idea of options for a context. This is another feature picked up from riot-rails work.
Essentially, these are useful for middlewares. For instance, if you wanted to tell a middleware that was looking for a "transactional" option before running code in a transaction block, you might do this:
- context User do
- set :transactional, true
- end # User
+```
+context User do
+ set :transactional, true
+end # User
+```
The middleware might do something with it:
- class TransactionalMiddleware < Riot::ContextMiddleware
- register
+```
+class TransactionalMiddleware < Riot::ContextMiddleware
+ register
- def handle?(context) context.option(:transactional) == true; end
+ def handle?(context) context.option(:transactional) == true; end
- def prepare(context)
- # transactional stuff
- end
- end # TransactionalMiddleware
+ def prepare(context)
+ # transactional stuff
+ end
+end # TransactionalMiddleware
+```
You can call set as many times as you like
- context User do
- set :transactional, true
- set :foo, :bar
- end
+```
+context User do
+ set :transactional, true
+ set :foo, :bar
+end
+```
-==== [jaknowlden] ContextMiddleware: a construction pattern that allows for custom code to be applied to any context given that the middleware chooses to.
+* [jaknowlden] ContextMiddleware: a construction pattern that allows for custom code to be applied to any context given that the middleware chooses to.
This is something I started building into riot-rails and decided it was useful enough to just put it into riot itself. If, for instance, you wanted to add a setup with some stuff only if the context description was equal to "Your Mom":
- class YourMomMiddleware < Riot::ContextMiddleware
- register
-
- def handle?(context)
- context.description == "Your Mom"
- end
-
- def prepare(context)
- context.setup do
- "your mom is the topic"
- end
- end
- end # YourMomMiddleware
-
-== 0.10.13
-
-==== [jaknowlden] Helpers are now run with other setups, not separately. Which means you could use a helper in a setup.
-
- context "Foo" do
- helper(:user) { User.new }
- setup do
- Baz.new(:user => user) # :)
- end
- end # Foo
-
-==== [vandrijevik] Correctly report non-RR assertion failures and errors when RR is used.
-
- context "Foo.bar" do
- asserts("baz is called") do
- mock(Foo).baz
- raise RuntimeError.new("oh noes")
- end
- end
-
- would previously return [:fail, "baz() Called 0 times. Expected 1 times."], and will now
- correctly return [:error, #<RuntimeError: oh noes>]
-
-==== [jaknowlden] Recording description as is. Providing #detailed_description for proper behavior
-
- foo_context = context(Foo) {}
- bar_context = foo_context.context(Bar) {}
- bar_context.description
- => Bar
- bar_context.detailed_description
- => "Foo Bar"
-
-==== [jaknowlden] No longer assuming topic when no block provided to an assertion. Instead, assuming block fails by default. Use `asserts_topic` only now.
-
- context "foo" do
- setup { "bar" }
- asserts_topic.kind_of(String)
- asserts("topic").kind_of(String) # Will fail since block returns `false`
- asserts("topic").equals(false) # Will actually pass :)
- end
-
-== 0.10.12
+```
+class YourMomMiddleware < Riot::ContextMiddleware
+ register
-==== [vandrijevik] Recognizing file and line number of an assertion declaration on failure
+ def handle?(context)
+ context.description == "Your Mom"
+ end
-==== [vandrijevik,jaknowlden] RR support in Riot
-
- # teststrap.rb
- require 'riot'
- require 'riot/rr'
-
- # your-test.rb
- context "foo" do
- asserts("failure due to not calling hello") { mock!.hello {"world"} } # actually fails
- end
-
-==== [jaknowlden] Added Riot::Message to make messages in macros easier to write
-
- def evaluate(actual, expected)
- # ...
- expected == actual pass(new_message.received(expected)) ? fail(expected(expected).not(actual))
- # ...
+ def prepare(context)
+ context.setup do
+ "your mom is the topic"
end
+ end
+end # YourMomMiddleware
+```
+
+# 0.10.13
+
+* [jaknowlden] Helpers are now run with other setups, not separately. Which means you could use a helper in a setup.
+
+```
+context "Foo" do
+ helper(:user) { User.new }
+ setup do
+ Baz.new(:user => user) # :)
+ end
+end # Foo
+```
+
+* [vandrijevik] Correctly report non-RR assertion failures and errors when RR is used.
+
+```
+context "Foo.bar" do
+ asserts("baz is called") do
+ mock(Foo).baz
+ raise RuntimeError.new("oh noes")
+ end
+end
+```
+
+would previously return [:fail, "baz() Called 0 times. Expected 1 times."], and will now correctly return [:error, #<RuntimeError: oh noes>]
+
+* [jaknowlden] Recording description as is. Providing #detailed_description for proper behavior
+
+```
+foo_context = context(Foo) {}
+bar_context = foo_context.context(Bar) {}
+bar_context.description
+=> Bar
+bar_context.detailed_description
+=> "Foo Bar"
+```
+
+* [jaknowlden] No longer assuming topic when no block provided to an assertion. Instead, assuming block fails by default. Use `asserts_topic` only now.
+
+```
+context "foo" do
+ setup { "bar" }
+ asserts_topic.kind_of(String)
+ asserts("topic").kind_of(String) # Will fail since block returns `false`
+ asserts("topic").equals(false) # Will actually pass :)
+end
+```
+
+# 0.10.12
+
+* [vandrijevik] Recognizing file and line number of an assertion declaration on failure
+* [vandrijevik,jaknowlden] RR support in Riot
+
+```
+# teststrap.rb
+require 'riot'
+require 'riot/rr'
+
+# your-test.rb
+context "foo" do
+ asserts("failure due to not calling hello") { mock!.hello {"world"} } # actually fails
+end
+```
+
+* [jaknowlden] Added Riot::Message to make messages in macros easier to write
+
+```
+def evaluate(actual, expected)
+ # ...
+ expected == actual pass(new_message.received(expected)) ? fail(expected(expected).not(actual))
+ # ...
+end
+```
+
+* [jaknowlden] Added responds_to as a respond_to alias
+* [jaknowlden] Added the equivalent_to macro to compare case equality (===). equals is now (==)
+* [jaknowlden] Assuming RootContext if nil parent provided. Added Context#parent to the API
+
+```
+Riot::Context.new("Hi", nil) {}.parent.class
+=> Riot::RootContext
+```
+
+# 0.10.11
+
+* [gabrielg, jaknowlden] Context#asserts_topic now takes an optional description
+
+```
+asserts_topic.exists
+asserts_topic("some kind of description").exists
+```
+
+* [gabrielg, jaknowlden] Added not! assertion macro
+
+```
+setup { User.new(:funny? => false) }
+asserts(:funny?).not!
+```
-==== [jaknowlden] Added responds_to as a respond_to alias
-
-==== [jaknowlden] Added the equivalent_to macro to compare case equality (===). equals is now (==)
-
-==== [jaknowlden] Assuming RootContext if nil parent provided. Added Context#parent to the API
-
- Riot::Context.new("Hi", nil) {}.parent.class
- => Riot::RootContext
-
-== 0.10.11
-
-==== [gabrielg, jaknowlden] Context#asserts_topic now takes an optional description
-
- asserts_topic.exists
- asserts_topic("some kind of description").exists
+* [jaknowlden] Added Context#hookup to add some setup code to an already defined topic
+
+```
+context "yo mama" do
+ setup { YoMama.new }
+ # ...
+ context "is cool" do
+ hookup { topic.do_something_involving_state }
+ asserts_topic.kind_of?(YoMama)
+ end
+end
+```
-==== [gabrielg, jaknowlden] Added not! assertion macro
+* [jaknowlden] Added Riot.alone! mode to ensure Riot.run is not run at-exit
+
+```
+Riot.alone!
+Riot.run
+```
- setup { User.new(:funny? => false) }
- asserts(:funny?).not!
+This will still print output unless you also Riot.silently!
-==== [jaknowlden] Added Context#hookup to add some setup code to an already defined topic
+* [gabrielg, jaknowlden] Returning non-zero status at-exit when tests don't pass
- context "yo mama" do
- setup { YoMama.new }
- # ...
- context "is cool" do
- hookup { topic.do_something_involving_state }
- asserts_topic.kind_of?(YoMama)
- end
- end
+# 0.10.10
-==== [jaknowlden] Added Riot.alone! mode to ensure Riot.run is not run at-exit
+* [dasch, jaknowlden] Passing assertion macros can now return a custom message
- Riot.alone!
- Riot.run
+```
+def evaluate(actual, *expectings)
+ 1 == 1 ? pass("1 does equal 1") : fail("1 does not equal 1 in this universe")
+end
+```
- This will still print output unless you also Riot.silently!
+* [jaknowlden] Removing Context#extend_assertions and related code
+* [dasch] Allow the use of symbolic descriptions as shorthands for sending the message to the topic
-==== [gabrielg, jaknowlden] Returning non-zero status at-exit when tests don't pass
+```
+setup { "foo" }
+asserts(:upcase).equals("FOO")
+```
-== 0.10.10
+* [jaknowlden, splattael] Added AssertionMacro and #register for macros
-==== [dasch, jaknowlden] Passing assertion macros can now return a custom message
+```
+module My
+ class CustomThingAssertion < Riot::AssertionMacro
+ register :custom_thing
+ expects_exception!
def evaluate(actual, *expectings)
- 1 == 1 ? pass("1 does equal 1") : fail("1 does not equal 1 in this universe")
- end
-
-==== [jaknowlden] Removing Context#extend_assertions and related code
-
-==== [dasch] Allow the use of symbolic descriptions as shorthands for sending the message to the topic
-
- setup { "foo" }
- asserts(:upcase).equals("FOO")
-
-==== [jaknowlden, splattael] Added AssertionMacro and #register for macros
-
- module My
- class CustomThingAssertion < Riot::AssertionMacro
- register :custom_thing
- expects_exception!
-
- def evaluate(actual, *expectings)
- # ...
- end
- end
-
- Riot::Assertion.register_macro :custom_thing, CustomThingAssertion
- end
-
-==== [splattael] Replace IOReporter#say with #puts. Also add #print.
-
- class SomeNewReporter < IOReporter
- def pass
- puts "I PASSED"
- end
-
- def fail
- print "F"
- end
# ...
end
-
-== 0.10.9 and before
+ end
+
+ Riot::Assertion.register_macro :custom_thing, CustomThingAssertion
+end
+```
+
+* [splattael] Replace IOReporter#say with #puts. Also add #print.
+
+```
+class SomeNewReporter < IOReporter
+ def pass
+ puts "I PASSED"
+ end
+
+ def fail
+ print "F"
+ end
+ # ...
+end
+```
+
+# 0.10.9 and before
See the commit log: http://github.com/thumblemonks/riot/commits/master
View
499 README.markdown
@@ -15,34 +15,34 @@ In contrast to other popular Ruby testing frameworks such as Test::Unit, [Should
In Riot, tests reside in `contexts`. Within these, a `topic` object is defined through a `setup` block. The actual assertions are then made with an `asserts` or `denies` block.
```ruby
- context "An empty Array" do
- setup { Array.new }
- asserts("it is empty") { topic.empty? }
- denies("it has any elements") { topic.any? }
- end # An Array
+context "An empty Array" do
+ setup { Array.new }
+ asserts("it is empty") { topic.empty? }
+ denies("it has any elements") { topic.any? }
+end # An Array
```
As you can see, the setup block doesn't use any instance variables to save the object under test &mdash; rather, the return value of the block is used as the `topic`. This object can then be accessed in the assertions using the `topic` attribute. Furthermore, at their very basic level, assertions need only return a boolean. When using `asserts`, `true` indicates a pass while `false` indicates a fail; subsequently, when using `denies`, `true` indicates a failure whereas `false` indicates success.
Of course, you can nest contexts as well; the `setup` blocks are executed outside-in; as in, the parents' setups are run before the current context allowing for a setup hierarchy. `teardown` blocks are run inside out; the current context's teardowns are run before any of its parents'. This is what you would expect from other frameworks as well.
```ruby
- context "An Array" do
- setup { Array.new }
+context "An Array" do
+ setup { Array.new }
- asserts("is empty") { topic.empty? }
+ asserts("is empty") { topic.empty? }
- context "with one element" do
- setup { topic << "foo" }
- asserts("array is not empty") { !topic.empty? }
- asserts("returns the element on #first") { topic.first == "foo" }
- end
- end # An Array
+ context "with one element" do
+ setup { topic << "foo" }
+ asserts("array is not empty") { !topic.empty? }
+ asserts("returns the element on #first") { topic.first == "foo" }
+ end
+end # An Array
```
By the way, you can put any kind of ruby object in your context description. Riot will call `to_s` on the actual value before it is used in a reporting context. This fact will become [useful later](http://thumblemonks.github.com/riot/hacking.html#context-middleware) ;)
-### Assertions {#assertions}
+## Assertions
Well, how useful would Riot be if you could only return true/false from an assertion? Pretty useful, actually; but, we can make it more useful! No; that's not crazy. No it isn't. Yes; I'm sure.
@@ -51,217 +51,278 @@ We can do this with assertion macros. You can think of these as special assertio
Let's take this little for instance:
```ruby
- context "Yummy things" do
- setup { ["cookies", "donuts"] }
+context "Yummy things" do
+ setup { ["cookies", "donuts"] }
- asserts("#first") { topic.first }.equals("cookies")
- end # Yummy things
+ asserts("#first") { topic.first }.equals("cookies")
+end # Yummy things
```
First, how's that for a readable test? Second, you should notice that the assertion block will return the `first` item from the `topic` (which is assumed to be `Enumerable` in this case); if it isn't `Enumerable`, then you have other problems. Since the first element in the array is "cookies", the assertion will pass. Yay!
But wait, there's more. Riot is about helping you write faster and more readable tests. Notice any duplication in the example above (besides the value "cookies")? I do. How about that `first` notation in the assertion name and reference in the assertion block. Riot provides a shortcut which allows you to reference methods on the topic through the assertion name. Here's another way to write the same test:
```ruby
- context "Yummy things" do
- setup { ["cookies", "donuts"] }
+context "Yummy things" do
+ setup { ["cookies", "donuts"] }
- asserts(:first).equals("cookies")
- end # Yummy things
+ asserts(:first).equals("cookies")
+end # Yummy things
```
Now that's real yummy. Want some more? Perhaps you just want to test the topic itself &mdash; not a method or attribute of it. You could do this:
```ruby
- context "Yummy things" do
- setup { ["cookies", "donuts"] }
+context "Yummy things" do
+ setup { ["cookies", "donuts"] }
- asserts("topic") { topic }.size(2)
- end # Yummy things
+ asserts("topic") { topic }.size(2)
+end # Yummy things
```
But, as you can probably already guess, that's gross and redundant. To solve this, Riot provides the `asserts_topic` shortcut which is a helper that pretty much just does `asserts("topic") { topic }` for you.
```ruby
- context "Yummy things" do
- setup { ["cookies", "donuts"] }
+context "Yummy things" do
+ setup { ["cookies", "donuts"] }
- asserts_topic.size(2)
- end # Yummy things
+ asserts_topic.size(2)
+end # Yummy things
```
Yep, more readable.
-#### Negative Assertions {#negative-assertions}
+### Negative Assertions
Way back in the first code example we saw a reference to `denies`; this is what is called the negative assertion. You could probably also call it a counter assertion, but I don't. You can use `denies` with any assertion macro that you can use `asserts` with; it's just that `denies` expects the assertion to fail for the test to pass. For instance:
```ruby
- context "My wallet" do
- setup do
- Wallet.new(1000) # That's 1000 cents, or $10USD yo
- end
-
- asserts(:enough_for_lunch?)
- denies(:enough_for_lunch?)
- end # My wallet
+context "My wallet" do
+ setup do
+ Wallet.new(1000) # That's 1000 cents, or $10USD yo
+ end
+
+ asserts(:enough_for_lunch?)
+ denies(:enough_for_lunch?)
+end # My wallet
```
One of those will pass and the other will fail. If $10 is not enough for lunch the `denies` statement will pass; and then you should move to Chicago where it is enough (if only barely).
-#### Built-in Assertion Macros {#builtin-macros}
+### Built-in Assertion Macros
There are a bunch of built-in assertion macros for your everyday use. Be sure to [write your own](http://thumblemonks.github.com/riot/hacking.html#writing-assertion-macros) if these don't satisfy your every need. You will notice the two varying mechanisms for passing arguments into the macros: one is the conventional form of message passing (via actual arguments) and the other is derived from a provided block. If the macro expects one argument, you can use either form (but not both). If the macro accepts multiple arguments, the last argument you want to pass in can be provided via the block.
The advantage of using the block is that its innards are evaluated against the same scope that the assertion was evaluated against. This means you can use the same helpers and instance variables in the macro block to generate an expected value (if you so desire). It's also useful if you have a fairly complex routine for generating the expected value.
-{#builtin-macro-list}
-* **Equals**: compares equality of the actual value to the expected value using the `==` operator
- * `asserts.equals(Object)`
- * `denies.equals(Object)`
- * `asserts.equals { Object }`
- * `denies.equals { Object }`
-
-* **Equivalent To**: compares equivalence of actual value to the expected value using the `===` operator
- * `asserts.equivalent_to(Object)`
- * `denies.equivalent_to(Object)`
- * `asserts.equivalent_to { Object }`
- * `denies.equivalent_to { Object }`
-
-* **Assigns**: checks that the actual value has an instance variable defined within it's scope. You can also validate the value of that variable. Very much mimicing the `assigns` found in Rails-ish tests from way back in form, function, and need.
- * `asserts("a person") { Person.new }.assigns(:email)`
- * `denies("a person") { Person.new }.assigns(:email)`
- * `asserts("a person") { Person.new(:email => "a@b.com") }.assigns(:email, "a@b.com")`
- * `denies("a person") { Person.new(:email => "a@b.com") }.assigns(:email, "a@b.com")`
- * `asserts.assigns { :email }`
- * `denies.assigns { :email }`
- * `asserts.assigns(:email) { "a@b.com" }`
- * `denies.assigns(:email) { "a@b.com" }`
-
-* **Nil**: simply checks the actual value for its nil-ness. Expects no arguments.
- * `asserts.nil`
- * `denies.nil`
-
-* **Matches**: compares the actual value to a provided regular expression
- * `asserts.matches(%r{Regex})`
- * `denies.matches(%r{Regex})`
- * `asserts.matches { /Regex/ }`
- * `denies.matches { /Regex/ }`
-
-* **Raises**: validates the type of exception raised from the assertion block. Optionally, you can give it the message you expected in the form of a literal string or even a portion of it.
- * `asserts.raises(ExceptionClass)`
- * `denies.raises(ExceptionClass)`
- * `asserts.raises(ExceptionClass, "Expected message")`
- * `denies.raises(ExceptionClass, "Expected message")`
- * `asserts.raises(ExceptionClass) { "ted mess" }`
- * `denies.raises(ExceptionClass) { "ted mess" }`
-
-* **Kind Of**: validates the type of object returned from the assertion block
- * `asserts.kind_of(Class)`
- * `denies.kind_of(Class)`
- * `asserts.kind_of { Class }`
- * `denies.kind_of { Class }`
-
-* **Responds To**: checks that the actual object `respond_to?` to a particular message
- * `asserts.respond_to(:foo)`
- * `denies.respond_to(:foo)`
- * `asserts.respond_to { "foo" }`
- * `denies.respond_to { "foo" }`
- * `asserts.responds_to("foo")`
- * `denies.responds_to("foo")`
- * `asserts.responds_to { :foo }`
- * `denies.responds_to { :foo }`
-
-* **Includes**: checks for the existence of: a character or sequence of characters in a string, an element in an array, or a key in a hash.
- * `asserts("this string") { "barbie q" }.includes("foo")`
- * `denies("this string") { "barbie q" }.includes("foo")`
- * `asserts("this array") { [1,2,3] }.includes(2)`
- * `denies("this array") { [1,2,3] }.includes(2)`
- * `asserts("this hash") { {:key1 => "foo"} }.includes(:key2)`
- * `denies("this hash") { {:key1 => "foo"} }.includes(:key2)`
- * `asserts.includes { "foo" }`
- * `denies.includes { "foo" }`
- * `asserts.includes { 2 }`
- * `denies.includes { 2 }`
- * `asserts.includes { :key }`
- * `denies.includes { :key }`
-
-* **Size**: compares the size of the actual object to the number you provide. Works with anything that responds to `size(Numeric)` (strings, arrays, hashes, etc).
- * `asserts.size(Numeric)`
- * `denies.size(Numeric)`
- * `asserts.size { Numeric }`
- * `denies.size { Numeric }`
-
-* **Empty**: checks the result of calling `empty?` on the actual value. Expects no arguments.
- * `asserts.empty`
- * `denies.empty`
-
-* **Same Elements**: compares actual to expected to see if they contain the same elements. Uses `Set` under-the-hood, just so you know.
- * `asserts.same_elements(Array)`
- * `denies.same_elements(Array)`
- * `asserts.same_elements { Array }`
- * `denies.same_elements { Array }`
-
-### Setups, Hookups, and Helpers {#setups-hookups}
+#### Equals
+
+Compares equality of the actual value to the expected value using the `==` operator
+
+```ruby
+asserts.equals(Object)
+denies.equals(Object)
+asserts.equals { Object }
+denies.equals { Object }
+```
+
+#### Equivalent To
+
+Compares equivalence of actual value to the expected value using the `===` operator
+
+```ruby
+asserts.equivalent_to(Object)
+denies.equivalent_to(Object)
+asserts.equivalent_to { Object }
+denies.equivalent_to { Object }
+```
+
+#### Assigns
+
+Checks that the actual value has an instance variable defined within it's scope. You can also validate the value of that variable. Very much mimicing the `assigns` found in Rails-ish tests from way back in form, function, and need.
+
+```ruby
+asserts("a person") { Person.new }.assigns(:email)`
+denies("a person") { Person.new }.assigns(:email)`
+asserts("a person") { Person.new(:email => "a@b.com") }.assigns(:email, "a@b.com")`
+denies("a person") { Person.new(:email => "a@b.com") }.assigns(:email, "a@b.com")`
+asserts.assigns { :email }`
+denies.assigns { :email }`
+asserts.assigns(:email) { "a@b.com" }`
+denies.assigns(:email) { "a@b.com" }`
+```
+
+#### Nil
+
+Simply checks the actual value for its nil-ness. Expects no arguments.
+
+```ruby
+asserts.nil
+denies.nil
+```
+
+#### Matches
+
+Compares the actual value to a provided regular expression
+
+```ruby
+asserts.matches(%r{Regex})
+denies.matches(%r{Regex})
+asserts.matches { /Regex/ }
+denies.matches { /Regex/ }
+```
+
+#### Raises
+
+Validates the type of exception raised from the assertion block. Optionally, you can give it the message you expected in the form of a literal string or even a portion of it.
+
+```ruby
+asserts.raises(ExceptionClass)
+denies.raises(ExceptionClass)
+asserts.raises(ExceptionClass, "Expected message")
+denies.raises(ExceptionClass, "Expected message")
+asserts.raises(ExceptionClass) { "ted mess" }
+denies.raises(ExceptionClass) { "ted mess" }
+```
+
+#### Kind Of
+
+Validates the type of object returned from the assertion block
+
+```ruby
+asserts.kind_of(Class)
+denies.kind_of(Class)
+asserts.kind_of { Class }
+denies.kind_of { Class }
+```
+
+#### Responds To
+
+Checks that the actual object `respond_to?` to a particular message
+
+```ruby
+asserts.respond_to(:foo)
+denies.respond_to(:foo)
+asserts.respond_to { "foo" }
+denies.respond_to { "foo" }
+asserts.responds_to("foo")
+denies.responds_to("foo")
+asserts.responds_to { :foo }
+denies.responds_to { :foo }
+```
+
+#### Includes
+
+Checks for the existence of: a character or sequence of characters in a string, an element in an array, or a key in a hash.
+
+```ruby
+asserts("this string") { "barbie q" }.includes("foo")
+denies("this string") { "barbie q" }.includes("foo")
+asserts("this array") { [1,2,3] }.includes(2)
+denies("this array") { [1,2,3] }.includes(2)
+asserts("this hash") { {:key1 => "foo"} }.includes(:key2)
+denies("this hash") { {:key1 => "foo"} }.includes(:key2)
+asserts.includes { "foo" }
+denies.includes { "foo" }
+asserts.includes { 2 }
+denies.includes { 2 }
+asserts.includes { :key }
+denies.includes { :key }
+```
+
+#### Size
+
+Compares the size of the actual object to the number you provide. Works with anything that responds to `size(Numeric)` (strings, arrays, hashes, etc).
+
+```ruby
+asserts.size(Numeric)
+denies.size(Numeric)
+asserts.size { Numeric }
+denies.size { Numeric }
+```
+
+#### Empty
+
+Checks the result of calling `empty?` on the actual value. Expects no arguments.
+
+```ruby
+asserts.empty
+denies.empty
+```
+
+#### Same Elements
+
+Compares actual to expected to see if they contain the same elements. Uses `Set` under-the-hood, just so you know.
+
+```ruby
+asserts.same_elements(Array)
+denies.same_elements(Array)
+asserts.same_elements { Array }
+denies.same_elements { Array }
+```
+
+### Setups, Hookups, and Helpers
We're not even close to done yet; there's a lot more cool stuff for you to know about. You know about `setup` already; but you may not know that you can call `setup` multiple times within a Context. Well, you can. They run in the order you write them (top-down) and the result of a prior `setup` will be the `topic` for the next setup. In this way you **could** chain together some partitioned setup criteria without ever explicitly setting a variable (instance or local).
- context "A cheesey order" do
- setup { Cheese.create!(:name => "Blue") }
- setup { Order.create!(:cheese => topic, :purchase_order => "123-abc") }
-
- asserts_topic.kind_of(Order) # I love tests that are readable
- end # A cheesey order
+```ruby
+context "A cheesey order" do
+ setup { Cheese.create!(:name => "Blue") }
+ setup { Order.create!(:cheese => topic, :purchase_order => "123-abc") }
+
+ asserts_topic.kind_of(Order) # I love tests that are readable
+end # A cheesey order
+```
This notion about a prior `setup` being the `topic` for a latter `setup` is true even when the `setup` is called from a parent Context.
More than likely, however, you'll want to modify something about the topic without changing what the topic for the context is. To do this, Riot provides the `hookup` block, which is just like a `setup` block except that `hookup` will always return the `topic` that was provided to it. It's kind of like calling `Object#tap`. Here's a for-instance:
```ruby
- context "A Person" do
- setup { Person.new(:name => "Master Blasterr") }
+context "A Person" do
+ setup { Person.new(:name => "Master Blasterr") }
- denies(:valid?) # :(
+ denies(:valid?) # :(
- context "with valid email" do
- hookup { topic.email = "master@blast.err" }
- asserts(:valid?) # Yay!
- end # with valid email
- end # A complex thing
+ context "with valid email" do
+ hookup { topic.email = "master@blast.err" }
+ asserts(:valid?) # Yay!
+ end # with valid email
+end # A complex thing
```
If the point didn't smack you in the face there, think about using `setup` instead of `hookup` in the sub-context. Had you written that as a `setup` block, you'd have to return `topic` after setting the email address, or else the new topic would be the actual email address; and you probably don't want to actually be calling `"master@blast.err".valid?` in the assertion.
You can also call `hookup` as many times as you like; the great part is that the `topic` never changes.
-#### Helpers {#helpers}
+#### Helpers
You remember how you used to &mdash; or currently do &mdash; create instance variables to hold some data that you're going to use in your tests? Well, Riot allows you to still do that yucky stuff, but would rather you use a helper to encapsulate it. For instance, you could do this:
```ruby
- context "A greedy monkey" do
- setup do
- @a_ripe_banana = Banana.new(:ripe => true)
- Monkey.new
- end
+context "A greedy monkey" do
+ setup do
+ @a_ripe_banana = Banana.new(:ripe => true)
+ Monkey.new
+ end
- hookup { topic.takes(@a_ripe_banana) }
+ hookup { topic.takes(@a_ripe_banana) }
- asserts(:bananas).size(1)
- end # A greedy monkey
+ asserts(:bananas).size(1)
+end # A greedy monkey
```
Or, you could do this
```ruby
- context "A greedy monkey" do
- helper(:a_ripe_banana) { Banana.new(:ripe => true) }
- setup { Monkey.new }
+context "A greedy monkey" do
+ helper(:a_ripe_banana) { Banana.new(:ripe => true) }
+ setup { Monkey.new }
- hookup { topic.takes(a_ripe_banana) }
+ hookup { topic.takes(a_ripe_banana) }
- asserts(:bananas).size(1)
- end # A greedy monkey
+ asserts(:bananas).size(1)
+end # A greedy monkey
```
"So! What's the difference?", you ask. Nothing really. It's all aesthetic; but, it's a better aesthetic for a couple of reasons. Let me tell you why:
@@ -274,73 +335,75 @@ Or, you could do this
What's that about (4)? Yes, helpers are really just over-glorified methods, which means you can pass arguments to them. Which means you can build factories with them. Which means those factories can go away when the context is no longer used and they're no longer cluttering up your object space. You want another for instance, eh?
```ruby
- context "A greedy monkey" do
- helper(:make_a_banana) do |color|
- Banana.new(:color => color)
- end
-
- setup { Monkey.new }
-
- hookup do
- topic.takes(make_a_banana("green"))
- topic.takes(make_a_banana("blue"))
- end
-
- asserts(:bananas).size(2)
- asserts("green bananas") { topic.bananas.green }.size(1)
- asserts("blue bananas") { topic.bananas.blue }.size(1)
- end # A greedy monkey
+context "A greedy monkey" do
+ helper(:make_a_banana) do |color|
+ Banana.new(:color => color)
+ end
+
+ setup { Monkey.new }
+
+ hookup do
+ topic.takes(make_a_banana("green"))
+ topic.takes(make_a_banana("blue"))
+ end
+
+ asserts(:bananas).size(2)
+ asserts("green bananas") { topic.bananas.green }.size(1)
+ asserts("blue bananas") { topic.bananas.blue }.size(1)
+end # A greedy monkey
```
Or you could `make_many_bananas` or whatever. There are also lots of clever ways to get helpers included into a context which you will hopefully see when you read up on Context Middleware and look through the Recipes. Riot Rails makes liberal use of helpers when [setting up a context](http://github.com/thumblemonks/riot-rails/master/lib/riot/action_controller/context_middleware.rb) to test controllers.
Again, you define as many helpers as you like; you can also replace existing helpers by simply defining a helper with the same name (*that's because they're just methods defined within the context instance ... shhh*).
-### Running Riot {#running}
+### Running Riot
Running your Riot tests is pretty simple. You can put your test files wherever you want, but it's generally a good idea to put them in a "test" directory. You can run individual test files using the normal ruby command:
- !!!plain
- ruby test/units/monkey_test.rb
- # or
- ruby -Itest test/units/monkey_test.rb
+```plain
+ruby test/units/monkey_test.rb
+# or
+ruby -Itest test/units/monkey_test.rb
+```
I like the latter and use it often. It means the test directory is loaded into the load path, which means I don't have to be explicit about where to find my `teststrap.rb` file (which you might have named `test_helper.rb` in other projects even though it's a silly name). In your teststrap file you'll put all your common setup; maybe even including your Riot hacks. An out-of-the-box teststrap might look like this:
```ruby
- require 'rubygems'
- require '<my-library>'
- require 'riot'
+require 'rubygems'
+require '<my-library>'
+require 'riot'
```
Of course, you probably want to use rake to run your tests. Here's a basic Rakefile that will find our tests in the test directory or its subdirectories if the filename ends in `_test.rb`:
```ruby
- require 'rubygems'
+require 'rubygems'
- require 'rake'
- require 'rake/testtask'
+require 'rake'
+require 'rake/testtask'
- desc "Run all our tests"
- task :test do
- Rake::TestTask.new do |t|
- t.libs << "test"
- t.pattern = "test/**/*_test.rb"
- t.verbose = false
- end
- end
+desc "Run all our tests"
+task :test do
+ Rake::TestTask.new do |t|
+ t.libs << "test"
+ t.pattern = "test/**/*_test.rb"
+ t.verbose = false
+ end
+end
- task :default => :test
+task :default => :test
```
And then on the command line you simply run:
- !!!plain
- rake
- # or
- rake test
+```plain
+rake
+# or
+rake test
+```
-### Mocking {#mocking}
+### Mocking
Mocking seems to be all the rage this decade. I try very hard to avoid it altogether through judicious use of anonymous classes, but sometimes you just need to mock. For Riot, [RR](http://github.com/btakita/rr) seemed to fit the bill nicely because it's:
@@ -358,28 +421,28 @@ However, there are a number of things you expect from a test framework when mock
But enough of this hemming and hawing. What's it look like?! In your `teststrap.rb` you need to require in `riot/rr`:
```ruby
- # I'm teststrap.rb
+# I'm teststrap.rb
- require 'rubygems'
- require 'riot/rr'
+require 'rubygems'
+require 'riot/rr'
```
Then, in your tests, you use standard RR syntax for all of your mocking needs:
```ruby
- require 'teststrap.rb'
-
- context "A nice Person" do
- setup do
- Nice::Person.new
- end
-
- should("find a nice thing to say") do
- mock(topic).make_network_request { "Nice haircut" }
- topic.say_something_nice
- end.equals("Nice haircut")
-
- end # A nice Person
+require 'teststrap.rb'
+
+context "A nice Person" do
+ setup do
+ Nice::Person.new
+ end
+
+ should("find a nice thing to say") do
+ mock(topic).make_network_request { "Nice haircut" }
+ topic.say_something_nice
+ end.equals("Nice haircut")
+
+end # A nice Person
```
So, if `#say_something_nice` never calls `#make_network_request`, that assertion will fail for that reason first. If it does call `#make_network_request`, but for some reason "Nice haircut" is not returned, the tests will fail for that reason instead. It's like catching two birds with one test.
@@ -393,11 +456,13 @@ Riot is slowly solidifying its internal and external API. That being said, we wo
Source code is hosted on [GitHub](http://github.com), and can be fetched with
[Git](http://git-scm.com) by running:
- !!!plain
- git clone git://github.com/thumblemonks/riot.git
+```plain
+git clone git://github.com/thumblemonks/riot.git
+```
If you want to make changes, please feel free to do so. The best process is to fork, fix, and send a pull request.
## License
Riot is released under the MIT license. See [MIT LICENSE](https://github.com/thumblemonks/riot/blob/master/MIT-LICENSE).
+
View
2 lib/riot/message.rb
@@ -19,7 +19,7 @@ class BlankSlate
# => "hello world whats the news"
#
# For every method called it is also acceptable to pass any number of arguments. These arguments will be
- # added to the final message after having {Kernel#inspect} called on them. Another for instance:
+ # added to the final message after having `inspect` called on them. Another for instance:
#
# message = Riot::Message.new
# message.expected([1, 2, 3], "foo").not([3, 2, 1], "bar")
View
2 lib/riot/reporter.rb
@@ -2,7 +2,7 @@ module Riot
# A Reporter decides how to output the result of a test. When a context is set to be executed, the
# {Riot::Reporter#describe_context} method is called with the context that will be running; this remains
- # so until the next context is executed. After each {Riot#Assertion#evaluate assertion is evaluated},
+ # so until the next context is executed. After each {Riot::AssertionMacro#evaluate assertion is evaluated},
# {Riot::Reporter#report} is called with the description of the assertion and the resulting response.
#
# The general idea is that a sub-class of Reporter should be defined that knows specifically how to
View
2 lib/riot/situation.rb
@@ -52,7 +52,7 @@ def helper(name, &block)
end
# Anonymously evaluates any block given to it against the current instance of +self+. This is how
- # {Riot::Assertion assertion} and {Riot::AssertionMAcro assertion macro} blocks are evaluated,
+ # {Riot::Assertion assertion} and {Riot::AssertionMacro assertion macro} blocks are evaluated,
# for instance.
#
# @param [lambda] &block the block to evaluate against +self+

0 comments on commit 9ea2edd

Please sign in to comment.
Something went wrong with that request. Please try again.