turnip-parallel_tests 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ vendor
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ script: bundle exec rspec
data/README.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  Helper [parallel_tests](https://github.com/grosser/parallel_tests) for [turnip](https://github.com/jnicklas/turnip).
4
4
 
5
+ [![Build Status](https://travis-ci.org/gongo/turnip-parallel_tests.png?branch=master)](https://travis-ci.org/gongo/turnip-parallel_tests)
6
+ [![Coverage Status](https://coveralls.io/repos/gongo/turnip-parallel_tests/badge.png)](https://coveralls.io/r/gongo/turnip-parallel_tests)
7
+
8
+
9
+
5
10
  ## Motivation
6
11
 
7
12
  I wanted to run a turnip project using `parallel_rspec`.
@@ -29,6 +34,33 @@ Add `--type turnip` (or `-t turnip`) to the commands:
29
34
 
30
35
  $ parallel_rspec -n 3 --type turnip spec
31
36
 
37
+ ## About grouping of tests.
38
+
39
+ Group tests by:
40
+
41
+ * `.feature`: number of steps.
42
+ * `_spec.rb`: file size.
43
+
44
+ eg:
45
+
46
+ ```sh
47
+ $ ls spec
48
+ features/battle1.feature # 12 steps.
49
+ features/battle2.feature # 8 steps.
50
+ features/battle3.feature # 4 steps.
51
+ features/battle4.feature # 6 steps.
52
+ ```
53
+
54
+ When 3 cpus:
55
+
56
+ ```sh
57
+ $ parallel_rspec -n 3 --type turnip spec
58
+ ```
59
+
60
+ * thread1: `battle1.feature`
61
+ * thread2: `battle2.feature`
62
+ * thread3: `battle3.feature` , `battle4.feature`
63
+
32
64
  ## License
33
65
 
34
66
  see `LICENSE.txt`
@@ -1,4 +1,5 @@
1
1
  require 'parallel_tests/rspec/runner'
2
+ require 'parallel_tests/grouper'
2
3
 
3
4
  module ParallelTests
4
5
  module Turnip
@@ -10,19 +11,43 @@ module ParallelTests
10
11
  'turnip'
11
12
  end
12
13
 
13
- def test_suffix_regexp
14
- '(\.feature|_spec\.rb)'
14
+ #
15
+ # @note
16
+ # Conditions of the grouping:
17
+ # feature: number of turnip steps.
18
+ # spec: filesize.
19
+ #
20
+ # @param [Array] tests Selected files and folders at commandline.
21
+ # @param [Integer] num_groups Number of processes to use.
22
+ # @param [Hash] options
23
+ #
24
+ # @return [Array] Test filenames that are grouped.
25
+ #
26
+ def tests_in_groups(tests, num_groups, options={})
27
+ features, specs = find_features_and_specs(tests, options)
28
+
29
+ ftests = ::ParallelTests::Grouper.by_steps(features, num_groups, options)
30
+ stests = ::ParallelTests::Grouper.in_even_groups_by_size(with_runtime_info(specs), num_groups, options)
31
+ ftests.zip(stests).map { |t| t.flatten }
15
32
  end
16
33
 
17
- def find_tests(tests, options = {})
18
- (tests || []).map do |file_or_folder|
34
+ #
35
+ # @param [Array] tests see +tests_in_groups+
36
+ # @param [Hash] options see +tests_in_groups+
37
+ #
38
+ # @return [Array] two array of feature and spec filename
39
+ #
40
+ def find_features_and_specs(tests, options = {})
41
+ files = (tests || []).map do |file_or_folder|
19
42
  if File.directory?(file_or_folder)
20
43
  files = files_in_folder(file_or_folder, options)
21
- files.grep(/#{test_suffix_regexp}$/).grep(options[:pattern]||//)
44
+ files.grep(/(\.feature|_spec\.rb)$/).grep(options[:pattern]||//)
22
45
  else
23
46
  file_or_folder
24
47
  end
25
48
  end.flatten.uniq
49
+
50
+ files.partition { |file| file =~ /\.feature$/ }
26
51
  end
27
52
  end
28
53
  end
@@ -1,5 +1,5 @@
1
1
  module Turnip
2
2
  module ParallelTests
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
@@ -0,0 +1,30 @@
1
+ # 30 lines
2
+ #
3
+ #
4
+ #
5
+ #
6
+ #
7
+ #
8
+ #
9
+ #
10
+ #
11
+ #
12
+ #
13
+ #
14
+ #
15
+ #
16
+ #
17
+ #
18
+ #
19
+ #
20
+ #
21
+ #
22
+ #
23
+ #
24
+ #
25
+ #
26
+ #
27
+ #
28
+ #
29
+ #
30
+ #
@@ -0,0 +1 @@
1
+ Feature files in this directory is using [this project](https://github.com/gongo/turnip_formatter/tree/master/example/spec/features).
@@ -0,0 +1,36 @@
1
+ Feature: Battle a monster
2
+
3
+ Scenario: normal monster
4
+ Given there is a monster
5
+ When I attack it
6
+ Then it should die
7
+ And Fanfare
8
+
9
+ Scenario: strong monster
10
+
11
+ This scenario will error
12
+ So, fanfare is not...oh...
13
+
14
+ Given there is a strong monster
15
+ When I attack it
16
+ Then it should die
17
+ And Fanfare
18
+
19
+ Scenario: spell magic
20
+
21
+ This scenario will error because he can't cast spell
22
+
23
+ Given there is a strong monster
24
+ When I cast a spell 'fireball'
25
+ And I attack it
26
+ Then it should die
27
+ And Fanfare
28
+
29
+ @magician
30
+ Scenario: spell magic
31
+
32
+ Given there is a strong monster
33
+ When I cast a spell 'fireball'
34
+ And I attack it
35
+ Then it should die
36
+ And Fanfare
@@ -0,0 +1,26 @@
1
+ Feature: Battle a monster with weapon
2
+
3
+ Background:
4
+ Given I equip a weapon
5
+
6
+ Scenario: normal monster
7
+ Given there is a monster
8
+ When I attack it
9
+ Then it should die
10
+ And Fanfare
11
+
12
+ Scenario: strong monster
13
+ Given there is a strong monster
14
+ When I attack it
15
+ Then it should die
16
+ And Fanfare
17
+
18
+ Scenario: boss monster
19
+
20
+ This scenario will error
21
+ So, fanfare is not...oh...
22
+
23
+ Given there is a boss monster
24
+ When I attack it
25
+ Then it should die
26
+ And Fanfare
@@ -0,0 +1,26 @@
1
+ @escape
2
+ Feature: Battle monsters
3
+
4
+ Scenario: Escape
5
+ Given there are monsters:
6
+ | gargoyle |
7
+ | Cockatrice |
8
+ When I escape
9
+ Then I was able to escape
10
+
11
+ Scenario: Inescapable
12
+ Given there are monsters:
13
+ | gargoyle |
14
+ | Cockatrice |
15
+ | basilisk |
16
+ When I escape
17
+ Then I could not escape
18
+
19
+ @master_of_escape
20
+ Scenario: Escape because he is master
21
+ Given there are monsters:
22
+ | gargoyle |
23
+ | Cockatrice |
24
+ | basilisk |
25
+ When I escape
26
+ Then I was able to escape
@@ -0,0 +1,5 @@
1
+ # 5 lines
2
+ #
3
+ #
4
+ #
5
+ #
@@ -0,0 +1,26 @@
1
+ # Based on turnip/examples
2
+
3
+ Feature: Battle a monster
4
+ Scenario: normal monster
5
+ Given there is a monster
6
+ When I attack it
7
+ Then it should die
8
+ And Fanfare
9
+
10
+ Scenario Outline: a simple outline
11
+ Given there is a monster with <hp> hitpoints
12
+ When I attack the monster and do <damage> points damage
13
+ Then the monster should be <state>
14
+
15
+ Examples:
16
+ | hp | damage | state |
17
+ | 10 | 13 | alive |
18
+ | 12 | 8 | dead |
19
+ | 3 | 10 | alive |
20
+ | 8 | 5 | dead |
21
+
22
+ Scenario: strong monster
23
+ Given there is a strong monster
24
+ When I attack it
25
+ Then it should die
26
+ And Fanfare
@@ -0,0 +1,191 @@
1
+ require 'spec_helper.rb'
2
+ require 'parallel_tests/turnip/runner'
3
+
4
+ describe ParallelTests::Turnip::Runner do
5
+ let(:runner) do
6
+ ParallelTests::Turnip::Runner
7
+ end
8
+
9
+ let(:helper) do
10
+ Turnip::ParallelTests::Spec
11
+ end
12
+
13
+ let(:options) do
14
+ {}
15
+ end
16
+
17
+ let(:find_features_and_specs) do
18
+ features, specs = runner.find_features_and_specs(tests, options)
19
+ [helper.format_filename(features), helper.format_filename(specs)]
20
+ end
21
+
22
+ let(:tests_in_groups) do
23
+ runner.tests_in_groups(tests, cpus, options).map do |group|
24
+ helper.format_filename(group)
25
+ end
26
+ end
27
+
28
+ context 'selected directories' do
29
+ let(:tests) do
30
+ [helper.test_file_directory, helper.test_file_directory + '/features']
31
+ end
32
+
33
+ describe '.find_features_and_specs' do
34
+ it 'get all feature and spec files' do
35
+ actual_features, actual_specs = find_features_and_specs
36
+
37
+ expect_features = [
38
+ 'features/battle.feature', 'features/battle2.feature',
39
+ 'features/battle3.feature', 'features/songs.feature'
40
+ ]
41
+ expect_specs = ['big_size_spec.rb', 'features/small_size_spec.rb']
42
+
43
+ actual_features.should =~ expect_features
44
+ actual_specs.should =~ expect_specs
45
+ end
46
+ end
47
+
48
+ context '1 processor' do
49
+ let(:cpus) do
50
+ 1
51
+ end
52
+
53
+ it 'get a test group' do
54
+ tests_in_groups.size.should eq 1
55
+ end
56
+ end
57
+
58
+ context '3 processors' do
59
+ let(:cpus) do
60
+ 3
61
+ end
62
+
63
+ it 'get test groups' do
64
+ expect_group1 = ['features/songs.feature', 'big_size_spec.rb']
65
+ expect_group2 = ['features/battle.feature', 'features/small_size_spec.rb']
66
+ expect_group3 = ['features/battle2.feature', 'features/battle3.feature']
67
+
68
+ groups = tests_in_groups
69
+ groups.size.should eq 3
70
+ groups[0].should =~ expect_group1
71
+ groups[1].should =~ expect_group2
72
+ groups[2].should =~ expect_group3
73
+ end
74
+ end
75
+ end
76
+
77
+ context 'selected directory and pattern option' do
78
+ let(:tests) do
79
+ [helper.test_file_directory]
80
+ end
81
+
82
+ let(:options) do
83
+ { :pattern => /songs/ }
84
+ end
85
+
86
+ describe '.find_features_and_specs' do
87
+ it 'get specify pattern file' do
88
+ actual_features, actual_specs = find_features_and_specs
89
+
90
+ expect_features = [ 'features/songs.feature' ]
91
+
92
+ actual_features.should =~ expect_features
93
+ actual_specs.should be_empty
94
+ end
95
+ end
96
+
97
+ context '1 processor' do
98
+ let(:cpus) do
99
+ 1
100
+ end
101
+
102
+ it 'get a test group' do
103
+ tests_in_groups.size.should eq 1
104
+ tests_in_groups[0].size.should eq 1
105
+ end
106
+ end
107
+
108
+ context '3 processors' do
109
+ let(:cpus) do
110
+ 3
111
+ end
112
+
113
+ it 'get test groups' do
114
+ expect_group1 = ['features/songs.feature']
115
+
116
+ groups = tests_in_groups
117
+ groups.size.should eq 3
118
+ groups[0].should =~ expect_group1
119
+ groups[1].should be_empty
120
+ groups[2].should be_empty
121
+ end
122
+ end
123
+ end
124
+
125
+ context 'selected files' do
126
+ let(:tests) do
127
+ [
128
+ helper.test_file_directory + '/features/battle.feature',
129
+ helper.test_file_directory + '/features/battle2.feature',
130
+ helper.test_file_directory + '/features/battle3.feature',
131
+ helper.test_file_directory + '/features/battle2.feature', # duplication
132
+ helper.test_file_directory + '/features/battle2.feature', # duplication
133
+ helper.test_file_directory + '/features/battle.feature', # duplication
134
+ ]
135
+ end
136
+
137
+ let(:options) do
138
+ { :pattern => /songs/ }
139
+ end
140
+
141
+ describe '.find_features_and_specs' do
142
+ it 'get selected files' do
143
+ actual_features, actual_specs = find_features_and_specs
144
+
145
+ expect_features = [
146
+ 'features/battle.feature',
147
+ 'features/battle2.feature',
148
+ 'features/battle3.feature',
149
+ ]
150
+
151
+ actual_features.should =~ expect_features
152
+ actual_specs.should be_empty
153
+ end
154
+ end
155
+
156
+ context '1 processor' do
157
+ let(:cpus) do
158
+ 1
159
+ end
160
+
161
+ it 'get a test group' do
162
+ expect_group = [
163
+ 'features/battle.feature',
164
+ 'features/battle2.feature',
165
+ 'features/battle3.feature',
166
+ ]
167
+
168
+ tests_in_groups.size.should eq 1
169
+ tests_in_groups[0].should =~ expect_group
170
+ end
171
+ end
172
+
173
+ context '3 processors' do
174
+ let(:cpus) do
175
+ 3
176
+ end
177
+
178
+ it 'get test groups' do
179
+ expect_group1 = ['features/battle.feature']
180
+ expect_group2 = ['features/battle2.feature']
181
+ expect_group3 = ['features/battle3.feature']
182
+
183
+ groups = tests_in_groups
184
+ groups.size.should eq 3
185
+ groups[0].should =~ expect_group1
186
+ groups[1].should =~ expect_group2
187
+ groups[2].should =~ expect_group3
188
+ end
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,18 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+
4
+ module Turnip::ParallelTests
5
+ module Spec
6
+ extend self
7
+
8
+ def test_file_directory
9
+ File.dirname(__FILE__) + '/data'
10
+ end
11
+
12
+ def format_filename(filenames)
13
+ filenames.map do |filename|
14
+ filename.sub(test_file_directory + '/', '')
15
+ end
16
+ end
17
+ end
18
+ end
@@ -18,7 +18,10 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency 'parallel_tests'
21
+ spec.add_dependency 'parallel_tests', '~> 0.16'
22
+ spec.add_dependency 'gherkin'
22
23
  spec.add_development_dependency "bundler", "~> 1.3"
23
24
  spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "rspec"
26
+ spec.add_development_dependency "coveralls"
24
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turnip-parallel_tests
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,10 +9,26 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-23 00:00:00.000000000 Z
12
+ date: 2013-10-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: parallel_tests
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '0.16'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '0.16'
30
+ - !ruby/object:Gem::Dependency
31
+ name: gherkin
16
32
  requirement: !ruby/object:Gem::Requirement
17
33
  none: false
18
34
  requirements:
@@ -59,6 +75,38 @@ dependencies:
59
75
  - - ! '>='
60
76
  - !ruby/object:Gem::Version
61
77
  version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: coveralls
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
62
110
  description: Helper ParallelTests for Turnip
63
111
  email:
64
112
  - gonngo@gmail.com
@@ -67,6 +115,7 @@ extensions: []
67
115
  extra_rdoc_files: []
68
116
  files:
69
117
  - .gitignore
118
+ - .travis.yml
70
119
  - Gemfile
71
120
  - LICENSE.txt
72
121
  - README.md
@@ -74,6 +123,15 @@ files:
74
123
  - lib/parallel_tests/turnip/runner.rb
75
124
  - lib/turnip/parallel_tests.rb
76
125
  - lib/turnip/parallel_tests/version.rb
126
+ - spec/data/big_size_spec.rb
127
+ - spec/data/features/README.md
128
+ - spec/data/features/battle.feature
129
+ - spec/data/features/battle2.feature
130
+ - spec/data/features/battle3.feature
131
+ - spec/data/features/small_size_spec.rb
132
+ - spec/data/features/songs.feature
133
+ - spec/parallel_tests/turnip/runner_spec.rb
134
+ - spec/spec_helper.rb
77
135
  - turnip-parallel_tests.gemspec
78
136
  homepage: https://github.com/gongo/turnip-parallel_tests
79
137
  licenses:
@@ -88,16 +146,31 @@ required_ruby_version: !ruby/object:Gem::Requirement
88
146
  - - ! '>='
89
147
  - !ruby/object:Gem::Version
90
148
  version: '0'
149
+ segments:
150
+ - 0
151
+ hash: 2410521719137719469
91
152
  required_rubygems_version: !ruby/object:Gem::Requirement
92
153
  none: false
93
154
  requirements:
94
155
  - - ! '>='
95
156
  - !ruby/object:Gem::Version
96
157
  version: '0'
158
+ segments:
159
+ - 0
160
+ hash: 2410521719137719469
97
161
  requirements: []
98
162
  rubyforge_project:
99
163
  rubygems_version: 1.8.23
100
164
  signing_key:
101
165
  specification_version: 3
102
166
  summary: Helper ParallelTests for Turnip
103
- test_files: []
167
+ test_files:
168
+ - spec/data/big_size_spec.rb
169
+ - spec/data/features/README.md
170
+ - spec/data/features/battle.feature
171
+ - spec/data/features/battle2.feature
172
+ - spec/data/features/battle3.feature
173
+ - spec/data/features/small_size_spec.rb
174
+ - spec/data/features/songs.feature
175
+ - spec/parallel_tests/turnip/runner_spec.rb
176
+ - spec/spec_helper.rb