riot 0.10.1 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,12 +2,35 @@
2
2
 
3
3
  An extremely fast, expressive, and context-driven unit-testing framework. Protest the slow test.
4
4
 
5
+ ## Contents
6
+
7
+ - [Installation](#installation)
8
+ - [Note on speed](#speed)
9
+ - [Examples](#examples)
10
+ - [Boolean](#examples-boolean)
11
+ - [Shortcuts](#examples-shortcut)
12
+ - [Equality](#examples-equality)
13
+ - [Matches](#examples-matches)
14
+ - [Raises](#examples-raises)
15
+ - [Kind Of](#examples-kind-of)
16
+ - [Empty](#examples-empty)
17
+ - [Respond To](#examples-respond-to)
18
+ - [Assigns](#examples-assigns)
19
+ - [Nested contexts](#examples-nested)
20
+ - [OMG! Why did you write this](#omg)
21
+ - [Running tests](#running)
22
+ - [With Sinatra](#sinatra)
23
+ - [With Rails](#rails)
24
+ - [Extending Riot with Macros](#extending)
25
+ - [Assertion macros](#assertion-macros)
26
+
5
27
  When you're done reading here, take a gander at:
6
28
 
7
29
  * [Riot Rails](http://github.com/thumblemonks/riot_rails): Rails support for Riot testing. A definite work in progress (help welcomed). See [evoke-app](http://github.com/thumblemonks/evoke-app) for live examples.
8
30
  * [Riot.js](http://github.com/alexyoung/riotjs): for you JavaScript people, a version of Riot just for you. Both implementations will be informing the other. Lots of stuff to learn.
9
31
 
10
- #### Installation
32
+ <a name="installation"></a>
33
+ #### Installation
11
34
 
12
35
  The Riot gem is hosted on gemcutter.org. It used to be hosted on GitHub, but they turned off gem support while moving to Rackspace, so we moved to gemcutter. If you have not already done so, add gemcutter.org to your list of gem sources like so:
13
36
 
@@ -17,6 +40,7 @@ Then, simply install the Riot gem like so:
17
40
 
18
41
  sudo gem install riot
19
42
 
43
+ <a name="speed"></a>
20
44
  #### Note on speed
21
45
 
22
46
  I have done a really simple benchmarking (10,000 runs), but right now, Riot is running about **2 times** faster than Test::unit and thusly Shoulda:
@@ -51,8 +75,10 @@ All tests ran with `ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin9.8.0], M
51
75
 
52
76
  Riot also works very well with Ruby 1.9. The same benchmarks from above run through ruby-1.9 show Riot to be twice as fast as it is already. See our [benchmarks gist](http://gist.github.com/240353) for more details.
53
77
 
78
+ <a name="examples"></a>
54
79
  ## Examples
55
80
 
81
+ <a name="examples-boolean"></a>
56
82
  #### Example: Basic booleans
57
83
 
58
84
  **NOTE:** For no specific reason, I'm going to use an ActiveRecord model in the following examples.
@@ -83,6 +109,7 @@ The other important thing to note in the examples above is the use of the `topic
83
109
 
84
110
  I'm going to use `asserts` for the rest of this introduction, but you should know that you can replace any instance of `asserts` with `should` and nothing would change.
85
111
 
112
+ <a name="examples-shortcut"></a>
86
113
  #### Example: Shortcut - Asserting the topic itself
87
114
 
88
115
  Over the course of developing Riot it became somewhat obvious to some of us that we were creating assertions that returned the `topic` just so we could assert things about the topic itself. For instance, were doing this:
@@ -110,6 +137,7 @@ together as follows:
110
137
  asserts("is a trazillionaire").kind_of(Trazillionaire)
111
138
  end
112
139
 
140
+ <a name="examples-equality"></a>
113
141
  #### Example: Equality
114
142
 
115
143
  One of the most common assertions you will (or do already) utilize is that of equality; is this equal to that? Riot supports this in a slightly different manner than most other frameworks. With Riot, you add the expectation to the assertion itself.
@@ -154,6 +182,7 @@ Which, to me, seems like a redundancy. The test already says it's nil! Maybe Sho
154
182
 
155
183
  In my opinion, the same redundancy exists. Sure, I could write a macro like `should_be_nil {@user.email}`, but the redundancy exists in the framework itself.
156
184
 
185
+ <a name="examples-matches"></a>
157
186
  #### Example: Matches
158
187
 
159
188
  If you need to assert that a test result matches a regular expression, use the `matches` modifier like so:
@@ -165,6 +194,7 @@ If you need to assert that a test result matches a regular expression, use the `
165
194
  asserts("random phone number") { topic.random_phone_number }.matches(/^\d{3}-\d{3}-\d{4}$/)
166
195
  end
167
196
 
197
+ <a name="examples-raises"></a>
168
198
  #### Example: Raises
169
199
 
170
200
  Sometimes, your test raises an exception that you actually expected.
@@ -181,6 +211,7 @@ And if you wanted to check that the exception and message match what you expect:
181
211
  asserts("invalid data") { topic.save! }.raises(ActiveRecord::RecordInvalid, /has errors/)
182
212
  end
183
213
 
214
+ <a name="examples-kind-of"></a>
184
215
  #### Example: Kind Of
185
216
 
186
217
  When you want to test that an expression returns an object of an expected type:
@@ -190,6 +221,23 @@ When you want to test that an expression returns an object of an expected type:
190
221
  asserts("its balance") { topic.balance }.kind_of(Currency)
191
222
  end
192
223
 
224
+ <a name="examples-empty"></a>
225
+ #### Example: Empty
226
+
227
+ When you want to assert a test result is empty (length == 0):
228
+
229
+ context "a new user" do
230
+ setup { User.new }
231
+ should("have no first name") { topic.first_name }.empty
232
+
233
+ #let's imagine phone numbers is an array
234
+ should("have no phone numbers") { topic.phone_numbers }.empty
235
+
236
+ #let's imagine attributes is a hash
237
+ should("have no attributes") { topic.attributes }.empty
238
+ end
239
+
240
+ <a name="examples-respond-to"></a>
193
241
  #### Example: Respond To
194
242
 
195
243
  When you want to test that an object responds to a specific method:
@@ -199,6 +247,7 @@ When you want to test that an object responds to a specific method:
199
247
  asserts("email is defined") { topic }.respond_to(:email)
200
248
  end
201
249
 
250
+ <a name="examples-assigns"></a>
202
251
  #### Example: Assigns
203
252
 
204
253
  Sometimes you want to check and see if an instance variable is defined.
@@ -221,6 +270,7 @@ While other times you also want to make sure the value of the instance variable
221
270
  asserts("has a first name") { topic }.assigns(:first_name, "Joe") # This will fail
222
271
  end
223
272
 
273
+ <a name="examples-nested"></a>
224
274
  #### Example: Nested contexts
225
275
 
226
276
  Oh yeah, Riot does those, too. The `setup` from each parent is "loaded" into the context and then the context is executed as normal. Test naming is a composite of the parent contexts' names. Here, we'll do a little Sinatra testing (see below for instructions on how to make it Riot work seamlessly with Sinatra tests).
@@ -255,6 +305,7 @@ See the TODO section for everything that's missing.
255
305
 
256
306
  Also, see [the wiki](http://wiki.github.com/thumblemonks/riot) for more examples and documentation.
257
307
 
308
+ <a name="omg"></a>
258
309
  ## You say, "OMG! Why did you write this?"
259
310
 
260
311
  ### Some background, I guess
@@ -298,6 +349,7 @@ I like this approach because I only want to test one thing, but that one thing m
298
349
 
299
350
  I imagine this approach will persuade many of you to avoid Riot altogether. I don't blame you. A few years ago I would have avoided it, too. As of this writing though, I have ported Chicago and Slvu (which were previously written in Test::Unit + Shoulda) to Riot, cut the number of lines of code in almost half, definitely more than halved the amount of time the tests took to run, and did so in less than half a day (I was building Riot while porting them :).
300
351
 
352
+ <a name="running"></a>
301
353
  ## Running tests
302
354
 
303
355
  Create or modify your existing Rakefile to define a test task like so:
@@ -314,6 +366,7 @@ Create or modify your existing Rakefile to define a test task like so:
314
366
 
315
367
  Basically, it's like setting up any other test runner. Then, from the command line, you only need to run `rake` or `rake test`. Please make sure to remove all references to any other testing frameworks before running tests. For instance, do not require `test/unit`, `shoulda`, `minitest`, or anything else like it.
316
368
 
369
+ <a name="sinatra"></a>
317
370
  ### With Sinatra
318
371
 
319
372
  Riot definitely works with the latest Sinatra. I personally use it to run tests for [Chicago](http://github.com/thumblemonks/chicago) and [Slvu](http://github.com/jaknowlden/slvu). Setup is pretty easy and very much like getting your tests to run with Test::Unit. In a test helper file that gets loaded into all of your tests (that need it), enter the following:
@@ -339,10 +392,12 @@ And then define a context (or many) for testing your Sinatra app. For instance:
339
392
 
340
393
  Make sure to check out the Riot + Sinatra testing macros in Chicago.
341
394
 
395
+ <a name="rails"></a>
342
396
  ### With Rails
343
397
 
344
398
  It's doubtful that Riot works with Rails very easily as Riot completely replaces Test::Unit. I haven't tried it yet, but intend to with my next new Rails project. Porting would probably take some time unless you only have a few test cases. Porting is made somewhat easier if you're already using Shoulda; you can replace the `TestCase` definition with a `context` of the same name as the class under test I suppose.
345
399
 
400
+ <a name="extending"></a>
346
401
  ## Extending Riot with Macros
347
402
 
348
403
  To extend Riot, similar to how you would with Shoulda, you simply need to include your methods into the `Riot::Context` class. For example, let's say you wanted to add a helpful macro for asserting the response status of some HTTP result in Sinatra. You could do this easily by defining your macro like so:
@@ -371,6 +426,7 @@ And then in your actual test, you might do the following:
371
426
 
372
427
  **COMING SOON:** Riot will look into test/riot\_macros, but not today.
373
428
 
429
+ <a name="assertion-macros"></a>
374
430
  #### Assertion macros
375
431
 
376
432
  If you want to add special macros to an Assertion, this is as easy as adding them to a Context. Assertion macros, however, have a special mechanism for adding themselves onto an assertion. Thus, you will want to open the Riot::Assertion class and then define your assertion macro.
@@ -0,0 +1,11 @@
1
+ - Documentation
2
+ - Introduction
3
+ - overall example
4
+ - Assertion
5
+ - scope
6
+ - extensions (e.g. rack/test)
7
+ - Assertion Macros
8
+ - include/any/contains (array,hash, maybe string?)
9
+ - perhaps able to take an enumerable and compare...
10
+ { [1,2,3] }.contains(2,3)
11
+ { "the song that never ends" }.contains("never","ends")
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.10.1
1
+ 0.10.2
@@ -25,6 +25,8 @@ module Riot
25
25
  Riot.silently? ? Riot::SilentReporter : (@reporter_class || Riot::StoryReporter)
26
26
  end
27
27
  def self.reporter=(reporter_class) @reporter_class = reporter_class; end
28
+ # TODO: make this a flag that DotMatrix and Story respect and cause them to print errors/failures
29
+ def self.verbose; Riot.reporter = Riot::VerboseReporter; end
28
30
  def self.dots; Riot.reporter = Riot::DotMatrixReporter; end
29
31
 
30
32
  at_exit { run unless Riot.silently? }
@@ -1,10 +1,12 @@
1
1
  module Riot
2
2
  class Assertion
3
- # Asserts that the result of the test equals the expected value
3
+ # Asserts that the result of the test equals the expected value. Using the +===+ operator to assert
4
+ # equality.
4
5
  # asserts("test") { "foo" }.equals("foo")
5
6
  # should("test") { "foo" }.equals("foo")
7
+ # asserts("test") { "foo" }.equals { "foo" }
6
8
  assertion(:equals) do |actual, expected|
7
- expected == actual ? pass : fail("expected #{actual.inspect} to equal #{expected.inspect}")
9
+ expected === actual ? pass : fail("expected #{expected.inspect}, not #{actual.inspect}")
8
10
  end
9
11
 
10
12
  # Asserts that the result of the test is nil
@@ -28,7 +30,7 @@ module Riot
28
30
  # asserts("test") { "foo" }.kind_of(String)
29
31
  # should("test") { "foo" }.kind_of(String)
30
32
  assertion(:kind_of) do |actual, expected|
31
- actual.kind_of?(expected) ? pass : fail("expected kind of #{expected}, not #{actual.inspect}")
33
+ actual.kind_of?(expected) ? pass : fail("expected kind of #{expected}, not #{actual.class.inspect}")
32
34
  end
33
35
 
34
36
  # Asserts that an instance variable is defined for the result of the assertion. Value of instance
@@ -97,5 +99,21 @@ module Riot
97
99
  end
98
100
  end
99
101
 
102
+ # Asserts the result is empty
103
+ # asserts("a string") { "" }.empty
104
+ # asserts("an array") { [] }.empty
105
+ # asserts("a hash") { Hash.new }.empty
106
+ assertion(:empty) do |actual|
107
+ actual.length == 0 ? pass : fail("expected #{actual.inspect} to be empty")
108
+ end
109
+
110
+ # Asserts the result contains the expected element
111
+ # asserts("a string") { "world" }.includes('o')
112
+ # asserts("an array") { [1,2,3] }.includes(2)
113
+ # asserts("a range") { (1..15) }.includes(10)
114
+ assertion(:includes) do |actual, expected|
115
+ actual.include?(expected) ? pass : fail("expected #{actual.inspect} to include #{expected.inspect}")
116
+ end
117
+
100
118
  end # Assertion
101
119
  end # Riot
@@ -50,10 +50,19 @@ module Riot
50
50
  def error(description, e) say " ! " + "#{description}: #{e.message}".red; end
51
51
  end
52
52
 
53
+ class VerboseReporter < StoryReporter
54
+ def error(description, e)
55
+ super(description, e)
56
+ say " #{e.class.name} occured".red
57
+ e.backtrace.each { |line| say " at #{line}".red }
58
+ end
59
+ end
60
+
53
61
  class DotMatrixReporter < IOReporter
54
62
  def pass(description); @writer.write ".".green; end
55
63
  def fail(description, message); @writer.write "F".yellow; end
56
64
  def error(description, e); @writer.write "E".red; end
65
+ # TODO: Print the failures and errors at the end. Sorry :|
57
66
  end
58
67
 
59
68
  class SilentReporter < Reporter
@@ -32,8 +32,9 @@ module Riot
32
32
  end
33
33
 
34
34
  def self.assertion(name, expect_exception=false, &assertion_block)
35
- define_method(name) do |*expectings|
35
+ define_method(name) do |*expectings, &expectation_block|
36
36
  (class << self; self; end).send(:define_method, :run) do |situation|
37
+ expectings << situation.evaluate(&expectation_block) if expectation_block
37
38
  process_macro(situation, expect_exception) { |actual| assertion_block.call(actual, *expectings) }
38
39
  end # redefine run method when the assertion is called
39
40
  self
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{riot}
8
- s.version = "0.10.1"
8
+ s.version = "0.10.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Justin 'Gus' Knowlden"]
12
- s.date = %q{2009-11-23}
12
+ s.date = %q{2009-11-27}
13
13
  s.description = %q{An extremely fast, expressive, and context-driven unit-testing framework. A replacement for all other testing frameworks. Protest the slow test.}
14
14
  s.email = %q{gus@gusg.us}
15
15
  s.extra_rdoc_files = [
@@ -30,8 +30,10 @@ Gem::Specification.new do |s|
30
30
  "lib/riot/situation.rb",
31
31
  "riot.gemspec",
32
32
  "test/assertion_macros/assigns_test.rb",
33
+ "test/assertion_macros/empty_test.rb",
33
34
  "test/assertion_macros/equals_test.rb",
34
35
  "test/assertion_macros/exists_test.rb",
36
+ "test/assertion_macros/includes_test.rb",
35
37
  "test/assertion_macros/kind_of_test.rb",
36
38
  "test/assertion_macros/matching_test.rb",
37
39
  "test/assertion_macros/nil_test.rb",
@@ -55,8 +57,10 @@ Gem::Specification.new do |s|
55
57
  s.summary = %q{An extremely fast, expressive, and context-driven unit-testing framework. Protest the slow test.}
56
58
  s.test_files = [
57
59
  "test/assertion_macros/assigns_test.rb",
60
+ "test/assertion_macros/empty_test.rb",
58
61
  "test/assertion_macros/equals_test.rb",
59
62
  "test/assertion_macros/exists_test.rb",
63
+ "test/assertion_macros/includes_test.rb",
60
64
  "test/assertion_macros/kind_of_test.rb",
61
65
  "test/assertion_macros/matching_test.rb",
62
66
  "test/assertion_macros/nil_test.rb",
@@ -0,0 +1,24 @@
1
+ require 'teststrap'
2
+
3
+ context "An empty assertion macro" do
4
+ setup do
5
+ def assert_empty(string)
6
+ Riot::Assertion.new("test") { string }.empty
7
+ end
8
+ end
9
+
10
+ assertion_test_passes("when string is empty") { assert_empty("") }
11
+ assertion_test_fails("when string has content", "expected \" \" to be empty") do
12
+ assert_empty(" ")
13
+ end
14
+
15
+ assertion_test_passes("when an array is empty") { assert_empty([]) }
16
+ assertion_test_fails("when an array has items", "expected [1] to be empty") do
17
+ assert_empty([1])
18
+ end
19
+
20
+ assertion_test_passes("when a hash is empty") { assert_empty({}) }
21
+ assertion_test_fails("when a hash has items", "expected {:name=>\"washington\"} to be empty") do
22
+ assert_empty({:name => 'washington'})
23
+ end
24
+ end
@@ -1,5 +1,8 @@
1
1
  require 'teststrap'
2
2
 
3
+ # Using == to verify the tes because this is the test for :equals itself. Look at assertion_test_passes
4
+ # and assertion_test_fails for testing other macros.
5
+
3
6
  context "An equals assertion macro" do
4
7
  setup do
5
8
  Riot::Assertion.new("blue") { "foo" }
@@ -13,6 +16,34 @@ context "An equals assertion macro" do
13
16
  setup { topic.equals("bar").run(Riot::Situation.new) }
14
17
 
15
18
  asserts(":fail") { topic.first == :fail }
16
- asserts("message") { topic.last == %Q{expected "foo" to equal "bar"} }
19
+ asserts("message") { topic.last == %Q{expected "bar", not "foo"} }
17
20
  end # that is failing
21
+
22
+ context "with numeric topic" do
23
+ setup do
24
+ Riot::Assertion.new("blue") { 31415 }
25
+ end
26
+
27
+ asserts(":pass when in expected range") do
28
+ topic.equals(30000..32000).run(Riot::Situation.new) == [:pass]
29
+ end
30
+
31
+ context "when not in expected range" do
32
+ setup { topic.equals(32000..33000).run(Riot::Situation.new) }
33
+
34
+ asserts(":fail") { topic.first == :fail }
35
+ asserts("message") { topic.last == %Q{expected 32000..33000, not 31415} }
36
+ end
37
+ end # with numeric topic
38
+
39
+ context "with block as the expectation" do
40
+ asserts(":pass when block expectation met") do
41
+ topic.equals { "foo" }.run(Riot::Situation.new)
42
+ end.equals([:pass])
43
+
44
+ asserts(":fail with message when block expectation not met") do
45
+ topic.equals { "bar" }.run(Riot::Situation.new)
46
+ end.equals([:fail, %Q{expected "bar", not "foo"}])
47
+ end # with block as the expectation
48
+
18
49
  end # An equals assertion macro
@@ -0,0 +1,13 @@
1
+ require 'teststrap'
2
+
3
+ context "An includes assertion macro" do
4
+ setup do
5
+ Riot::Assertion.new("an array") { [1, 6, 42, 7] }
6
+ end
7
+
8
+ assertion_test_passes("when array includes 42") { topic.includes(42) }
9
+
10
+ assertion_test_fails("when 99 not included in array", "expected [1, 6, 42, 7] to include 99") do
11
+ topic.includes(99)
12
+ end
13
+ end # An includes assertion macro
@@ -9,9 +9,9 @@ context "A kind_of assertion macro" do
9
9
 
10
10
  asserts ":fail when not a kind of String" do
11
11
  Riot::Assertion.new("foo") { 0 }.kind_of(String).run(topic)
12
- end.equals([:fail, %Q{expected kind of String, not 0}])
12
+ end.equals([:fail, %Q{expected kind of String, not Fixnum}])
13
13
 
14
14
  asserts ":fail when nil" do
15
15
  Riot::Assertion.new("foo") { }.kind_of(String).run(topic)
16
- end.equals([:fail, %Q{expected kind of String, not nil}])
16
+ end.equals([:fail, %Q{expected kind of String, not NilClass}])
17
17
  end # A kind_of assertion macro
@@ -43,4 +43,16 @@ context "An assertion" do
43
43
  result = topic.run(@situation)
44
44
  end.equals([:pass])
45
45
  end
46
+
47
+ context "with block expectation" do
48
+ setup do
49
+ @situation = Riot::Situation.new
50
+ @situation.topic = "hello"
51
+ Riot::Assertion.new("test")
52
+ end
53
+ should("use block returning topic as default") do
54
+ topic.equals { "hello" }
55
+ result = topic.run(@situation)
56
+ end.equals([:pass])
57
+ end
46
58
  end # An assertion block
@@ -42,3 +42,35 @@ context "A reporter" do
42
42
  topic.report("break it down", [:error, "error time"])
43
43
  end.equals("errored(break it down, error time)")
44
44
  end # A reporter
45
+
46
+ require 'stringio'
47
+ context "StoryReporter" do
48
+ setup {
49
+ @out = StringIO.new
50
+ Riot::StoryReporter.new(@out)
51
+ }
52
+
53
+ context 'reporting on an empty context' do
54
+ setup do
55
+ context = Riot::Context.new('empty context') do
56
+ context "a nested empty context" do
57
+ end
58
+ end
59
+ context.run(topic)
60
+ end
61
+ should("not output context name") { @out.string }.empty
62
+ end
63
+
64
+ context "reporting on a non-empty context" do
65
+ setup do
66
+ context = Riot::Context.new('supercontext') do
67
+ asserts("truth") { true }
68
+ end
69
+ context.run(topic)
70
+ end
71
+
72
+ should('output context name') { @out.string }.matches(/supercontext/)
73
+ should('output name of passed assertion') { @out.string }.matches(/truth/)
74
+ end
75
+
76
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.1
4
+ version: 0.10.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin 'Gus' Knowlden
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-23 00:00:00 -06:00
12
+ date: 2009-11-27 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -45,8 +45,10 @@ files:
45
45
  - lib/riot/situation.rb
46
46
  - riot.gemspec
47
47
  - test/assertion_macros/assigns_test.rb
48
+ - test/assertion_macros/empty_test.rb
48
49
  - test/assertion_macros/equals_test.rb
49
50
  - test/assertion_macros/exists_test.rb
51
+ - test/assertion_macros/includes_test.rb
50
52
  - test/assertion_macros/kind_of_test.rb
51
53
  - test/assertion_macros/matching_test.rb
52
54
  - test/assertion_macros/nil_test.rb
@@ -92,8 +94,10 @@ specification_version: 3
92
94
  summary: An extremely fast, expressive, and context-driven unit-testing framework. Protest the slow test.
93
95
  test_files:
94
96
  - test/assertion_macros/assigns_test.rb
97
+ - test/assertion_macros/empty_test.rb
95
98
  - test/assertion_macros/equals_test.rb
96
99
  - test/assertion_macros/exists_test.rb
100
+ - test/assertion_macros/includes_test.rb
97
101
  - test/assertion_macros/kind_of_test.rb
98
102
  - test/assertion_macros/matching_test.rb
99
103
  - test/assertion_macros/nil_test.rb