minitest-given 0.1.pre → 3.0.0.beta.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +7 -0
  3. data/Gemfile.lock +27 -0
  4. data/{README.rdoc → MIT-LICENSE} +1 -29
  5. data/README.md +763 -0
  6. data/Rakefile +225 -15
  7. data/TODO +13 -0
  8. data/doc/main.rdoc +7 -0
  9. data/examples/example_helper.rb +10 -0
  10. data/examples/failing/natural_failing_spec.rb +48 -0
  11. data/examples/failing/sample_spec.rb +7 -0
  12. data/examples/integration/and_spec.rb +44 -0
  13. data/examples/integration/failing/eval_subexpression_spec.rb +9 -0
  14. data/examples/integration/failing/module_nesting_spec.rb +13 -0
  15. data/examples/integration/failing/undefined_method_spec.rb +9 -0
  16. data/examples/integration/failing_messages_spec.rb +38 -0
  17. data/examples/integration/focused_line_spec.rb +9 -0
  18. data/examples/integration/given_spec.rb +73 -0
  19. data/examples/integration/invariant_spec.rb +31 -0
  20. data/examples/integration/then_spec.rb +8 -0
  21. data/examples/loader.rb +4 -0
  22. data/examples/minitest_helper.rb +38 -0
  23. data/examples/other/line_example.rb +9 -0
  24. data/examples/stack/stack.rb +29 -0
  25. data/examples/stack/stack_spec.rb +60 -0
  26. data/examples/stack/stack_spec1.rb +3 -0
  27. data/lib/given.rb +2 -0
  28. data/lib/minitest/given.rb +1 -32
  29. data/lib/minitest-given.rb +9 -1
  30. data/rakelib/bundler_fix.rb +17 -0
  31. data/rakelib/gemspec.rake +161 -0
  32. data/rakelib/metrics.rake +30 -0
  33. data/rakelib/preview.rake +14 -0
  34. data/test/before_test.rb +22 -0
  35. data/test/meme_test.rb +36 -0
  36. metadata +69 -85
  37. data/.autotest +0 -23
  38. data/.gemtest +0 -0
  39. data/CHANGELOG.rdoc +0 -3
  40. data/Manifest.txt +0 -11
  41. data/minitest-given.gemspec +0 -42
  42. data/test/test_assertions.rb +0 -30
  43. data/test/test_comparison.rb +0 -25
  44. data/test/test_version.rb +0 -10
