rspec-given 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md ADDED
@@ -0,0 +1,167 @@
1
+ # rspec-given
2
+
3
+ rspec-given is an RSpec 2 extension to allow Given/When/Then notation
4
+ in RSpec specifications. It is a natural extension of the
5
+ experimental work done on the Given framework. It turns out that 90%
6
+ of the Given framework can be trivially implemented on top of RSpec.
7
+
8
+ # Why Given/When/Then
9
+
10
+ RSpec has done a great job of making specifications more readable for
11
+ humans. However, I really like the given / when / then nature of
12
+ Cucumber stories and would like to follow the same structure in my
13
+ unit tests. rspec-given allows a simple given/when/then structure
14
+ RSpec specifications.
15
+
16
+ ## Status
17
+
18
+ rspec-given is quite usable at the moment, although is is lacking
19
+ several features.
20
+
21
+ * Invariants are not supported yet.
22
+ * Then assertions without _should_ are not supported yet.
23
+
24
+ ## Example Zero
25
+
26
+ Here's the spec that I've been playing with. Its gone through
27
+ mulitple revisions and several prototype implementations. And this is
28
+ probably not the final form.
29
+
30
+ With all that in mind, here's a specification in my imaginary
31
+ framework:
32
+
33
+ <pre>
34
+ require 'spec_helper'
35
+ require 'stack'
36
+
37
+ describe Stack do
38
+ # NOTE: Invariants are not yet supported in rspec-given
39
+ # Invariant { stack.depth >= 0 }
40
+ # Invariant { stack.empty? == (stack.depth == 0) }
41
+
42
+ Given(:an_empty_stack) { Stack.new }
43
+
44
+ Given(:a_stack_with_one_item) do
45
+ Stack.new.tap do |s|
46
+ s.push(:an_item)
47
+ end
48
+ end
49
+
50
+ Given(:a_stack_with_several_items) do
51
+ Stack.new.tap do |s|
52
+ s.push(:second_item)
53
+ s.push(:top_item)
54
+ end
55
+ end
56
+
57
+ context "an empty stack" do
58
+ Given(:stack) { an_empty_stack }
59
+
60
+ Then { stack.depth.should == 0 }
61
+
62
+ context "Pushing onto an empty stack" do
63
+ When { stack.push(:an_item) }
64
+
65
+ Then { stack.depth.should == 1 }
66
+ Then { stack.top.should == :an_item }
67
+ end
68
+ end
69
+
70
+ context "a stack with one item do" do
71
+ Given(:stack) { a_stack_with_one_item }
72
+
73
+ context "popping an item empties the stack" do
74
+ When(:pop_result) { stack.pop }
75
+
76
+ Then { pop_result.should == :an_item }
77
+ Then { stack.should be_empty }
78
+ end
79
+ end
80
+
81
+ context "a stack with several items" do
82
+ Given(:stack) { a_stack_with_several_items }
83
+ Given!(:original_depth) { stack.depth }
84
+
85
+ context "pushing a new item adds a new top" do
86
+ When { stack.push(:new_item) }
87
+
88
+ Then { stack.top.should == :new_item }
89
+ Then { stack.depth.should == original_depth + 1 }
90
+ end
91
+
92
+ context "popping an item removes the top item" do
93
+ When(:pop_result) { stack.pop }
94
+
95
+ Then { pop_result.should == :top_item }
96
+ Then { stack.top.should == :second_item }
97
+ Then { stack.depth.should == original_depth - 1 }
98
+ end
99
+ end
100
+ end
101
+ </pre>
102
+
103
+ Let's talk about the individual sections.
104
+
105
+ ### Given
106
+
107
+ The _Given_ section specifies a starting point, a set of preconditions
108
+ that must be true before the code under test is allowed to be run. In
109
+ standard test frameworks the preconditions are established with a
110
+ combination of setup methods (or :before actions in RSpec) and code in
111
+ the test.
112
+
113
+ In the example code above, we see three starting points of interest.
114
+ One is an empty, just freshly created stack. The next is a stack with
115
+ exactly one item. The final starting point is a stack with several
116
+ items.
117
+
118
+ A precondition in the form "Given(:var) {...}" creates an accessor
119
+ method named "var". The accessor is lazily initialized by the code
120
+ block. If you want a non-lazy given, use "Given!(:var) {...}".
121
+
122
+ A precondition in the form "Given {...}" just executes the code block
123
+ for side effects. Since there is no accessor, the code block is
124
+ executed immediately (i.e. no lazy evaluation).
125
+
126
+ The preconditions are run in order of definition. Nested contexts
127
+ will inherit the preconditions from the enclosing context, with out
128
+ preconditions running before inner preconditions.
129
+
130
+ ### When
131
+
132
+ The _When_ block specifies the code to be tested ... oops, excuse me
133
+ ... specified. After the preconditions in the given section are met,
134
+ the when code block is run.
135
+
136
+ There should only be one _When_ block for a given context.
137
+
138
+ ### Then
139
+
140
+ The _Then_ sections are the postconditions of the specification. These
141
+ then conditions must be true after the code under test (the _When_
142
+ block) is run.
143
+
144
+ The code in the _Then_ block should be a single boolean condition that
145
+ devaluates to true if the code in the _When_ block is correct. If the
146
+ _Then_ block evaluates to false, then that is recorded as a failure.
147
+
148
+ ### Invariant
149
+
150
+ The _Invariant_ block is a new idea that doesn't have an analog in
151
+ RSpec or Test::Unit. The invariant allows you specify things that
152
+ must always be true. In the stack example, <tt>empty?</tt> is defined
153
+ in term of <tt>size</tt>. Whenever <tt>size</tt> is 0,
154
+ <tt>empty?</tt> should be true. Whenever <tt>size</tt> is non-zero,
155
+ <tt>empty?</tt> should be false.
156
+
157
+ You can conceptually think of an _Invariant_ block as a _Then_ block
158
+ that automatically gets added to every _When_ within its scope.
159
+
160
+ Invariants nested within a context only apply to the _When_ blocks in
161
+ that context.
162
+
163
+ Invariants that reference a _Given_ precondition accessor must only be
164
+ used in contexts that define that accessor.
165
+
166
+ NOTE: Invariants are not yet implemented in the current version of
167
+ rspec-given.
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/ruby -wKU
2
+
3
+ require 'rake/clean'
4
+
5
+ CLOBBER.include("*.gemspec", "html")
6
+
7
+
8
+ # README Formatting --------------------------------------------------
9
+
10
+ require 'bluecloth'
11
+
12
+
13
+ task :default => :examples
14
+
15
+ # Running examples ---------------------------------------------------
16
+
17
+ desc "Run the examples"
18
+ task :examples do
19
+ sh "rspec examples"
20
+ end
21
+
22
+ # Formatting the README ----------------------------------------------
23
+
24
+ directory 'html'
25
+
26
+ desc "Display the README file"
27
+ task :readme => "html/README.html" do
28
+ sh "open html/README.html"
29
+ end
30
+
31
+ desc "format the README file"
32
+ task "html/README.html" => ['html', 'README.md'] do
33
+ open("README.md") do |source|
34
+ open('html/README.html', 'w') do |out|
35
+ out.write(BlueCloth.new(source.read).to_html)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,2 @@
1
+ require 'rspec/given'
2
+ $LOAD_PATH << './examples/stack'
@@ -0,0 +1,25 @@
1
+ class Stack
2
+ def initialize
3
+ @items = []
4
+ end
5
+
6
+ def depth
7
+ @items.size
8
+ end
9
+
10
+ def empty?
11
+ @items.empty?
12
+ end
13
+
14
+ def top
15
+ @items.last
16
+ end
17
+
18
+ def push(item)
19
+ @items << item
20
+ end
21
+
22
+ def pop
23
+ @items.pop
24
+ end
25
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+ require 'stack'
3
+
4
+ describe Stack do
5
+ # NOTE: Invariants are not yet supported in rspec-given
6
+ # Invariant { stack.depth >= 0 }
7
+ # Invariant { stack.empty? == (stack.depth == 0) }
8
+
9
+ Given(:an_empty_stack) { Stack.new }
10
+
11
+ Given(:a_stack_with_one_item) do
12
+ Stack.new.tap do |s|
13
+ s.push(:an_item)
14
+ end
15
+ end
16
+
17
+ Given(:a_stack_with_several_items) do
18
+ Stack.new.tap do |s|
19
+ s.push(:second_item)
20
+ s.push(:top_item)
21
+ end
22
+ end
23
+
24
+ context "an empty stack" do
25
+ Given(:stack) { an_empty_stack }
26
+
27
+ Then { stack.depth.should == 0 }
28
+
29
+ context "Pushing onto an empty stack" do
30
+ When { stack.push(:an_item) }
31
+
32
+ Then { stack.depth.should == 1 }
33
+ Then { stack.top.should == :an_item }
34
+ end
35
+ end
36
+
37
+ context "a stack with one item do" do
38
+ Given(:stack) { a_stack_with_one_item }
39
+
40
+ context "popping an item empties the stack" do
41
+ When(:pop_result) { stack.pop }
42
+
43
+ Then { pop_result.should == :an_item }
44
+ Then { stack.should be_empty }
45
+ end
46
+ end
47
+
48
+ context "a stack with several items" do
49
+ Given(:stack) { a_stack_with_several_items }
50
+ Given!(:original_depth) { stack.depth }
51
+
52
+ context "pushing a new item adds a new top" do
53
+ When { stack.push(:new_item) }
54
+
55
+ Then { stack.top.should == :new_item }
56
+ Then { stack.depth.should == original_depth + 1 }
57
+ end
58
+
59
+ context "popping an item removes the top item" do
60
+ When(:pop_result) { stack.pop }
61
+
62
+ Then { pop_result.should == :top_item }
63
+ Then { stack.top.should == :second_item }
64
+ Then { stack.depth.should == original_depth - 1 }
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,3 @@
1
+ require 'rspec/given/version'
2
+ require 'rspec/given/extensions'
3
+
@@ -0,0 +1,38 @@
1
+ require 'rspec/core/let'
2
+
3
+ module RSpec
4
+ module Core
5
+ class ExampleGroup
6
+ alias_example_to :Then
7
+ end
8
+ end
9
+ end
10
+
11
+ module RSpec
12
+ module Core
13
+ module Let
14
+ module ClassMethods
15
+
16
+ def Given(*args,&block)
17
+ if args.first.is_a?(Symbol)
18
+ let(args.first, &block)
19
+ else
20
+ before(&block)
21
+ end
22
+ end
23
+
24
+ def Given!(var, &block)
25
+ let!(var, &block)
26
+ end
27
+
28
+ def When(*args, &block)
29
+ if args.first.is_a?(Symbol)
30
+ let!(args.first, &block)
31
+ else
32
+ before(&block)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,9 @@
1
+ module RSpec
2
+ module Given
3
+ VERSION_MAJOR = 1
4
+ VERSION_MINOR = 0
5
+ VERSION_BUILD = 0
6
+ VERSION_NUMBERS = [VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD]
7
+ VERSION = VERSION_NUMBERS.join(".")
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec-given
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
10
+ platform: ruby
11
+ authors:
12
+ - Jim Weirich
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-11-27 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: |
22
+ Given is an RSpec extension that allows explicit definition of the
23
+ pre and post-conditions for code under test.
24
+
25
+ email: jim.weirich@gmail.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files: []
31
+
32
+ files:
33
+ - Rakefile
34
+ - README.md
35
+ - lib/rspec/given/extensions.rb
36
+ - lib/rspec/given/version.rb
37
+ - lib/rspec/given.rb
38
+ - examples/spec_helper.rb
39
+ - examples/stack/stack.rb
40
+ - examples/stack/stack_spec.rb
41
+ has_rdoc: true
42
+ homepage: http://github.com/jimweirich/rspec-given
43
+ licenses: []
44
+
45
+ post_install_message:
46
+ rdoc_options:
47
+ - --line-numbers
48
+ - --inline-source
49
+ - --main
50
+ - README.md
51
+ - --title
52
+ - RSpec Given Extensions
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ requirements: []
70
+
71
+ rubyforge_project: given
72
+ rubygems_version: 1.3.6
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: Given/When/Then Specification Extensions for RSpec.
76
+ test_files: []
77
+