rspec-given 2.3.2 → 2.4.0

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