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 CHANGED
@@ -3,7 +3,7 @@ source "http://rubygems.org"
3
3
  group :development do
4
4
  gem 'rake', '>= 0.9.2'
5
5
  gem 'rspec'
6
- gem 'rspec-expectations', :git => "git://github.com/rspec/rspec-expectations.git"
6
+ gem 'rspec-expectations'
7
7
  end
8
8
 
9
9
  gemspec
@@ -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.1)
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.2)
18
- gherkin (2.4.11)
10
+ diff-lcs (1.1.3)
11
+ gherkin (2.7.6)
19
12
  json (>= 1.4.6)
20
- json (1.5.3)
21
- rake (0.9.2)
22
- rspec (2.6.0)
23
- rspec-core (~> 2.6.0)
24
- rspec-expectations (~> 2.6.0)
25
- rspec-mocks (~> 2.6.0)
26
- rspec-core (2.6.4)
27
- rspec-mocks (2.6.0)
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
- At present, you *must* specify all tags that are to 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.
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. This also means it doesn't know about your `support` or `step_definitions` folders, so make sure to add those to the command-line as well.
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
 
@@ -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
- Trollop::die "Couldn't find iterations file '#{opts[:iteration_file]}'" unless File.exist?(opts[:iteration_file])
14
- iterations = YAML.load(File.read(opts[:iteration_file]))
16
+ features_dir = opts[:features_dir]
17
+ Trollop::die "Couldn't find features dir '#{features_dir}'" unless Dir.exist?(features_dir)
15
18
 
16
- all_scenarios = []
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
- CukeIterations::ScenarioListGenerator.for_iteration(features, iteration).each do |scenario|
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}
@@ -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)
@@ -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] = File.basename(feature_file)}
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(parsed_features, iteration)
5
- parsed_features.select do |f|
6
- next if (f[:tags] & iteration[:exclude_tags]).any?
7
- (f[:tags] & iteration[:include_tags]).any?
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
@@ -1,3 +1,3 @@
1
1
  module CukeIterations
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -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.1
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: 2011-08-27 00:00:00.000000000Z
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: &2155927060 !ruby/object:Gem::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: *2155927060
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.6
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