spinach 0.1.5.4 → 0.2.0.1
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/Gemfile +2 -0
- data/README.markdown +18 -12
- data/features/background.feature +13 -0
- data/features/reporting/show_step_source_location.feature +11 -1
- data/features/steps/automatic_feature_generation.rb +7 -7
- data/features/steps/background.rb +30 -0
- data/features/steps/exit_status.rb +12 -13
- data/features/steps/feature_name_guessing.rb +7 -7
- data/features/steps/reporting/display_run_summary.rb +22 -22
- data/features/steps/reporting/error_reporting.rb +7 -7
- data/features/steps/reporting/show_step_source_location.rb +63 -14
- data/features/steps/reporting/undefined_feature_reporting.rb +7 -7
- data/features/steps/rspec_compatibility.rb +14 -14
- data/features/support/error_reporting.rb +5 -5
- data/features/support/filesystem.rb +71 -0
- data/features/support/spinach_runner.rb +5 -6
- data/lib/spinach.rb +11 -6
- data/lib/spinach/background.rb +11 -0
- data/lib/spinach/capybara.rb +7 -1
- data/lib/spinach/cli.rb +36 -13
- data/lib/spinach/config.rb +40 -6
- data/lib/spinach/dsl.rb +14 -11
- data/lib/spinach/exceptions.rb +1 -1
- data/lib/spinach/feature.rb +16 -0
- data/lib/spinach/frameworks.rb +2 -0
- data/lib/spinach/{suites → frameworks}/minitest.rb +0 -0
- data/lib/spinach/{suites → frameworks}/rspec.rb +0 -0
- data/lib/spinach/generators/feature_generator.rb +12 -23
- data/lib/spinach/generators/step_generator.rb +5 -5
- data/lib/spinach/hookable.rb +6 -4
- data/lib/spinach/hooks.rb +12 -4
- data/lib/spinach/parser.rb +6 -8
- data/lib/spinach/parser/visitor.rb +109 -0
- data/lib/spinach/reporter.rb +10 -6
- data/lib/spinach/reporter/stdout.rb +41 -16
- data/lib/spinach/reporter/stdout/error_reporting.rb +2 -2
- data/lib/spinach/runner.rb +9 -6
- data/lib/spinach/runner/feature_runner.rb +40 -34
- data/lib/spinach/runner/scenario_runner.rb +63 -36
- data/lib/spinach/scenario.rb +12 -0
- data/lib/spinach/step.rb +10 -0
- data/lib/spinach/version.rb +1 -1
- data/spinach.gemspec +3 -3
- data/test/spinach/background_test.rb +6 -0
- data/test/spinach/capybara_test.rb +30 -13
- data/test/spinach/cli_test.rb +46 -1
- data/test/spinach/config_test.rb +39 -0
- data/test/spinach/dsl_test.rb +12 -10
- data/test/spinach/feature_steps_test.rb +3 -3
- data/test/spinach/feature_test.rb +6 -0
- data/test/spinach/{suites → frameworks}/minitest_test.rb +2 -2
- data/test/spinach/generators/feature_generator_test.rb +18 -58
- data/test/spinach/generators/step_generator_test.rb +3 -3
- data/test/spinach/generators_test.rb +12 -10
- data/test/spinach/hookable_test.rb +8 -0
- data/test/spinach/hooks_test.rb +6 -7
- data/test/spinach/parser/visitor_test.rb +173 -0
- data/test/spinach/parser_test.rb +14 -27
- data/test/spinach/reporter/stdout/error_reporting_test.rb +9 -9
- data/test/spinach/reporter/stdout_test.rb +15 -19
- data/test/spinach/reporter_test.rb +15 -0
- data/test/spinach/runner/feature_runner_test.rb +79 -69
- data/test/spinach/runner/scenario_runner_test.rb +118 -92
- data/test/spinach/runner_test.rb +10 -6
- data/test/spinach/scenario_test.rb +6 -0
- data/test/spinach/step_test.rb +6 -0
- data/test/spinach_test.rb +7 -7
- metadata +60 -39
- data/lib/spinach/suites.rb +0 -2
data/test/spinach/config_test.rb
CHANGED
@@ -5,6 +5,17 @@ describe Spinach::Config do
|
|
5
5
|
Spinach::Config.new
|
6
6
|
end
|
7
7
|
|
8
|
+
describe '#features_path' do
|
9
|
+
it 'returns a default' do
|
10
|
+
subject[:features_path].must_be_kind_of String
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'can be overwritten' do
|
14
|
+
subject[:features_path] = 'test'
|
15
|
+
subject[:features_path].must_equal 'test'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
8
19
|
describe '#step_definitions_path' do
|
9
20
|
it 'returns a default' do
|
10
21
|
subject[:step_definitions_path].must_be_kind_of String
|
@@ -42,4 +53,32 @@ describe Spinach::Config do
|
|
42
53
|
subject[:failure_exceptions].must_include RuntimeError
|
43
54
|
end
|
44
55
|
end
|
56
|
+
|
57
|
+
describe '#config_path' do
|
58
|
+
it 'returns a default' do
|
59
|
+
subject[:config_path].must_equal 'config/spinach.yml'
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'can be overwritten' do
|
63
|
+
subject[:config_path] = 'my_config_file.yml'
|
64
|
+
subject[:config_path].must_equal 'my_config_file.yml'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#parse_from_file' do
|
69
|
+
before do
|
70
|
+
subject[:config_path] = 'a_path'
|
71
|
+
YAML.stubs(:load_file).returns({support_path: 'my_path', config_path: 'another_path'})
|
72
|
+
subject.parse_from_file
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'sets the options' do
|
76
|
+
subject[:support_path].must_equal 'my_path'
|
77
|
+
end
|
78
|
+
|
79
|
+
it "doesn't set the config_path option" do
|
80
|
+
subject[:config_path].must_equal 'a_path'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
45
84
|
end
|
data/test/spinach/dsl_test.rb
CHANGED
@@ -15,18 +15,9 @@ describe Spinach::DSL do
|
|
15
15
|
step_executed = true
|
16
16
|
end
|
17
17
|
|
18
|
-
@feature.new.
|
18
|
+
@feature.new.execute(stub(name: 'I say goodbye'))
|
19
19
|
step_executed.must_equal true
|
20
20
|
end
|
21
|
-
|
22
|
-
it 'returns step source location' do
|
23
|
-
@feature.When('I say goodbye') do
|
24
|
-
'You say hello'
|
25
|
-
end
|
26
|
-
|
27
|
-
@feature.new.execute_step('I say goodbye').first.must_include '/dsl_test.rb'
|
28
|
-
@feature.new.execute_step('I say goodbye').last.must_be_kind_of Fixnum
|
29
|
-
end
|
30
21
|
end
|
31
22
|
|
32
23
|
describe '#When, #Then, #And, #But' do
|
@@ -50,5 +41,16 @@ describe Spinach::DSL do
|
|
50
41
|
@feature.new.name.must_equal "A cool feature"
|
51
42
|
end
|
52
43
|
end
|
44
|
+
|
45
|
+
describe '#step_location_for' do
|
46
|
+
it 'returns step source location' do
|
47
|
+
@feature.When('I say goodbye') do
|
48
|
+
'You say hello'
|
49
|
+
end
|
50
|
+
|
51
|
+
@feature.new.step_location_for('I say goodbye').first.must_include '/dsl_test.rb'
|
52
|
+
@feature.new.step_location_for('I say goodbye').last.must_be_kind_of Fixnum
|
53
|
+
end
|
54
|
+
end
|
53
55
|
end
|
54
56
|
end
|
@@ -31,16 +31,16 @@ describe Spinach::FeatureSteps do
|
|
31
31
|
end.new
|
32
32
|
end
|
33
33
|
|
34
|
-
describe '
|
34
|
+
describe 'execute' do
|
35
35
|
it 'runs defined step correctly' do
|
36
|
-
feature.
|
36
|
+
feature.execute(stub(name: 'I go to the toilet'))
|
37
37
|
|
38
38
|
feature.pee.must_equal true
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'raises an exception if step is not defined' do
|
42
42
|
proc {
|
43
|
-
feature.
|
43
|
+
feature.execute(stub(name: 'I am lost'))
|
44
44
|
}.must_raise Spinach::StepNotDefinedException
|
45
45
|
end
|
46
46
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require_relative '../../test_helper'
|
2
2
|
|
3
|
-
describe "minitest
|
3
|
+
describe "minitest framework" do
|
4
4
|
before do
|
5
|
-
require_relative '../../../lib/spinach/
|
5
|
+
require_relative '../../../lib/spinach/frameworks/minitest'
|
6
6
|
end
|
7
7
|
|
8
8
|
it "adds MiniTest::Assertion into the failure exceptions" do
|
@@ -4,81 +4,41 @@ require_relative '../../../lib/spinach/generators'
|
|
4
4
|
module Spinach::Generators
|
5
5
|
describe FeatureGenerator do
|
6
6
|
subject do
|
7
|
-
FeatureGenerator.new(
|
7
|
+
FeatureGenerator.new(feature)
|
8
8
|
end
|
9
9
|
|
10
|
-
let(:
|
11
|
-
Spinach::Parser.new("
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
10
|
+
let(:feature) do
|
11
|
+
Spinach::Parser.new("""
|
12
|
+
Feature: Cheezburger can I has
|
13
|
+
Background:
|
14
|
+
Given I liek cheezburger
|
15
|
+
Scenario: Some Lulz
|
16
|
+
Given I haz a sad
|
17
|
+
When I get some lulz
|
18
|
+
Then I haz a happy
|
19
|
+
Scenario: Some sad
|
20
|
+
Given I haz a happy
|
21
|
+
When I get some lulz
|
22
|
+
Then I am OMG ROFLMAO""").parse
|
21
23
|
end
|
22
24
|
|
23
25
|
describe "#name" do
|
24
|
-
it "returns the
|
26
|
+
it "returns the feature name" do
|
25
27
|
subject.name.must_equal 'Cheezburger can I has'
|
26
28
|
end
|
27
|
-
|
28
|
-
it "returns nil if no name present" do
|
29
|
-
data['name'] = nil
|
30
|
-
subject.name.must_equal nil
|
31
|
-
end
|
32
29
|
end
|
33
30
|
|
34
31
|
describe "#steps" do
|
35
32
|
it "returns a correct number different steps for this data" do
|
36
|
-
subject.steps.length.must_equal
|
37
|
-
end
|
38
|
-
|
39
|
-
describe "includes the correct steps" do
|
40
|
-
it "includes 'Given I haz a sad'" do
|
41
|
-
subject.steps.any?{ |step|
|
42
|
-
(step['keyword'] == 'Given') && (step['name'] == 'I haz a sad')
|
43
|
-
}.must_equal true
|
44
|
-
end
|
45
|
-
|
46
|
-
it "includes 'When I get some lulz'" do
|
47
|
-
subject.steps.any?{ |step|
|
48
|
-
(step['keyword'] == 'When') && (step['name'] == 'I get some lulz')
|
49
|
-
}.must_equal true
|
50
|
-
end
|
51
|
-
|
52
|
-
it "includes 'Then I has a happy'" do
|
53
|
-
subject.steps.any?{ |step|
|
54
|
-
(step['keyword'] == 'Then') && (step['name'] == 'I haz a happy')
|
55
|
-
}.must_equal true
|
56
|
-
end
|
57
|
-
|
58
|
-
it "does not include 'Given I haz a happy'" do
|
59
|
-
subject.steps.any?{ |step|
|
60
|
-
(step['keyword'] == 'Given') && (step['name'] == 'I haz a happy')
|
61
|
-
}.must_equal false
|
62
|
-
end
|
63
|
-
|
64
|
-
it "includes 'Then I am OMG ROFLMAO'" do
|
65
|
-
subject.steps.any?{ |step|
|
66
|
-
(step['keyword'] == 'Then') && (step['name'] == 'I am OMG ROFLMAO')
|
67
|
-
}.must_equal true
|
68
|
-
end
|
33
|
+
subject.steps.length.must_equal 5
|
69
34
|
end
|
70
35
|
end
|
71
36
|
|
72
37
|
describe "#generate" do
|
73
38
|
it "generates an entire feature_steps class definition" do
|
74
39
|
result = subject.generate
|
75
|
-
|
76
|
-
|
77
|
-
feature_runner.stubs(data: data)
|
78
|
-
error_count = 0
|
79
|
-
CheezburgerCanIHas.any_instance.
|
80
|
-
expects(:raise).with("step not implemented").times(6).returns(nil)
|
81
|
-
feature_runner.run.must_equal true
|
40
|
+
result.must_match /Given 'I haz a sad' do/
|
41
|
+
result.must_match /raise 'step not implemented'/
|
82
42
|
end
|
83
43
|
end
|
84
44
|
|
@@ -4,11 +4,11 @@ require_relative '../../../lib/spinach/generators'
|
|
4
4
|
module Spinach::Generators
|
5
5
|
describe StepGenerator do
|
6
6
|
subject do
|
7
|
-
StepGenerator.new(
|
7
|
+
StepGenerator.new(step)
|
8
8
|
end
|
9
9
|
|
10
|
-
let(:
|
11
|
-
|
10
|
+
let(:step) do
|
11
|
+
stub(keyword: 'Given', name: 'I has a sad')
|
12
12
|
end
|
13
13
|
|
14
14
|
describe "#generate" do
|
@@ -6,16 +6,18 @@ describe Spinach::Generators do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
let(:data) do
|
9
|
-
Spinach::Parser.new("
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
9
|
+
Spinach::Parser.new("""
|
10
|
+
Feature: Cheezburger can I has
|
11
|
+
Background:
|
12
|
+
Given I liek cheezburger
|
13
|
+
Scenario: Some Lulz
|
14
|
+
Given I haz a sad
|
15
|
+
When I get some lulz
|
16
|
+
Then I haz a happy
|
17
|
+
Scenario: Some sad
|
18
|
+
Given I haz a happy
|
19
|
+
When I get some lulz
|
20
|
+
Then I am OMG ROFLMAO""").parse
|
19
21
|
end
|
20
22
|
|
21
23
|
describe "#bind" do
|
@@ -48,6 +48,14 @@ describe Spinach::Hookable do
|
|
48
48
|
subject.run_hook(:before_save, 1, 2)
|
49
49
|
array.must_equal [1, 2]
|
50
50
|
end
|
51
|
+
|
52
|
+
it "yields to hook block even if nothing is hooked" do
|
53
|
+
called = false
|
54
|
+
subject.run_hook(:before_save) do
|
55
|
+
called = true
|
56
|
+
end
|
57
|
+
called.must_equal true
|
58
|
+
end
|
51
59
|
end
|
52
60
|
|
53
61
|
describe "#reset_hooks" do
|
data/test/spinach/hooks_test.rb
CHANGED
@@ -7,7 +7,7 @@ describe Spinach::Hooks do
|
|
7
7
|
|
8
8
|
describe "hooks" do
|
9
9
|
%w{before_run after_run before_feature after_feature on_undefined_feature
|
10
|
-
before_scenario after_scenario before_step after_step on_successful_step
|
10
|
+
before_scenario around_scenario after_scenario before_step after_step on_successful_step
|
11
11
|
on_failed_step on_error_step on_undefined_step on_skipped_step}.each do |callback|
|
12
12
|
describe "#{callback}" do
|
13
13
|
it "responds to #{callback}" do
|
@@ -26,11 +26,10 @@ describe Spinach::Hooks do
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
29
30
|
describe "#on_tag" do
|
30
|
-
let(:
|
31
|
-
|
32
|
-
'tags' => [{'name' => '@javascript'}, {'name' => '@capture'}]
|
33
|
-
}
|
31
|
+
let(:scenario) do
|
32
|
+
stub(tags: ['javascript', 'capture'])
|
34
33
|
end
|
35
34
|
|
36
35
|
it "calls the block if the scenario includes the tag" do
|
@@ -38,7 +37,7 @@ describe Spinach::Hooks do
|
|
38
37
|
subject.on_tag('javascript') do
|
39
38
|
assertion = true
|
40
39
|
end
|
41
|
-
subject.run_before_scenario(
|
40
|
+
subject.run_before_scenario(scenario)
|
42
41
|
assertion.must_equal true
|
43
42
|
end
|
44
43
|
|
@@ -47,7 +46,7 @@ describe Spinach::Hooks do
|
|
47
46
|
subject.on_tag('screenshot') do
|
48
47
|
assertion = true
|
49
48
|
end
|
50
|
-
subject.run_before_scenario(
|
49
|
+
subject.run_before_scenario(scenario)
|
51
50
|
assertion.wont_equal true
|
52
51
|
end
|
53
52
|
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Spinach
|
4
|
+
class Parser
|
5
|
+
describe Visitor do
|
6
|
+
let(:feature) { Feature.new }
|
7
|
+
let(:visitor) { Visitor.new }
|
8
|
+
|
9
|
+
describe '#visit' do
|
10
|
+
it 'makes ast accept self' do
|
11
|
+
ast = stub('AST')
|
12
|
+
ast.expects(:accept).with(visitor)
|
13
|
+
|
14
|
+
visitor.visit(ast)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'returns the feature' do
|
18
|
+
ast = stub_everything
|
19
|
+
visitor.instance_variable_set(:@feature, feature)
|
20
|
+
visitor.visit(ast).must_equal feature
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#visit_Feature' do
|
25
|
+
before do
|
26
|
+
@background = stub_everything
|
27
|
+
@scenarios = [stub_everything, stub_everything, stub_everything]
|
28
|
+
@node = stub(scenarios: @scenarios, name: 'Go shopping', background: @background)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'sets the name' do
|
32
|
+
visitor.visit_Feature(@node)
|
33
|
+
visitor.feature.name.must_equal 'Go shopping'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'iterates over its children' do
|
37
|
+
@scenarios.each do |scenario|
|
38
|
+
scenario.expects(:accept).with visitor
|
39
|
+
end
|
40
|
+
|
41
|
+
visitor.visit_Feature(@node)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#visit_Scenario' do
|
46
|
+
before do
|
47
|
+
@steps = [stub_everything, stub_everything, stub_everything]
|
48
|
+
@tags = [stub_everything, stub_everything, stub_everything]
|
49
|
+
@node = stub(
|
50
|
+
tags: @tags,
|
51
|
+
steps: @steps,
|
52
|
+
name: 'Go shopping on Saturday morning',
|
53
|
+
line: 3
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'adds the scenario to the feature' do
|
58
|
+
visitor.visit_Scenario(@node)
|
59
|
+
visitor.feature.scenarios.length.must_equal 1
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'sets the name' do
|
63
|
+
visitor.visit_Scenario(@node)
|
64
|
+
visitor.feature.scenarios.first.name.must_equal 'Go shopping on Saturday morning'
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'sets the line' do
|
68
|
+
visitor.visit_Scenario(@node)
|
69
|
+
visitor.feature.scenarios.first.line.must_equal 3
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'sets the tags' do
|
73
|
+
@tags.each do |step|
|
74
|
+
step.expects(:accept).with visitor
|
75
|
+
end
|
76
|
+
visitor.visit_Scenario(@node)
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'iterates over its children' do
|
80
|
+
@steps.each do |step|
|
81
|
+
step.expects(:accept).with visitor
|
82
|
+
end
|
83
|
+
visitor.visit_Scenario(@node)
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#visit_Background' do
|
89
|
+
before do
|
90
|
+
@steps = [stub_everything, stub_everything, stub_everything]
|
91
|
+
@node = stub(
|
92
|
+
steps: @steps,
|
93
|
+
line: 3
|
94
|
+
)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'adds the background to the feature' do
|
98
|
+
visitor.visit_Background(@node)
|
99
|
+
visitor.feature.background.must_be_kind_of Background
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'sets the line' do
|
103
|
+
visitor.visit_Background(@node)
|
104
|
+
visitor.feature.background.line.must_equal 3
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'iterates over its children' do
|
108
|
+
@steps.each do |step|
|
109
|
+
step.expects(:accept).with visitor
|
110
|
+
end
|
111
|
+
visitor.visit_Background(@node)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'visits the background' do
|
115
|
+
visitor.visit_Background(@node)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe '#visit_Tag' do
|
120
|
+
it 'adds the tag to the current scenario' do
|
121
|
+
tags = ['tag1', 'tag2', 'tag3']
|
122
|
+
scenario = stub(tags: tags)
|
123
|
+
visitor.instance_variable_set(:@current_scenario, scenario)
|
124
|
+
|
125
|
+
visitor.visit_Tag(stub(name: 'tag4'))
|
126
|
+
scenario.tags.must_equal ['tag1', 'tag2', 'tag3', 'tag4']
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe '#visit_Step' do
|
131
|
+
before do
|
132
|
+
@node = stub(name: 'Baz', line: 3, keyword: 'Given')
|
133
|
+
@steps = [stub(name: 'Foo'), stub(name: 'Bar')]
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'adds the step to the step set' do
|
137
|
+
step_set = stub(steps: @steps)
|
138
|
+
visitor.instance_variable_set(:@current_step_set, step_set)
|
139
|
+
|
140
|
+
visitor.visit_Step(@node)
|
141
|
+
step_set.steps.length.must_equal 3
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'sets the name' do
|
145
|
+
step_set = stub(steps: [])
|
146
|
+
visitor.instance_variable_set(:@current_step_set, step_set)
|
147
|
+
|
148
|
+
visitor.visit_Step(@node)
|
149
|
+
|
150
|
+
step_set.steps.first.name.must_equal 'Baz'
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'sets the keyword' do
|
154
|
+
step_set = stub(steps: [])
|
155
|
+
visitor.instance_variable_set(:@current_step_set, step_set)
|
156
|
+
|
157
|
+
visitor.visit_Step(@node)
|
158
|
+
|
159
|
+
step_set.steps.first.keyword.must_equal 'Given'
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'sets the line' do
|
163
|
+
step_set = stub(steps: [])
|
164
|
+
visitor.instance_variable_set(:@current_step_set, step_set)
|
165
|
+
|
166
|
+
visitor.visit_Step(@node)
|
167
|
+
|
168
|
+
step_set.steps.first.line.must_equal 3
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|