selective-ruby-minitest 0.1.3 → 0.1.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: 41cc2c0f392507e524f828b3b353b83a071d6d5716d95ccccf9ef793662e79d0
4
- data.tar.gz: db7e463ae55a89a1beba6e6c10ed449c67c34605d96370e19383ac16987871a4
3
+ metadata.gz: 9080fdfdf4a93da215f6530f52f5e5540c6844dbddb27cb22b61f5a7e8689110
4
+ data.tar.gz: 49dafe3c5f9098c532c9f295fc7be4b5c715414f61b84d1e10fb5b72c73624ac
5
5
  SHA512:
6
- metadata.gz: 9baf717b9749184b2759cb5070334abdf042d9ab5f2a7ec315fd42277d7dd10db670ce9b0332a57e241df963404bf4c53d229c05f18c261d264be15a7f4d545f
7
- data.tar.gz: 4bd2f6a0edd9364ec2f7f2cd6f2219e6739ea590e4a26ee6fcff92346631eaaec8b3c20e4bd414d5ab3143cc6906d0b1109b2b088ad1a1a3d8490e72e1a281b1
6
+ metadata.gz: a75f4d55d5c8ee0a145ff71d8bcfe9dbaa68093f05e3993ec275ad71fca60b7364eb2fa491c8b28203b9d75726d4710f0d769c6786efc50f0aa3a9ce43fb15f2
7
+ data.tar.gz: 7a0efb69ed056c57fe0ac231eaf8f4675b304666587e87a6ce2ce7aa9013f7e3f4adcf4226e35a06bd742043ff5e9b410cb8cb189c2ab6e850d152d8692d6c91
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --require spec_helper
2
+ --format documentation
data/.rwx/ci.yml ADDED
@@ -0,0 +1,22 @@
1
+ on:
2
+ cli:
3
+ init:
4
+ commit-sha: ${{ event.git.sha }}
5
+ github:
6
+ push:
7
+ if: ${{ event.git.branch == 'main' }}
8
+ init:
9
+ commit-sha: ${{ event.git.sha }}
10
+ pull_request:
11
+ init:
12
+ commit-sha: ${{ event.git.sha }}
13
+
14
+ tasks:
15
+ - key: tests
16
+ parallel:
17
+ matrix:
18
+ ruby-version: ["3.1.7", "3.2.9", "3.3.10", "3.4.9", "4.0.3"]
19
+ call: ${{ run.dir }}/test.yml
20
+ init:
21
+ commit-sha: ${{ init.commit-sha }}
22
+ ruby-version: ${{ parallel.ruby-version }}
data/.rwx/test.yml ADDED
@@ -0,0 +1,24 @@
1
+ base:
2
+ image: ubuntu:24.04
3
+ config: rwx/base 1.0.3
4
+
5
+ tasks:
6
+ - key: code
7
+ call: git/clone 2.0.7
8
+ with:
9
+ repository: https://github.com/selectiveci/selective-ruby-minitest.git
10
+ ref: ${{ init.commit-sha }}
11
+ github-token: ${{ github.token }}
12
+
13
+ - key: ruby
14
+ call: ruby/install 1.2.27
15
+ with:
16
+ ruby-version: ${{ init.ruby-version }}
17
+
18
+ - key: bundle-install
19
+ use: [code, ruby]
20
+ run: bundle install
21
+
22
+ - key: rspec
23
+ use: bundle-install
24
+ run: bundle exec rspec
data/LICENSE CHANGED
File without changes
data/Rakefile CHANGED
File without changes
File without changes
@@ -42,7 +42,10 @@ module Selective
42
42
  def run_test_cases(test_case_ids)
43
43
  test_case_ids.map do |test_id|
44
44
  klass, method_name = get_test_from_map(test_id)
45
- real_time = time { klass.run_one_method(klass, method_name, reporter) }
45
+ discard_previous_results(klass, method_name)
46
+ real_time = time do
47
+ with_test_map(test_id) { klass.run_one_method(klass, method_name, reporter) }
48
+ end
46
49
  foo = format_test_case(test_id, klass, method_name, real_time)
47
50
  test_case_callback.call(foo)
48
51
  end
@@ -96,6 +99,87 @@ module Selective
96
99
  Benchmark.measure(&block).real
