rbehave 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.txt ADDED
@@ -0,0 +1,2 @@
1
+ == Version 0.1.0
2
+ * First running version
data/History.txt ADDED
File without changes
data/Manifest.txt ADDED
@@ -0,0 +1,31 @@
1
+ lib/rbehave/reporter/plain_text_reporter.rb
2
+ lib/rbehave/exceptions.rb
3
+ lib/rbehave/documenter/plain_text_documenter.rb
4
+ lib/rbehave/world.rb
5
+ lib/rbehave/runner/story_runner.rb
6
+ lib/rbehave/runner/scenario_collector.rb
7
+ lib/rbehave/runner/scenario_runner.rb
8
+ lib/rbehave/story.rb
9
+ lib/rbehave/version.rb
10
+ lib/rbehave/scenario.rb
11
+ lib/rbehave.rb
12
+ behaviour/everything.rb
13
+ behaviour/examples/rbehave/reporter/plain_text_reporter_behaviour.rb
14
+ behaviour/examples/rbehave/world_behaviour.rb
15
+ behaviour/examples/rbehave/documenter/plain_text_documenter_behaviour.rb
16
+ behaviour/examples/rbehave/story_behaviour.rb
17
+ behaviour/examples/rbehave/runner/scenario_runner_behaviour.rb
18
+ behaviour/examples/rbehave/runner/story_runner_behaviour.rb
19
+ behaviour/examples/rbehave/runner/scenario_collector_behaviour.rb
20
+ behaviour/examples/rbehave/exception_behaviour.rb
21
+ behaviour/examples/rspec_adapter.rb
22
+ behaviour/examples/everything.rb
23
+ behaviour/examples/helper.rb
24
+
25
+ CHANGELOG.txt
26
+ History.txt
27
+ Manifest.txt
28
+ NOTES.txt
29
+ Rakefile
30
+ README.txt
31
+ setup.rb
data/NOTES.txt ADDED
@@ -0,0 +1,11 @@
1
+ StoryRunner
2
+ * should collect all the stories
3
+ * should count all the scenarios in the stories
4
+ * should execute the scenarios
5
+
6
+ ScenarioRunner
7
+ - should run scenarios in a World
8
+
9
+ Additions for rspec:
10
+ pending(msg)
11
+
data/README.txt ADDED
@@ -0,0 +1,4 @@
1
+ == RBehave
2
+
3
+ RBehave is a behaviour-driven development framework for Ruby.
4
+
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ require 'fileutils'
10
+ require 'hoe'
11
+ include FileUtils
12
+ require File.join(File.dirname(__FILE__), 'lib', 'rbehave', 'version')
13
+
14
+ AUTHOR = "dan" # can also be an array of Authors
15
+ EMAIL = "dan@rbehave.org"
16
+ DESCRIPTION = "RBehave"
17
+ GEM_NAME = "rbehave" # what ppl will type to install your gem
18
+ RUBYFORGE_PROJECT = "rbehave" # The unix name for your project
19
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
20
+
21
+
22
+ NAME = "rbehave"
23
+ REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
24
+ VERS = ENV['VERSION'] || (Rbehave::VERSION::STRING + (REV ? ".#{REV}" : ""))
25
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config']
26
+ RDOC_OPTS = ['--quiet', '--title', "rbehave documentation",
27
+ "--opname", "index.html",
28
+ "--line-numbers",
29
+ "--main", "README",
30
+ "--inline-source"]
31
+
32
+ class Hoe
33
+ def extra_deps
34
+ @extra_deps.reject { |x| Array(x).first == 'hoe' }
35
+ end
36
+ end
37
+
38
+ # Generate all the Rake tasks
39
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
40
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
41
+ p.author = AUTHOR
42
+ p.description = DESCRIPTION
43
+ p.email = EMAIL
44
+ p.summary = DESCRIPTION
45
+ p.url = HOMEPATH
46
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
47
+ p.test_globs = ["behaviour/everything.rb"]
48
+ p.clean_globs = CLEAN #An array of file patterns to delete on clean.
49
+
50
+ # == Optional
51
+ #p.changes - A description of the release's latest changes.
52
+ #p.extra_deps - An array of rubygem dependencies.
53
+ #p.spec_extras - A hash of extra values to set in the gemspec.
54
+ end
@@ -0,0 +1 @@
1
+ require 'behaviour/examples/everything'
@@ -0,0 +1,3 @@
1
+ Dir[File.join(File.dirname(__FILE__), 'rbehave/**/*_behaviour.rb')].each do |f|
2
+ require f
3
+ end
@@ -0,0 +1,2 @@
1
+ require 'behaviour/examples/rspec_adapter'
2
+ require 'lib/rbehave'
@@ -0,0 +1,58 @@
1
+ require 'behaviour/examples/helper'
2
+
3
+ module RBehave
4
+ module Documenter
5
+ describe PlainTextDocumenter do
6
+ setup do
7
+ @out = String.new
8
+ @documenter = PlainTextDocumenter.new(@out)
9
+ end
10
+
11
+ it 'should document a story title and narrative' do
12
+ # when
13
+ @documenter.story_started 'story', 'narrative'
14
+
15
+ # then
16
+ @out.should contain("Story: story\nnarrative\n")
17
+ end
18
+
19
+ it 'should document a scenario name' do
20
+ # when
21
+ @documenter.scenario_started 'story', 'scenario'
22
+
23
+ # then
24
+ @out.should contain("\nScenario: scenario\n")
25
+ end
26
+
27
+ it 'should document a step by sentence-casing its name' do
28
+ # when
29
+ @documenter.found_step :given, 'a context'
30
+ @documenter.found_step :when, 'an event'
31
+ @documenter.found_step :then, 'an outcome'
32
+
33
+ # then
34
+ @out.should contain(" Given a context\n When an event\n Then an outcome\n")
35
+ end
36
+
37
+ it 'should print some white space after each story' do
38
+ # when
39
+ @documenter.story_ended 'title', 'narrative'
40
+
41
+ # then
42
+ @out.should contain("\n\n")
43
+ end
44
+
45
+ it 'should ignore uninteresting calls' do
46
+ # when
47
+ @documenter.run_started(42)
48
+ @documenter.run_ended
49
+ @documenter.scenario_succeeded('story', 'scenario')
50
+ @documenter.scenario_failed('story', 'scenario', RuntimeError.new)
51
+ @documenter.scenario_pending('story', 'scenario', 'todo')
52
+
53
+ # then
54
+ @out.should be_empty
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,27 @@
1
+ require 'behaviour/examples/helper'
2
+
3
+ describe Exception do
4
+ it 'should filter boring elements from its backtrace' do
5
+ # given
6
+ err = Exception.new 'oops'
7
+ err.set_backtrace [
8
+ '/an/interesting/line:1',
9
+ '/a/boring/line',
10
+ '/an/interesting/line:2',
11
+ '/another/dull/line',
12
+ '/an/interesting/line:3',
13
+ ]
14
+ Exception.add_backtrace_filter(/boring/)
15
+ Exception.add_backtrace_filter(/dull/)
16
+
17
+ # when
18
+ backtrace = err.filtered_backtrace
19
+
20
+ # then
21
+ backtrace.should == [
22
+ '/an/interesting/line:1',
23
+ '/an/interesting/line:2',
24
+ '/an/interesting/line:3',
25
+ ]
26
+ end
27
+ end
@@ -0,0 +1,112 @@
1
+ require 'behaviour/examples/helper'
2
+
3
+ module RBehave
4
+ module Reporter
5
+ describe PlainTextReporter do
6
+ setup do
7
+ # given
8
+ @out = String.new
9
+ @reporter = PlainTextReporter.new(@out)
10
+ end
11
+
12
+ it 'should write a dot when a scenario succeeds' do
13
+ # when
14
+ @reporter.scenario_succeeded('story', 'scenario')
15
+
16
+ # then
17
+ @out.should == '.'
18
+ end
19
+
20
+ it 'should write a F when a scenario fails' do
21
+ # when
22
+ @reporter.scenario_failed('story', 'scenario', RuntimeError.new('oops'))
23
+
24
+ # then
25
+ @out.should == 'F'
26
+ end
27
+
28
+ it 'should write a P when a scenario is pending' do
29
+ # when
30
+ @reporter.scenario_pending('story', 'scenario', 'todo')
31
+
32
+ # then
33
+ @out.should == 'P'
34
+ end
35
+
36
+ it 'should summarize the number of scenarios when the run ends' do
37
+ # when
38
+ @reporter.run_started(3)
39
+ @reporter.scenario_succeeded('story', 'scenario1')
40
+ @reporter.scenario_succeeded('story', 'scenario2')
41
+ @reporter.scenario_succeeded('story', 'scenario3')
42
+ @reporter.run_ended
43
+
44
+ # then
45
+ @out.should contain('3 scenarios')
46
+ end
47
+
48
+ it 'should summarize the number of failed scenarios when the run ends' do
49
+ # when
50
+ @reporter.run_started(3)
51
+ @reporter.scenario_succeeded('story', 'scenario1')
52
+ @reporter.scenario_failed('story', 'scenario2', exception_from { raise RuntimeError, 'oops' })
53
+ @reporter.scenario_failed('story', 'scenario3', exception_from { raise RuntimeError, 'oops' })
54
+ @reporter.run_ended
55
+
56
+ # then
57
+ @out.should contain("3 scenarios: 1 succeeded, 2 failed")
58
+ end
59
+
60
+ it 'should produce details of each failed scenario when the run ends' do
61
+ # when
62
+ @reporter.run_started(3)
63
+ @reporter.scenario_succeeded('story', 'scenario1')
64
+ @reporter.scenario_failed('story', 'scenario2', exception_from { raise RuntimeError, 'oops2' })
65
+ @reporter.scenario_failed('story', 'scenario3', exception_from { raise RuntimeError, 'oops3' })
66
+ @reporter.run_ended
67
+
68
+ # then
69
+ @out.should contain("FAILURES:\n")
70
+ @out.should contain("1) story (scenario2) FAILED")
71
+ @out.should contain("RuntimeError: oops2")
72
+ @out.should contain("2) story (scenario3) FAILED")
73
+ @out.should contain("RuntimeError: oops3")
74
+ end
75
+
76
+ it 'should summarize the number of pending scenarios when the run ends' do
77
+ # when
78
+ @reporter.run_started(3)
79
+ @reporter.scenario_succeeded('story', 'scenario1')
80
+ @reporter.scenario_pending('story', 'scenario2', 'todo')
81
+ @reporter.scenario_pending('story', 'scenario3', 'todo')
82
+ @reporter.run_ended
83
+
84
+ # then
85
+ @out.should contain("3 scenarios: 1 succeeded, 0 failed, 2 pending")
86
+ end
87
+
88
+ it 'should produce details of each pending scenario when the run ends' do
89
+ # when
90
+ @reporter.run_started(3)
91
+ @reporter.scenario_succeeded('story', 'scenario1')
92
+ @reporter.scenario_pending('story', 'scenario2', 'todo2')
93
+ @reporter.scenario_pending('story', 'scenario3', 'todo3')
94
+ @reporter.run_ended
95
+
96
+ # then
97
+ @out.should contain("Pending:\n")
98
+ @out.should contain("1) story (scenario2): todo2")
99
+ @out.should contain("2) story (scenario3): todo3")
100
+ end
101
+
102
+ it 'should ignore uninteresting callbacks' do
103
+ # when
104
+ @reporter.story_started 'story', 'narrative'
105
+ @reporter.scenario_started 'story', 'scenario'
106
+
107
+ # then
108
+ @out.should be_empty
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,25 @@
1
+ require 'behaviour/examples/helper'
2
+
3
+ module RBehave
4
+ module Runner
5
+ describe ScenarioCollector do
6
+ it 'should construct scenarios with the supplied story' do
7
+ # given
8
+ story = stub_everything('story')
9
+ scenario_collector = ScenarioCollector.new(story)
10
+
11
+ # when
12
+ scenario_collector.Scenario 'scenario1' do end
13
+ scenario_collector.Scenario 'scenario2' do end
14
+ scenarios = scenario_collector.scenarios
15
+
16
+ # then
17
+ ensure_that scenarios.size, is(2)
18
+ ensure_that scenarios[0].name, is('scenario1')
19
+ ensure_that scenarios[0].story, is(story)
20
+ ensure_that scenarios[1].name, is('scenario2')
21
+ ensure_that scenarios[1].story, is(story)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,143 @@
1
+ require 'behaviour/examples/helper'
2
+
3
+ module RBehave
4
+ module Runner
5
+ describe ScenarioRunner do
6
+ it 'should run a scenario in its story' do
7
+ # given
8
+ world = stub_everything
9
+ scenario_runner = ScenarioRunner.new
10
+ $answer = nil
11
+ story = Story.new 'story', 'narrative' do
12
+ @answer = 42 # this should be available to the scenario
13
+ end
14
+ scenario = Scenario.new story, 'scenario' do
15
+ $answer = @answer
16
+ end
17
+
18
+ # when
19
+ scenario_runner.run(scenario, world)
20
+
21
+ # then
22
+ ensure_that $answer, is(42)
23
+ end
24
+
25
+ it 'should allow scenarios to share methods' do
26
+ # given
27
+ world = stub_everything
28
+ $shared_invoked = 0
29
+ story = Story.new 'story', 'narrative' do
30
+ def shared
31
+ $shared_invoked += 1
32
+ end
33
+ end
34
+ scenario1 = Scenario.new story, 'scenario1' do
35
+ shared()
36
+ end
37
+ scenario2 = Scenario.new story, 'scenario2' do
38
+ shared()
39
+ end
40
+ scenario_runner = ScenarioRunner.new
41
+
42
+ # when
43
+ scenario_runner.run(scenario1, world)
44
+ scenario_runner.run(scenario2, world)
45
+
46
+ # then
47
+ $shared_invoked.should == 2
48
+ end
49
+
50
+ it 'should notify listeners when a scenario starts' do
51
+ # given
52
+ world = stub_everything
53
+ story = Story.new 'story', 'narrative' do end
54
+ scenario = Scenario.new story, 'scenario1' do
55
+ # succeeds
56
+ end
57
+ scenario_runner = ScenarioRunner.new
58
+ mock_listener1 = stub_everything('listener1')
59
+ mock_listener2 = stub_everything('listener2')
60
+ scenario_runner.add_listener(mock_listener1)
61
+ scenario_runner.add_listener(mock_listener2)
62
+
63
+ # expect
64
+ mock_listener1.expects(:scenario_started).with('story', 'scenario1')
65
+ mock_listener2.expects(:scenario_started).with('story', 'scenario1')
66
+
67
+ # when
68
+ scenario_runner.run(scenario, world)
69
+
70
+ # then
71
+ verify_mocks
72
+ end
73
+
74
+ it 'should notify listeners when a scenario succeeds' do
75
+ # given
76
+ world = stub_everything
77
+ story = Story.new 'story', 'narrative' do end
78
+ scenario = Scenario.new story, 'scenario1' do
79
+ # succeeds
80
+ end
81
+ scenario_runner = ScenarioRunner.new
82
+ mock_listener1 = stub_everything('listener1')
83
+ mock_listener2 = stub_everything('listener2')
84
+ scenario_runner.add_listener(mock_listener1)
85
+ scenario_runner.add_listener(mock_listener2)
86
+
87
+ # expect
88
+ mock_listener1.expects(:scenario_succeeded).with('story', 'scenario1')
89
+ mock_listener2.expects(:scenario_succeeded).with('story', 'scenario1')
90
+
91
+ # when
92
+ scenario_runner.run(scenario, world)
93
+
94
+ # then
95
+ verify_mocks
96
+ end
97
+
98
+ it 'should notify listeners when a scenario raises an error' do
99
+ # given
100
+ error = RuntimeError.new('oops')
101
+ story = Story.new 'title', 'narrative' do end
102
+ scenario = Scenario.new story, 'scenario1' do
103
+ raise error
104
+ end
105
+ scenario_runner = ScenarioRunner.new
106
+ mock_listener = stub_everything('listener')
107
+ scenario_runner.add_listener(mock_listener)
108
+ world = stub_everything
109
+
110
+ # expect
111
+ mock_listener.expects(:scenario_failed).with('title', 'scenario1', error)
112
+
113
+ # when
114
+ scenario_runner.run scenario, world
115
+
116
+ # then
117
+ verify_mocks
118
+ end
119
+
120
+
121
+ it 'should notify listeners when a scenario raises an error' do
122
+ # given
123
+ story = Story.new 'title', 'narrative' do end
124
+ scenario = Scenario.new story, 'scenario1' do
125
+ pending 'todo'
126
+ end
127
+ scenario_runner = ScenarioRunner.new
128
+ mock_listener = stub_everything('listener')
129
+ scenario_runner.add_listener(mock_listener)
130
+ world = World.create
131
+
132
+ # expect
133
+ mock_listener.expects(:scenario_pending).with('title', 'scenario1', 'todo')
134
+
135
+ # when
136
+ scenario_runner.run scenario, world
137
+
138
+ # then
139
+ verify_mocks
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,169 @@
1
+ require 'behaviour/examples/helper'
2
+
3
+ module RBehave
4
+ module Runner
5
+ describe StoryRunner do
6
+ it 'should collect all the stories' do
7
+ # given
8
+ story_runner = StoryRunner.new(stub)
9
+
10
+ # when
11
+ story_runner.Story 'title1', 'narrative1' do end
12
+ story_runner.Story 'title2', 'narrative2' do end
13
+ stories = story_runner.stories
14
+
15
+ # then
16
+ ensure_that stories.size, is(2)
17
+ ensure_that stories[0].title, is('title1')
18
+ ensure_that stories[0].narrative, is('narrative1')
19
+ ensure_that stories[1].title, is('title2')
20
+ ensure_that stories[1].narrative, is('narrative2')
21
+ end
22
+
23
+ it 'should gather all the scenarios in the stories' do
24
+ # given
25
+ story_runner = StoryRunner.new(stub)
26
+
27
+ # when
28
+ story_runner.Story "story1", "narrative1" do
29
+ Scenario "scenario1" do end
30
+ Scenario "scenario2" do end
31
+ end
32
+ story_runner.Story "story2", "narrative2" do
33
+ Scenario "scenario3" do end
34
+ end
35
+ scenarios = story_runner.scenarios
36
+
37
+ # then
38
+ ensure_that scenarios.size, is(3)
39
+ ensure_that scenarios[0].name, is('scenario1')
40
+ ensure_that scenarios[1].name, is('scenario2')
41
+ ensure_that scenarios[2].name, is('scenario3')
42
+ end
43
+
44
+ # captures worlds passed into a ScenarioRunner
45
+ class ScenarioRunnerThatStoresWorlds
46
+ attr_accessor :worlds
47
+ def run(scenario, world)
48
+ (@worlds ||= []) << world
49
+ end
50
+ end
51
+
52
+ it 'should run each scenario in a separate object' do
53
+ # given
54
+ scenario_world_catcher = ScenarioRunnerThatStoresWorlds.new
55
+ story_runner = StoryRunner.new(scenario_world_catcher)
56
+ story_runner.Story 'story', 'narrative' do
57
+ Scenario 'scenario1' do end
58
+ Scenario 'scenario2' do end
59
+ end
60
+
61
+ # when
62
+ story_runner.run_stories
63
+
64
+ # then
65
+ worlds = scenario_world_catcher.worlds
66
+ ensure_that worlds.size, is(2)
67
+ worlds[0].should_not == worlds[1]
68
+ end
69
+
70
+ it 'should use the provided world creator to create worlds' do
71
+ # given
72
+ stub_scenario_runner = stub_everything
73
+ mock_world_creator = mock('world creator')
74
+ story_runner = StoryRunner.new(stub_scenario_runner, mock_world_creator)
75
+ story_runner.Story 'story', 'narrative' do
76
+ Scenario 'scenario1' do end
77
+ Scenario 'scenario2' do end
78
+ end
79
+
80
+ # expect
81
+ mock_world_creator.expects(:create).times(2)
82
+
83
+ # when
84
+ story_runner.run_stories
85
+
86
+ # then
87
+ verify_mocks
88
+ end
89
+
90
+ it 'should notify listeners of the scenario count when the run starts' do
91
+ # given
92
+ story_runner = StoryRunner.new(stub_everything)
93
+ mock_listener1 = stub_everything('listener1')
94
+ mock_listener2 = stub_everything('listener2')
95
+ story_runner.add_listener(mock_listener1)
96
+ story_runner.add_listener(mock_listener2)
97
+
98
+ story_runner.Story 'story1', 'narrative1' do
99
+ Scenario 'scenario1' do end
100
+ end
101
+ story_runner.Story 'story2', 'narrative2' do
102
+ Scenario 'scenario2' do end
103
+ Scenario 'scenario3' do end
104
+ end
105
+
106
+ # expect
107
+ mock_listener1.expects(:run_started).with(3)
108
+ mock_listener2.expects(:run_started).with(3)
109
+
110
+ # when
111
+ story_runner.run_stories
112
+
113
+ # then
114
+ verify_mocks
115
+ end
116
+
117
+ it 'should notify listeners when a story starts' do
118
+ # given
119
+ story_runner = StoryRunner.new(stub_everything)
120
+ mock_listener1 = stub_everything('listener1')
121
+ mock_listener2 = stub_everything('listener2')
122
+ story_runner.add_listener(mock_listener1)
123
+ story_runner.add_listener(mock_listener2)
124
+
125
+ story_runner.Story 'story1', 'narrative1' do
126
+ Scenario 'scenario1' do end
127
+ end
128
+ story_runner.Story 'story2', 'narrative2' do
129
+ Scenario 'scenario2' do end
130
+ Scenario 'scenario3' do end
131
+ end
132
+
133
+ # expect
134
+ mock_listener1.expects(:story_started).with('story1', 'narrative1')
135
+ mock_listener1.expects(:story_ended).with('story1', 'narrative1')
136
+ mock_listener2.expects(:story_started).with('story2', 'narrative2')
137
+ mock_listener2.expects(:story_ended).with('story2', 'narrative2')
138
+
139
+ # when
140
+ story_runner.run_stories
141
+
142
+ # then
143
+ verify_mocks
144
+ end
145
+
146
+ it 'should notify listeners when the run ends' do
147
+ # given
148
+ story_runner = StoryRunner.new(stub_everything)
149
+ mock_listener1 = stub_everything('listener1')
150
+ mock_listener2 = stub_everything('listener2')
151
+ story_runner.add_listener mock_listener1
152
+ story_runner.add_listener mock_listener2
153
+ story_runner.Story 'story1', 'narrative1' do
154
+ Scenario 'scenario1' do end
155
+ end
156
+
157
+ # expect
158
+ mock_listener1.expects(:run_ended)
159
+ mock_listener2.expects(:run_ended)
160
+
161
+ # when
162
+ story_runner.run_stories
163
+
164
+ # then
165
+ verify_mocks
166
+ end
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,20 @@
1
+ require 'behaviour/examples/helper'
2
+
3
+ module RBehave
4
+ describe Story do
5
+ it 'should run itself in a given object' do
6
+ # given
7
+ $instance = nil
8
+ story = Story.new 'title', 'narrative' do
9
+ $instance = self
10
+ end
11
+ object = Object.new
12
+
13
+ # when
14
+ story.run_in(object)
15
+
16
+ # then
17
+ $instance.should be(object)
18
+ end
19
+ end
20
+ end