rspec-given 1.6.0 → 2.0.0.beta.1

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 1.6.0.beta.1.
3
+ Covering rspec-given, version 2.0.0.beta.1.
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
@@ -36,6 +36,7 @@ describe Stack do
36
36
  end
37
37
 
38
38
  Given(:stack) { stack_with(initial_contents) }
39
+ Invariant { stack.empty?.should == (stack.depth == 0) }
39
40
 
40
41
  context "when empty" do
41
42
  Given(:initial_contents) { [] }
data/Rakefile CHANGED
@@ -3,6 +3,7 @@
3
3
  require 'rake/clean'
4
4
  require './lib/rspec/given/version'
5
5
 
6
+ CLEAN.include("pkg/rspec-given-*").exclude("pkg/*.gem")
6
7
  CLOBBER.include("*.gemspec", "html", "README", "README.old")
7
8
 
8
9
  # README Formatting --------------------------------------------------
@@ -15,6 +16,36 @@ end
15
16
 
16
17
  task :default => :ex2
17
18
 
19
+ def version
20
+ RSpec::Given::VERSION
21
+ end
22
+
23
+ def tag_name
24
+ "rspec-given-#{version}"
25
+ end
26
+
27
+ def tagged?
28
+ `git tag`.split.include?(tag_name)
29
+ end
30
+
31
+ def git_clean?
32
+ sh "git status | grep 'nothing to commit'", :verbose => false do |status|
33
+ return status
34
+ end
35
+ end
36
+
37
+ desc "Display the current version tag"
38
+ task :version do
39
+ puts tag_name
40
+ end
41
+
42
+ desc "Tag the current commit with #{tag_name}"
43
+ task :tag do
44
+ fail "Cannot tag, project directory is not clean" unless git_clean?
45
+ fail "Cannot tag, #{tag_name} already exists." if tagged?
46
+ sh "git tag #{tag_name}"
47
+ end
48
+
18
49
  # Running examples ---------------------------------------------------
19
50
 
20
51
  desc "Run all the examples"
@@ -23,6 +54,7 @@ task :examples => [:specs, :examples1, :examples2]
23
54
  desc "Run the RSpec 2 specs and examples"
24
55
  task :ex2 => [:specs, :examples2]
25
56
 
57
+
26
58
  desc "Run the specs"
27
59
  task :specs do
28
60
  puts "Running specs"