data/README.md ADDED
@@ -0,0 +1,763 @@
1
+ # rspec-given
2
+
3
+ | Master |
4
+ | :----: |
5
+ | [![Master Build Status](https://secure.travis-ci.org/jimweirich/rspec-given.png?branch=master)](https://travis-ci.org/jimweirich/rspec-given) |
6
+
7
+ Covering rspec-given, minitest-given, and given-core, version 3.0.0.beta.1.
8
+
9
+ rspec-given and minitest-given are extensions to your favorite testing
10
+ framework to allow Given/When/Then notation when writing specs.
11
+
12
+ # Why Given/When/Then
13
+
14
+ RSpec has done a great job of making specifications more readable for
15
+ humans. However, I really like the given/when/then nature of Cucumber
16
+ stories and would like to follow the same structure in my unit tests.
17
+ rspec-given (and now minitest-given) allows a simple given/when/then
18
+ structure RSpec specifications.
19
+
20
+ ## Status
21
+
22
+ * rspec-given is ready for production use.
23
+ * minitest-given is experimental.
24
+
25
+ ### RSpec/Given
26
+
27
+ The rspec-given gem is the original given/when/then extension for
28
+ RSpec. It now depends on a given_core gem for the basic functionality
29
+ and then adds the RSpec specific code.
30
+
31
+ * rspec-given now require RSpec version 2.12 or better.
32
+
33
+ ### Minitest/Given
34
+
35
+ A new minitest-given gem allows Given/When/Then notation directly in
36
+ Minitest::Spec specifications.
37
+
38
+ To use minitest-given, just place the following require at the top of
39
+ the file (or in a convenient spec_helper).
40
+
41
+ ```ruby
42
+ require 'minitest/given'
43
+ ```
44
+
45
+ All the features of rspec-given are available in minitest-given.
46
+
47
+ When switching from RSpec/Given to Minitest/Given, here are some
48
+ things to watch out for:
49
+
50
+ * You need to use Minitest version 4.3 or better (yes, Minitest 5.x
51
+ should work as well).
52
+
53
+ * Minitest/Given adds the missing "context" block to Minitest::Spec.
54
+
55
+ * Only one before block is allowed in any given Minitest::Spec
56
+ describe block. This doesn't effect the number of Givens you are
57
+ allowed to use, but it may surprise if you are use to RSpec.
58
+
59
+ ### Auto Selecting
60
+
61
+ If you exclusively use natural assertions in your specs, it's quite
62
+ possible to write specs that run under both RSpec and Minitest::Spec.
63
+
64
+ Use this at the start of your spec file:
65
+
66
+ ```ruby
67
+ if defined?(RSpec)
68
+ require 'rspec/given'
69
+ else
70
+ require 'minitest/autorun'
71
+ require 'minitest/given'
72
+ end
73
+ ```
74
+
75
+ See
76
+ [stack_spec.rb](https://github.com/jimweirich/rspec-given/blob/minispec/examples/stack/stack_spec.rb)
77
+ and
78
+ [example_helper.rb](https://github.com/jimweirich/rspec-given/blob/minispec/examples/example_helper.rb)
79
+
80
+ ## Example
81
+
82
+ Here is a specification written in the rspec-given framework:
83
+
84
+ ```ruby
85
+ require 'rspec/given'
86
+ require 'spec_helper'
87
+ require 'stack'
88
+
89
+ describe Stack do
90
+ def stack_with(initial_contents)
91
+ stack = Stack.new
92
+ initial_contents.each do |item| stack.push(item) end
93
+ stack
94
+ end
95
+
96
+ Given(:stack) { stack_with(initial_contents) }
97
+ Invariant { stack.empty?.should == (stack.depth == 0) }
98
+
99
+ context "with no items" do
100
+ Given(:initial_contents) { [] }
101
+ Then { stack.depth.should == 0 }
102
+
103
+ context "when pushing" do
104
+ When { stack.push(:an_item) }
105
+
106
+ Then { stack.depth.should == 1 }
107
+ Then { stack.top.should == :an_item }
108
+ end
109
+
110
+ context "when popping" do
111
+ When(:result) { stack.pop }
112
+ Then { result.should have_failed(Stack::UnderflowError, /empty/) }
113
+ end
114
+ end
115
+
116
+ context "with one item" do
117
+ Given(:initial_contents) { [:an_item] }
118
+
119
+ context "when popping" do
120
+ When(:pop_result) { stack.pop }
121
+
122
+ Then { pop_result.should == :an_item }
123
+ Then { stack.depth.should == 0 }
124
+ end
125
+ end
126
+
127
+ context "with several items" do
128
+ Given(:initial_contents) { [:second_item, :top_item] }
129
+ Given!(:original_depth) { stack.depth }
130
+
131
+ context "when pushing" do
132
+ When { stack.push(:new_item) }
133
+
134
+ Then { stack.top.should == :new_item }
135
+ Then { stack.depth.should == original_depth + 1 }
136
+ end
137
+
138
+ context "when popping" do
139
+ When(:pop_result) { stack.pop }
140
+
141
+ Then { pop_result.should == :top_item }
142
+ Then { stack.top.should == :second_item }
143
+ Then { stack.depth.should == original_depth - 1 }
144
+ end
145
+ end
146
+ end
147
+ ```
148
+
149
+ Let's talk about the individual statements used in the Given
150
+ framework.
151
+
152
+ ### Given
153
+
154
+ The _Given_ section specifies a starting point, a set of preconditions
155
+ that must be true before the code under test is allowed to be run. In
156
+ standard test frameworks the preconditions are established with a
157
+ combination of setup methods (or :before actions in RSpec) and code in
158
+ the test.
159
+
160
+ In the example code above the preconditions are started with _Given_
161
+ statements. A top level _Given_ (that applies to the entire describe
162
+ block) says that one of the preconditions is that there is a stack
163
+ with some initial contents.
164
+
165
+ Note that initial contents are not specified in the top level describe
166
+ block, but are given in each of the nested contexts. By pushing the
167
+ definition of "initial_contents" into the nested contexts, we can vary
168
+ them as needed for that particular context.
169
+
170
+ A precondition in the form "Given(:var) {...}" creates an accessor
171
+ method named "var". The accessor is lazily initialized by the code
172
+ block. If you want a non-lazy given, use "Given!(:var) {...}".
173
+
174
+ A precondition in the form "Given {...}" just executes the code block
175
+ for side effects. Since there is no accessor, the code block is
176
+ executed immediately (i.e. no lazy evaluation).
177
+
178
+ The preconditions are run in order of definition. Nested contexts
179
+ will inherit the preconditions from the enclosing context, with outer
180
+ preconditions running before inner preconditions.
181
+
182
+ #### Given examples:
183
+
184
+ ```ruby
185
+ Given(:stack) { Stack.new }
186
+ ```
187
+
188
+ The block for the given clause is lazily run and its value bound to
189
+ 'stack' if 'stack' is ever referenced in the test.
190
+ The first reference to 'stack' in the specification will cause the
191
+ code block to execute. Futher references to 'stack' will reuse the
192
+ previously generated value.
193
+
194
+ ```ruby
195
+ Given!(:original_size) { stack.size }
196
+ ```
197
+
198
+ The code block is run unconditionally once before each test and the
199
+ value of the block is bound to 'original_size'. This form is useful
200
+ when you want to record the value of something that might be affected
201
+ by the When code.
202
+
203
+ ```ruby
204
+ Given { stack.clear }
205
+ ```
206
+
207
+ The block for the given clause is run unconditionally once before each
208
+ test. This form of given is used for code that is executed for side
209
+ effects.
210
+
211
+ ### When
212
+
213
+ The _When_ clause specifies the code to be tested ... oops, excuse me
214
+ ... specified. After the preconditions in the given section are met,
215
+ the when code block is run.
216
+
217
+ In general there should not be more than one _When_ clause for a given
218
+ direct context. However, a _When_ in an outer context will be run
219
+ after all the _Givens_ but before the inner _When_. You can think of
220
+ an outer _When_ as setting up additional given state for the inner
221
+ _When_.
222
+
223
+ E.g.
224
+
225
+ ```ruby
226
+ context "outer context" do
227
+ When { code specified in the outer context }
228
+ Then { assert something about the outer context }
229
+
230
+ context "inner context" do
231
+
232
+ # At this point, the _When_ of the outer context
233
+ # should be treated as a _Given_ of the inner context
234
+
235
+ When { code specified in the inner context }
236
+ Then { assert something about the inner context }
237
+ end
238
+ end
239
+ ```
240
+
241
+ #### When examples:
242
+
243
+ ```ruby
244
+ When { stack.push(:item) }
245
+ ```
246
+
247
+ The code block is executed once per test. The effect of the _When{}_
248
+ block is very similar to _Given{}_. However, When is used to identify
249
+ the particular code that is being specified in the current context or
250
+ describe block.
251
+
252
+ ```ruby
253
+ When(:result) { stack.pop }
254
+ ```
255
+
256
+ The code block is executed once per test and the value of the code
257
+ block is bound to 'result'. Use this form when the code under test
258
+ returns a value that you wish to interrogate in the _Then_ code.
259
+
260
+ If an exception occurs during the execution of the block for the When
261
+ clause, the exception is caught and a failure object is bound to
262
+ 'result'. The failure can be checked in a then block with the
263
+ 'have_failed' matcher.
264
+
265
+ The failure object will rethrow the captured exception if anything
266
+ other than have_failed matcher is used on the failure object.
267
+
268
+ For example, if the stack is empty when it is popped, then it is
269
+ reasonable for pop to raise an UnderflowError. This is how you might
270
+ specify that behavior:
271
+
272
+ ```ruby
273
+ When(:result) { stack.pop }
274
+ Then { result.should have_failed(UnderflowError, /empty/) }
275
+ ```
276
+
277
+ Note that the arguments to the 'have_failed' matcher are the same as
278
+ those given to the standard RSpec matcher 'raise_error'.
279
+
280
+ ### Then
281
+
282
+ The _Then_ clauses are the postconditions of the specification. These
283
+ then conditions must be true after the code under test (the _When_
284
+ clause) is run.
285
+
286
+ The code in the block of a _Then_ clause should be a single _should_
287
+ assertion. Code in _Then_ clauses should not have any side effects.
288
+
289
+ Let me repeat that: <b>_Then_ clauses should not have any side
290
+ effects!</b> _Then_ clauses with side effects are erroneous. _Then_
291
+ clauses need to be idempotent, so that running them once, twice, a
292
+ hundred times, or never does not change the state of the program. (The
293
+ same is true of _And_ and _Invariant_ clauses).
294
+
295
+ In RSpec terms, a _Then_ clause forms a RSpec Example that runs in the
296
+ context of an Example Group (defined by a describe or context clause).
297
+
298
+ Each Example Group must have at least one _Then_ clause, otherwise
299
+ there will be no examples to be run for that group. If all the
300
+ assertions in an example group are done via Invariants, then the group
301
+ should use an empty _Then_ clause, like this:
302
+
303
+ ```ruby
304
+ Then { }
305
+ ```
306
+
307
+ #### Then examples:
308
+
309
+ ```ruby
310
+ Then { stack.should be_empty }
311
+ ```
312
+
313
+ After the related block for the _When_ clause is run, the stack should
314
+ be empty. If it is not empty, the test will fail.
315
+
316
+ ### And
317
+
318
+ The _And_ clause is similar to _Then_, but does not form its own RSpec
319
+ example. This means that _And_ clauses reuse the setup from a sibling
320
+ _Then_ clause. Using a single _Then_ and multiple _And_ clauses in an
321
+ example group means the setup for that group is run only once (for the
322
+ _Then_ clause) and reused for all the _And_ clauses. This can be a
323
+ significant speed savings where the setup for an example group is
324
+ expensive.
325
+
326
+ Some things to keep in mind about _And_ clauses:
327
+
328
+ * There must be at least one _Then_ in the example group and it must
329
+ be declared before the _And_ clauses. Forgetting the _Then_ clause
330
+ is an error.
331
+
332
+ * The code in the _And_ clause is run immediately after the first
333
+ (executed) _Then_ of an example group.
334
+
335
+ * An assertion failure in a _Then_ clause or an _And_ clause will
336
+ cause all the subsequent _And_ clauses to be skipped.
337
+
338
+ * Since _And_ clauses do not form their own RSpec examples, they are
339
+ not represented in the formatted output of RSpec. That means _And_
340
+ clauses do not produce dots in the Progress format, nor do they
341
+ appear in the documentation, html or textmate formats (options
342
+ -fhtml, -fdoc, or -ftextmate).
343
+
344
+ * Like _Then_ clauses, _And_ clauses must be idempotent. That means
345
+ they should not execute any code that changes global program state.
346
+ (See the section on the _Then_ clause).
347
+
348
+ The choice to use an _And_ clause is primarily a speed consideration.
349
+ If an example group has expensive setup and there are a lot of _Then_
350
+ clauses, then choosing to make some of the _Then_ clauses into _And_
351
+ clauses will speed up the spec. Otherwise it is probably better to
352
+ stick with _Then_ clauses.
353
+
354
+ #### Then/And examples:
355
+
356
+ ```ruby
357
+ Then { pop_result.should == :top_item } # Required
358
+ And { stack.top.should == :second_item } # No Setup rerun
359
+ And { stack.depth.should == original_depth - 1 } # ... for these
360
+ ```
361
+
362
+ ### Invariant
363
+
364
+ The _Invariant_ clause is a new idea that doesn't have an analog in
365
+ RSpec or Test::Unit. The invariant allows you specify things that must
366
+ always be true in the scope of the invariant. In the stack example, the method
367
+ <tt>empty?</tt> is defined in term of <tt>size</tt>.
368
+
369
+ ```ruby
370
+ Invariant { stack.empty? == (stack.depth == 0) }
371
+ ```
372
+
373
+ This invariant states that <code>empty?</code> is true if and only if
374
+ the stack depth is zero, and that assertion is checked at every _Then_
375
+ clause that is in the same scope.
376
+
377
+ You can conceptually think of an _Invariant_ clause as a _Then_ block
378
+ that automatically gets added to every _Then_ within its scope.
379
+ Invariants nested within a context only apply to the _Then_ clauses
380
+ that are in the scope of that context.
381
+
382
+ Invariants that reference a _Given_ precondition accessor must only be
383
+ used in contexts that define that accessor.
384
+
385
+ Notes:
386
+
387
+ * Since Invariants do not form their own RSpec example, they are not
388
+ represented in the RSpec formatted output (e.g. the '--format html'
389
+ option).
390
+
391
+ ## Execution Ordering
392
+
393
+ When running the test for a specific _Then_ clause, the following will
394
+ be true:
395
+
396
+ * The non-lazy _Given_ clauses will be run in the order that they are
397
+ specified, from the outermost scope to the innermost scope
398
+ containing the _Then_. (The lazy _Given_ clauses will be run upon
399
+ demand).
400
+
401
+ * All of the _Given_ clauses in all of the relevant scopes will run
402
+ before the first (outermost) _When_ clause in those same scopes.
403
+ That means that the _When_ code can assume that the givens have been
404
+ established, even if the givens are in a more nested scope than the
405
+ When.
406
+
407
+ * _When_ clauses and RSpec _before_ blocks will be executed in the
408
+ order that they are specified, from the outermost block to the
409
+ innermost block. This makes _before_ blocks an excellent choice when
410
+ writing narrative tests to specify actions that happen between the
411
+ "whens" of a narrative-style test.
412
+
413
+ Note that the ordering between _Given_ clauses and _before_ blocks are
414
+ not strongly specified. Hoisting a _When_ clause out of an inner scope
415
+ to an outer scope may change the order of execution between related
416
+ _Given_ clauses and any _before_ blocks (hoisting the _When_ clause
417
+ might cause the related _Given_ clauses to possibly run earlier).
418
+ Because of this, do not split order dependent code between _Given_
419
+ clauses and _before_ blocks.
420
+
421
+ ## Natural Assertions
422
+
423
+ **NOTE:** <em>Natural assertions are currently an experimental feature
424
+ of RSpec/Given. They are currently disabled by default, but can be
425
+ enabled by a simple configuration option (see "use_natural_assertions"
426
+ below).</em>
427
+
428
+ RSpec/Given now supports the use of "natural assertions" in _Then_,
429
+ _And_, and _Invariant_ blocks. Natural assertions are just Ruby
430
+ conditionals, without the _should_ or _expect_ methods that RSpec
431
+ provides. Here are the Then/And examples from above, but written using
432
+ natural assertions:
433
+
434
+ ```ruby
435
+ Then { pop_result == :top_item }
436
+ And { stack.top == :second_item }
437
+ And { stack.depth == original_depth - 1 }
438
+ ```
439
+
440
+ Natural assertions must be enabled, either globally or on a per
441
+ context basis, to be recognized.
442
+
443
+ Here's a heads up: If you use natural assertions, but fail to enable
444
+ them, all your specs will mysteriously pass. This is why the **red**
445
+ part of _Red/Green/Refactor_ is so important.
446
+
447
+ ### Failure Messages with Natural Assertions
448
+
449
+ Since natural assertions do not depend upon matchers, you don't get
450
+ customized error messages from them. What you _do_ get is a complete
451
+ analsysis of the expression that failed.
452
+
453
+ For example, given the following failing specification:
454
+
455
+ ```ruby
456
+ Given.use_natural_assertions
457
+
458
+ describe "Natural Assertions" do
459
+ Given(:foo) { 1 }
460
+ Given(:bar) { 2 }
461
+ Then { foo + bar == 2 }
462
+ end
463
+ ```
464
+
465
+ You would get:
466
+
467
+ ```
468
+ 1) Natural Assertions
469
+ Failure/Error: Then { foo + bar == 2 }
470
+ Then expression failed at /Users/jim/working/git/rspec-given/examples/failing/sample_spec.rb:6
471
+ expected: 3
472
+ to equal: 2
473
+ false <- foo + bar == 2
474
+ 3 <- foo + bar
475
+ 1 <- foo
476
+ 2 <- bar
477
+ # ./examples/failing/sample_spec.rb:6:in `block in Then'
478
+ ```
479
+
480
+ Notice how the failing expression "<code>foo+bar == 2</code>" was
481
+ broken down into subexpressions and values for each subexpression.
482
+ This gives you all the information you need to figure out exactly what
483
+ part of the expression is causing the failure.
484
+
485
+ Natural assertions will give additional information (e.g. "expected:
486
+ 3 to equal: 2") for top level expressions involving any of the
487
+ comparison operators (==, !=, <, <=, >, >=) or matching operators (=~,
488
+ !~).
489
+
490
+ ### Checking for exceptions with Natural Assertions
491
+
492
+ If you wish to see if the result of a _When_ clause is an exception,
493
+ you can use the following:
494
+
495
+ ```ruby
496
+ When(:result) { stack.pop }
497
+ Then { result == Failure(UnderflowError, /empty/) }
498
+ ```
499
+
500
+ The <code>Failure()</code> method accepts the same arguments as
501
+ <code>have_failed</code> and <code>raise_error</code>.
502
+
503
+ ### Caveats on Natural Assertions
504
+
505
+ Keep the following in mind when using natural assertions.
506
+
507
+ * Only a single expression/assertion per _Then_. The single expression
508
+ of the _Then_ block will be considered when determining pass/fail
509
+ for the assertion. If you _want_ to express a complex condition for
510
+ the _Then_, you need to use ||, && or some other logical operation
511
+ to join the conditions into a single expression (and the failure
512
+ message will break down the values for each part).
513
+
514
+ * Then clauses need be **idempotent**. This is true in general, but it
515
+ is particularly important for natural assertions to obey this
516
+ restriction. This means that assertions in a Then clause should not
517
+ change anything. Since the Natural Assertion error message contains
518
+ the values of all the subexpressions, the expression and its
519
+ subexpressions will be evaluated multiple times. If the Then clause
520
+ is not idempotent, you will get changing answers as the
521
+ subexpressions are evaluated.
522
+
523
+ That last point is important. If you write code like this:
524
+
525
+ ```ruby
526
+ # DO NOT WRITE CODE LIKE THIS
527
+ context "Incorrect non-idempotent conditions" do
528
+ Given(:ary) { [1, 2, 3] }
529
+ Then { ary.delete(1) == nil }
530
+ end
531
+ ```
532
+
533
+ Then the assertion will fail (because <code>ary.delete(1)</code> will
534
+ initially return 1). But when the error message is formated, the
535
+ system reports that <code>ary.delete(1)</code> returns nil. You will
536
+ scratch your head over that for a good while.
537
+
538
+ Instead, move the state changing code into a _When(:result)_ block, then
539
+ assert what you need to about :result. Something
540
+ like this is good:
541
+
542
+ ```ruby
543
+ context "Correct idempotent conditions" do
544
+ Given(:ary) { [1, 2, 3] }
545
+ When(:result) { ary.delete(1) }
546
+ Then { result == nil }
547
+ end
548
+ ```
549
+
550
+ It is good to note that non-idempotent assertions will also cause
551
+ problems with And clauses.
552
+
553
+ ### Mixing Natural Assertions and RSpec Assertions
554
+
555
+ Natural assertions and RSpec assertions for the most part can be
556
+ intermixed in a single test suite, even within a single context.
557
+ Because there are a few corner cases that might cause problems, they
558
+ must be explicitly enabled before they will be considered.
559
+
560
+ To enable natural assertions in a context, call the
561
+ _use_natural_assertions_ method in that context. For example:
562
+
563
+ ```ruby
564
+ context "Outer" do
565
+ use_natural_assertions
566
+
567
+ context "Inner" do
568
+ end
569
+
570
+ context "Disabled" do
571
+ use_natural_assertions false
572
+ end
573
+ end
574
+ ```
575
+
576
+ Both the _Outer_ and _Inner_ contexts will use natural assertions. The
577
+ _Disabled_ context overrides the setting inherited from _Outer_ and
578
+ will not process natural assertions.
579
+
580
+ See the **configuration** section below to see how to enable natural
581
+ assertions project wide.
582
+
583
+ ### Matchers and Natural Assertions
584
+
585
+ In RSpec, matchers are used to provide nice, readable error messages
586
+ when an assertion is not met. Natural assertions provide
587
+ self-explanatory failure messages for most things without requiring
588
+ any special matchers from the programmer.
589
+
590
+ In the rare case that some extra information would be helpful, it is
591
+ useful to create special objects that respond to the == operator.
592
+
593
+ #### Asserting Nearly Equal with Fuzzy Numbers
594
+
595
+ Operations on floating point numbers rarely create numbers that are
596
+ exactly equal, therefore it is useful to assert that two floating
597
+ point numbers are nearly equal. We do that by creating a fuzzy number
598
+ that has a looser interpretation of what it means to be equal.
599
+
600
+ For example, the following asserts that the square root of 10 is about
601
+ 3.1523 with an accuracy of 1 percent.
602
+
603
+ ```ruby
604
+ Then { Math.sqrt(10) == about(3.1623).percent(1) }
605
+ ```
606
+
607
+ As long as the real value of <code>Math.sqrt(10)</code> is within plus
608
+ or minus 1% of 3.1623 (i.e. 3.1623 +/- 0.031623), then the assertion
609
+ will pass.
610
+
611
+ There are several ways of creating fuzzy numbers:
612
+
613
+ * <code>about(n).delta(d)</code> -- A fuzzy number matching the range
614
+ (n-d)..(n+d)
615
+
616
+ * <code>about(n).percent(p)</code> -- A fuzzy number matching the
617
+ range (n-(n*p/100)) .. (n+(n*p/100))
618
+
619
+ * <code>about(n).epsilon(neps)</code> -- A fuzzy number matching the
620
+ range (n-(neps*e)) .. (n+(neps*e)), where e is the difference
621
+ between 1.0 and the next smallest floating point number.
622
+
623
+ * <code>about(n)</code> -- Same as <code>about(n).epsilon(10)</code>.
624
+
625
+ When the file <code>rspec/given/fuzzy_shortcuts</code> is required,
626
+ the following unicode shortcut methods are added to Numeric to create
627
+ fuzzy numbers.
628
+
629
+ * <code>n.±(del)</code> is the same as <code>about(n).delta(del)</code>
630
+
631
+ * <code>n.‰(percentage)</code> is the same as <code>about(n).percent(percentage)</code>
632
+
633
+ * <code>n.€(neps)</code> is the same as <code>about(n).epsilon(neps)</code>
634
+
635
+ * <code>n.±</code>, <code>n.‰</code>, and <code>n.€</code> are all
636
+ the same as <code>about(n)</code>
637
+
638
+ #### Detecting Exceptions
639
+
640
+ The RSpec matcher used for detecting exceptions will work with natural
641
+ assertions out of the box. Just check for equality against the
642
+ <code>have_failed</code> return value.
643
+
644
+ For example, the following two Then clauses are equivalent:
645
+
646
+ ```ruby
647
+ # Using an RSpec matcher
648
+ Then { result.should have_failed(StandardError, /message/) }
649
+
650
+ # Using natural assertions
651
+ Then { result == have_failed(StandardError, /message/) }
652
+ ```
653
+
654
+ ### Processing Natural Assertions
655
+
656
+ When natural assertions are enabled, they are only used if all of the
657
+ following are true:
658
+
659
+ 1. The block does not throw an RSpec assertion failure (or any other
660
+ exception for that matter).
661
+
662
+ 1. The block returns false (blocks that return true pass the
663
+ assertion and don't need a failure message).
664
+
665
+ 1. The block does not use RSpec's _should_ or _expect_ methods.
666
+
667
+ Detecting that last point (the use of _should_ and _expect_) is done
668
+ by modifying the RSpec runtime to report uses of _should_ and
669
+ _expect_.
670
+
671
+ ### Platform Support
672
+
673
+ Natural assertions use the Ripper library to parse the failing
674
+ condition and find all the sub-expression values upon a failure.
675
+ Currently Ripper is not supported on JRuby 1.7.2. Charles Nutter has
676
+ said that Ripper support is coming soon and may arrive as early as
677
+ version 1.7.3. Until then, natural assertions are disabled when
678
+ running under JRuby. Never fear, JRuby supports all the other features
679
+ of rspec-given and will work just fine.
680
+
681
+ ### Further Reading
682
+
683
+ Natural assertions were inspired by the [wrong assertion
684
+ library](http://rubygems.org/gems/wrong) by [Alex
685
+ Chaffee](http://rubygems.org/profiles/alexch) and [Steve
686
+ Conover](http://rubygems.org/profiles/sconoversf).
687
+
688
+ ## Configuration
689
+
690
+ Just require 'rspec/given' in the spec helper of your project and it
691
+ is ready to go.
692
+
693
+ If the RSpec format option document, html or textmate is chosen,
694
+ RSpec/Given will automatically add additional source code information to
695
+ the examples to produce better looking output. If you don't care about
696
+ the pretty output and wish to disable source code caching
697
+ unconditionally, then add the following line to your spec helper file:
698
+
699
+ ```ruby
700
+ RSpec::Given.source_caching_disabled = true
701
+ ```
702
+
703
+ Natural assertions are disabled by default. To globally configure
704
+ natural assertions, add one of the following lines to your spec_helper
705
+ file:
706
+
707
+ ```ruby
708
+ Given.use_natural_assertions # Enable natural assertions
709
+ Given.use_natural_assertions true # Same as above
710
+ Given.use_natural_assertions false # Disable natural assertions
711
+ Given.use_natural_assertions :always # Always process natural assertions
712
+ # ... even when should/expect are detected
713
+ ```
714
+
715
+ # License
716
+
717
+ RSpec-Given is available under the MIT License. See the MIT-LICENSE
718
+ file in the source distribution.
719
+
720
+ # History
721
+
722
+ * Version 3.0.0
723
+
724
+ * Support for minitest added.
725
+
726
+ * Gems rspec-given and minitest-given both use the core
727
+ functionality of gem given_core.
728
+
729
+ * Version 2.4.4
730
+
731
+ * Support for RSpec 2.13 added.
732
+
733
+ * Version 2.4.3
734
+
735
+ * Better natural assertion messages when dealing with multi-line
736
+ output.
737
+
738
+ * Version 2.4.2
739
+
740
+ * Minor adjustment to natural assertion error messages to better
741
+ handle multi-line values.
742
+
743
+ * Remove flog, flay and other development tools from the bundle and
744
+ gemspec. The Rakefile was updated to suggest installing them if
745
+ they are not there.
746
+
747
+ * Version 2.4.1
748
+
749
+ * Fix bug where constants from nested modules were not properly
750
+ accessed.
751
+
752
+ * Version 2.4.0
753
+
754
+ * Add fuzzy number helper methods (with unicode method shortcuts).
755
+
756
+ * Fix bug caused by blank lines in Thens.
757
+
758
+ # Links
759
+
760
+ * Github: [https://github.com/jimweirich/rspec-given](https://github.com/jimweirich/rspec-given)
761
+ * Clone URL: git://github.com/jimweirich/rspec-given.git
762
+ * Bug/Issue Reporting: [https://github.com/jimweirich/rspec-given/issues](https://github.com/jimweirich/rspec-given/issues)
763
+ * Continuous Integration: [http://travis-ci.org/#!/jimweirich/rspec-given](http://travis-ci.org/#!/jimweirich/rspec-given)