dchelimsky-rspec-stories 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.
Files changed (79) hide show
  1. data/History.txt +5 -0
  2. data/License.txt +22 -0
  3. data/Manifest.txt +78 -0
  4. data/README.txt +23 -0
  5. data/Rakefile +87 -0
  6. data/init.rb +4 -0
  7. data/lib/spec/runner/formatter/story/html_formatter.rb +174 -0
  8. data/lib/spec/runner/formatter/story/plain_text_formatter.rb +194 -0
  9. data/lib/spec/runner/formatter/story/progress_bar_formatter.rb +42 -0
  10. data/lib/spec/runner/options_extensions.rb +25 -0
  11. data/lib/spec/stories.rb +11 -0
  12. data/lib/spec/story/extensions.rb +3 -0
  13. data/lib/spec/story/extensions/main.rb +86 -0
  14. data/lib/spec/story/extensions/regexp.rb +9 -0
  15. data/lib/spec/story/extensions/string.rb +9 -0
  16. data/lib/spec/story/given_scenario.rb +14 -0
  17. data/lib/spec/story/runner.rb +57 -0
  18. data/lib/spec/story/runner/plain_text_story_runner.rb +48 -0
  19. data/lib/spec/story/runner/scenario_collector.rb +18 -0
  20. data/lib/spec/story/runner/scenario_runner.rb +54 -0
  21. data/lib/spec/story/runner/story_mediator.rb +137 -0
  22. data/lib/spec/story/runner/story_parser.rb +247 -0
  23. data/lib/spec/story/runner/story_runner.rb +74 -0
  24. data/lib/spec/story/scenario.rb +14 -0
  25. data/lib/spec/story/step.rb +70 -0
  26. data/lib/spec/story/step_group.rb +89 -0
  27. data/lib/spec/story/step_mother.rb +38 -0
  28. data/lib/spec/story/story.rb +39 -0
  29. data/lib/spec/story/version.rb +15 -0
  30. data/lib/spec/story/world.rb +124 -0
  31. data/resources/rake/verify_rcov.rake +7 -0
  32. data/rspec-stories.gemspec +35 -0
  33. data/spec/spec.opts +6 -0
  34. data/spec/spec/runner/formatter/story/html_formatter_spec.rb +135 -0
  35. data/spec/spec/runner/formatter/story/plain_text_formatter_spec.rb +600 -0
  36. data/spec/spec/runner/formatter/story/progress_bar_formatter_spec.rb +82 -0
  37. data/spec/spec/runner/most_recent_spec.rb +0 -0
  38. data/spec/spec/runner/options_extensions_spec.rb +31 -0
  39. data/spec/spec/runner/resources/a_bar.rb +0 -0
  40. data/spec/spec/runner/resources/a_foo.rb +0 -0
  41. data/spec/spec/runner/resources/a_spec.rb +1 -0
  42. data/spec/spec/runner/resources/custom_example_group_runner.rb +14 -0
  43. data/spec/spec/runner/resources/utf8_encoded.rb +7 -0
  44. data/spec/spec/runner_spec.rb +11 -0
  45. data/spec/spec/spec_classes.rb +133 -0
  46. data/spec/spec/story/builders.rb +46 -0
  47. data/spec/spec/story/extensions/main_spec.rb +161 -0
  48. data/spec/spec/story/extensions_spec.rb +14 -0
  49. data/spec/spec/story/given_scenario_spec.rb +27 -0
  50. data/spec/spec/story/runner/plain_text_story_runner_spec.rb +90 -0
  51. data/spec/spec/story/runner/scenario_collector_spec.rb +27 -0
  52. data/spec/spec/story/runner/scenario_runner_spec.rb +214 -0
  53. data/spec/spec/story/runner/story_mediator_spec.rb +143 -0
  54. data/spec/spec/story/runner/story_parser_spec.rb +401 -0
  55. data/spec/spec/story/runner/story_runner_spec.rb +294 -0
  56. data/spec/spec/story/runner_spec.rb +93 -0
  57. data/spec/spec/story/scenario_spec.rb +18 -0
  58. data/spec/spec/story/step_group_spec.rb +157 -0
  59. data/spec/spec/story/step_mother_spec.rb +84 -0
  60. data/spec/spec/story/step_spec.rb +272 -0
  61. data/spec/spec/story/story_helper.rb +2 -0
  62. data/spec/spec/story/story_spec.rb +84 -0
  63. data/spec/spec/story/world_spec.rb +423 -0
  64. data/spec/spec_helper.rb +84 -0
  65. data/story_server/prototype/javascripts/builder.js +136 -0
  66. data/story_server/prototype/javascripts/controls.js +972 -0
  67. data/story_server/prototype/javascripts/dragdrop.js +976 -0
  68. data/story_server/prototype/javascripts/effects.js +1117 -0
  69. data/story_server/prototype/javascripts/prototype.js +4140 -0
  70. data/story_server/prototype/javascripts/rspec.js +149 -0
  71. data/story_server/prototype/javascripts/scriptaculous.js +58 -0
  72. data/story_server/prototype/javascripts/slider.js +276 -0
  73. data/story_server/prototype/javascripts/sound.js +55 -0
  74. data/story_server/prototype/javascripts/unittest.js +568 -0
  75. data/story_server/prototype/lib/server.rb +24 -0
  76. data/story_server/prototype/stories.html +176 -0
  77. data/story_server/prototype/stylesheets/rspec.css +136 -0
  78. data/story_server/prototype/stylesheets/test.css +90 -0
  79. metadata +154 -0
