selective-ruby-rspec 0.1.5 → 0.1.7

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: 742c9d113ea3409cd38857cad3943deaf6bf8c660f8061e97c57957b35ff2d07
4
- data.tar.gz: 420c8ea9dac4e9b21a0346c7eba4ee8a0430ee83225f8f2dc1254bd175b0d413
3
+ metadata.gz: ec0984fc3f7bb4c0e7b38d9f89b75d9f62e75496c9381ef9f8e588a61951360d
4
+ data.tar.gz: 861480972fafe20898532edc2ddaff16c51ebe4d9346c7b5d2524d4d83c9b703
5
5
  SHA512:
6
- metadata.gz: 5e8e31650ee078e7f0cabf43120c99b06f3a500b463b3c04fbe49dd9723db2a97ced3565c82729956f1f13a8c3fc0d0442d4eac96e8f228a7a02b2e3e483592e
7
- data.tar.gz: 269a44800fb7a24bf58f32552d7313d54ddf6cb033eb252f1cebc220f2364b92fe67ee822d25cce1db731d1175266a85bf7d58931f770f1054409c32cfcff1d4
6
+ metadata.gz: 3c6d4c9b94b2be6e7f2194554604621c2ce43aa682dc5891ff7c3021821d8f89d2627d45cf90410c51a33478ba343f316cd81ee375be8b091e7b4707c6183646
7
+ data.tar.gz: 4ba8a04a33b92b644455ff168b2a3f379412ff4f1df1bb57800875a25911f5281f2fc17c56d9f4c05975503201f45aacef4caa993416eba6e7981bb376032ba9
@@ -6,17 +6,21 @@ module Selective
6
6
 
7
7
  def initialize(...); end
8
8
 
9
- def self.callback=(callback)
10
- @callback = callback
9
+ def self.runner_wrapper=(runner_wrapper)
10
+ @runner_wrapper = runner_wrapper
11
11
  end
12
12
 
13
- def self.callback
14
- @callback
13
+ def self.runner_wrapper
14
+ @runner_wrapper
15
15
  end
16
16
 
17
17
  %i(example_passed example_failed example_pending).each do |method|
18
18
  define_method(method) do |notification|
19
- self.class.callback.call(notification.example)
19
+ self.class.runner_wrapper.report_example(notification.example)
20
+ rescue Selective::Ruby::Core::ConnectionLostError
21
+ ::RSpec.world.wants_to_quit = true
22
+ self.class.runner_wrapper.connection_lost = true
23
+ self.class.runner_wrapper.remove_test_case_result(notification.example.id)
20
24
  end
21
25
  end
22
26
  end
@@ -97,6 +97,16 @@ module Selective
97
97
  super
98
98
  @example_map = {}
99
99
  end
100
+
101
+ def prepare_example_filtering
102
+ @filtered_examples = Hash.new do |hash, group|
103
+ hash[group] = if ::RSpec.configuration.dry_run?
104
+ filter_manager.prune(group.examples)
105
+ else
106
+ []
107
+ end
108
+ end
109
+ end
100
110
  end
101
111
 
102
112
  module Runner
@@ -106,7 +116,7 @@ module Selective
106
116
  module Example
107
117
  def initialize(*args)
108
118
  super
109
- ::RSpec.world.example_map[id] = example_group.parent_groups.last
119
+ ::RSpec.world.example_map[id] = self
110
120
  end
111
121
 
112
122
  def run(*args)
@@ -8,6 +8,7 @@ module Selective
8
8
  class TestManifestError < StandardError; end
9
9
 
10
10
  attr_reader :rspec_runner, :config, :example_callback
11
+ attr_accessor :connection_lost
11
12
 
12
13
  FRAMEWORK = "rspec"
13
14
  DEFAULT_SPEC_PATH = "./spec"
@@ -23,29 +24,12 @@ module Selective
23
24
  config.options[:files_or_directories_to_run] = [DEFAULT_SPEC_PATH]
24
25
  end
25
26
 
26
- Formatter.callback = method(:report_example)
27
+ Formatter.runner_wrapper = self
27
28
 
28
29
  @rspec_runner = ::RSpec::Core::Runner.new(@config)
29
30
  @rspec_runner.setup($stderr, $stdout)
30
31
  end
31
32
 
32
- def parse_args(args)
33
- supported_wrapper_args = %w[--require-each-hooks]
34
- wrapper_args, rspec_args = args.partition do |arg|
35
- supported_wrapper_args.any? do |p|
36
- arg.start_with?(p)
37
- end
38
- end
39
-
40
- wrapper_config_hash = wrapper_args.each_with_object({}) do |arg, hash|
41
- key = arg.sub('--', '').tr('-', '_').to_sym
42
- hash[key] = true
43
- end
44
-
45
- rspec_args << "--format=progress" unless args.any? { |e| e.start_with?("--format") }
46
- [rspec_args, wrapper_config_hash]
47
- end
48
-
49
33
  def manifest
50
34
  output = nil
51
35
  Tempfile.create("selective-rspec-dry-run") do |f|
@@ -63,28 +47,20 @@ module Selective
63
47
  end
64
48
 
65
49
  def run_test_cases(test_case_ids)
