spinach 0.10.1 → 0.12.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.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +30 -0
- data/.ruby-version +1 -1
- data/.tool-versions +1 -0
- data/Gemfile +0 -1
- data/README.markdown +35 -38
- data/Rakefile +1 -1
- data/bin/spinach +1 -1
- data/features/feature_hooks_and_tags.feature +22 -0
- data/features/randomization.feature +16 -0
- data/features/reporting/display_run_summary.feature +19 -3
- data/features/steps/automatic_feature_generation.rb +1 -1
- data/features/steps/feature_hooks_and_tags.rb +55 -0
- data/features/steps/randomizing_features_scenarios.rb +68 -0
- data/features/steps/reporting/display_run_summary.rb +29 -1
- data/features/support/env.rb +0 -13
- data/features/support/spinach_runner.rb +11 -0
- data/lib/spinach/cli.rb +29 -2
- data/lib/spinach/config.rb +25 -0
- data/lib/spinach/feature.rb +8 -0
- data/lib/spinach/orderers/default.rb +25 -0
- data/lib/spinach/orderers/random.rb +35 -0
- data/lib/spinach/orderers.rb +2 -0
- data/lib/spinach/reporter/progress.rb +1 -1
- data/lib/spinach/reporter/reporting.rb +3 -1
- data/lib/spinach/reporter/stdout.rb +1 -1
- data/lib/spinach/reporter.rb +1 -0
- data/lib/spinach/runner/feature_runner.rb +7 -3
- data/lib/spinach/runner.rb +40 -17
- data/lib/spinach/scenario.rb +10 -0
- data/lib/spinach/tags_matcher.rb +11 -2
- data/lib/spinach/version.rb +1 -1
- data/lib/spinach.rb +1 -0
- data/spinach.gemspec +4 -5
- data/test/spinach/cli_test.rb +39 -5
- data/test/spinach/config_test.rb +22 -0
- data/test/spinach/dsl_test.rb +1 -1
- data/test/spinach/feature_test.rb +10 -0
- data/test/spinach/generators/feature_generator_test.rb +1 -1
- data/test/spinach/hooks_test.rb +1 -1
- data/test/spinach/orderers/default_test.rb +31 -0
- data/test/spinach/orderers/random_test.rb +39 -0
- data/test/spinach/reporter_test.rb +2 -2
- data/test/spinach/runner_test.rb +28 -8
- data/test/spinach/scenario_test.rb +14 -0
- data/test/test_helper.rb +1 -14
- metadata +26 -40
- data/.travis.yml +0 -8
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'digest'
|
2
|
+
|
3
|
+
module Spinach
|
4
|
+
module Orderers
|
5
|
+
class Random
|
6
|
+
attr_reader :seed
|
7
|
+
|
8
|
+
def initialize(seed:)
|
9
|
+
@seed = seed.to_s
|
10
|
+
end
|
11
|
+
|
12
|
+
# Output the randomization seed in the report summary.
|
13
|
+
#
|
14
|
+
# @param [IO] io
|
15
|
+
# Output buffer for report.
|
16
|
+
#
|
17
|
+
# @api public
|
18
|
+
def attach_summary(io)
|
19
|
+
io.puts("Randomized with seed #{seed}\n\n")
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns a reordered version of the provided array
|
23
|
+
#
|
24
|
+
# @param [Array] items
|
25
|
+
# Items to order
|
26
|
+
#
|
27
|
+
# @api public
|
28
|
+
def order(items)
|
29
|
+
items.sort_by do |item|
|
30
|
+
Digest::MD5.hexdigest(seed + item.ordering_id)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -221,7 +221,9 @@ module Spinach
|
|
221
221
|
error_summary = format_summary(:red, error_steps, 'Error')
|
222
222
|
|
223
223
|
out.puts "Steps Summary: #{successful_summary}, #{pending_summary}, #{undefined_summary}, #{failed_summary}, #{error_summary}\n\n"
|
224
|
-
out.puts "Finished in #{Time.now - @start_time} seconds" if @start_time
|
224
|
+
out.puts "Finished in #{Time.now - @start_time} seconds\n\n" if @start_time
|
225
|
+
|
226
|
+
@orderer.attach_summary(out) if @orderer
|
225
227
|
end
|
226
228
|
end
|
227
229
|
end
|
data/lib/spinach/reporter.rb
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
require_relative '../tags_matcher'
|
2
|
+
require 'spinach/orderers/default'
|
2
3
|
|
3
4
|
module Spinach
|
4
5
|
class Runner
|
5
6
|
# A feature runner handles a particular feature run.
|
6
7
|
#
|
7
8
|
class FeatureRunner
|
8
|
-
attr_reader :feature
|
9
|
+
attr_reader :feature, :orderer
|
9
10
|
|
10
11
|
# @param [GherkinRuby::AST::Feature] feature
|
11
12
|
# The feature to run.
|
12
13
|
#
|
13
14
|
# @api public
|
14
|
-
def initialize(feature)
|
15
|
+
def initialize(feature, orderer: Spinach::Orderers::Default.new)
|
15
16
|
@feature = feature
|
17
|
+
@orderer = orderer
|
16
18
|
end
|
17
19
|
|
18
20
|
# @return [String]
|
@@ -80,7 +82,7 @@ module Spinach
|
|
80
82
|
end
|
81
83
|
|
82
84
|
def scenarios_to_run
|
83
|
-
feature.scenarios.select do |scenario|
|
85
|
+
unordered_scenarios = feature.scenarios.select do |scenario|
|
84
86
|
has_a_tag_that_will_be_run = TagsMatcher.match(feature_tags + scenario.tags)
|
85
87
|
on_a_line_that_will_be_run = if feature.run_every_scenario?
|
86
88
|
true
|
@@ -90,6 +92,8 @@ module Spinach
|
|
90
92
|
|
91
93
|
has_a_tag_that_will_be_run && on_a_line_that_will_be_run
|
92
94
|
end
|
95
|
+
|
96
|
+
orderer.order(unordered_scenarios)
|
93
97
|
end
|
94
98
|
end
|
95
99
|
end
|
data/lib/spinach/runner.rb
CHANGED
@@ -30,10 +30,10 @@ module Spinach
|
|
30
30
|
def initialize(filenames, options = {})
|
31
31
|
@filenames = filenames
|
32
32
|
|
33
|
-
@step_definitions_path = options.delete(:step_definitions_path
|
33
|
+
@step_definitions_path = options.delete(:step_definitions_path) ||
|
34
34
|
Spinach.config.step_definitions_path
|
35
35
|
|
36
|
-
@support_path = options.delete(:support_path
|
36
|
+
@support_path = options.delete(:support_path) ||
|
37
37
|
Spinach.config.support_path
|
38
38
|
end
|
39
39
|
|
@@ -42,7 +42,9 @@ module Spinach
|
|
42
42
|
# @api public
|
43
43
|
def init_reporters
|
44
44
|
Spinach.config[:reporter_classes].each do |reporter_class|
|
45
|
-
|
45
|
+
reporter_options = default_reporter_options.merge(Spinach.config.reporter_options)
|
46
|
+
reporter = Support.constantize(reporter_class).new(reporter_options)
|
47
|
+
|
46
48
|
reporter.bind
|
47
49
|
end
|
48
50
|
end
|
@@ -58,24 +60,12 @@ module Spinach
|
|
58
60
|
require_frameworks
|
59
61
|
init_reporters
|
60
62
|
|
61
|
-
features = filenames.map do |filename|
|
62
|
-
file, *lines = filename.split(":") # little more complex than just a "filename"
|
63
|
-
|
64
|
-
# FIXME Feature should be instantiated directly, not through an unrelated class method
|
65
|
-
feature = Parser.open_file(file).parse
|
66
|
-
feature.filename = file
|
67
|
-
|
68
|
-
feature.lines_to_run = lines if lines.any?
|
69
|
-
|
70
|
-
feature
|
71
|
-
end
|
72
|
-
|
73
63
|
suite_passed = true
|
74
64
|
|
75
65
|
Spinach.hooks.run_before_run
|
76
66
|
|
77
|
-
|
78
|
-
feature_passed = FeatureRunner.new(feature).run
|
67
|
+
features_to_run.each do |feature|
|
68
|
+
feature_passed = FeatureRunner.new(feature, orderer: orderer).run
|
79
69
|
suite_passed &&= feature_passed
|
80
70
|
|
81
71
|
break if fail_fast? && !feature_passed
|
@@ -139,11 +129,44 @@ module Spinach
|
|
139
129
|
support_files + step_definition_files
|
140
130
|
end
|
141
131
|
|
132
|
+
# The orderer for this run.
|
133
|
+
#
|
134
|
+
# @api public
|
135
|
+
def orderer
|
136
|
+
@orderer ||= Support.constantize(Spinach.config[:orderer_class]).new(
|
137
|
+
seed: Spinach.config.seed
|
138
|
+
)
|
139
|
+
end
|
140
|
+
|
141
|
+
# Default initialization options for the reporter
|
142
|
+
#
|
143
|
+
def default_reporter_options
|
144
|
+
{orderer: orderer}
|
145
|
+
end
|
146
|
+
|
142
147
|
private
|
143
148
|
|
144
149
|
def fail_fast?
|
145
150
|
Spinach.config.fail_fast
|
146
151
|
end
|
152
|
+
|
153
|
+
def features_to_run
|
154
|
+
unordered_features = filenames.reduce([]) do |features, filename|
|
155
|
+
file, *lines = filename.split(":") # little more complex than just a "filename"
|
156
|
+
|
157
|
+
# FIXME Feature should be instantiated directly, not through an unrelated class method
|
158
|
+
feature = Parser.open_file(file).parse
|
159
|
+
feature.filename = file
|
160
|
+
|
161
|
+
feature.lines_to_run = lines if lines.any?
|
162
|
+
|
163
|
+
features << feature if TagsMatcher.match_feature(feature)
|
164
|
+
|
165
|
+
features
|
166
|
+
end
|
167
|
+
|
168
|
+
orderer.order(unordered_features)
|
169
|
+
end
|
147
170
|
end
|
148
171
|
end
|
149
172
|
|
data/lib/spinach/scenario.rb
CHANGED
@@ -9,5 +9,15 @@ module Spinach
|
|
9
9
|
@tags = []
|
10
10
|
@lines = []
|
11
11
|
end
|
12
|
+
|
13
|
+
# Identifier used by orderers.
|
14
|
+
#
|
15
|
+
# Needs to involve the relative file path and line number so that the
|
16
|
+
# ordering a seed generates is stable across both runs and machines.
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
def ordering_id
|
20
|
+
"#{feature.ordering_id}:#{lines.first}"
|
21
|
+
end
|
12
22
|
end
|
13
23
|
end
|
data/lib/spinach/tags_matcher.rb
CHANGED
@@ -6,9 +6,9 @@ module Spinach
|
|
6
6
|
class << self
|
7
7
|
|
8
8
|
# Matches an array of tags (e.g. of a scenario) against the tags present
|
9
|
-
# in Spinach' runtime options.
|
9
|
+
# in Spinach's runtime options.
|
10
10
|
#
|
11
|
-
# Spinach' tag option is an array which consists of (possibly) multiple
|
11
|
+
# Spinach's tag option is an array which consists of (possibly) multiple
|
12
12
|
# arrays containing tags provided by the user running the features and
|
13
13
|
# scenarios. Each of these arrays is considered a tag group.
|
14
14
|
#
|
@@ -23,6 +23,15 @@ module Spinach
|
|
23
23
|
}
|
24
24
|
end
|
25
25
|
|
26
|
+
# Matches the tags of a feature (and its scenarios) against the tags present
|
27
|
+
# in Spinach's runtime options.
|
28
|
+
#
|
29
|
+
# A feature matches when, for any of its scenarios, the combination of the
|
30
|
+
# feature's tags and that scenario's tags match the configured tags.
|
31
|
+
def match_feature(feature)
|
32
|
+
feature.scenarios.any? { |scenario| match(feature.tags + scenario.tags) }
|
33
|
+
end
|
34
|
+
|
26
35
|
private
|
27
36
|
|
28
37
|
def tag_groups
|
data/lib/spinach/version.rb
CHANGED
data/lib/spinach.rb
CHANGED
@@ -9,6 +9,7 @@ require_relative 'spinach/parser'
|
|
9
9
|
require_relative 'spinach/dsl'
|
10
10
|
require_relative 'spinach/feature_steps'
|
11
11
|
require_relative 'spinach/reporter'
|
12
|
+
require_relative 'spinach/orderers'
|
12
13
|
require_relative 'spinach/cli'
|
13
14
|
require_relative 'spinach/generators'
|
14
15
|
require_relative 'spinach/auditor'
|
data/spinach.gemspec
CHANGED
@@ -3,8 +3,7 @@ require File.expand_path('../lib/spinach/version', __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
5
|
gem.authors = ["Josep Jaume Rey", "Josep M. Bach", "Oriol Gual", "Marc Divins Castellvi"]
|
6
|
-
gem.email = ["
|
7
|
-
"oriolgual@gmail.com", "josepjaume@gmail.com", "marcdivc@gmail.com"]
|
6
|
+
gem.email = ["josep.m.bach@gmail.com", "oriolgual@gmail.com", "josepjaume@gmail.com", "marcdivc@gmail.com"]
|
8
7
|
gem.description = %q{Spinach is a BDD framework on top of gherkin}
|
9
8
|
gem.summary = %q{Spinach is a BDD framework on top of gherkin}
|
10
9
|
gem.homepage = "http://github.com/codegram/spinach"
|
@@ -12,17 +11,17 @@ Gem::Specification.new do |gem|
|
|
12
11
|
|
13
12
|
gem.add_runtime_dependency 'gherkin-ruby', '>= 0.3.2'
|
14
13
|
gem.add_runtime_dependency 'colorize'
|
15
|
-
gem.add_runtime_dependency 'json'
|
16
14
|
gem.add_development_dependency 'rake'
|
17
|
-
gem.add_development_dependency 'mocha',
|
15
|
+
gem.add_development_dependency 'mocha', "~> 1.5.0"
|
18
16
|
gem.add_development_dependency 'sinatra'
|
19
17
|
gem.add_development_dependency 'capybara'
|
20
18
|
gem.add_development_dependency 'pry'
|
21
|
-
gem.add_development_dependency 'simplecov'
|
22
19
|
gem.add_development_dependency 'rspec'
|
23
20
|
gem.add_development_dependency 'minitest', '< 5.0'
|
24
21
|
gem.add_development_dependency 'fakefs', ">= 0.5.2"
|
25
22
|
|
23
|
+
gem.required_ruby_version = Gem::Requirement.new(">= 2.4".freeze)
|
24
|
+
|
26
25
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
27
26
|
gem.files = `git ls-files`.split("\n")
|
28
27
|
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/test/spinach/cli_test.rb
CHANGED
@@ -89,6 +89,40 @@ tags:
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
+
describe 'rand' do
|
93
|
+
let(:config) { Spinach::Config.new }
|
94
|
+
|
95
|
+
before do
|
96
|
+
Spinach.stubs(:config).returns(config)
|
97
|
+
Spinach::Cli.new(%w(--rand)).options
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'uses the Random orderer' do
|
101
|
+
config.orderer_class.must_equal 'Spinach::Orderers::Random'
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'sets a numeric seed' do
|
105
|
+
config.seed.must_equal config.seed.to_i
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe 'seed' do
|
110
|
+
let(:config) { Spinach::Config.new }
|
111
|
+
|
112
|
+
before do
|
113
|
+
Spinach.stubs(:config).returns(config)
|
114
|
+
Spinach::Cli.new(%w(--seed 42)).options
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'uses the random orderer' do
|
118
|
+
config.orderer_class.must_equal 'Spinach::Orderers::Random'
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'sets the seed' do
|
122
|
+
config.seed.must_equal 42
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
92
126
|
describe 'features_path' do
|
93
127
|
%w{-f --features_path}.each do |opt|
|
94
128
|
it 'sets the given features_path' do
|
@@ -242,14 +276,14 @@ tags:
|
|
242
276
|
describe 'the feature really exists' do
|
243
277
|
it 'runs the feature' do
|
244
278
|
cli = Spinach::Cli.new(['features/some_feature.feature'])
|
245
|
-
File.stubs(:
|
279
|
+
File.stubs(:exist?).returns(true)
|
246
280
|
cli.feature_files.must_equal ['features/some_feature.feature']
|
247
281
|
end
|
248
282
|
end
|
249
283
|
|
250
284
|
it 'it fails if the feature does not exist' do
|
251
285
|
cli = Spinach::Cli.new(['features/some_feature.feature'])
|
252
|
-
File.stubs(:
|
286
|
+
File.stubs(:exist?).returns(false)
|
253
287
|
cli.expects(:fail!).with('features/some_feature.feature could not be found')
|
254
288
|
|
255
289
|
cli.feature_files
|
@@ -259,7 +293,7 @@ tags:
|
|
259
293
|
describe 'when a particular feature list is passed with line' do
|
260
294
|
it 'returns the feature with the line number' do
|
261
295
|
cli = Spinach::Cli.new(['features/some_feature.feature:10'])
|
262
|
-
File.stubs(:
|
296
|
+
File.stubs(:exist?).returns(true)
|
263
297
|
|
264
298
|
cli.feature_files.must_equal ['features/some_feature.feature:10']
|
265
299
|
end
|
@@ -268,7 +302,7 @@ tags:
|
|
268
302
|
describe "when a particular feature list is passed with multiple lines" do
|
269
303
|
it "returns the feature with the line numbers" do
|
270
304
|
cli = Spinach::Cli.new(['features/some_feature.feature:10:20'])
|
271
|
-
File.stubs(:
|
305
|
+
File.stubs(:exist?).returns(true)
|
272
306
|
|
273
307
|
cli.feature_files.must_equal ["features/some_feature.feature:10:20"]
|
274
308
|
end
|
@@ -303,7 +337,7 @@ tags:
|
|
303
337
|
Dir.expects(:glob).with('path/to/features/**/*.feature')
|
304
338
|
.returns(['several features'])
|
305
339
|
|
306
|
-
File.stubs(:
|
340
|
+
File.stubs(:exist?).returns(true)
|
307
341
|
|
308
342
|
cli.feature_files.must_equal ['several features', 'some_feature.feature']
|
309
343
|
end
|
data/test/spinach/config_test.rb
CHANGED
@@ -27,6 +27,28 @@ describe Spinach::Config do
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
describe '#orderer_class' do
|
31
|
+
it 'returns a default' do
|
32
|
+
subject[:orderer_class].must_equal "Spinach::Orderers::Default"
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'can be overwritten' do
|
36
|
+
subject[:orderer_class] = "MyOwnOrderer"
|
37
|
+
subject[:orderer_class].must_equal "MyOwnOrderer"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#seed' do
|
42
|
+
it 'has a default' do
|
43
|
+
subject[:seed].must_be_kind_of Integer
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'can be overwritten' do
|
47
|
+
subject[:seed] = 54321
|
48
|
+
subject[:seed].must_equal 54321
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
30
52
|
describe '#step_definitions_path' do
|
31
53
|
it 'returns a default' do
|
32
54
|
subject[:step_definitions_path].must_be_kind_of String
|
data/test/spinach/dsl_test.rb
CHANGED
@@ -157,7 +157,7 @@ describe Spinach::DSL do
|
|
157
157
|
end
|
158
158
|
|
159
159
|
@feature.new.step_location_for('I say goodbye').first.must_include '/dsl_test.rb'
|
160
|
-
@feature.new.step_location_for('I say goodbye').last.must_be_kind_of
|
160
|
+
@feature.new.step_location_for('I say goodbye').last.must_be_kind_of Integer
|
161
161
|
end
|
162
162
|
end
|
163
163
|
end
|
@@ -29,5 +29,15 @@ module Spinach
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
32
|
+
|
33
|
+
describe "#ordering_id" do
|
34
|
+
subject { Feature.new }
|
35
|
+
|
36
|
+
before { subject.filename = "features/foo/bar.feature" }
|
37
|
+
|
38
|
+
it 'is the filename' do
|
39
|
+
subject.ordering_id.must_equal "features/foo/bar.feature"
|
40
|
+
end
|
41
|
+
end
|
32
42
|
end
|
33
43
|
end
|
@@ -71,7 +71,7 @@ Feature: Cheezburger can I has
|
|
71
71
|
in_current_dir do
|
72
72
|
subject.store
|
73
73
|
File.directory?("features/steps/").must_equal true
|
74
|
-
File.
|
74
|
+
File.exist?("features/steps/cheezburger_can_i_has.rb").must_equal true
|
75
75
|
File.read("features/steps/cheezburger_can_i_has.rb").strip.must_equal(
|
76
76
|
subject.generate.strip
|
77
77
|
)
|
data/test/spinach/hooks_test.rb
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative '../../test_helper'
|
2
|
+
|
3
|
+
describe Spinach::Orderers::Default do
|
4
|
+
let(:orderer) { Spinach::Orderers::Default.new }
|
5
|
+
|
6
|
+
describe "#attach_summary" do
|
7
|
+
let(:io) { StringIO.new }
|
8
|
+
|
9
|
+
it 'appends nothing' do
|
10
|
+
contents_before_running = io.string.dup
|
11
|
+
|
12
|
+
orderer.attach_summary(io)
|
13
|
+
|
14
|
+
io.string.must_equal contents_before_running
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#order" do
|
19
|
+
let(:items) { Array(1..10) }
|
20
|
+
|
21
|
+
it "doesn't change the order of the items" do
|
22
|
+
orderer.order(items).must_equal items
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#initialize" do
|
27
|
+
it "can be provided options without raising an error" do
|
28
|
+
Spinach::Orderers::Default.new(seed: "seed")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative '../../test_helper'
|
2
|
+
|
3
|
+
describe Spinach::Orderers::Random do
|
4
|
+
let(:orderer) { Spinach::Orderers::Random.new(seed: Spinach.config.seed) }
|
5
|
+
|
6
|
+
describe "#attach_summary" do
|
7
|
+
let(:io) { StringIO.new }
|
8
|
+
|
9
|
+
it 'appends the seed' do
|
10
|
+
orderer.attach_summary(io)
|
11
|
+
|
12
|
+
io.string.must_match /Randomized\ with\ seed\ #{orderer.seed}/
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#order" do
|
17
|
+
Identifiable = Struct.new(:ordering_id)
|
18
|
+
|
19
|
+
let(:items) { (1..10).map { |n| Identifiable.new(n.to_s) } }
|
20
|
+
|
21
|
+
it "randomizes the items" do
|
22
|
+
orderer.order(items).wont_equal items
|
23
|
+
end
|
24
|
+
|
25
|
+
it "always randomizes items the same way with the same seed" do
|
26
|
+
orderer.order(items).must_equal orderer.order(items)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#initialize" do
|
31
|
+
it "requires a seed parameter" do
|
32
|
+
proc {
|
33
|
+
Spinach::Orderers::Random.new
|
34
|
+
}.must_raise ArgumentError
|
35
|
+
|
36
|
+
Spinach::Orderers::Random.new(seed: 4)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -89,8 +89,8 @@ module Spinach
|
|
89
89
|
|
90
90
|
it "binds a callback around every scenario" do
|
91
91
|
@reporter.expects(:around_scenario_run)
|
92
|
-
Spinach.hooks.run_around_scenario(anything) do
|
93
|
-
|
92
|
+
Spinach.hooks.run_around_scenario(anything) do |&block|
|
93
|
+
block.call
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
data/test/spinach/runner_test.rb
CHANGED
@@ -65,7 +65,10 @@ describe Spinach::Runner do
|
|
65
65
|
config.reporter_options = {backtrace: true}
|
66
66
|
reporter = stub
|
67
67
|
reporter.stubs(:bind)
|
68
|
-
Spinach::Reporter::Stdout.expects(new: reporter).with(
|
68
|
+
Spinach::Reporter::Stdout.expects(new: reporter).with(
|
69
|
+
backtrace: true,
|
70
|
+
**runner.default_reporter_options
|
71
|
+
)
|
69
72
|
runner.init_reporters
|
70
73
|
end
|
71
74
|
end
|
@@ -74,15 +77,21 @@ describe Spinach::Runner do
|
|
74
77
|
describe '#run' do
|
75
78
|
before(:each) do
|
76
79
|
@feature_runner = stub
|
80
|
+
@feature_runner.stubs(:run).returns(true)
|
81
|
+
|
77
82
|
filenames.each do |filename|
|
78
|
-
|
79
|
-
|
83
|
+
parser = stub
|
84
|
+
Spinach::Parser.stubs(:open_file).with(filename).returns(parser)
|
85
|
+
|
86
|
+
feature = Spinach::Feature.new
|
87
|
+
feature.scenarios << Spinach::Scenario.new(feature)
|
88
|
+
parser.stubs(:parse).returns(feature)
|
89
|
+
|
80
90
|
Spinach::Runner::FeatureRunner.stubs(:new).
|
81
91
|
with(feature, anything).
|
82
92
|
returns(@feature_runner)
|
83
93
|
end
|
84
94
|
|
85
|
-
@feature_runner.stubs(:run).returns(true)
|
86
95
|
runner.stubs(required_files: [])
|
87
96
|
end
|
88
97
|
|
@@ -130,12 +139,18 @@ describe Spinach::Runner do
|
|
130
139
|
let(:runner) { Spinach::Runner.new(filenames) }
|
131
140
|
|
132
141
|
before(:each) do
|
142
|
+
parser = stub
|
143
|
+
Spinach::Parser.stubs(:open_file).with(filename).returns(parser)
|
144
|
+
|
145
|
+
@feature = Spinach::Feature.new
|
146
|
+
@feature.scenarios << Spinach::Scenario.new(@feature)
|
147
|
+
parser.stubs(:parse).returns(@feature)
|
148
|
+
|
133
149
|
@feature_runner = stub
|
134
|
-
Spinach::Parser.stubs(:open_file).with(filename).returns parser = stub
|
135
|
-
parser.stubs(:parse).returns @feature = Spinach::Feature.new
|
136
150
|
Spinach::Runner::FeatureRunner.stubs(:new).
|
137
151
|
with(@feature, anything).
|
138
152
|
returns(@feature_runner)
|
153
|
+
|
139
154
|
runner.stubs(required_files: [])
|
140
155
|
end
|
141
156
|
|
@@ -171,8 +186,13 @@ describe Spinach::Runner do
|
|
171
186
|
|
172
187
|
before(:each) do
|
173
188
|
filenames.each_with_index do |filename, i|
|
174
|
-
|
175
|
-
|
189
|
+
parser = stub
|
190
|
+
Spinach::Parser.stubs(:open_file).with(filename).returns(parser)
|
191
|
+
|
192
|
+
feature = Spinach::Feature.new
|
193
|
+
feature.scenarios << Spinach::Scenario.new(feature)
|
194
|
+
parser.stubs(:parse).returns(feature)
|
195
|
+
|
176
196
|
Spinach::Runner::FeatureRunner.stubs(:new).
|
177
197
|
with(feature, anything).
|
178
198
|
returns(feature_runners[i])
|
@@ -2,5 +2,19 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
module Spinach
|
4
4
|
describe Scenario do
|
5
|
+
describe "#ordering_id" do
|
6
|
+
let(:feature) { Feature.new }
|
7
|
+
|
8
|
+
subject { Scenario.new(feature) }
|
9
|
+
|
10
|
+
before do
|
11
|
+
feature.filename = "features/foo/bar.feature"
|
12
|
+
subject.lines = Array(4..12)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'is the filename and starting line number' do
|
16
|
+
subject.ordering_id.must_equal "features/foo/bar.feature:4"
|
17
|
+
end
|
18
|
+
end
|
5
19
|
end
|
6
20
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,19 +1,6 @@
|
|
1
|
-
require 'simplecov'
|
2
|
-
require 'coveralls'
|
3
|
-
|
4
|
-
SimpleCov.formatter = Coveralls::SimpleCov::Formatter
|
5
|
-
if ENV['CI'] && !defined?(Rubinius)
|
6
|
-
require 'simplecov'
|
7
|
-
|
8
|
-
SimpleCov.start do
|
9
|
-
add_filter '/test/'
|
10
|
-
add_filter '/features/'
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
1
|
require 'minitest/autorun'
|
15
2
|
require 'minitest/spec'
|
16
|
-
require 'mocha/
|
3
|
+
require 'mocha/minitest'
|
17
4
|
require 'ostruct'
|
18
5
|
require 'stringio'
|
19
6
|
require 'pry'
|