given_core 3.0.0 → 3.1.0

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