cuke_iterations 0.0.1 → 0.0.2
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 +1 -1
- data/Gemfile.lock +14 -19
- data/README.md +3 -5
- data/bin/cuke_iterations +7 -12
- data/changelog.md +7 -0
- data/example/features/{i_love_cukes.feature → subdirectory/i_love_cukes.feature} +0 -0
- data/lib/cuke_iterations.rb +5 -1
- data/lib/cuke_iterations/cuke_parser.rb +7 -1
- data/lib/cuke_iterations/iteration_file_finder.rb +17 -0
- data/lib/cuke_iterations/scenario_file_writer.rb +20 -0
- data/lib/cuke_iterations/scenario_list_generator.rb +16 -4
- data/lib/cuke_iterations/version.rb +1 -1
- data/spec/cuke_parser_spec.rb +7 -7
- data/spec/scenario_file_writer_spec.rb +0 -0
- data/spec/scenario_list_generator_spec.rb +12 -0
- metadata +11 -6
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,30 +1,25 @@
|
|
1
|
-
GIT
|
2
|
-
remote: git://github.com/rspec/rspec-expectations.git
|
3
|
-
revision: 0b63bf446ce84a613875417121980492571bfa90
|
4
|
-
specs:
|
5
|
-
rspec-expectations (2.6.0)
|
6
|
-
diff-lcs (~> 1.1.2)
|
7
|
-
|
8
1
|
PATH
|
9
2
|
remote: .
|
10
3
|
specs:
|
11
|
-
cuke_iterations (0.0.
|
4
|
+
cuke_iterations (0.0.2)
|
12
5
|
gherkin
|
13
6
|
|
14
7
|
GEM
|
15
8
|
remote: http://rubygems.org/
|
16
9
|
specs:
|
17
|
-
diff-lcs (1.1.
|
18
|
-
gherkin (2.
|
10
|
+
diff-lcs (1.1.3)
|
11
|
+
gherkin (2.7.6)
|
19
12
|
json (>= 1.4.6)
|
20
|
-
json (1.5
|
21
|
-
rake (0.9.2)
|
22
|
-
rspec (2.
|
23
|
-
rspec-core (~> 2.
|
24
|
-
rspec-expectations (~> 2.
|
25
|
-
rspec-mocks (~> 2.
|
26
|
-
rspec-core (2.
|
27
|
-
rspec-
|
13
|
+
json (1.6.5)
|
14
|
+
rake (0.9.2.2)
|
15
|
+
rspec (2.8.0)
|
16
|
+
rspec-core (~> 2.8.0)
|
17
|
+
rspec-expectations (~> 2.8.0)
|
18
|
+
rspec-mocks (~> 2.8.0)
|
19
|
+
rspec-core (2.8.0)
|
20
|
+
rspec-expectations (2.8.0)
|
21
|
+
diff-lcs (~> 1.1.2)
|
22
|
+
rspec-mocks (2.8.0)
|
28
23
|
|
29
24
|
PLATFORMS
|
30
25
|
ruby
|
@@ -33,4 +28,4 @@ DEPENDENCIES
|
|
33
28
|
cuke_iterations!
|
34
29
|
rake (>= 0.9.2)
|
35
30
|
rspec
|
36
|
-
rspec-expectations
|
31
|
+
rspec-expectations
|
data/README.md
CHANGED
@@ -48,12 +48,10 @@ android:
|
|
48
48
|
- ! '@iphone_only'
|
49
49
|
```
|
50
50
|
|
51
|
-
|
51
|
+
If you specify an empty array for `include_tags`, then all scenarios will be included. Excluded tags have priority over included ones (e.g. an `@iphone_only` scenario would not be included in the `android` iteration, even if it had the `@mobile` tag.
|
52
52
|
|
53
53
|
### Running it
|
54
54
|
|
55
|
-
`cd features`
|
56
|
-
|
57
55
|
With defaults:
|
58
56
|
`cuke_iterations`
|
59
57
|
|
@@ -62,7 +60,7 @@ To see other options:
|
|
62
60
|
|
63
61
|
### What did it do?
|
64
62
|
|
65
|
-
First, it created a set of empty directories under the `iterations` folder - one for each iteration that you defined. You should add this folder to your source-control ignore list (unless you're using Git which doesn't track empty folders).
|
63
|
+
First, it created a set of empty directories under the `iterations` folder inside your features folder - one for each iteration that you defined. You should add this folder to your source-control ignore list (unless you're using Git which doesn't track empty folders).
|
66
64
|
|
67
65
|
Next, it created a run file for Cucumber. If you didn't specify a filename it will be called `run.txt`. Definitely add this to your source-control ignore list.
|
68
66
|
|
@@ -70,7 +68,7 @@ Next, it created a run file for Cucumber. If you didn't specify a filename it w
|
|
70
68
|
|
71
69
|
`cucumber @run.txt`
|
72
70
|
|
73
|
-
Note we haven't told Cucumber about our `features` folder like we normally would.
|
71
|
+
Note we haven't told Cucumber about our `features` folder like we normally would. If you're not using the conventional Cucumber folder structure, then you will need to explicitly require your `support` and `step_definitions` folders.
|
74
72
|
|
75
73
|
### Use the iterations inside your scenarios
|
76
74
|
|
data/bin/cuke_iterations
CHANGED
@@ -5,23 +5,18 @@ require 'cuke_iterations'
|
|
5
5
|
require 'trollop'
|
6
6
|
require 'fileutils'
|
7
7
|
|
8
|
+
include CukeIterations
|
9
|
+
|
8
10
|
opts = Trollop::options do
|
11
|
+
opt :features_dir, "Features directory", :default => 'features'
|
9
12
|
opt :iteration_file, "Iterations file to use", :default => 'cuke_iterations.yml'
|
10
13
|
opt :out, "Name of runfile to write", :default => 'run.txt'
|
11
14
|
end
|
12
15
|
|
13
|
-
|
14
|
-
|
16
|
+
features_dir = opts[:features_dir]
|
17
|
+
Trollop::die "Couldn't find features dir '#{features_dir}'" unless Dir.exist?(features_dir)
|
15
18
|
|
16
|
-
|
17
|
-
features = CukeIterations::CukeParser.parse_features(Dir.getwd)
|
18
|
-
iterations.each do |iteration_name, iteration|
|
19
|
-
iteration_dir = File.join('iterations', iteration_name, '..', '..')
|
20
|
-
FileUtils.mkdir_p iteration_dir
|
19
|
+
iteration_file = IterationFileFinder.new.find(features_dir, opts[:iteration_file])
|
21
20
|
|
22
|
-
|
23
|
-
all_scenarios << File.join(iteration_dir, scenario[:filename] + ":#{scenario[:line]}")
|
24
|
-
end
|
25
|
-
end
|
21
|
+
ScenarioFileWriter.new.write_scenarios(features_dir, iteration_file, opts[:out])
|
26
22
|
|
27
|
-
File.open(opts[:out], 'w') {|f| f.puts all_scenarios}
|
data/changelog.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
## [v0.0.2](https://github.com/jmerrifield/cuke_iterations/compare/v0.0.1...v0.0.2)
|
2
|
+
|
3
|
+
* Deal with feature files that live in subdirectories of the `features` folder ([#1](https://github.com/jmerrifield/cuke_iterations/issues/1))
|
4
|
+
* Default to including all tags if none are specified ([#2](https://github.com/jmerrifield/cuke_iterations/issues/2))
|
5
|
+
* Don't require that we run from inside `features`, assume we're at the root and look for features in `features`, unless overridden by the `-f` parameter.
|
6
|
+
|
7
|
+
## [v0.0.1](https://github.com/jmerrifield/cuke_iterations/tree/v0.0.1)
|
File without changes
|
data/lib/cuke_iterations.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
$:.push File.expand_path("../cuke_iterations", __FILE__)
|
2
2
|
|
3
|
+
require 'fileutils'
|
4
|
+
|
3
5
|
require 'version'
|
6
|
+
require 'cucumber_helper'
|
4
7
|
require 'cuke_parser'
|
8
|
+
require 'iteration_file_finder'
|
5
9
|
require 'scenario_extracting_formatter'
|
10
|
+
require 'scenario_file_writer'
|
6
11
|
require 'scenario_list_generator'
|
7
|
-
require 'cucumber_helper'
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'gherkin'
|
2
|
+
require 'pathname'
|
2
3
|
|
3
4
|
module CukeIterations
|
4
5
|
class CukeParser
|
@@ -11,11 +12,16 @@ module CukeIterations
|
|
11
12
|
text = File.open(feature_file, 'r') { |f| f.read }
|
12
13
|
parser.parse(text, __FILE__, __LINE__-1)
|
13
14
|
|
14
|
-
scenarios << formatter.discovered_scenarios.each {|s| s[:filename] =
|
15
|
+
scenarios << formatter.discovered_scenarios.each {|s| s[:filename] = relative_path(feature_file, dir)}
|
15
16
|
end
|
16
17
|
|
17
18
|
scenarios.flatten
|
18
19
|
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def relative_path(file, base_dir)
|
23
|
+
Pathname.new(file).relative_path_from(Pathname.new(base_dir)).to_s
|
24
|
+
end
|
19
25
|
end
|
20
26
|
end
|
21
27
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module CukeIterations
|
2
|
+
class IterationFileFinder
|
3
|
+
def find(features_dir, iteration_file = 'cuke_iterations.yml')
|
4
|
+
raise 'features_dir cannot be nil' unless features_dir
|
5
|
+
|
6
|
+
iteration_file_locations = [
|
7
|
+
iteration_file,
|
8
|
+
File.join(features_dir, iteration_file)
|
9
|
+
]
|
10
|
+
|
11
|
+
location = iteration_file_locations.select { |location| File.exist? location }.first
|
12
|
+
|
13
|
+
raise "Couldn't find iterations file, tried the following: #{iteration_file_locations.join(', ')}" unless location
|
14
|
+
location
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module CukeIterations
|
2
|
+
class ScenarioFileWriter
|
3
|
+
def write_scenarios(features_dir, iteration_file, out_file)
|
4
|
+
iterations = YAML.load(File.read(iteration_file))
|
5
|
+
|
6
|
+
all_scenarios = []
|
7
|
+
features = CukeParser.parse_features(features_dir)
|
8
|
+
iterations.each do |iteration_name, iteration|
|
9
|
+
iteration_dir = File.join(features_dir, 'iterations', iteration_name, '..', '..')
|
10
|
+
FileUtils.mkdir_p iteration_dir
|
11
|
+
|
12
|
+
ScenarioListGenerator.for_iteration(features, iteration).each do |scenario|
|
13
|
+
all_scenarios << File.join(iteration_dir, scenario[:filename] + ":#{scenario[:line]}")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
File.open(out_file, 'w') { |f| f.puts all_scenarios }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,12 +1,24 @@
|
|
1
1
|
module CukeIterations
|
2
2
|
class ScenarioListGenerator
|
3
3
|
class << self
|
4
|
-
def for_iteration(
|
5
|
-
|
6
|
-
next if (
|
7
|
-
(
|
4
|
+
def for_iteration(scenarios, iteration_info)
|
5
|
+
scenarios.select do |s|
|
6
|
+
next if is_excluded?(s, iteration_info)
|
7
|
+
is_included_by_tag?(s, iteration_info) || no_include_tags_specified?(iteration_info)
|
8
8
|
end
|
9
9
|
end
|
10
|
+
|
11
|
+
def no_include_tags_specified?(iteration)
|
12
|
+
iteration[:include_tags] == []
|
13
|
+
end
|
14
|
+
|
15
|
+
def is_included_by_tag?(scenario, iteration)
|
16
|
+
(scenario[:tags] & iteration[:include_tags]).any?
|
17
|
+
end
|
18
|
+
|
19
|
+
def is_excluded?(scenario, iteration)
|
20
|
+
(scenario[:tags] & iteration[:exclude_tags]).any?
|
21
|
+
end
|
10
22
|
end
|
11
23
|
end
|
12
24
|
end
|
data/spec/cuke_parser_spec.rb
CHANGED
@@ -13,10 +13,10 @@ describe "Extracting scenarios" do
|
|
13
13
|
{filename: 'cuking_rocks.feature', line: 10},
|
14
14
|
{filename: 'cuking_rocks.feature', line: 21},
|
15
15
|
{filename: 'cuking_rocks.feature', line: 22},
|
16
|
-
{filename: 'i_love_cukes.feature', line: 4},
|
17
|
-
{filename: 'i_love_cukes.feature', line: 15},
|
18
|
-
{filename: 'i_love_cukes.feature', line: 16},
|
19
|
-
{filename: 'i_love_cukes.feature', line: 25},
|
16
|
+
{filename: 'subdirectory/i_love_cukes.feature', line: 4},
|
17
|
+
{filename: 'subdirectory/i_love_cukes.feature', line: 15},
|
18
|
+
{filename: 'subdirectory/i_love_cukes.feature', line: 16},
|
19
|
+
{filename: 'subdirectory/i_love_cukes.feature', line: 25},
|
20
20
|
]
|
21
21
|
|
22
22
|
parsed_files_with_lines = @parsed_features.map{|x| {filename: x[:filename], line: x[:line]}}
|
@@ -24,7 +24,7 @@ describe "Extracting scenarios" do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
it "should read scenario-level tags" do
|
27
|
-
@parsed_features.should include filename: 'i_love_cukes.feature',
|
27
|
+
@parsed_features.should include filename: 'subdirectory/i_love_cukes.feature',
|
28
28
|
line: 4,
|
29
29
|
tags: ['@tag1', '@tag2']
|
30
30
|
end
|
@@ -36,7 +36,7 @@ describe "Extracting scenarios" do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
it "should read scenario-level tags on example rows" do
|
39
|
-
@parsed_features.should include filename: 'i_love_cukes.feature',
|
39
|
+
@parsed_features.should include filename: 'subdirectory/i_love_cukes.feature',
|
40
40
|
line: 15,
|
41
41
|
tags: ['@tag3', '@tag4']
|
42
42
|
end
|
@@ -48,7 +48,7 @@ describe "Extracting scenarios" do
|
|
48
48
|
end
|
49
49
|
|
50
50
|
it "should read example-group tags on example rows" do
|
51
|
-
@parsed_features.should include filename: 'i_love_cukes.feature',
|
51
|
+
@parsed_features.should include filename: 'subdirectory/i_love_cukes.feature',
|
52
52
|
line: 25,
|
53
53
|
tags: ['@tag5', '@tag6', '@tag7', '@tag8']
|
54
54
|
end
|
File without changes
|
@@ -9,6 +9,18 @@ describe "Scenario list generator" do
|
|
9
9
|
]
|
10
10
|
end
|
11
11
|
|
12
|
+
it "should include all non-excluded scenarios if no include tags are specified" do
|
13
|
+
iteration = {
|
14
|
+
name: "iphone",
|
15
|
+
include_tags: [],
|
16
|
+
exclude_tags: ['@tag8']
|
17
|
+
}
|
18
|
+
|
19
|
+
list = ScenarioListGenerator.for_iteration(@parsed_features, iteration)
|
20
|
+
|
21
|
+
list.should =~ [@test1, @test2]
|
22
|
+
end
|
23
|
+
|
12
24
|
it "should include the scenarios that have tags specified in the iteration" do
|
13
25
|
iteration = {
|
14
26
|
name: "iphone",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cuke_iterations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-02-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: gherkin
|
16
|
-
requirement: &
|
16
|
+
requirement: &70344800299600 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70344800299600
|
25
25
|
description: Run your Cucumber features multiple times within one Cucumber invocation
|
26
26
|
email:
|
27
27
|
- jon@jmerrifield.com
|
@@ -37,20 +37,24 @@ files:
|
|
37
37
|
- README.md
|
38
38
|
- Rakefile
|
39
39
|
- bin/cuke_iterations
|
40
|
+
- changelog.md
|
40
41
|
- cuke_iterations.gemspec
|
41
42
|
- example/features/cuke_iterations.yml
|
42
43
|
- example/features/cuking_rocks.feature
|
43
|
-
- example/features/i_love_cukes.feature
|
44
|
+
- example/features/subdirectory/i_love_cukes.feature
|
44
45
|
- example/features/support/env.rb
|
45
46
|
- example/features/support/hooks.rb
|
46
47
|
- lib/cuke_iterations.rb
|
47
48
|
- lib/cuke_iterations/cucumber_helper.rb
|
48
49
|
- lib/cuke_iterations/cuke_parser.rb
|
50
|
+
- lib/cuke_iterations/iteration_file_finder.rb
|
49
51
|
- lib/cuke_iterations/scenario_extracting_formatter.rb
|
52
|
+
- lib/cuke_iterations/scenario_file_writer.rb
|
50
53
|
- lib/cuke_iterations/scenario_list_generator.rb
|
51
54
|
- lib/cuke_iterations/version.rb
|
52
55
|
- lib/trollop.rb
|
53
56
|
- spec/cuke_parser_spec.rb
|
57
|
+
- spec/scenario_file_writer_spec.rb
|
54
58
|
- spec/scenario_list_generator_spec.rb
|
55
59
|
- spec/spec_helper.rb
|
56
60
|
homepage: https://github.com/jmerrifield/cuke_iterations
|
@@ -73,11 +77,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
77
|
version: '0'
|
74
78
|
requirements: []
|
75
79
|
rubyforge_project: cuke_iterations
|
76
|
-
rubygems_version: 1.8.
|
80
|
+
rubygems_version: 1.8.10
|
77
81
|
signing_key:
|
78
82
|
specification_version: 3
|
79
83
|
summary: Multiple iterations for Cucumber features
|
80
84
|
test_files:
|
81
85
|
- spec/cuke_parser_spec.rb
|
86
|
+
- spec/scenario_file_writer_spec.rb
|
82
87
|
- spec/scenario_list_generator_spec.rb
|
83
88
|
- spec/spec_helper.rb
|