turbo_tests 1.3.0 → 2.2.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 83d546a7efd52f8d3c1e20d6973b3a956c7cbf2f2b51b5e78c7d2ad67819b7db
4
- data.tar.gz: 6f9d1a0841e3121a814c9f98a6ab0ac7146a78506d7a8adec622b9cf6e8e4a53
3
+ metadata.gz: 0ce3db5b3cf918f8152cd3986f44505ab55127fcdba96194cfb5479416182b20
4
+ data.tar.gz: ae140be91a1b0db66f272fc7cc16bcc0d74d8ddc5d769ead501d8e3c5aa41aea
5
5
  SHA512:
6
- metadata.gz: ad2917d505e40659a07e665523eff5af84f7b3ed9e2dacd8e7e1dd08ecc3eea88e507572f49c31cb973bbc63e1922825ef8a2c690db954689cf3afa071dbcb40
7
- data.tar.gz: 7da1494e59ecaff728dd8a0231e96d83a89f15cc67a0f9a5a67dbc4539fc3c0268cf43824ade7caed0aa2565e8b559e0996d0706e0b210061fd02d8990d71fc1
6
+ metadata.gz: 9e80161b5d0ed9b656a59efc2c341a71e3bbc299bcedcfcf284f695aee5c34ba275c2c4b75cea33255db7f5c9c98a242048a72cd1d07534329bf3160f3766a04
7
+ data.tar.gz: 261e0183d586a59076db43f1b378ca6425b6bb79cadfca050b705c2fcde4cd847f26201d57716305d42add671c94421ab5e7b671f0324c0c3dacd2921b0114a9
@@ -0,0 +1,82 @@
1
+ name: Tag and Release
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ branches:
7
+ - master
8
+ paths:
9
+ - "lib/turbo_tests/version.rb"
10
+
11
+ jobs:
12
+ release:
13
+ env:
14
+ GEM_NAME: turbo_tests
15
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16
+ name: Tag and Release
17
+ runs-on: ubuntu-latest
18
+ permissions:
19
+ contents: write
20
+ packages: write
21
+
22
+ steps:
23
+ - uses: actions/checkout@v3
24
+ - name: Set up Ruby 2.7
25
+ uses: ruby/setup-ruby@v1
26
+ with:
27
+ ruby-version: 2.7
28
+ bundler-cache: true
29
+
30
+ - name: Run tests
31
+ run: |
32
+ bundle exec rake install:local
33
+ bundle install
34
+ bundle exec turbo_tests
35
+
36
+ - uses: actions/upload-artifact@v3
37
+ with:
38
+ name: "ruby-gem"
39
+ path: "pkg/*.gem"
40
+
41
+ - name: Configure Git
42
+ run: |
43
+ git config --local user.email "actions@github.com"
44
+ git config --local user.name "Actions Auto Build"
45
+
46
+ - name: Get current version
47
+ id: version-label
48
+ run: |
49
+ VERSION=$(grep VERSION lib/turbo_tests/version.rb | head -n 1 | cut -d'"' -f2)
50
+ echo "version=${VERSION}" >> $GITHUB_OUTPUT
51
+
52
+ - name: Create tag
53
+ run: |
54
+ git tag -a v${{ steps.version-label.outputs.version }} -m "Release v${{ steps.version-label.outputs.version }}"
55
+ git push origin --tags
56
+
57
+ - name: Publish release
58
+ env:
59
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
60
+ run: |
61
+ gh release create v${{ steps.version-label.outputs.version }} --generate-notes
62
+
63
+ - name: Publish to GPR
64
+ run: |
65
+ mkdir -p $HOME/.gem
66
+ touch $HOME/.gem/credentials
67
+ chmod 0600 $HOME/.gem/credentials
68
+ printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
69
+ gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} pkg/*.gem
70
+ env:
71
+ GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
72
+ OWNER: ${{ github.repository_owner }}
73
+
74
+ - name: Publish to RubyGems
75
+ run: |
76
+ mkdir -p $HOME/.gem
77
+ touch $HOME/.gem/credentials
78
+ chmod 0600 $HOME/.gem/credentials
79
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
80
+ gem push pkg/*.gem
81
+ env:
82
+ GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_API_KEY}}"
@@ -1,25 +1,30 @@
1
1
  name: Tests
2
2
 
3
- on: [push, pull_request]
3
+ on:
4
+ pull_request:
5
+
6
+ permissions:
7
+ contents: read
4
8
 
5
9
  jobs:
6
10
  test:
7
11
  runs-on: ubuntu-latest
8
12
 
9
13
  strategy:
14
+ fail-fast: true
10
15
  matrix:
11
- ruby:
12
- - 2.6
13
- - 2.7
16
+ ruby: [ 2.7, "3.0", 3.1, 3.2, 3.3 ]
17
+ os: [ ubuntu-latest, windows-latest ]
14
18
 
15
19
  steps:
16
- - uses: actions/checkout@v2
17
- - uses: ruby/setup-ruby@master
20
+ - uses: actions/checkout@v3
21
+ - uses: ruby/setup-ruby@v1
18
22
  with:
19
23
  ruby-version: ${{matrix.ruby}}
24
+ rubygems: latest
20
25
  bundler-cache: true
21
26
 
22
27
  - name: Run tests
23
28
  timeout-minutes: 5
24
29
  run: |
25
- ${{matrix.env}} bundle exec turbo_tests -n4
30
+ bundle exec turbo_tests -n4
data/Gemfile.lock CHANGED
@@ -1,37 +1,36 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- turbo_tests (1.3.0)
5
- bundler
6
- parallel_tests (~> 3.3)
7
- rspec (~> 3.10)
4
+ turbo_tests (2.2.4)
5
+ parallel_tests (>= 3.3.0, < 5)
6
+ rspec (>= 3.10)
8
7
 
9
8
  GEM
10
9
  remote: https://rubygems.org/
11
10
  specs:
12
11
  coderay (1.1.3)
13
- diff-lcs (1.4.4)
12
+ diff-lcs (1.5.0)
14
13
  method_source (1.0.0)
15
- parallel (1.21.0)
16
- parallel_tests (3.7.3)
14
+ parallel (1.22.1)
15
+ parallel_tests (4.2.0)
17
16
  parallel
18
- pry (0.14.1)
17
+ pry (0.14.2)
19
18
  coderay (~> 1.1)
20
19
  method_source (~> 1.0)
21
20
  rake (13.0.6)
22
- rspec (3.10.0)
23
- rspec-core (~> 3.10.0)
24
- rspec-expectations (~> 3.10.0)
25
- rspec-mocks (~> 3.10.0)
26
- rspec-core (3.10.1)
27
- rspec-support (~> 3.10.0)
28
- rspec-expectations (3.10.1)
21
+ rspec (3.12.0)
22
+ rspec-core (~> 3.12.0)
23
+ rspec-expectations (~> 3.12.0)
24
+ rspec-mocks (~> 3.12.0)
25
+ rspec-core (3.12.1)
26
+ rspec-support (~> 3.12.0)
27
+ rspec-expectations (3.12.2)
29
28
  diff-lcs (>= 1.2.0, < 2.0)
30
- rspec-support (~> 3.10.0)
31
- rspec-mocks (3.10.2)
29
+ rspec-support (~> 3.12.0)
30
+ rspec-mocks (3.12.4)
32
31
  diff-lcs (>= 1.2.0, < 2.0)
33
- rspec-support (~> 3.10.0)
34
- rspec-support (3.10.2)
32
+ rspec-support (~> 3.12.0)
33
+ rspec-support (3.12.0)
35
34
 
36
35
  PLATFORMS
37
36
  ruby
@@ -42,4 +41,4 @@ DEPENDENCIES
42
41
  turbo_tests!
43
42
 
44
43
  BUNDLED WITH
45
- 2.2.27
44
+ 2.4.19
data/README.md CHANGED
@@ -1,10 +1,21 @@
1
- ![Tests](https://github.com/serpapi/turbo_tests/workflows/Tests/badge.svg)
1
+ <h1 align="center">
2
+ TurboTests
3
+ </h1>
2
4
 
3
- # TurboTests
5
+ <div align="center">
6
+ <img src="https://user-images.githubusercontent.com/78694043/233910064-87a6d557-1120-42d2-b965-2a9403c6f2f4.svg" width="500" alt="Turbo-Tests">
4
7
 
5
- Runner for [`grosser/parallel_tests`](https://github.com/grosser/parallel_tests) with incremental summarized output. Based on [Discourse](https://github.com/discourse/discourse/blob/6b9784cf8a18636bce281a7e4d18e65a0cbc6290/lib/turbo_tests.rb) and [RubyGems](https://github.com/rubygems/rubygems/tree/390335ceb351668cd433bd5bb9823dd021f82533/bundler/tool) work in this area.
8
+ </div>
6
9
 
7
- This feature [doesn't fit vision of `parallel_tests` author](https://github.com/grosser/parallel_tests/issues/708) and [RSpec doesn't support built-in parallel testing yet](https://github.com/rspec/rspec-rails/issues/2104#issuecomment-658474900). This gem would not be useful once one of the issues above will be implemented.
10
+ <div align="center">
11
+
12
+ ![Tests](https://github.com/serpapi/turbo_tests/workflows/Tests/badge.svg)
13
+
14
+ </div>
15
+
16
+ `turbo_tests` is a drop-in replacement for [`grosser/parallel_tests`](https://github.com/grosser/parallel_tests) with incremental summarized output. Source code of this gem is based on [Discourse](https://github.com/discourse/discourse/blob/6b9784cf8a18636bce281a7e4d18e65a0cbc6290/lib/turbo_tests.rb) and [RubyGems](https://github.com/rubygems/rubygems/tree/390335ceb351668cd433bd5bb9823dd021f82533/bundler/tool) work in this area.
17
+
18
+ Incremental summarized output [doesn't fit vision of `parallel_tests` author](https://github.com/grosser/parallel_tests/issues/708) and [RSpec doesn't support built-in parallel testing yet](https://github.com/rspec/rspec-rails/issues/2104#issuecomment-658474900). This gem will not be useful once one of the issues above will be implemented.
8
19
 
9
20
  ## Why incremental output?
10
21
 
@@ -49,11 +60,15 @@ gem 'turbo_tests'
49
60
 
50
61
  And then execute:
51
62
 
52
- $ bundle install
63
+ ```bash
64
+ $ bundle install
65
+ ```
53
66
 
54
67
  Or install it yourself as:
55
68
 
56
- $ gem install turbo_tests
69
+ ```bash
70
+ $ gem install turbo_tests
71
+ ```
57
72
 
58
73
  ## Usage
59
74
 
@@ -81,6 +96,7 @@ Options:
81
96
  --runtime-log FILE Location of previously recorded test runtimes
82
97
  -v, --verbose More output
83
98
  --fail-fast=[N]
99
+ --seed SEED Seed for rspec
84
100
  ```
85
101
 
86
102
  ## Development
@@ -0,0 +1,13 @@
1
+ RSpec.describe "Failing example group" do
2
+ after(:each) do |example|
3
+ example.metadata[:extra_failure_lines] ||= []
4
+
5
+ lines = example.metadata[:extra_failure_lines]
6
+
7
+ lines << "Test info in extra_failure_lines"
8
+ end
9
+
10
+ it "fails" do
11
+ expect(2).to eq(3)
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ RSpec.describe "NoMethodError spec" do
2
+ it("fails") { expect(nil[:key]).to eql("value") }
3
+ end
@@ -16,12 +16,15 @@ module TurboTests
16
16
  runtime_log = nil
17
17
  verbose = false
18
18
  fail_fast = nil
19
+ seed = nil
19
20
 
20
21
  OptionParser.new { |opts|
21
22
  opts.banner = <<~BANNER
22
23
  Run all tests in parallel, giving each process ENV['TEST_ENV_NUMBER'] ('1', '2', '3', ...).
23
24
 
24
- Uses parallel_tests under the hood, but reports test results incrementally. Based on Discourse and RubyGems work in this area.
25
+ Reports test results incrementally. Uses methods from `parallel_tests` gem to split files to groups.
26
+
27
+ Source code of `turbo_tests` gem is based on Discourse and RubyGems work in this area (see README file of the source repository).
25
28
 
26
29
  Usage: turbo_tests [options]
27
30
 
@@ -74,6 +77,10 @@ module TurboTests
74
77
  end
75
78
  fail_fast = n.nil? || n < 1 ? 1 : n
76
79
  end
80
+
81
+ opts.on("--seed SEED", "Seed for rspec") do |s|
82
+ seed = s
83
+ end
77
84
  }.parse!(@argv)
78
85
 
79
86
  requires.each { |f| require(f) }
@@ -91,7 +98,7 @@ module TurboTests
91
98
  end
92
99
  end
93
100
 
94
- success = TurboTests::Runner.run(
101
+ exitstatus = TurboTests::Runner.run(
95
102
  formatters: formatters,
96
103
  tags: tags,
97
104
  files: @argv.empty? ? ["spec"] : @argv,
@@ -99,13 +106,11 @@ module TurboTests
99
106
  verbose: verbose,
100
107
  fail_fast: fail_fast,
101
108
  count: count,
109
+ seed: seed
102
110
  )
103
111
 
104
- if success
105
- exit 0
106
- else
107
- exit 1
108
- end
112
+ # From https://github.com/serpapi/turbo_tests/pull/20/
113
+ exit exitstatus
109
114
  end
110
115
  end
111
116
  end
@@ -141,9 +141,10 @@ module TurboTests
141
141
  shared_group_inclusion_backtrace:
142
142
  example
143
143
  .metadata[:shared_group_inclusion_backtrace]
144
- .map { |frame| stack_frame_to_json(frame) }
144
+ .map { |frame| stack_frame_to_json(frame) },
145
+ extra_failure_lines: example.metadata[:extra_failure_lines],
145
146
  },
146
- location_rerun_argument: example.location_rerun_argument
147
+ location_rerun_argument: example.location_rerun_argument,
147
148
  }
148
149
  end
149
150
 
@@ -163,7 +164,7 @@ module TurboTests
163
164
  end
164
165
 
165
166
  def output_row(obj)
166
- output.puts(obj.to_json)
167
+ output.puts ENV["RSPEC_FORMATTER_OUTPUT_ID"] + obj.to_json
167
168
  output.flush
168
169
  end
169
170
  end
@@ -4,8 +4,8 @@ module TurboTests
4
4
  class Reporter
5
5
  attr_writer :load_time
6
6
 
7
- def self.from_config(formatter_config, start_time)
8
- reporter = new(start_time)
7
+ def self.from_config(formatter_config, start_time, seed, seed_used)
8
+ reporter = new(start_time, seed, seed_used)
9
9
 
10
10
  formatter_config.each do |config|
11
11
  name, outputs = config.values_at(:name, :outputs)
@@ -23,13 +23,15 @@ module TurboTests
23
23
  attr_reader :pending_examples
24
24
  attr_reader :failed_examples
25
25
 
26
- def initialize(start_time)
26
+ def initialize(start_time, seed, seed_used)
27
27
  @formatters = []
28
28
  @pending_examples = []
29
29
  @failed_examples = []
30
30
  @all_examples = []
31
31
  @messages = []
32
32
  @start_time = start_time
33
+ @seed = seed
34
+ @seed_used = seed_used
33
35
  @load_time = 0
34
36
  @errors_outside_of_examples_count = 0
35
37
  end
@@ -50,6 +52,38 @@ module TurboTests
50
52
  end
51
53
  end
52
54
 
55
+ # Borrowed from RSpec::Core::Reporter
56
+ # https://github.com/rspec/rspec-core/blob/5699fcdc4723087ff6139af55bd155ad9ad61a7b/lib/rspec/core/reporter.rb#L71
57
+ def report(example_groups)
58
+ start(example_groups)
59
+ begin
60
+ yield self
61
+ ensure
62
+ finish
63
+ end
64
+ end
65
+
66
+ def start(example_groups, time=RSpec::Core::Time.now)
67
+ @start = time
68
+ @load_time = (@start - @start_time).to_f
69
+
70
+ report_number_of_tests(example_groups)
71
+ expected_example_count = example_groups.flatten(1).count
72
+
73
+ delegate_to_formatters(:seed, RSpec::Core::Notifications::SeedNotification.new(@seed, @seed_used))
74
+ delegate_to_formatters(:start, RSpec::Core::Notifications::StartNotification.new(expected_example_count, @load_time))
75
+ end
76
+
77
+ def report_number_of_tests(groups)
78
+ name = ParallelTests::RSpec::Runner.test_file_name
79
+
80
+ num_processes = groups.size
81
+ num_tests = groups.map(&:size).sum
82
+ tests_per_process = (num_processes == 0 ? 0 : num_tests.to_f / num_processes).round
83
+
84
+ puts "#{num_processes} processes for #{num_tests} #{name}s, ~ #{tests_per_process} #{name}s per process"
85
+ end
86
+
53
87
  def group_started(notification)
54
88
  delegate_to_formatters(:example_group_started, notification)
55
89
  end
@@ -83,16 +117,18 @@ module TurboTests
83
117
  @messages << message
84
118
  end
85
119
 
86
- def error_outside_of_examples
120
+ def error_outside_of_examples(error_message)
87
121
  @errors_outside_of_examples_count += 1
122
+ message error_message
88
123
  end
89
124
 
90
125
  def finish
91
- # SEE: https://bit.ly/2NP87Cz
92
- end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
126
+ end_time = RSpec::Core::Time.now
127
+
128
+ @duration = end_time - @start_time
129
+ delegate_to_formatters :stop, RSpec::Core::Notifications::ExamplesNotification.new(self)
93
130
 
94
- delegate_to_formatters(:start_dump,
95
- RSpec::Core::Notifications::NullNotification)
131
+ delegate_to_formatters :start_dump, RSpec::Core::Notifications::NullNotification
96
132
  delegate_to_formatters(:dump_pending,
97
133
  RSpec::Core::Notifications::ExamplesNotification.new(
98
134
  self
@@ -110,8 +146,13 @@ module TurboTests
110
146
  @load_time,
111
147
  @errors_outside_of_examples_count
112
148
  ))
113
- delegate_to_formatters(:close,
114
- RSpec::Core::Notifications::NullNotification)
149
+ delegate_to_formatters(:seed,
150
+ RSpec::Core::Notifications::SeedNotification.new(
151
+ @seed,
152
+ @seed_used,
153
+ ))
154
+ ensure
155
+ delegate_to_formatters :close, RSpec::Core::Notifications::NullNotification
115
156
  end
116
157
 
117
158
  protected
@@ -14,18 +14,19 @@ module TurboTests
14
14
  formatters = opts[:formatters]
15
15
  tags = opts[:tags]
16
16
 
17
- # SEE: https://bit.ly/2NP87Cz
18
- start_time = opts.fetch(:start_time) { Process.clock_gettime(Process::CLOCK_MONOTONIC) }
17
+ start_time = opts.fetch(:start_time) { RSpec::Core::Time.now }
19
18
  runtime_log = opts.fetch(:runtime_log, nil)
20
19
  verbose = opts.fetch(:verbose, false)
21
20
  fail_fast = opts.fetch(:fail_fast, nil)
22
21
  count = opts.fetch(:count, nil)
22
+ seed = opts.fetch(:seed)
23
+ seed_used = !seed.nil?
23
24
 
24
25
  if verbose
25
- STDERR.puts "VERBOSE"
26
+ warn "VERBOSE"
26
27
  end
27
28
 
28
- reporter = Reporter.from_config(formatters, start_time)
29
+ reporter = Reporter.from_config(formatters, start_time, seed, seed_used)
29
30
 
30
31
  new(
31
32
  reporter: reporter,
@@ -34,7 +35,9 @@ module TurboTests
34
35
  runtime_log: runtime_log,
35
36
  verbose: verbose,
36
37
  fail_fast: fail_fast,
37
- count: count
38
+ count: count,
39
+ seed: seed,
40
+ seed_used: seed_used,
38
41
  ).run
39
42
  end
40
43
 
@@ -46,11 +49,14 @@ module TurboTests
46
49
  @verbose = opts[:verbose]
47
50
  @fail_fast = opts[:fail_fast]
48
51
  @count = opts[:count]
52
+ @seed = opts[:seed]
53
+ @seed_used = opts[:seed_used]
54
+
49
55
  @load_time = 0
50
56
  @load_count = 0
51
57
  @failure_count = 0
52
58
 
53
- @messages = Queue.new
59
+ @messages = Thread::Queue.new
54
60
  @threads = []
55
61
  @error = false
56
62
  end
@@ -81,22 +87,25 @@ module TurboTests
81
87
  setup_tmp_dir
82
88
 
83
89
  subprocess_opts = {
84
- record_runtime: use_runtime_info
90
+ record_runtime: use_runtime_info,
85
91
  }
86
92
 
87
- report_number_of_tests(tests_in_groups)
88
-
89
- wait_threads = tests_in_groups.map.with_index do |tests, process_id|
90
- start_regular_subprocess(tests, process_id + 1, **subprocess_opts)
91
- end
92
-
93
- handle_messages
93
+ @reporter.report(tests_in_groups) do |reporter|
94
+ wait_threads = tests_in_groups.map.with_index do |tests, process_id|
95
+ start_regular_subprocess(tests, process_id + 1, **subprocess_opts)
96
+ end
94
97
 
95
- @reporter.finish
98
+ handle_messages
96
99
 
97
- @threads.each(&:join)
100
+ @threads.each(&:join)
98
101
 
99
- @reporter.failed_examples.empty? && wait_threads.map(&:value).all?(&:success?)
102
+ if @reporter.failed_examples.empty? && wait_threads.map(&:value).all?(&:success?)
103
+ 0
104
+ else
105
+ # From https://github.com/serpapi/turbo_tests/pull/20/
106
+ wait_threads.map { |thread| thread.value.exitstatus }.max
107
+ end
108
+ end
100
109
  end
101
110
 
102
111
  private
@@ -124,19 +133,19 @@ module TurboTests
124
133
  if tests.empty?
125
134
  @messages << {
126
135
  type: "exit",
127
- process_id: process_id
136
+ process_id: process_id,
128
137
  }
129
138
  else
130
- tmp_filename = "tmp/test-pipes/subprocess-#{process_id}"
131
-
132
- begin
133
- File.mkfifo(tmp_filename)
134
- rescue Errno::EEXIST
135
- end
136
-
139
+ env["RSPEC_FORMATTER_OUTPUT_ID"] = SecureRandom.uuid
137
140
  env["RUBYOPT"] = ["-I#{File.expand_path("..", __dir__)}", ENV["RUBYOPT"]].compact.join(" ")
138
141
  env["RSPEC_SILENCE_FILTER_ANNOUNCEMENTS"] = "1"
139
142
 
143
+ if ENV["BUNDLE_BIN_PATH"]
144
+ command_name = [ENV["BUNDLE_BIN_PATH"], "exec", "rspec"]
145
+ else
146
+ command_name = "rspec"
147
+ end
148
+
140
149
  record_runtime_options =
141
150
  if record_runtime
142
151
  [
@@ -147,23 +156,30 @@ module TurboTests
147
156
  []
148
157
  end
149
158
 
159
+ seed_option = if @seed_used
160
+ [
161
+ "--seed", @seed,
162
+ ]
163
+ else
164
+ []
165
+ end
166
+
150
167
  command = [
151
- ENV["BUNDLE_BIN_PATH"], "exec", "rspec",
168
+ *command_name,
152
169
  *extra_args,
153
- "--seed", rand(0xFFFF).to_s,
170
+ *seed_option,
154
171
  "--format", "TurboTests::JsonRowsFormatter",
155
- "--out", tmp_filename,
156
172
  *record_runtime_options,
157
- *tests
173
+ *tests,
158
174
  ]
159
175
 
160
176
  if @verbose
161
177
  command_str = [
162
178
  env.map { |k, v| "#{k}=#{v}" }.join(" "),
163
- command.join(" ")
179
+ command.join(" "),
164
180
  ].select { |x| x.size > 0 }.join(" ")
165
181
 
166
- STDERR.puts "Process #{process_id}: #{command_str}"
182
+ warn "Process #{process_id}: #{command_str}"
167
183
  end
168
184
 
169
185
  stdin, stdout, stderr, wait_thr = Open3.popen3(env, *command)
@@ -171,26 +187,30 @@ module TurboTests
171
187
 
172
188
  @threads <<
173
189
  Thread.new do
174
- File.open(tmp_filename) do |fd|
175
- fd.each_line do |line|
176
- message = JSON.parse(line, symbolize_names: true)
190
+ stdout.each_line do |line|
191
+ result = line.split(env["RSPEC_FORMATTER_OUTPUT_ID"])
192
+
193
+ output = result.shift
194
+ print(output) unless output.empty?
177
195
 
178
- message[:process_id] = process_id
179
- @messages << message
180
- end
196
+ message = result.shift
197
+ next unless message
198
+
199
+ message = JSON.parse(message, symbolize_names: true)
200
+ message[:process_id] = process_id
201
+ @messages << message
181
202
  end
182
203
 
183
- @messages << {type: "exit", process_id: process_id}
204
+ @messages << { type: "exit", process_id: process_id }
184
205
  end
185
206
 
186
- @threads << start_copy_thread(stdout, STDOUT)
187
207
  @threads << start_copy_thread(stderr, STDERR)
188
208
 
189
- @threads << Thread.new {
209
+ @threads << Thread.new do
190
210
  unless wait_thr.value.success?
191
- @messages << {type: "error"}
211
+ @messages << { type: "error" }
192
212
  end
193
- }
213
+ end
194
214
 
195
215
  wait_thr
196
216
  end
@@ -239,12 +259,17 @@ module TurboTests
239
259
  break
240
260
  end
241
261
  when "message"
242
- @reporter.message(message[:message])
262
+ if message[:message].include?("An error occurred") || message[:message].include?("occurred outside of examples")
263
+ @reporter.error_outside_of_examples(message[:message])
264
+ @error = true
265
+ else
266
+ @reporter.message(message[:message])
267
+ end
243
268
  when "seed"
244
269
  when "close"
245
270
  when "error"
246
- @reporter.error_outside_of_examples
247
- @error = true
271
+ # Do nothing
272
+ nil
248
273
  when "exit"
249
274
  exited += 1
250
275
  if exited == @num_processes
@@ -260,17 +285,7 @@ module TurboTests
260
285
  end
261
286
 
262
287
  def fail_fast_met
263
- !@fail_fast.nil? && @fail_fast >= @failure_count
264
- end
265
-
266
- def report_number_of_tests(groups)
267
- name = ParallelTests::RSpec::Runner.test_file_name
268
-
269
- num_processes = groups.size
270
- num_tests = groups.map(&:size).sum
271
- tests_per_process = (num_processes == 0 ? 0 : num_tests.to_f / num_processes).round
272
-
273
- puts "#{num_processes} processes for #{num_tests} #{name}s, ~ #{tests_per_process} #{name}s per process"
288
+ !@fail_fast.nil? && @failure_count >= @fail_fast
274
289
  end
275
290
  end
276
291
  end
@@ -1,3 +1,3 @@
1
1
  module TurboTests
2
- VERSION = "1.3.0"
2
+ VERSION = "2.2.4"
3
3
  end
data/lib/turbo_tests.rb CHANGED
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "securerandom"
3
4
  require "open3"
4
5
  require "fileutils"
5
6
  require "json"
7
+
6
8
  require "rspec"
7
9
 
8
10
  require "parallel_tests"
@@ -1,9 +1,7 @@
1
1
  module CoreExtensions
2
2
  refine Hash do
3
3
  def to_struct
4
- OpenStruct.new(self.each_with_object({}) do |(key, val), acc|
5
- acc[key] = val.is_a?(Hash) ? val.to_struct : val
6
- end)
4
+ Struct.new(*self.keys).new(*self.values.map { |value| value.is_a?(Hash) ? value.to_struct : value })
7
5
  end
8
6
  end
9
7
  end
data/turbo_tests.gemspec CHANGED
@@ -3,26 +3,27 @@ require_relative "lib/turbo_tests/version"
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "turbo_tests"
5
5
  spec.version = TurboTests::VERSION
6
- spec.authors = ["Ilya Zub"]
7
- spec.email = ["zaoooza92@gmail.com"]
6
+ spec.platform = Gem::Platform::RUBY
7
+ spec.date = Time.now.strftime('%Y-%m-%d')
8
8
 
9
- spec.summary = "Runner for grosser/parallel_tests with incremental summarized output. Based on Discourse and Rubygems work in this area."
9
+ spec.summary = "`turbo_tests` is a drop-in replacement for `grosser/parallel_tests` with incremental summarized output. Source code of `turbo_test` gem is based on Discourse and Rubygems work in this area (see README file of the source repository)."
10
10
  spec.homepage = "https://github.com/serpapi/turbo_tests"
11
11
  spec.license = "MIT"
12
12
 
13
+ spec.authors = ["Illia Zub"]
14
+ spec.email = ["ilya@serpapi.com"]
15
+
13
16
  spec.metadata["homepage_uri"] = spec.homepage
14
17
  spec.metadata["source_code_uri"] = "https://github.com/serpapi/turbo_tests"
15
18
  spec.metadata["changelog_uri"] = "https://github.com/serpapi/turbo_tests/releases"
16
19
 
17
- spec.required_ruby_version = ">= 2.4"
20
+ spec.required_ruby_version = ">= 2.7"
18
21
 
19
- spec.add_dependency "rspec", "~> 3.10"
20
- spec.add_dependency "parallel_tests", "~> 3.3"
22
+ spec.add_dependency "rspec", ">= 3.10"
23
+ spec.add_dependency "parallel_tests", ">= 3.3.0", "< 5"
21
24
 
22
25
  spec.add_development_dependency "pry", "~> 0.14"
23
26
 
24
- spec.add_runtime_dependency "bundler"
25
-
26
27
  # Specify which files should be added to the gem when it is released.
27
28
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
28
29
  spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do
metadata CHANGED
@@ -1,43 +1,49 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turbo_tests
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 2.2.4
5
5
  platform: ruby
6
6
  authors:
7
- - Ilya Zub
7
+ - Illia Zub
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-04 00:00:00.000000000 Z
11
+ date: 2024-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '3.10'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.10'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: parallel_tests
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '3.3'
33
+ version: 3.3.0
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '5'
34
37
  type: :runtime
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
- - - "~>"
41
+ - - ">="
39
42
  - !ruby/object:Gem::Version
40
- version: '3.3'
43
+ version: 3.3.0
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '5'
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: pry
43
49
  requirement: !ruby/object:Gem::Requirement
@@ -52,33 +58,18 @@ dependencies:
52
58
  - - "~>"
53
59
  - !ruby/object:Gem::Version
54
60
  version: '0.14'
55
- - !ruby/object:Gem::Dependency
56
- name: bundler
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
61
  description:
70
62
  email:
71
- - zaoooza92@gmail.com
63
+ - ilya@serpapi.com
72
64
  executables:
73
65
  - turbo_tests
74
66
  extensions: []
75
67
  extra_rdoc_files: []
76
68
  files:
77
- - ".github/workflows/snyk_ruby-analysis.yml"
69
+ - ".github/workflows/tag_and_release.yml"
78
70
  - ".github/workflows/tests.yml"
79
71
  - ".gitignore"
80
72
  - ".rspec"
81
- - ".travis.yml"
82
73
  - CODE_OF_CONDUCT.md
83
74
  - Gemfile
84
75
  - Gemfile.lock
@@ -87,6 +78,8 @@ files:
87
78
  - Rakefile
88
79
  - bin/turbo_tests
89
80
  - fixtures/rspec/errors_outside_of_examples_spec.rb
81
+ - fixtures/rspec/failing_spec.rb
82
+ - fixtures/rspec/no_method_error_spec.rb
90
83
  - fixtures/rspec/pending_exceptions_spec.rb
91
84
  - lib/turbo_tests.rb
92
85
  - lib/turbo_tests/cli.rb
@@ -111,16 +104,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
111
104
  requirements:
112
105
  - - ">="
113
106
  - !ruby/object:Gem::Version
114
- version: '2.4'
107
+ version: '2.7'
115
108
  required_rubygems_version: !ruby/object:Gem::Requirement
116
109
  requirements:
117
110
  - - ">="
118
111
  - !ruby/object:Gem::Version
119
112
  version: '0'
120
113
  requirements: []
121
- rubygems_version: 3.2.27
114
+ rubygems_version: 3.1.6
122
115
  signing_key:
123
116
  specification_version: 4
124
- summary: Runner for grosser/parallel_tests with incremental summarized output. Based
125
- on Discourse and Rubygems work in this area.
117
+ summary: "`turbo_tests` is a drop-in replacement for `grosser/parallel_tests` with
118
+ incremental summarized output. Source code of `turbo_test` gem is based on Discourse
119
+ and Rubygems work in this area (see README file of the source repository)."
126
120
  test_files: []
@@ -1,33 +0,0 @@
1
- # A sample workflow which checks out your Infrastructure as Code Configuration files,
2
- # such as Kubernetes, Helm & Terraform and scans them for any security issues.
3
- # The results are then uploaded to GitHub Security Code Scanning
4
- #
5
- # For more examples, including how to limit scans to only high-severity issues
6
- # and fail PR checks, see https://github.com/snyk/actions/
7
-
8
- name: Snyk Ruby
9
-
10
- on:
11
- push:
12
- branches: [ master ]
13
- pull_request:
14
- # The branches below must be a subset of the branches above
15
- branches: [ master ]
16
- schedule:
17
- - cron: '0 0 * * 0'
18
-
19
- jobs:
20
- snyk:
21
- runs-on: ubuntu-latest
22
- steps:
23
- - uses: actions/checkout@v2
24
- - name: Run Snyk to check configuration files for security issues
25
- # Snyk can be used to break the build when it detects security issues.
26
- # In this case we want to upload the issues to GitHub Code Scanning
27
- continue-on-error: true
28
- uses: snyk/actions/ruby@master
29
- env:
30
- # In order to use the Snyk Action you will need to have a Snyk API token.
31
- # More details in https://github.com/snyk/actions#getting-your-snyk-token
32
- # or you can signup for free at https://snyk.io/login
33
- SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
data/.travis.yml DELETED
@@ -1,6 +0,0 @@
1
- ---
2
- language: ruby
3
- cache: bundler
4
- rvm:
5
- - 2.6.3
6
- before_install: gem install bundler -v 2.1.4