@@ -79,8 +111,8 @@ file "README.md" => ["examples/stack/stack_spec.rb", "lib/rspec/given/version.rb
79
111
  while line = ins.gets
80
112
  case state
81
113
  when :copy
82
- if line =~ /version +\d+\.\d+\.\d+/
83
- line.gsub!(/version +\d+\.\d+\.\d+/, "version #{RSpec::Given::VERSION}")
114
+ if line =~ /version +\d+(\.(\d+|beta))+/
115
+ line.gsub!(/version +\d+(\.(\d+|beta))+/, "version #{RSpec::Given::VERSION}")
84
116
  outs.puts line
85
117
  elsif line =~ /^<pre>/
86
118
  state = :insert
@@ -0,0 +1,51 @@
1
+ require 'rspec-given'
2
+
3
+ describe "Running Givens before Whens" do
4
+ Given(:info) { [] }
5
+ Given { info << "outer1" }
6
+ Given { info << "outer2" }
7
+
8
+ context "using a when without result" do
9
+ When { info << "when" }
10
+
11
+ context "inner with When" do
12
+ Given { info << "inner1" }
13
+ Given { info << "inner2" }
14
+ Then { info.should == ["outer1", "outer2", "inner1", "inner2", "when"] }
15
+
16
+ context "using a nested When" do
17
+ When { info << "when2" }
18
+ Then { info.should == ["outer1", "outer2", "inner1", "inner2", "when", "when2"] }
19
+ end
20
+ end
21
+ end
22
+
23
+ context "using a when with a result" do
24
+ When(:result) { info << "when" }
25
+
26
+ context "inner with when" do
27
+ Given { info << "inner1" }
28
+ Given { info << "inner2" }
29
+ Then { info.should == ["outer1", "outer2", "inner1", "inner2", "when"] }
30
+ end
31
+ end
32
+
33
+ context "using no whens" do
34
+ Given { info << "inner1" }
35
+ Given { info << "inner2" }
36
+ Then { info.should == ["outer1", "outer2", "inner1", "inner2"] }
37
+ end
38
+ end
39
+
40
+ describe "Lazy Givens" do
41
+ Given(:bomb) { fail "SHOULD NEVER BE CALLED" }
42
+
43
+ context "when called" do
44
+ Then { lambda { bomb }.should raise_error(StandardError, /NEVER/) }
45
+ end
46
+
47
+ context "when not called" do
48
+ Given(:value) { :ok }
49
+ Then { value.should == :ok }
50
+ end
51
+ end
@@ -0,0 +1,31 @@
1
+ require 'rspec/given'
2
+
3
+ describe "Invariants" do
4
+ Given(:info) { [] }
5
+
6
+ Invariant { info << "I1" }
7
+
8
+ Then { info.should == ["I1"] }
9
+
10
+ context "with nested invariants" do
11
+ Invariant { info << "I2" }
12
+
13
+ Then { info.should == ["I1", "I2"] }
14
+ end
15
+
16
+ context "with multiple invariants" do
17
+ Invariant { info << "I2a" }
18
+ Invariant { info << "I2b" }
19
+
20
+ Then { info.should == ["I1", "I2a", "I2b"] }
21
+ end
22
+
23
+ context "with a when" do
24
+ Invariant { info << "I2" }
25
+
26
+ When(:when_info) { info.dup }
27
+
28
+ Then { info.should == ["I1", "I2"] }
29
+ Then { when_info.should == [] }
30
+ end
31
+ end
@@ -10,6 +10,7 @@ describe Stack do
10
10
  end
11
11
 
12
12
  Given(:stack) { stack_with(initial_contents) }
13
+ Invariant { stack.empty?.should == (stack.depth == 0) }
13
14
 
14
15
  context "when empty" do
15
16
  Given(:initial_contents) { [] }
@@ -3,7 +3,7 @@ require 'rspec/given/extensions'
3
3
  require 'rspec/given/have_failed'
4
4
 
5
5
  RSpec.configure do |c|
6
- c.alias_example_to :Then
7
- c.extend(RSpec::Given::Extensions)
6
+ c.extend(RSpec::Given::ClassExtensions)
7
+ c.include(RSpec::Given::InstanceExtensions)
8
8
  c.include(RSpec::Given::HaveFailed)
9
9
  end
@@ -2,13 +2,55 @@ require 'rspec/given/failure'
2
2
 
3
3
  module RSpec
4
4
  module Given
5
- module Extensions
5
+
6
+ # Provide run-time methods to support RSpec/Given infrastructure.
7
+ # All the methods in this module are considered private and
8
+ # implementation-specific.
9
+ module InstanceExtensions # :nodoc:
10
+
11
+ # Establish all the Given preconditions the current and
12
+ # surrounding describe/context blocks, starting with the
13
+ # outermost context.
14
+ def _rg_establish_givens # :nodoc:
15
+ return if defined?(@_rg_ran)
16
+ self.class.ancestors.reverse.each do |context|
17
+ context._rg_givens.each do |block|
18
+ instance_eval(&block)
19
+ end
20
+ end
21
+ @_rg_ran = true
22
+ end
23
+
24
+ # Check all the invariants in the current and surrounding
25
+ # describe/context blocks, starting with the outermost context.
26
+ def _rg_check_invariants # :nodoc:
27
+ self.class.ancestors.reverse.each do |context|
28
+ context._rg_invariants.each do |block|
29
+ instance_eval(&block)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ module ClassExtensions
36
+
37
+ # List of all givens directly in the current describe/context
38
+ # block.
39
+ def _rg_givens # :nodoc:
40
+ @_rg_givens ||= []
41
+ end
42
+
43
+ # List of all invariants directly in the current
44
+ # describe/context block.
45
+ def _rg_invariants # :nodoc:
46
+ @_rg_invariants ||= []
47
+ end
6
48
 
7
49
  # *DEPRECATED:*
8
50
  #
9
- # The Scenario command is deprecated. Future versions of
10
- # rspec/given will start displaying warnings when used.
11
- # Eventually the command will be removed.
51
+ # The Scenario command is deprecated. Using Scenario in a spec
52
+ # will result in a warning message. Eventually the command will
53
+ # be removed.
12
54
  #
13
55
  # Declare a scenario to contain Given/When/Then declarations. A
14
56
  # Scenario is essentially an RSpec context, with the additional
@@ -21,6 +63,9 @@ module RSpec
21
63
  # Scenario "a scenario description" do ... end
22
64
  #
23
65
  def Scenario(description, &block)
66
+ line = eval("__LINE__", block.binding)
67
+ file = eval("__FILE__", block.binding)
68
+ puts "WARNING: Scenario is deprecated, please use either describe or context (#{file}:#{line})"
24
69
  context(description, &block)
25
70
  end
26
71
 
@@ -38,7 +83,7 @@ module RSpec
38
83
  if args.first.is_a?(Symbol)
39
84
  let(args.first, &block)
40
85
  else
41
- before(&block)
86
+ _rg_givens << block
42
87
  end
43
88
  end
44
89
 
@@ -62,15 +107,38 @@ module RSpec
62
107
  if args.first.is_a?(Symbol)
63
108
  let!(args.first) do
64
109
  begin
110
+ _rg_establish_givens
65
111
  instance_eval(&block)
66
112
  rescue Exception => ex
67
113
  Failure.new(ex)
68
114
  end
69
115
  end
70
116
  else
71
- before(&block)
117
+ before do
118
+ _rg_establish_givens
119
+ instance_eval(&block)
120
+ end
72
121
  end
73
122
  end
123
+
124
+ # Provide an assertion about the specification.
125
+ #
126
+ # Then supplies an assertion that should be true after all the
127
+ # Given and When blocks have been run. All invariants in scope
128
+ # will be checked before the Then block is run.
129
+ def Then(&block)
130
+ specify do
131
+ _rg_establish_givens
132
+ _rg_check_invariants
133
+ instance_eval(&block)
134
+ end
135
+ end
136
+
137
+ # Establish an invariant that must be true for all Then blocks
138
+ # in the current (and nested) scopes.
139
+ def Invariant(&block)
140
+ _rg_invariants << block
141
+ end
74
142
  end
75
143
  end
76
144
  end
@@ -1,9 +1,11 @@
1
1
  module RSpec
2
2
  module Given
3
3
  VERSION_NUMBERS = [
4
- VERSION_MAJOR = 1,
5
- VERSION_MINOR = 6,
4
+ VERSION_MAJOR = 2,
5
+ VERSION_MINOR = 0,
6
6
  VERSION_BUILD = 0,
7
+ VERSION_BETA = 'beta',
8
+ VERSION_BETANUM = 1,
7
9
  ]
8
10
  VERSION = VERSION_NUMBERS.join(".")
9
11
  end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-given
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
5
- prerelease:
4
+ version: 2.0.0.beta.1
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Jim Weirich
@@ -13,7 +13,7 @@ date: 2012-08-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70231666072020 !ruby/object:Gem::Requirement
16
+ requirement: &70366429396080 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>'
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.2.8
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70231666072020
24
+ version_requirements: *70366429396080
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: bluecloth
27
- requirement: &70231666071580 !ruby/object:Gem::Requirement
27
+ requirement: &70366429395640 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70231666071580
35
+ version_requirements: *70366429395640
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rdoc
38
- requirement: &70231666070900 !ruby/object:Gem::Requirement
38
+ requirement: &70366429394960 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>'
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: 2.4.2
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70231666070900
46
+ version_requirements: *70366429394960
47
47
  description: ! 'Given is an RSpec extension that allows explicit definition of the
48
48
 
49
49
  pre and post-conditions for code under test.
@@ -56,7 +56,6 @@ extra_rdoc_files: []
56
56
  files:
57
57
  - MIT-LICENSE
58
58
  - Rakefile
59
- - README
60
59
  - README.md
61
60
  - lib/rspec-given.rb
62
61
  - lib/rspec/given/configure.rb
@@ -66,6 +65,8 @@ files:
66
65
  - lib/rspec/given/rspec1_given.rb
67
66
  - lib/rspec/given/version.rb
68
67
  - lib/rspec/given.rb
68
+ - examples/integration/given_spec.rb
69
+ - examples/integration/invariant_spec.rb
69
70
  - examples/spec_helper.rb
70
71
  - examples/stack/stack.rb
71
72
  - examples/stack/stack_spec.rb
@@ -91,9 +92,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
91
92
  required_rubygems_version: !ruby/object:Gem::Requirement
92
93
  none: false
93
94
  requirements:
94
- - - ! '>='
95
+ - - ! '>'
95
96
  - !ruby/object:Gem::Version
96
- version: '0'
97
+ version: 1.3.1
97
98
  requirements: []
98
99
  rubyforge_project: given
99
100
  rubygems_version: 1.8.15
data/README DELETED
@@ -1,242 +0,0 @@
1
- = rspec-given
2
-
3
- Covering rspec-given, version 1.6.0.beta.1.
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
- require 'rspec/given'
27
- require 'spec_helper'
28
- require 'stack'
29
-
30
- describe Stack do
31
- def stack_with(initial_contents)
32
- stack = Stack.new
33
- initial_contents.each do |item| stack.push(item) end
34
- stack
35
- end
36
-
37
- Given(:stack) { stack_with(initial_contents) }
38
-
39
- context "when empty" do
40
- Given(:initial_contents) { [] }
41
- Then { stack.depth.should == 0 }
42
-
43
- context "when pushing" do
44
- When { stack.push(:an_item) }
45
-
46
- Then { stack.depth.should == 1 }
47
- Then { stack.top.should == :an_item }
48
- end
49
-
50
- context "when popping" do
51
- When(:result) { stack.pop }
52
- Then { result.should have_failed(Stack::UnderflowError, /empty/) }
53
- end
54
- end
55
-
56
- context "with one item" do
57
- Given(:initial_contents) { [:an_item] }
58
-
59
- context "when popping" do
60
- When(:pop_result) { stack.pop }
61
-
62
- Then { pop_result.should == :an_item }
63
- Then { stack.should be_empty }
64
- end
65
- end
66
-
67
- context "with several items" do
68
- Given(:initial_contents) { [:second_item, :top_item] }
69
- Given!(:original_depth) { stack.depth }
70
-
71
- context "when pushing" do
72
- When { stack.push(:new_item) }
73
-
74
- Then { stack.top.should == :new_item }
75
- Then { stack.depth.should == original_depth + 1 }
76
- end
77
-
78
- context "when popping" do
79
- When(:pop_result) { stack.pop }
80
-
81
- Then { pop_result.should == :top_item }
82
- Then { stack.top.should == :second_item }
83
- Then { stack.depth.should == original_depth - 1 }
84
- end
85
- end
86
- end
87
-
88
- Let's talk about the individual statements used in the Given
89
- framework.
90
-
91
- === Given
92
-
93
- The _Given_ section specifies a starting point, a set of preconditions
94
- that must be true before the code under test is allowed to be run. In
95
- standard test frameworks the preconditions are established with a
96
- combination of setup methods (or :before actions in RSpec) and code in
97
- the test.
98
-
99
- In the example code above the preconditions are started with _Given_
100
- statements. A top level _Given_ (that applies to the entire describe
101
- block) says that one of the preconditions is that there is a stack
102
- with some initial contents.
103
-
104
- Note that initial contents are not specified in the top level describe
105
- block, but are given in each of the nested contexts. By pushing the
106
- definition of "initial_contents" into the nested contexts, we can vary
107
- them as needed for that particular context.
108
-
109
- A precondition in the form "Given(:var) {...}" creates an accessor
110
- method named "var". The accessor is lazily initialized by the code
111
- block. If you want a non-lazy given, use "Given!(:var) {...}".
112
-
113
- A precondition in the form "Given {...}" just executes the code block
114
- for side effects. Since there is no accessor, the code block is
115
- executed immediately (i.e. no lazy evaluation).
116
-
117
- The preconditions are run in order of definition. Nested contexts
118
- will inherit the preconditions from the enclosing context, with out
119
- preconditions running before inner preconditions.
120
-
121
- ==== Given examples:
122
-
123
- Given(:stack) { Stack.new }
124
-
125
- The given block is lazily run if 'stack' is ever referenced in the
126
- test and the value of the block is bound to 'stack'. The first
127
- reference to 'stack' in the specification will cause the code block to
128
- execute. Futher references to 'stack' will reuse the previously
129
- generated value.
130
-
131
- Given!(:original_size) { stack.size }
132
-
133
- The code block is run unconditionally once before each test and the
134
- value of the block is bound to 'original_size'. This form is useful
135
- when you want to record the value of something that might be affected
136
- by the When code.
137
-
138
- Given { stack.clear }
139
-
140
- The given block is run unconditionally once before each test. This
141
- form of given is used for code that is executed for side effects.
142
-
143
- === When
144
-
145
- The _When_ block specifies the code to be tested ... oops, excuse me
146
- ... specified. After the preconditions in the given section are met,
147
- the when code block is run.
148
-
149
- There should only be one _When_ block for a given context. However, a
150
- _When_ in an outer context shoud be treated as a _Given_ in an inner
151
- context. E.g.
152
-
153
- context "outer context" do
154
- When { code specified in the outer context }
155
- Then { assert something about the outer context }
156
-
157
- context "inner context" do
158
-
159
- # At this point, the _When_ of the outer context
160
- # should be treated as a _Given_ of the inner context
161
-
162
- When { code specified in the inner context }
163
- Then { assert something about the inner context }
164
- end
165
- end
166
-
167
- ==== When examples:
168
-
169
- When { stack.push(:item) }
170
-
171
- The code block is executed once per test. The effect of the _When{}_
172
- block is very similar to _Given{}_. However, When is used to identify
173
- the particular code that is being specified in the current context or
174
- describe block.
175
-
176
- When(:result) { stack.pop }
177
-
178
- The code block is executed once per test and the value of the code
179
- block is bound to 'result'. Use this form when the code under test
180
- returns a value that you wish to interrogate in the _Then_ code.
181
-
182
- If an exception occurs during the execution of the When block, the
183
- exception is caught and a failure object is bound to 'result'. The
184
- failure can be checked in a then block with the 'have_failed' matcher.
185
-
186
- The failure object will rethrow the captured exception if anything
187
- other than have_failed matcher is used on the failure object.
188
-
189
- For example, if the stack is empty when it is popped, then it is
190
- reasonable for pop to raise an UnderflowError. This is how you might
191
- specify that behavior:
192
-
193
- When(:result) { stack.pop }
194
- Then { result.should have_failed(UnderflowError, /empty/) }
195
-
196
- Note that the arguments to the 'have_failed' matcher are the same as
197
- those given to the standard RSpec matcher 'raise_error'.
198
-
199
- === Then
200
-
201
- The _Then_ sections are the postconditions of the specification. These
202
- then conditions must be true after the code under test (the _When_
203
- block) is run.
204
-
205
- The code in the _Then_ block should be a single _should_
206
- assertion. Code in _Then_ blocks should not have any side effects.
207
-
208
- ==== Then examples:
209
-
210
- Then { stack.should be_empty }
211
-
212
- After the related _When_ block is run, the stack should be empty. If
213
- it is not empty, the test will fail.
214
-
215
-
216
- = Future Directions
217
-
218
- I really like the way the Given framework is working out. I feel my
219
- tests are much more like specifications when I use it. However, I'm
220
- not entirely happy with it.
221
-
222
- First, I would like to introduce invariants. An _Invariant_ block
223
- would essentially be a post-conditions that should be true after
224
- _Then_ block in the same (or nested) context as the invariant.
225
-
226
- Second, I would like to remove the need for the ".should" in all the
227
- _Then_ blocks. In other words, instead of saying:
228
-
229
- Then { x.should == y }
230
-
231
- we could say:
232
-
233
- Then { x == y }
234
-
235
- I think the [wrong assertion library](http://rubygems.org/gems/wrong)
236
- has laid some groundwork in this area.
237
-
238
- = Links
239
-
240
- * Github: [https://github.com/jimweirich/rspec-given](https://github.com/jimweirich/rspec-given)
241
- * Clone URL: git://github.com/jimweirich/rspec-given.git
242
- * Bug/Issue Reporting: [https://github.com/jimweirich/rspec-given/issues](https://github.com/jimweirich/rspec-given/issues)