rbehave 0.1.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/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