butternut 0.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/.document +5 -0
- data/.gitignore +22 -0
- data/LICENSE +20 -0
- data/README.rdoc +18 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/butternut.gemspec +79 -0
- data/lib/butternut/cucumber.css +112 -0
- data/lib/butternut/cucumber.sass +152 -0
- data/lib/butternut/formatter.rb +465 -0
- data/lib/butternut/helpers.rb +51 -0
- data/lib/butternut/scenario_extensions.rb +7 -0
- data/lib/butternut.rb +32 -0
- data/spec/butternut/formatter_spec.rb +288 -0
- data/spec/butternut/helpers_spec.rb +128 -0
- data/spec/butternut_spec.rb +53 -0
- data/spec/fixtures/foo.css +3 -0
- data/spec/fixtures/foo.html +20 -0
- data/spec/fixtures/foo.js +3 -0
- data/spec/fixtures/picard.jpg +0 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +78 -0
- data/tmp/features/.gitignore +2 -0
- data/tmp/main/.gitignore +2 -0
- metadata +121 -0
@@ -0,0 +1,288 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
module Butternut
|
4
|
+
describe Formatter do
|
5
|
+
extend SpecHelperDsl
|
6
|
+
include SpecHelper
|
7
|
+
|
8
|
+
Spec::Matchers.define :have_css_node do |css, regexp|
|
9
|
+
match do |doc|
|
10
|
+
nodes = doc.css(css)
|
11
|
+
nodes.detect{ |node| node.text =~ regexp }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def setup_formatter(options = {})
|
16
|
+
@out = StringIO.new
|
17
|
+
@formatter = Butternut::Formatter.new(step_mother, @out, options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def most_recent_html_file(dir)
|
21
|
+
path = Pathname.new(dir)
|
22
|
+
files = path.entries.collect { |file|
|
23
|
+
path+file
|
24
|
+
}.sort { |file1,file2|
|
25
|
+
file2.mtime <=> file1.mtime
|
26
|
+
}
|
27
|
+
files.detect { |f| f.to_s =~ /\.html$/ }
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "visiting blank feature name" do
|
31
|
+
before(:each) do
|
32
|
+
setup_formatter
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should not raise an error when visiting a blank feature name" do
|
36
|
+
lambda { @formatter.feature_name("") }.should_not raise_error
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "given a single feature" do
|
41
|
+
before(:each) do
|
42
|
+
setup_formatter
|
43
|
+
run_defined_feature
|
44
|
+
@doc = Nokogiri.HTML(@out.string)
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "with a comment" do
|
48
|
+
define_feature <<-FEATURE
|
49
|
+
# Healthy
|
50
|
+
FEATURE
|
51
|
+
|
52
|
+
it { @out.string.should =~ /^\<!DOCTYPE/ }
|
53
|
+
it { @out.string.should =~ /\<\/html\>$/ }
|
54
|
+
it { @doc.should have_css_node('.feature .comment', /Healthy/) }
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "with a tag" do
|
58
|
+
define_feature <<-FEATURE
|
59
|
+
@foo
|
60
|
+
FEATURE
|
61
|
+
|
62
|
+
it { @doc.should have_css_node('.feature .tag', /foo/) }
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "with a narrative" do
|
66
|
+
define_feature <<-FEATURE
|
67
|
+
Feature: Bananas
|
68
|
+
In order to find my inner monkey
|
69
|
+
As a human
|
70
|
+
I must eat bananas
|
71
|
+
FEATURE
|
72
|
+
|
73
|
+
it { @doc.should have_css_node('.feature h2', /Bananas/) }
|
74
|
+
it { @doc.should have_css_node('.feature .narrative', /must eat bananas/) }
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "with a background" do
|
78
|
+
define_feature <<-FEATURE
|
79
|
+
Feature: Bananas
|
80
|
+
|
81
|
+
Background:
|
82
|
+
Given there are bananas
|
83
|
+
FEATURE
|
84
|
+
|
85
|
+
it { @doc.should have_css_node('.feature .background', /there are bananas/) }
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "with a scenario" do
|
89
|
+
define_feature <<-FEATURE
|
90
|
+
Scenario: Monkey eats banana
|
91
|
+
Given there are bananas
|
92
|
+
FEATURE
|
93
|
+
|
94
|
+
it { @doc.should have_css_node('.feature h3', /Monkey eats banana/) }
|
95
|
+
it { @doc.should have_css_node('.feature .scenario .step', /there are bananas/) }
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "with a scenario outline" do
|
99
|
+
define_feature <<-FEATURE
|
100
|
+
Scenario Outline: Monkey eats a balanced diet
|
101
|
+
Given there are <Things>
|
102
|
+
|
103
|
+
Examples: Fruit
|
104
|
+
| Things |
|
105
|
+
| apples |
|
106
|
+
| bananas |
|
107
|
+
Examples: Vegetables
|
108
|
+
| Things |
|
109
|
+
| broccoli |
|
110
|
+
| carrots |
|
111
|
+
FEATURE
|
112
|
+
|
113
|
+
it { @doc.should have_css_node('.feature .scenario.outline h4', /Fruit/) }
|
114
|
+
it { @doc.should have_css_node('.feature .scenario.outline h4', /Vegetables/) }
|
115
|
+
it { @doc.css('.feature .scenario.outline h4').length.should == 2}
|
116
|
+
it { @doc.should have_css_node('.feature .scenario.outline table', //) }
|
117
|
+
it { @doc.should have_css_node('.feature .scenario.outline table td', /carrots/) }
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "with a step with a py string" do
|
121
|
+
define_feature <<-FEATURE
|
122
|
+
Scenario: Monkey goes to town
|
123
|
+
Given there is a monkey called:
|
124
|
+
"""
|
125
|
+
foo
|
126
|
+
"""
|
127
|
+
FEATURE
|
128
|
+
|
129
|
+
it { @doc.should have_css_node('.feature .scenario .val', /foo/) }
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "with a multiline step arg" do
|
133
|
+
define_feature <<-FEATURE
|
134
|
+
Scenario: Monkey goes to town
|
135
|
+
Given there are monkeys:
|
136
|
+
| name |
|
137
|
+
| foo |
|
138
|
+
| bar |
|
139
|
+
FEATURE
|
140
|
+
|
141
|
+
it { @doc.should have_css_node('.feature .scenario table td', /foo/) }
|
142
|
+
end
|
143
|
+
|
144
|
+
describe "with a table in the background and the scenario" do
|
145
|
+
define_feature <<-FEATURE
|
146
|
+
Background:
|
147
|
+
Given table:
|
148
|
+
| a | b |
|
149
|
+
| c | d |
|
150
|
+
Scenario:
|
151
|
+
Given another table:
|
152
|
+
| e | f |
|
153
|
+
| g | h |
|
154
|
+
FEATURE
|
155
|
+
|
156
|
+
it { @doc.css('td').length.should == 8 }
|
157
|
+
end
|
158
|
+
|
159
|
+
describe "with a py string in the background and the scenario" do
|
160
|
+
define_feature <<-FEATURE
|
161
|
+
Background:
|
162
|
+
Given stuff:
|
163
|
+
"""
|
164
|
+
foo
|
165
|
+
"""
|
166
|
+
Scenario:
|
167
|
+
Given more stuff:
|
168
|
+
"""
|
169
|
+
bar
|
170
|
+
"""
|
171
|
+
FEATURE
|
172
|
+
|
173
|
+
it { @doc.css('.feature .background pre.val').length.should == 1 }
|
174
|
+
it { @doc.css('.feature .scenario pre.val').length.should == 1 }
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "with a step that fails in the scenario" do
|
178
|
+
define_steps do
|
179
|
+
Given(/boo/) { raise 'eek' }
|
180
|
+
end
|
181
|
+
|
182
|
+
define_feature(<<-FEATURE)
|
183
|
+
Scenario: Monkey gets a fright
|
184
|
+
Given boo
|
185
|
+
FEATURE
|
186
|
+
|
187
|
+
it { @doc.should have_css_node('.feature .scenario .step.failed', /eek/) }
|
188
|
+
end
|
189
|
+
|
190
|
+
describe "with a step that fails in the backgound" do
|
191
|
+
define_steps do
|
192
|
+
Given(/boo/) { raise 'eek' }
|
193
|
+
end
|
194
|
+
|
195
|
+
define_feature(<<-FEATURE)
|
196
|
+
Background:
|
197
|
+
Given boo
|
198
|
+
Scenario:
|
199
|
+
Given yay
|
200
|
+
FEATURE
|
201
|
+
|
202
|
+
it { @doc.should have_css_node('.feature .background .step.failed', /eek/) }
|
203
|
+
it { @doc.should_not have_css_node('.feature .scenario .step.failed', //) }
|
204
|
+
it { @doc.should have_css_node('.feature .scenario .step.undefined', /yay/) }
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
describe "displaying page source to stdout" do
|
209
|
+
before(:each) do
|
210
|
+
setup_formatter
|
211
|
+
run_defined_feature
|
212
|
+
@doc = Nokogiri.HTML(@out.string)
|
213
|
+
end
|
214
|
+
|
215
|
+
define_steps do
|
216
|
+
Given(/foo/) do
|
217
|
+
visit("file://" + File.expand_path(File.dirname(__FILE__) + "/../fixtures/foo.html"))
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
define_feature(<<-FEATURE)
|
222
|
+
Scenario: Monkey goes to the zoo
|
223
|
+
Given foo
|
224
|
+
FEATURE
|
225
|
+
|
226
|
+
it do
|
227
|
+
step = @doc.at('.feature .scenario .step.passed')
|
228
|
+
link = step.at('a[href^="file:///tmp/"]')
|
229
|
+
link.should_not be_nil
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe "displaying page source to file" do
|
234
|
+
before(:each) do
|
235
|
+
@tmpdir = File.join(File.dirname(__FILE__), "..", "..", "tmp")
|
236
|
+
setup_formatter({:formats => [
|
237
|
+
['Butternut::Formatter', File.join(@tmpdir, "main", "huge.html")]
|
238
|
+
]})
|
239
|
+
run_defined_feature
|
240
|
+
@doc = Nokogiri.HTML(@out.string)
|
241
|
+
|
242
|
+
dir = File.join(@tmpdir, "features", Date.today.to_s)
|
243
|
+
file = most_recent_html_file(dir)
|
244
|
+
@page_doc = Nokogiri.HTML(open(file).read)
|
245
|
+
end
|
246
|
+
|
247
|
+
define_steps do
|
248
|
+
Given(/foo/) do
|
249
|
+
visit("file://" + File.expand_path(File.dirname(__FILE__) + "/../fixtures/foo.html"))
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
define_feature(<<-FEATURE)
|
254
|
+
Scenario: Monkey goes to the zoo
|
255
|
+
Given foo
|
256
|
+
FEATURE
|
257
|
+
|
258
|
+
it "links to the page source" do
|
259
|
+
step = @doc.at('.feature .scenario .step.passed')
|
260
|
+
link = step.at("a")
|
261
|
+
link.should_not be_nil
|
262
|
+
file = link['href']
|
263
|
+
file.should match(%r{^/features/#{Date.today.to_s}/butternut.+\.html})
|
264
|
+
end
|
265
|
+
|
266
|
+
it "saves images and stylesheets and rewrites urls in page source" do
|
267
|
+
@page_doc.at('img')['src'].should == "picard.jpg"
|
268
|
+
@page_doc.at('link[rel="stylesheet"]')['href'].should == "foo.css"
|
269
|
+
end
|
270
|
+
|
271
|
+
it "turns off links" do
|
272
|
+
@page_doc.css('a').each do |link|
|
273
|
+
link['href'].should == "#"
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
it "turns off scripts" do
|
278
|
+
@page_doc.css('script').length.should == 0
|
279
|
+
end
|
280
|
+
|
281
|
+
it "disables form elements" do
|
282
|
+
@page_doc.css('input, select, textarea').each do |elt|
|
283
|
+
elt['disabled'].should == "disabled"
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
module Butternut
|
4
|
+
describe Helpers do
|
5
|
+
include Helpers
|
6
|
+
|
7
|
+
def define_stub_chain
|
8
|
+
# This is what I hate about RSpec.
|
9
|
+
@stub_request_url = stub("fake request url", :toString => "http://example.com")
|
10
|
+
@stub_response = stub("fake web response", :getRequestUrl => @stub_request_url)
|
11
|
+
@stub_page = stub("fake html page", {
|
12
|
+
:as_xml => "<cheese>pepperjack</cheese>",
|
13
|
+
:getWebResponse => @stub_response
|
14
|
+
})
|
15
|
+
@stub_element = stub("fake element", :value= => nil, :select => nil, :click => nil, :exist? => true)
|
16
|
+
@stub_empty = stub("fake empty element", :exist? => false)
|
17
|
+
|
18
|
+
@stub_browser = stub("fake celerity browser", {
|
19
|
+
:goto => @stub_page, :page => @stub_page,
|
20
|
+
:text_field => @stub_element, :select_list => @stub_element,
|
21
|
+
:button => @stub_element
|
22
|
+
})
|
23
|
+
stub!(:browser).and_return(@stub_browser)
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#browser" do
|
27
|
+
it { browser.should be_a(Celerity::Browser) }
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#page_changed?" do
|
31
|
+
it { page_changed?.should_not be_true }
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#visit" do
|
35
|
+
before(:each) { define_stub_chain }
|
36
|
+
|
37
|
+
it "should go to the page" do
|
38
|
+
@stub_browser.should_receive(:goto).with("http://google.com")
|
39
|
+
visit("http://google.com")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should flag page as changed" do
|
43
|
+
visit("http://google.com")
|
44
|
+
page_changed?.should be_true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#current_url" do
|
49
|
+
before(:each) { define_stub_chain }
|
50
|
+
it do
|
51
|
+
@stub_request_url.should_receive(:toString).and_return("http://google.com")
|
52
|
+
current_url.should == "http://google.com"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#current_page_source" do
|
57
|
+
before(:each) { define_stub_chain }
|
58
|
+
|
59
|
+
it "returns the current page's source" do
|
60
|
+
@stub_page.should_receive(:as_xml).and_return("pants")
|
61
|
+
current_page_source.should == "pants"
|
62
|
+
end
|
63
|
+
|
64
|
+
it "returns nil if page is nil" do
|
65
|
+
@stub_browser.stub!(:page).and_return(nil)
|
66
|
+
current_page_source.should be_nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#fill_in" do
|
71
|
+
before(:each) { define_stub_chain }
|
72
|
+
|
73
|
+
it "should find by label" do
|
74
|
+
@stub_browser.should_receive(:text_field).with(:label, "pants").and_return(@stub_element)
|
75
|
+
@stub_element.should_receive(:value=).with("khakis")
|
76
|
+
fill_in("pants", :with => "khakis")
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should find by name" do
|
80
|
+
@stub_browser.should_receive(:text_field).with(:label, "pants").and_return(@stub_empty)
|
81
|
+
@stub_browser.should_receive(:text_field).with(:name, "pants").and_return(@stub_element)
|
82
|
+
@stub_element.should_receive(:value=).with("khakis")
|
83
|
+
fill_in("pants", :with => "khakis")
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should flag page as changed" do
|
87
|
+
fill_in("pants", :with => "khakis")
|
88
|
+
page_changed?.should be_true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#select" do
|
93
|
+
before(:each) { define_stub_chain }
|
94
|
+
|
95
|
+
it "should find by label" do
|
96
|
+
@stub_browser.should_receive(:select_list).with(:label, "pants").and_return(@stub_element)
|
97
|
+
@stub_element.should_receive(:select).with("khakis")
|
98
|
+
select("khakis", :from => "pants")
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should find by name" do
|
102
|
+
@stub_browser.should_receive(:select_list).with(:label, "pants").and_return(@stub_empty)
|
103
|
+
@stub_browser.should_receive(:select_list).with(:name, "pants").and_return(@stub_element)
|
104
|
+
@stub_element.should_receive(:select).with("khakis")
|
105
|
+
select("khakis", :from => "pants")
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should flag page as changed" do
|
109
|
+
select("khakis", :from => "pants")
|
110
|
+
page_changed?.should be_true
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "#click_button" do
|
115
|
+
before(:each) { define_stub_chain }
|
116
|
+
it do
|
117
|
+
@stub_browser.should_receive(:button).with("pants").and_return(@stub_element)
|
118
|
+
@stub_element.should_receive(:click)
|
119
|
+
click_button("pants")
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should flag page as changed" do
|
123
|
+
click_button("pants")
|
124
|
+
page_changed?.should be_true
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Butternut do
|
4
|
+
describe "running a scenario" do
|
5
|
+
extend SpecHelperDsl
|
6
|
+
include SpecHelper
|
7
|
+
|
8
|
+
describe "saving last page info" do
|
9
|
+
define_steps do
|
10
|
+
Given('waffles') do
|
11
|
+
visit("file://" + File.expand_path(File.dirname(__FILE__) + "/fixtures/foo.html"))
|
12
|
+
end
|
13
|
+
AfterStep do |scenario|
|
14
|
+
begin
|
15
|
+
scenario.last_page_source.should match(/Foo/)
|
16
|
+
scenario.last_page_url.should match(/foo\.html/)
|
17
|
+
rescue Exception => e
|
18
|
+
p e
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
define_feature <<-FEATURE
|
24
|
+
Scenario: Roffle waffles
|
25
|
+
Given waffles
|
26
|
+
FEATURE
|
27
|
+
|
28
|
+
it { run_defined_feature }
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "resetting page_changed" do
|
32
|
+
define_steps do
|
33
|
+
Given('waffles') do
|
34
|
+
visit("file://" + File.expand_path(File.dirname(__FILE__) + "/fixtures/foo.txt"))
|
35
|
+
end
|
36
|
+
AfterStep do |scenario|
|
37
|
+
begin
|
38
|
+
page_changed?.should be_false
|
39
|
+
rescue Exception => e
|
40
|
+
p e
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
define_feature <<-FEATURE
|
46
|
+
Scenario: Roffle waffles
|
47
|
+
Given waffles
|
48
|
+
FEATURE
|
49
|
+
|
50
|
+
it { run_defined_feature }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>Foo</title>
|
4
|
+
<link rel="stylesheet" href="foo.css" type="text/css"/>
|
5
|
+
<script type="text/javascript" src="foo.js"></script>
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
Foo
|
9
|
+
<img src="picard.jpg"/>
|
10
|
+
<a href="http://picard.ytmnd.com/">Picard song</a>
|
11
|
+
<form action="foo.html" method="post">
|
12
|
+
<input type="text" name="foo" />
|
13
|
+
<select name="bar">
|
14
|
+
<option>pants</option>
|
15
|
+
</select>
|
16
|
+
<textarea name="yar"></textarea>
|
17
|
+
<input type="submit" value="Submit" />
|
18
|
+
</form>
|
19
|
+
</body>
|
20
|
+
</html>
|
Binary file
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'rspec'
|
3
|
+
require 'spec'
|
4
|
+
require 'spec/autorun'
|
5
|
+
require 'ruby-debug'
|
6
|
+
|
7
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
9
|
+
require 'butternut'
|
10
|
+
|
11
|
+
require 'cucumber/rb_support/rb_language'
|
12
|
+
require 'nokogiri'
|
13
|
+
|
14
|
+
module SpecHelperDsl
|
15
|
+
attr_reader :feature_content, :step_defs
|
16
|
+
|
17
|
+
def define_feature(string)
|
18
|
+
@feature_content = string
|
19
|
+
end
|
20
|
+
|
21
|
+
def define_steps(&block)
|
22
|
+
@step_defs = block
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module SpecHelper
|
27
|
+
def run_defined_feature
|
28
|
+
setup_world
|
29
|
+
define_steps
|
30
|
+
features = load_features(self.class.feature_content || raise("No feature content defined!"))
|
31
|
+
run(features)
|
32
|
+
end
|
33
|
+
|
34
|
+
def step_mother
|
35
|
+
@step_mother ||= Cucumber::StepMother.new
|
36
|
+
end
|
37
|
+
|
38
|
+
def load_features(content)
|
39
|
+
feature_file = Cucumber::FeatureFile.new('spec.feature', content)
|
40
|
+
features = Cucumber::Ast::Features.new
|
41
|
+
features.add_feature feature_file.parse(step_mother, {})
|
42
|
+
features
|
43
|
+
end
|
44
|
+
|
45
|
+
def run(features)
|
46
|
+
# options = { :verbose => true }
|
47
|
+
options = {}
|
48
|
+
tree_walker = Cucumber::Ast::TreeWalker.new(step_mother, @formatter ? [@formatter] : [], options, STDOUT)
|
49
|
+
tree_walker.visit_features(features)
|
50
|
+
end
|
51
|
+
|
52
|
+
def dsl
|
53
|
+
unless @dsl
|
54
|
+
rb = step_mother.load_programming_language('rb')
|
55
|
+
@dsl = Object.new
|
56
|
+
@dsl.extend Cucumber::RbSupport::RbDsl
|
57
|
+
end
|
58
|
+
@dsl
|
59
|
+
end
|
60
|
+
|
61
|
+
def define_steps
|
62
|
+
return unless step_defs = self.class.step_defs
|
63
|
+
dsl.instance_exec &step_defs
|
64
|
+
end
|
65
|
+
|
66
|
+
def setup_world
|
67
|
+
dsl.instance_exec do
|
68
|
+
Butternut.setup_hooks(self)
|
69
|
+
World(Butternut::Helpers)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
Spec::Runner.configure do |config|
|
75
|
+
config.before(:each) do
|
76
|
+
Cucumber::Parser::NaturalLanguage.instance_variable_set(:@languages, nil)
|
77
|
+
end
|
78
|
+
end
|
data/tmp/main/.gitignore
ADDED