cuke_iterations 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|