97
100
  end
98
101
 
102
+ # Records the files a test executes (setup and teardown included) when
103
+ # the server has asked for a test map; a plain pass-through otherwise
104
+ # and on older cores that predate test maps.
105
+ def with_test_map(test_id, &block)
106
+ if ::Selective::Ruby::Core.const_defined?(:TestMap)
107
+ ::Selective::Ruby::Core::TestMap.around(test_id, &block)
108
+ else
109
+ yield
110
+ end
111
+ end
112
+
113
+ # Auto-retry (and a manual rerun) can hand a test case back to the very
114
+ # process that already ran it. Every reporter recorded that first attempt,
115
+ # so running it again without forgetting the first makes reporters that
116
+ # keep per-test records -- minitest-reporters' JUnitReporter, for example --
117
+ # emit the test twice with identical identity. Tools that key on test
118
+ # identity (Captain, for one) then hold a duplicate they can never
119
+ # reconcile: their own retries update one copy while the other stays
120
+ # failed, and the task can never go green. Drop the stale records first so
121
+ # only the latest attempt is reported, and keep the statistics counters
122
+ # honest about how many distinct tests ran.
123
+ def discard_previous_results(klass, method_name)
124
+ key = [klass.name, method_name]
125
+ previously_run = previous_runs.key?(key)
126
+ previous_runs[key] = true
127
+
128
+ all_reporters.each do |r|
129
+ stale = []
130
+
131
+ if r.respond_to?(:tests) && r.tests.is_a?(Array)
132
+ stale.concat(r.tests.select { |result| same_test?(result, klass, method_name) })
133
+ r.tests.reject! { |result| same_test?(result, klass, method_name) }
134
+ end
135
+
136
+ if r.respond_to?(:results) && r.results.is_a?(Array)
137
+ stale.concat(r.results.select { |result| same_test?(result, klass, method_name) })
138
+ r.results.reject! { |result| same_test?(result, klass, method_name) }
139
+ end
140
+
141
+ forget_statistics(r, stale.uniq, previously_run)
142
+ end
143
+ end
144
+
145
+ def previous_runs
146
+ @previous_runs ||= {}
147
+ end
148
+
149
+ # Every reporter in the composite, including the ones minitest-reporters
150
+ # hides behind its DelegateReporter (which can itself be nested).
151
+ def all_reporters(reporters = reporter.reporters, seen = {})
152
+ reporters.flat_map do |r|
153
+ next [] if seen[r.object_id]
154
+
155
+ seen[r.object_id] = true
156
+ nested = []
157
+ nested.concat(Array(r.send(:all_reporters))) if r.respond_to?(:all_reporters, true)
158
+ nested.concat(Array(r.reporters)) if r.respond_to?(:reporters)
159
+ [r, *all_reporters(nested, seen)]
160
+ end
161
+ end
162
+
163
+ def same_test?(result, klass, method_name)
164
+ result.respond_to?(:klass) && result.respond_to?(:name) &&
165
+ result.klass.to_s == klass.name && result.name == method_name
166
+ end
167
+
168
+ # Minitest::StatisticsReporter counts every recorded run, whether or not it
169
+ # kept the result object (it only keeps failures and skips). A previously
170
+ # passing test leaves nothing to find in `tests`/`results`, so the rerun
171
+ # itself is the signal that one count has to come off.
172
+ def forget_statistics(r, stale, previously_run)
173
+ if previously_run && r.respond_to?(:count) && r.respond_to?(:count=) && r.count.to_i.positive?
174
+ r.count -= 1
175
+ end
176
+
177
+ assertions = stale.sum { |result| result.respond_to?(:assertions) ? result.assertions.to_i : 0 }
178
+ if assertions.positive? && r.respond_to?(:assertions) && r.respond_to?(:assertions=)
179
+ r.assertions = [r.assertions.to_i - assertions, 0].max
180
+ end
181
+ end
182
+
99
183
  def get_test_from_map(test_id)
100
184
  t = test_map[test_id]
101
185
 
@@ -3,7 +3,7 @@
3
3
  module Selective
4
4
  module Ruby
5
5
  module Minitest
6
- VERSION = "0.1.3"
6
+ VERSION = "0.1.4"
7
7
  end