@@ -0,0 +1,14 @@
1
+ require File.dirname(__FILE__) + '/story_helper'
2
+
3
+ require 'spec/story'
4
+
5
+ describe Kernel, "#Story" do
6
+ before(:each) do
7
+ Kernel.stub!(:at_exit)
8
+ end
9
+
10
+ it "should delegate to ::Spec::Story::Runner.story_runner" do
11
+ ::Spec::Story::Runner.story_runner.should_receive(:Story)
12
+ story = Story("title","narrative"){}
13
+ end
14
+ end
@@ -0,0 +1,27 @@
1
+ require File.dirname(__FILE__) + '/story_helper'
2
+
3
+ module Spec
4
+ module Story
5
+ describe GivenScenario do
6
+ it 'should execute a scenario from the current story in its world' do
7
+ # given
8
+ class MyWorld
9
+ attr :scenario_ran
10
+ end
11
+ instance = World.create(MyWorld)
12
+ scenario = ScenarioBuilder.new.to_scenario do
13
+ @scenario_ran = true
14
+ end
15
+ Runner::StoryRunner.should_receive(:scenario_from_current_story).with('scenario name').and_return(scenario)
16
+
17
+ step = GivenScenario.new 'scenario name'
18
+
19
+ # when
20
+ step.perform(instance, nil)
21
+
22
+ # then
23
+ instance.scenario_ran.should be_true
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,90 @@
1
+ require File.dirname(__FILE__) + '/../story_helper'
2
+
3
+ module Spec
4
+ module Story
5
+ module Runner
6
+ describe PlainTextStoryRunner do
7
+ before(:each) do
8
+ StoryParser.stub!(:new).and_return(@parser = mock("parser"))
9
+ @parser.stub!(:parse).and_return([])
10
+ File.stub!(:read).with("path").and_return("this\nand that")
11
+ end
12
+
13
+ it "should provide access to steps" do
14
+ runner = PlainTextStoryRunner.new("path")
15
+
16
+ runner.steps do |add|
17
+ add.given("baz") {}
18
+ end
19
+
20
+ runner.steps.find(:given, "baz").should_not be_nil
21
+ end
22
+
23
+ it "should parse a story file" do
24
+ runner = PlainTextStoryRunner.new("path")
25
+ @parser.should_receive(:parse).with(["this", "and that"])
26
+ runner.run(mock('runner'))
27
+ end
28
+
29
+ it "should build up a mediator with its own steps and the singleton story_runner" do
30
+ @story_runner = mock('story runner', :null_object => true)
31
+
32
+ runner = PlainTextStoryRunner.new("path")
33
+
34
+ Spec::Story::Runner::StoryMediator.should_receive(:new).with(
35
+ runner.steps, @story_runner, {}
36
+ ).and_return(mediator = stub("mediator", :run_stories => nil))
37
+ runner.run(@story_runner)
38
+ end
39
+
40
+ it "should build up a parser with the mediator" do
41
+ runner = PlainTextStoryRunner.new("path")
42
+ Spec::Story::Runner::StoryMediator.should_receive(:new).and_return(mediator = stub("mediator", :run_stories => nil))
43
+ Spec::Story::Runner::StoryParser.should_receive(:new).with(mediator).and_return(@parser)
44
+ runner.run(stub("story_runner"))
45
+ end
46
+
47
+ it "should tell the mediator to run the stories" do
48
+ runner = PlainTextStoryRunner.new("path")
49
+ mediator = mock("mediator")
50
+ Spec::Story::Runner::StoryMediator.should_receive(:new).and_return(mediator)
51
+ mediator.should_receive(:run_stories)
52
+ runner.run(mock('runner'))
53
+ end
54
+
55
+ it "should accept a block instead of a path" do
56
+ runner = PlainTextStoryRunner.new do |runner|
57
+ runner.load("path/to/story")
58
+ end
59
+ File.should_receive(:read).with("path/to/story").and_return("this\nand that")
60
+ runner.run(mock('runner'))
61
+ end
62
+
63
+ it "should tell you if you try to run with no path set" do
64
+ runner = PlainTextStoryRunner.new
65
+ lambda {
66
+ runner.run(mock('runner'))
67
+ }.should raise_error(RuntimeError, "You must set a path to the file with the story. See the RDoc.")
68
+ end
69
+
70
+ it "should pass options to the mediator" do
71
+ runner = PlainTextStoryRunner.new("path", :foo => :bar)
72
+ Spec::Story::Runner::StoryMediator.should_receive(:new).
73
+ with(anything, anything, :foo => :bar).
74
+ and_return(mediator = stub("mediator", :run_stories => nil))
75
+ runner.run(mock('runner'))
76
+ end
77
+
78
+ it "should provide access to its options" do
79
+ runner = PlainTextStoryRunner.new("path")
80
+ runner[:foo] = :bar
81
+ Spec::Story::Runner::StoryMediator.should_receive(:new).
82
+ with(anything, anything, :foo => :bar).
83
+ and_return(mediator = stub("mediator", :run_stories => nil))
84
+ runner.run mock('runner')
85
+ end
86
+
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,27 @@
1
+ require File.dirname(__FILE__) + '/../story_helper'
2
+
3
+ module Spec
4
+ module Story
5
+ module Runner
6
+ describe ScenarioCollector do
7
+ it 'should construct scenarios with the supplied story' do
8
+ # given
9
+ story = stub_everything('story')
10
+ scenario_collector = ScenarioCollector.new(story)
11
+
12
+ # when
13
+ scenario_collector.Scenario 'scenario1' do end
14
+ scenario_collector.Scenario 'scenario2' do end
15
+ scenarios = scenario_collector.scenarios
16
+
17
+ # then
18
+ scenario_collector.should have(2).scenarios
19
+ scenarios.first.name.should == 'scenario1'
20
+ scenarios.first.story.should equal(story)
21
+ scenarios.last.name.should == 'scenario2'
22
+ scenarios.last.story.should equal(story)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,214 @@
1
+ require File.dirname(__FILE__) + '/../story_helper'
2
+
3
+ module Spec
4
+ module Story
5
+ module Runner
6
+ describe ScenarioRunner do
7
+ it 'should run a scenario in its story' do
8
+ # given
9
+ world = stub_everything
10
+ scenario_runner = ScenarioRunner.new
11
+ $answer = nil
12
+ story = Story.new 'story', 'narrative' do
13
+ @answer = 42 # this should be available to the scenario
14
+ end
15
+ scenario = Scenario.new story, 'scenario' do
16
+ $answer = @answer
17
+ end
18
+
19
+ # when
20
+ scenario_runner.run(scenario, world)
21
+
22
+ # then
23
+ $answer.should == 42
24
+ end
25
+
26
+ it 'should allow scenarios to share methods' do
27
+ # given
28
+ world = stub_everything
29
+ $shared_invoked = 0
30
+ story = Story.new 'story', 'narrative' do
31
+ def shared
32
+ $shared_invoked += 1
33
+ end
34
+ end
35
+ scenario1 = Scenario.new story, 'scenario1' do
36
+ shared()
37
+ end
38
+ scenario2 = Scenario.new story, 'scenario2' do
39
+ shared()
40
+ end
41
+ scenario_runner = ScenarioRunner.new
42
+
43
+ # when
44
+ scenario_runner.run(scenario1, world)
45
+ scenario_runner.run(scenario2, world)
46
+
47
+ # then
48
+ $shared_invoked.should == 2
49
+ end
50
+
51
+ it 'should notify listeners when a scenario starts' do
52
+ # given
53
+ world = stub_everything
54
+ story = Story.new 'story', 'narrative' do end
55
+ scenario = Scenario.new story, 'scenario1' do
56
+ # succeeds
57
+ end
58
+ scenario_runner = ScenarioRunner.new
59
+ mock_listener1 = stub_everything('listener1')
60
+ mock_listener2 = stub_everything('listener2')
61
+ scenario_runner.add_listener(mock_listener1)
62
+ scenario_runner.add_listener(mock_listener2)
63
+
64
+ # expect
65
+ mock_listener1.should_receive(:scenario_started).with('story', 'scenario1')
66
+ mock_listener2.should_receive(:scenario_started).with('story', 'scenario1')
67
+
68
+ # when
69
+ scenario_runner.run(scenario, world)
70
+
71
+ # then
72
+ end
73
+ describe "when a scenario succeeds" do
74
+ before(:each) do
75
+ # given
76
+ @world = stub_everything('world')
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
+ end
83
+
84
+ it 'should notify listeners' do
85
+ #given
86
+ mock_listener1 = stub_everything('listener1')
87
+ mock_listener2 = stub_everything('listener2')
88
+ @scenario_runner.add_listener(mock_listener1)
89
+ @scenario_runner.add_listener(mock_listener2)
90
+
91
+ # expect
92
+ mock_listener1.should_receive(:scenario_succeeded).with('story', 'scenario1')
93
+ mock_listener2.should_receive(:scenario_succeeded).with('story', 'scenario1')
94
+
95
+ # when
96
+ @scenario_runner.run(@scenario, @world)
97
+
98
+ # then
99
+ end
100
+
101
+ it "should return true" do
102
+ #when
103
+ success = @scenario_runner.run(@scenario, @world)
104
+
105
+ #then
106
+ success.should == true
107
+ end
108
+ end
109
+
110
+ describe "when a scenario raises an error (other than a pending error)" do
111
+ before(:each) do
112
+ # given
113
+ @error = RuntimeError.new('oops')
114
+ @story = Story.new 'title', 'narrative' do end
115
+ @scenario = Scenario.new @story, 'scenario1' do
116
+ end
117
+ @scenario_runner = ScenarioRunner.new
118
+ @world = stub_everything
119
+
120
+ # expect
121
+ @world.should_receive(:errors).twice.and_return([@error, @error])
122
+ end
123
+
124
+ it 'should notify listeners ONCE' do
125
+ #given
126
+ mock_listener = stub_everything('listener')
127
+ @scenario_runner.add_listener(mock_listener)
128
+
129
+ #expect
130
+ mock_listener.should_receive(:scenario_failed).with('title', 'scenario1', @error).once
131
+
132
+ # when
133
+ @scenario_runner.run @scenario, @world
134
+
135
+ # then
136
+ end
137
+
138
+ it "should return false" do
139
+ # when
140
+ success = @scenario_runner.run @scenario, @world
141
+
142
+ # then
143
+ success.should == false
144
+ end
145
+
146
+
147
+ end
148
+
149
+ describe "when a scenario is pending" do
150
+ before(:each) do
151
+ # given
152
+ @pending_error = Spec::Example::ExamplePendingError.new('todo')
153
+ @story = Story.new 'title', 'narrative' do end
154
+ @scenario = Scenario.new @story, 'scenario1' do
155
+ end
156
+ @scenario_runner = ScenarioRunner.new
157
+ @world = stub_everything
158
+
159
+ # expect
160
+ @world.should_receive(:errors).twice.and_return([@pending_error, @pending_error])
161
+ end
162
+
163
+ it 'should notify listeners' do
164
+ #given
165
+ mock_listener = mock('listener')
166
+ @scenario_runner.add_listener(mock_listener)
167
+
168
+ # expect
169
+ mock_listener.should_receive(:scenario_started).with('title', 'scenario1')
170
+ mock_listener.should_receive(:scenario_pending).with('title', 'scenario1', 'todo').once
171
+
172
+ # when
173
+ @scenario_runner.run @scenario, @world
174
+
175
+ # then
176
+ end
177
+
178
+ it "should return true" do
179
+ # when
180
+ success = @scenario_runner.run @scenario, @world
181
+
182
+ # then
183
+ success.should == true
184
+ end
185
+ end
186
+
187
+ describe "when a scenario has an empty body" do
188
+ before(:each) do
189
+ @story = Story.new 'title', 'narrative' do end
190
+ @scenario = Scenario.new @story, 'scenario'
191
+ @scenario_runner = ScenarioRunner.new
192
+ @world = stub_everything
193
+ end
194
+
195
+ it "should mark the scenario as pending" do
196
+ mock_listener = stub('listener', :scenario_started => true)
197
+ @scenario_runner.add_listener mock_listener
198
+
199
+ mock_listener.should_receive(:scenario_pending).with('title', 'scenario', '')
200
+ @scenario_runner.run @scenario, @world
201
+ end
202
+
203
+ it "should return true" do
204
+ # when
205
+ success = @scenario_runner.run @scenario, @world
206
+
207
+ # then
208
+ success.should == true
209
+ end
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,143 @@
1
+ require File.dirname(__FILE__) + '/../story_helper'
2
+
3
+ module Spec
4
+ module Story
5
+ module Runner
6
+
7
+ describe StoryMediator do
8
+ before(:each) do
9
+ $story_mediator_spec_value = nil
10
+ @step_group = StepGroup.new
11
+ @step_group.create_matcher(:given, "given") { $story_mediator_spec_value = "given matched" }
12
+ @step_group.create_matcher(:when, "when") { $story_mediator_spec_value = "when matched" }
13
+ @step_group.create_matcher(:then, "then") { $story_mediator_spec_value = "then matched" }
14
+
15
+ @scenario_runner = ScenarioRunner.new
16
+ @runner = StoryRunner.new @scenario_runner
17
+ @mediator = StoryMediator.new @step_group, @runner
18
+ end
19
+
20
+ def run_stories
21
+ @mediator.run_stories
22
+ @runner.run_stories
23
+ end
24
+
25
+ it "should have no stories" do
26
+ @mediator.stories.should be_empty
27
+ end
28
+
29
+ it "should create two stories" do
30
+ @mediator.create_story "story title", "story narrative"
31
+ @mediator.create_story "story title 2", "story narrative 2"
32
+ run_stories
33
+
34
+ @runner.should have(2).stories
35
+ @runner.stories.first.title.should == "story title"
36
+ @runner.stories.first.narrative.should == "story narrative"
37
+ @runner.stories.last.title.should == "story title 2"
38
+ @runner.stories.last.narrative.should == "story narrative 2"
39
+ end
40
+
41
+ it "should create a scenario" do
42
+ @mediator.create_story "title", "narrative"
43
+ @mediator.create_scenario "scenario name"
44
+ run_stories
45
+
46
+ @runner.should have(1).scenarios
47
+ @runner.scenarios.first.name.should == "scenario name"
48
+ @runner.scenarios.first.story.should == @runner.stories.first
49
+ end
50
+
51
+ it "should create a given scenario step if one matches" do
52
+ pending("need to untangle the dark mysteries of the story runner - something needs to get stubbed here") do
53
+ story = @mediator.create_story "title", "narrative"
54
+ @mediator.create_scenario "previous scenario"
55
+ @mediator.create_scenario "current scenario"
56
+ @mediator.create_given_scenario "previous scenario"
57
+ run_stories
58
+
59
+ $story_mediator_spec_value.should == "previous scenario matched"
60
+ end
61
+ end
62
+
63
+ it "should create a given step if one matches" do
64
+ @mediator.create_story "title", "narrative"
65
+ @mediator.create_scenario "scenario"
66
+ @mediator.create_given "given"
67
+ run_stories
68
+
69
+ $story_mediator_spec_value.should == "given matched"
70
+ end
71
+
72
+ it "should create a pending step if no given step matches" do
73
+ @mediator.create_story "title", "narrative"
74
+ @mediator.create_scenario "scenario"
75
+ @mediator.create_given "no match"
76
+ mock_listener = stub_everything("listener")
77
+ mock_listener.should_receive(:scenario_pending).with("title", "scenario", "Unimplemented step: no match")
78
+ @scenario_runner.add_listener mock_listener
79
+ run_stories
80
+ end
81
+
82
+ it "should create a when step if one matches" do
83
+ @mediator.create_story "title", "narrative"
84
+ @mediator.create_scenario "scenario"
85
+ @mediator.create_when "when"
86
+ run_stories
87
+
88
+ $story_mediator_spec_value.should == "when matched"
89
+ end
90
+
91
+ it "should create a pending step if no when step matches" do
92
+ @mediator.create_story "title", "narrative"
93
+ @mediator.create_scenario "scenario"
94
+ @mediator.create_when "no match"
95
+ mock_listener = stub_everything("listener")
96
+ mock_listener.should_receive(:scenario_pending).with("title", "scenario", "Unimplemented step: no match")
97
+ @scenario_runner.add_listener mock_listener
98
+ run_stories
99
+ end
100
+
101
+ it "should create a then step if one matches" do
102
+ @mediator.create_story "title", "narrative"
103
+ @mediator.create_scenario "scenario"
104
+ @mediator.create_then "then"
105
+ run_stories
106
+
107
+ $story_mediator_spec_value.should == "then matched"
108
+ end
109
+
110
+ it "should create a pending step if no 'then' step matches" do
111
+ @mediator.create_story "title", "narrative"
112
+ @mediator.create_scenario "scenario"
113
+ @mediator.create_then "no match"
114
+ mock_listener = stub_everything("listener")
115
+ mock_listener.should_receive(:scenario_pending).with("title", "scenario", "Unimplemented step: no match")
116
+ @scenario_runner.add_listener mock_listener
117
+ run_stories
118
+ end
119
+
120
+ it "should pass options to the stories it creates" do
121
+ @mediator = StoryMediator.new @step_group, @runner, :foo => :bar
122
+ @mediator.create_story "story title", "story narrative"
123
+
124
+ run_stories
125
+
126
+ @runner.stories.first[:foo].should == :bar
127
+ end
128
+
129
+ it "should description" do
130
+ @mediator = StoryMediator.new @step_group, @runner, :foo => :bar
131
+ @mediator.create_story "title", "narrative"
132
+ @mediator.create_scenario "scenario"
133
+ @mediator.create_given "something"
134
+ given = @mediator.last_step
135
+ @mediator.add_to_last " else"
136
+ given.name.should == "something else"
137
+ end
138
+
139
+ end
140
+
141
+ end
142
+ end
143
+ end