66
- ::RSpec.world.reporter.send(:start, nil)
67
- Selective::Ruby::Core::Controller.suppress_reporting!
68
-
69
- ::RSpec.configuration.reset_filters
70
- ::RSpec.world.prepare_example_filtering
71
- config.options[:files_or_directories_to_run] = test_case_ids
72
- ensure_formatter
73
-
74
- rspec_runner.setup($stderr, $stdout)
75
-
76
- example_groups = test_case_ids.each_with_object(Set.new) do |test_case_id, set|
77
- set << ::RSpec.world.example_map[test_case_id]
50
+ ensure_test_phase
51
+ configure(test_case_ids)
52
+ rspec_runner.run_specs(optimize_test_filtering(test_case_ids).to_a)
53
+ if connection_lost
54
+ self.connection_lost = false
55
+ raise Selective::Ruby::Core::ConnectionLostError
78
56
  end
79
-
80
- rspec_runner.run_specs(example_groups.to_a)
81
57
  end
82
58
 
83
59
  def exec
84
60
  rspec_runner.run($stderr, $stdout)
85
61
  end
86
62
 
87
- def remove_failed_test_case_result(test_case_id)
63
+ def remove_test_case_result(test_case_id)
88
64
  failure = ::RSpec.world.reporter.failed_examples.detect { |e| e.id == test_case_id }
89
65
  if (failed_example_index = ::RSpec.world.reporter.failed_examples.index(failure))
90
66
  ::RSpec.world.reporter.failed_examples.delete_at(failed_example_index)
@@ -119,8 +95,29 @@ module Selective
119
95
  RSpec::VERSION
120
96
  end
121
97
 
98
+ def report_example(example)
99
+ example_callback.call(format_example(example))
100
+ end
101
+
122
102
  private
123
103
 
104
+ def parse_args(args)
105
+ supported_wrapper_args = %w[--require-each-hooks]
106
+ wrapper_args, rspec_args = args.partition do |arg|
107
+ supported_wrapper_args.any? do |p|
108
+ arg.start_with?(p)
109
+ end
110
+ end
111
+
112
+ wrapper_config_hash = wrapper_args.each_with_object({}) do |arg, hash|
113
+ key = arg.sub('--', '').tr('-', '_').to_sym
114
+ hash[key] = true
115
+ end
116
+
117
+ rspec_args << "--format=progress" unless args.any? { |e| e.start_with?("--format") }
118
+ [rspec_args, wrapper_config_hash]
119
+ end
120
+
124
121
  def get_example_from_reporter(test_case_id)
125
122
  ::RSpec.world.reporter.examples.detect { |e| e.id == test_case_id }
126
123
  end
@@ -152,10 +149,6 @@ module Selective
152
149
  }
153
150
  end
154
151
 
155
- def report_example(example)
156
- example_callback.call(format_example(example))
157
- end
158
-
159
152
  def apply_rspec_configuration
160
153
  ::RSpec.configure do |config|
161
154
  config.backtrace_exclusion_patterns = config.backtrace_exclusion_patterns | [/lib\/selective/]
@@ -167,11 +160,40 @@ module Selective
167
160
  raise TestManifestError.new("Selective could not generate a test manifest. The output was:\n#{output}")
168
161
  end
169
162
 
170
- def ensure_formatter
171
- formatter = [Selective::Ruby::RSpec::Formatter.to_s]
172
- return if config.options[:formatters].include?(formatter)
163
+ def configure(test_case_ids)
164
+ ::RSpec.world.wants_to_quit = false
165
+ ::RSpec.configuration.reset_filters
166
+ ::RSpec.world.filtered_examples.clear
167
+
168
+ config.options[:files_or_directories_to_run] = test_case_ids
169
+ rspec_runner.configure($stderr, $stdout)
170
+ ::RSpec.configuration.load_spec_files
171
+ end
172
+
173
+ def optimize_test_filtering(test_case_ids)
174
+ # The following is an optimization to avoid RSpec's usual filtering mechanism
175
+ # which has a significant performance overhead.
176
+ test_case_ids.each_with_object(Set.new) do |test_case_id, set|
177
+ example = ::RSpec.world.example_map[test_case_id]
178
+ if ::RSpec.world.filtered_examples.key?(example.example_group)
179
+ ::RSpec.world.filtered_examples[example.example_group] << example
180
+ else
181
+ ::RSpec.world.filtered_examples[example.example_group] = [example]
182
+ end
183
+ set << example.example_group.parent_groups.last
184
+ end
185
+ end
186
+
187
+ def ensure_test_phase
188
+ @test_phase_initialized ||= begin
189
+ ::RSpec.world.reporter.send(:start, nil)
190
+ Selective::Ruby::Core::Controller.suppress_reporting!
191
+ apply_formatter
192
+ end
193
+ end
173
194
 
174
- config.options[:formatters] << formatter
195
+ def apply_formatter
196
+ config.options[:formatters] << [Selective::Ruby::RSpec::Formatter.to_s]
175
197
  end
176
198
  end
177
199
  end
@@ -3,7 +3,7 @@
3
3
  module Selective
4
4
  module Ruby
5
5
  module RSpec
6
- VERSION = "0.1.5"
6
+ VERSION = "0.1.7"
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: selective-ruby-rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Wood
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2024-01-26 00:00:00.000000000 Z
12
+ date: 2024-02-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: zeitwerk
@@ -31,14 +31,14 @@ dependencies:
31
31
  requirements:
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: 0.2.2
34
+ version: 0.2.3
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
- version: 0.2.2
41
+ version: 0.2.3
42
42
  description: Selective is an intelligent test runner for your current CI provider.
43
43
  Get real-time test results, intelligent ordering based on code changes, shorter
44
44
  run times, automatic flake detection, the ability to re-enqueue failed tests, and