8
8
  end
9
9
  end
File without changes
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/selective/ruby/minitest/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "selective-ruby-minitest"
7
+ spec.version = Selective::Ruby::Minitest::VERSION
8
+ spec.authors = ["Benjamin Wood", "Nate Vick"]
9
+ spec.email = ["ben@hint.io", "nate@hint.io"]
10
+ spec.license = "MIT"
11
+
12
+ spec.summary = "Selective Ruby Minitest Client"
13
+ spec.description = "Selective is an intelligent test runner for your current CI provider. Get real-time test results, intelligent ordering based on code changes, shorter run times, automatic flake detection, the ability to re-enqueue failed tests, and more."
14
+ spec.homepage = "https://www.selective.ci"
15
+ spec.required_ruby_version = ">= 2.6.0"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = "http://github.com/selectiveci/selective-ruby-minitest"
19
+ spec.metadata["changelog_uri"] = "https://github.com/selectiveci/selective-ruby-minitest/blob/main/CHANGELOG.md"
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(__dir__) do
24
+ `git ls-files -z`.split("\x0").reject do |f|
25
+ (File.expand_path(f) == __FILE__) || f.start_with?(*%w[bin/ test/ spec/ features/ log/ gemfiles/ .git .circleci appveyor .ruby-version .standard.yml README.md CHANGELOG.md CODE_OF_CONDUCT.md Gemfile Appraisals])
26
+ end
27
+ end
28
+
29
+ spec.bindir = "exe"
30
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ["lib"]
32
+
33
+ # Uncomment to register a new dependency of your gem
34
+ spec.add_dependency("zeitwerk", "~> 2.6.12")
35
+ spec.add_dependency("selective-ruby-core", ">= 0.2.5")
36
+
37
+ # benchmark was removed from Ruby's default gems in 4.0.
38
+ spec.add_dependency("benchmark")
39
+
40
+ # TODO: Do we really need rake? Most apps will have it, but we
41
+ # can probably avoid it.
42
+ spec.add_dependency("rake")
43
+
44
+ # For more information and examples about making a new gem, check out our
45
+ # guide at: https://bundler.io/guides/creating_gem.html
46
+ end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: selective-ruby-minitest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Wood
8
8
  - Nate Vick
9
- autorequire:
9
+ autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2026-04-22 00:00:00.000000000 Z
12
+ date: 2026-09-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: zeitwerk
@@ -39,6 +39,20 @@ dependencies:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: 0.2.5
42
+ - !ruby/object:Gem::Dependency
43
+ name: benchmark
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
42
56
  - !ruby/object:Gem::Dependency
43
57
  name: rake
44
58
  requirement: !ruby/object:Gem::Requirement
@@ -64,12 +78,16 @@ executables: []
64
78
  extensions: []
65
79
  extra_rdoc_files: []
66
80
  files:
81
+ - ".rspec"
82
+ - ".rwx/ci.yml"
83
+ - ".rwx/test.yml"
67
84
  - LICENSE
68
85
  - Rakefile
69
86
  - lib/selective-ruby-minitest.rb
70
87
  - lib/selective/ruby/minitest/monkeypatches.rb
71
88
  - lib/selective/ruby/minitest/runner_wrapper.rb
72
89
  - lib/selective/ruby/minitest/version.rb
90
+ - selective-ruby-minitest.gemspec
73
91
  homepage: https://www.selective.ci
74
92
  licenses:
75
93
  - MIT
@@ -77,7 +95,7 @@ metadata:
77
95
  homepage_uri: https://www.selective.ci
78
96
  source_code_uri: http://github.com/selectiveci/selective-ruby-minitest
79
97
  changelog_uri: https://github.com/selectiveci/selective-ruby-minitest/blob/main/CHANGELOG.md
80
- post_install_message:
98
+ post_install_message:
81
99
  rdoc_options: []
82
100
  require_paths:
83
101
  - lib
@@ -93,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
111
  version: '0'
94
112
  requirements: []
95
113
  rubygems_version: 3.5.22
96
- signing_key:
114
+ signing_key:
97
115
  specification_version: 4
98
116
  summary: Selective Ruby Minitest Client
99
117
  test_files: []