flakey_spec_catcher 0.9.7 → 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9fdaeca36cc9fd914875fff621500b2b220efd71f78a83528ca55df6eda40e2b
4
- data.tar.gz: 11cc4f997cb8be146904f04960ec140274752f0aafcdfa876fe0c977081f121c
3
+ metadata.gz: 6a88793e18d2fc8a483639620b2876b4955f3fc8a5425f41a25cc2e3509cd6e0
4
+ data.tar.gz: f4c0a38a03eb0fabcde7111f3bf8bfc3698a7c5c576a106fb7c7b4337ed782b8
5
5
  SHA512:
6
- metadata.gz: 216233d326b8bda265c44ff8218345fdd3897148b0637a27025a6ca02b82c0322050f90bd12645f4ac5a3ea0094e9107b0212b1c7cfd2a25c4024ed6dd7660e2
7
- data.tar.gz: fb2ce576288f4cef8a2c17a10a848763ac81bc68d0b65e5adb1e5aba3e2714da9bb377dfb3be048bd77e5393ec57f566a1600469f8591ac977252f21385e3899
6
+ metadata.gz: 8c033294dc195ab6784dc22919ff986f7e646657b85a7efe6a5780333b666b4a7c7bba5f10ab41839ee9574cd9f4307a6f9b6c276f5da4f9144b5828dd1f2e06
7
+ data.tar.gz: 00a950c3296e05a81c8294c2005d6c84b454296de2f697b7ef2152ec6f29ef02c6305b3749d3a2d1449436fa1b6fb6ac0ccc2d9e3f5ae9db7ebef04043db2b96
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ /.byebug_history
1
2
  /coverage
2
3
  /Gemfile.lock
3
4
  /flakey_spec_catcher-*.gem
data/README.md CHANGED
@@ -163,6 +163,7 @@ FSC_USAGE_PATTERNS = '{ spec/ui => bundle exec rspec }, { spec/api => parallel_r
163
163
  --verbose Send all output from running tests to stdout
164
164
  -v, --version Prints current flakey_spec_catcher_version
165
165
  -h, --help Displays available flakey_spec_catcher cli overrides
166
+ --rspec-options '[OPTIONS]' Execute default usage with rspec options
166
167
  ```
167
168
 
168
169
  Examples:
@@ -28,11 +28,13 @@ Gem::Specification.new do |gem|
28
28
  gem.require_paths = ['lib']
29
29
 
30
30
  gem.metadata['allowed_push_host'] = 'https://rubygems.org'
31
- gem.required_ruby_version = '>= 2.3'
31
+ gem.required_ruby_version = '>= 2.6'
32
32
 
33
- gem.add_dependency 'rspec', '~> 3.8'
33
+ gem.add_dependency 'rspec', '~> 3.10'
34
+ gem.add_development_dependency 'byebug', '~> 11.1'
34
35
  gem.add_development_dependency 'climate_control', '~> 0.2'
35
- gem.add_development_dependency 'rake', '~> 12.3'
36
- gem.add_development_dependency 'simplecov', '~> 0.17'
36
+ gem.add_development_dependency 'rake', '~> 13.0'
37
+ gem.add_development_dependency 'rubocop', '~> 0.93.1'
38
+ gem.add_development_dependency 'simplecov', '~> 0.19'
37
39
  end
38
40
  # rubocop:enable Layout/ExtraSpacing, Layout/SpaceAroundOperators
@@ -8,7 +8,7 @@ module FlakeySpecCatcher
8
8
  # A ChangeCapsule object will represent the changes made to a block of code. It
9
9
  # accomplishes this using ChangeContext and ChangeSummary objects.
10
10
  class ChangeCapsule
11
- attr_reader :file_name, :change_summary, :change_contexts
11
+ attr_reader :file_name, :change_summary, :change_contexts, :spec_tree
12
12
  SCOPE_SPECIFIERS = %w[it context describe scenario].freeze
13
13
  SHARED_EXAMPLES = %w[include_examples it_behaves_like it_should_behave_like matching].freeze
14
14
 
@@ -16,6 +16,7 @@ module FlakeySpecCatcher
16
16
  @file_name = file_name
17
17
  @change_summary = change_summary
18
18
  @change_contexts = []
19
+ @spec_tree = {}
19
20
  handle_initial_change_contexts(change_contexts)
20
21
  end
21
22
 
@@ -23,23 +24,30 @@ module FlakeySpecCatcher
23
24
  @change_contexts.map(&:rerun_info)
24
25
  end
25
26
 
27
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
26
28
  def fill_contexts
27
29
  change_context_stack = []
28
30
  ignore_scope_closure = 0
29
31
  lines_in_file = File.read(@file_name).split("\n")
30
32
  lines_in_file.each_with_index do |line, index|
33
+ shared_example_identified = false
34
+
31
35
  # Check if line matches an rspec example or examplegroup format
32
36
  if line =~ spec_scope
33
37
  handle_change_context(line, index, change_context_stack)
34
38
  # Else, ignore other blocks that might pollute context stack
39
+ elsif line =~ shared_example_scope
40
+ handle_change_context(line, index, change_context_stack)
41
+ shared_example_identified = true
35
42
  elsif line_matches_method_or_block(line)
36
43
  ignore_scope_closure += 1
37
44
  end
38
45
 
39
46
  fill_context(line, index, change_context_stack)
40
47
 
41
- # Note - some things use do-like loops and we need to be able to ignore those
42
- if line =~ pop_scope
48
+ if shared_example_identified
49
+ change_context_stack.pop
50
+ elsif line =~ pop_scope
43
51
  if ignore_scope_closure.positive?
44
52
  ignore_scope_closure -= 1
45
53
  else
@@ -48,6 +56,7 @@ module FlakeySpecCatcher
48
56
  end
49
57
  end
50
58
  end
59
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
51
60
 
52
61
  private
53
62
 
@@ -69,14 +78,15 @@ module FlakeySpecCatcher
69
78
  end
70
79
 
71
80
  def spec_scope
72
- # Not sure if we need to check for description in quotes
73
- # spec_scope = /^\s*(#{SCOPE_SPECIFIERS.join("|")})\s*('.*'|".*").*do\s*$/
74
-
75
81
  /\s*(#{SCOPE_SPECIFIERS.join("|")}).*\s+do.*$/
76
82
  end
77
83
 
84
+ def shared_example_scope
85
+ /\s*(#{SHARED_EXAMPLES.join("|")}).*\s+.*$/
86
+ end
87
+
78
88
  def line_matches_method_or_block(line)
79
- return true if line =~ /\s*do(\s+|$)/ || line =~ /^\s*def\s+/ || line =~ /^\s*if\s+/
89
+ return true if line =~ /\s*do(\s+|$)/ || line =~ /^\s*def\s+/ || line =~ /^\s*if\s+/ || line =~ /^\s*class\s+/
80
90
 
81
91
  false
82
92
  end
@@ -112,6 +122,20 @@ module FlakeySpecCatcher
112
122
 
113
123
  change_context_stack.push(change_context) unless
114
124
  change_context_stack.any? { |c| c == change_context }
125
+
126
+ build_spec_tree(change_context_stack)
127
+ end
128
+
129
+ def build_spec_tree(change_contexts)
130
+ return unless change_contexts.count > 1
131
+
132
+ current_scope = change_contexts[-1].rerun_info
133
+ parent_scope = change_contexts[-2].rerun_info
134
+ @spec_tree[parent_scope] = if @spec_tree[parent_scope]
135
+ @spec_tree[parent_scope] << current_scope
136
+ else
137
+ [current_scope]
138
+ end
115
139
  end
116
140
  end
117
141
  end
@@ -8,7 +8,8 @@ module FlakeySpecCatcher
8
8
  # Captures command line arguments for manual re-runs
9
9
  class CliOverride
10
10
  attr_reader :rerun_patterns, :rerun_usage, :repeat_factor, :enable_runs, :excluded_tags, :use_parent, :dry_run
11
- attr_reader :output_file, :split_nodes, :split_index, :verbose
11
+ attr_reader :output_file, :split_nodes, :split_index, :verbose, :test_options, :break_on_first_failure
12
+ attr_reader :list_child_specs
12
13
 
13
14
  def initialize
14
15
  @dry_run = false
@@ -16,6 +17,7 @@ module FlakeySpecCatcher
16
17
  @excluded_tags = []
17
18
  @use_parent = false
18
19
  @verbose = false
20
+ @test_options = []
19
21
  parse_command_line_args
20
22
  validate_arguments
21
23
  end
@@ -55,6 +57,14 @@ module FlakeySpecCatcher
55
57
  @repeat_factor = remove_formatter_quotes(repeat).to_i
56
58
  end
57
59
 
60
+ opts.on('--break-on-first-failure', 'Break on first failure') do |break_on_first_failure|
61
+ @break_on_first_failure = break_on_first_failure
62
+ end
63
+
64
+ opts.on('--list-child-specs', 'List Child Specs (Verbose Spec Listing') do |list_child_specs|
65
+ @list_child_specs = list_child_specs
66
+ end
67
+
58
68
  opts.on('-e', '--excluded-tags=EXCLUDED_TAGS',
59
69
  'Specify tags to exclude in a comma separated list') do |tags|
60
70
  @excluded_tags = parse_tags(tags)
@@ -87,6 +97,10 @@ module FlakeySpecCatcher
87
97
  puts opts
88
98
  @enable_runs = false
89
99
  end
100
+
101
+ opts.on("--rspec-options '[OPTIONS]'", 'execute default usage with rspec options') do |arg|
102
+ @test_options = arg.split(/[ ](?=(?:[^"]*"[^"]*")*[^"]*$)(?=(?:[^']*'[^']*')*[^']*$)/)
103
+ end
90
104
  end.parse!
91
105
  end
92
106
 
@@ -56,45 +56,12 @@ module FlakeySpecCatcher
56
56
  return nil if @remote.nil?
57
57
 
58
58
  working_branch = `git branch | grep '*'`.delete('*').gsub(/\s+/, '')
59
- # `git remote show origin` will show us if our branch is configured to push
60
- # to a non-master branch. Note that our push destination is what we're interested in
61
- # Assume master if no matches
62
-
63
- # Example output
64
- # * remote origin
65
- # Fetch URL: gerrit:repo
66
- # Push URL: gerrit:repo
67
- # HEAD branch: master
68
- # Remote branches:
69
- # dev/reports tracked
70
- # edge tracked
71
- # master tracked
72
- # Local branch configured for 'git pull':
73
- # master merges with remote master
74
- # Local refs configured for 'git push':
75
- # dev/reports pushes to dev/reports (up to date)
76
- # master pushes to master (up to date)
77
-
78
- remote_branches = `git remote show #{@remote}`.split("\n")
79
-
80
- # Separate 'dev/reports pushes to dev/reports (up to date)' into
81
- # ['dev/reports', 'dev/reports'] or [<LOCAL BRANCH>, <REMOTE BRANCH>]
82
- remote_pairs = remote_branches.map { |r| r.scan(/(\S*)\s+pushes to\s+(\S*)\s+/).flatten }
83
-
84
- # check if the working branch (currently checked out branch) corresponds to a remote_pair
85
- # if so, use that remote pair for comparison, else use master
86
- match = remote_pairs.find do |pair|
87
- # working branch (pair[0]) pushes to remote (pair[1])
88
- pair[0] == working_branch
89
- end
59
+ branch_remote = `git config branch.#{working_branch}.remote`.strip
60
+ return 'master' unless @remote == branch_remote
90
61
 
91
- remote_branch = if match.nil?
92
- 'master'
93
- else
94
- # match is formatted as [working_branch, remote]
95
- match[1]
96
- end
97
- remote_branch
62
+ remote_branch = `git config branch.#{branch}.merge`.strip.sub(%r{^refs/heads/}, '')
63
+ remote_branch = nil if remote_branch.empty?
64
+ remote_branch || 'master'
98
65
  end
99
66
 
100
67
  def initialize_git_comparison(test_mode)
@@ -108,7 +75,7 @@ module FlakeySpecCatcher
108
75
  @git_comparison = "#{@base_commit_sha}..#{@working_commit_sha}"
109
76
  end
110
77
 
111
- # rubocop:disable Metrics/AbcSize
78
+ # rubocop:disable Metrics/CyclomaticComplexity
112
79
  def parse_changes
113
80
  # For each file, get the change block
114
81
  diff_files.each do |filename|
@@ -128,7 +95,7 @@ module FlakeySpecCatcher
128
95
  end
129
96
  end
130
97
  end
131
- # rubocop:enable Metrics/AbcSize
98
+ # rubocop:enable Metrics/CyclomaticComplexity
132
99
 
133
100
  def identify_change_contexts
134
101
  @capsule_manager.change_capsules.each(&:fill_contexts)
@@ -39,6 +39,7 @@ module FlakeySpecCatcher
39
39
  else
40
40
  all_non_example_groups - identify_tag_excluded_reruns
41
41
  end
42
+ tests = transform_parent_specs(tests).flatten if @user_config.list_child_specs
42
43
  filter_reruns_by_ignore_files(tests)
43
44
  end
44
45
 
@@ -171,5 +172,23 @@ module FlakeySpecCatcher
171
172
  @rerun_capsules.push(FlakeySpecCatcher::RerunCapsule.new(testcase: testcase, usage: usage))
172
173
  end
173
174
  end
175
+
176
+ def transform_parent_specs(tests)
177
+ transformed_tests = []
178
+ tests.each do |test|
179
+ capsule = @git_controller.capsule_manager.change_capsules.find { |c| c.file_name == test.split(':')[0] }
180
+ spec_tree = capsule.spec_tree
181
+ # If test is a key in the spec_tree, it's an example group, so we queue up its descendant examples
182
+ if spec_tree[test]
183
+ spec_tree[test].each do |child|
184
+ transformed_tests << transform_parent_specs([child]).flatten
185
+ end
186
+ # Else test is just an example
187
+ else
188
+ transformed_tests << test
189
+ end
190
+ end
191
+ transformed_tests
192
+ end
174
193
  end
175
194
  end
@@ -36,6 +36,7 @@ module FlakeySpecCatcher
36
36
  puts " Current Sha: #{@git_controller.working_commit_sha}"
37
37
  puts " Base Sha: #{@git_controller.base_commit_sha}"
38
38
  puts " Repeat factor: #{@user_config.repeat_factor}"
39
+ puts " Break on first failure: #{@user_config.break_on_first_failure}" if @user_config.break_on_first_failure
39
40
  puts " Node Total: #{@user_config.split_nodes}" if @user_config.split_nodes
40
41
  puts " Node Index: #{@user_config.split_index}" if @user_config.split_index
41
42
  puts " Changed Specs Detected: #{@git_controller.changed_examples}"
@@ -75,6 +76,7 @@ module FlakeySpecCatcher
75
76
  @user_config.repeat_factor.times do
76
77
  iteration_status = handle_capsule_rerun(capsule)
77
78
  status = [status, iteration_status].max
79
+ break if @user_config.break_on_first_failure && !status.zero?
78
80
  end
79
81
  end
80
82
 
@@ -98,7 +100,7 @@ module FlakeySpecCatcher
98
100
  rspec_args = ['--format', 'documentation', '--out', @user_config.output_file, test]
99
101
  # Rspec output sent to stdout if verbose option is true
100
102
  rspec_args << '-fd' if @user_config.verbose
101
- return_status = RSpec::Core::Runner.run(rspec_args)
103
+ return_status = RSpec::Core::Runner.run(@user_config.test_options.concat(rspec_args))
102
104
  RSpec.clear_examples
103
105
  copy_output_to_temp_file unless @user_config.output_file == File::NULL
104
106
  return_status
@@ -11,11 +11,12 @@ module FlakeySpecCatcher
11
11
  attr_reader :rerun_file_only, :rspec_usage_patterns, :excluded_tags
12
12
  attr_reader :manual_rerun_patterns, :manual_rerun_usage
13
13
  attr_reader :enable_runs, :output_file, :use_parent, :dry_run
14
- attr_reader :split_nodes, :split_index, :verbose
14
+ attr_reader :split_nodes, :split_index, :verbose, :test_options
15
+ attr_reader :break_on_first_failure, :list_child_specs
15
16
 
16
17
  USER_CONFIG_ENV_VARS = %w[FSC_REPEAT_FACTOR FSC_IGNORE_FILES FSC_IGNORE_BRANCHES
17
18
  FSC_SILENT_MODE FSC_RERUN_FILE_ONLY FSC_USAGE_PATTERNS
18
- FSC_EXCLUDED_TAGS FSC_OUTPUT_FILE].freeze
19
+ FSC_EXCLUDED_TAGS FSC_OUTPUT_FILE FSC_LIST_CHILD_SPECS].freeze
19
20
 
20
21
  def initialize(cli_override: CliOverride.new)
21
22
  apply_env_var_settings
@@ -32,6 +33,7 @@ module FlakeySpecCatcher
32
33
  @ignore_branches = env_var_string_to_array(ENV['FSC_IGNORE_BRANCHES'])
33
34
  @silent_mode = env_var_string_to_bool(ENV['FSC_SILENT_MODE'])
34
35
  @rerun_file_only = env_var_string_to_bool(ENV['FSC_RERUN_FILE_ONLY'])
36
+ @list_child_specs = env_var_string_to_bool(ENV['FSC_LIST_CHILD_SPECS'])
35
37
  @rspec_usage_patterns = env_var_string_to_pairs(ENV['FSC_USAGE_PATTERNS'])
36
38
  @excluded_tags = env_var_string_to_tags(ENV['FSC_EXCLUDED_TAGS'])
37
39
  @output_file = ENV['FSC_OUTPUT_FILE']
@@ -44,6 +46,8 @@ module FlakeySpecCatcher
44
46
  @manual_rerun_usage = @cli_override.rerun_usage
45
47
  @use_parent = @cli_override.use_parent
46
48
  @repeat_factor = @cli_override.repeat_factor if @cli_override.repeat_factor.to_i.positive?
49
+ @break_on_first_failure = @cli_override.break_on_first_failure
50
+ @list_child_specs = @cli_override.list_child_specs unless @cli_override.list_child_specs.nil?
47
51
  @enable_runs = @cli_override.enable_runs
48
52
  @dry_run = @cli_override.dry_run
49
53
  @split_nodes = @cli_override.split_nodes unless @cli_override.split_nodes.nil?
@@ -55,6 +59,7 @@ module FlakeySpecCatcher
55
59
  end
56
60
  @output_file = set_output_file
57
61
  @verbose = @cli_override.verbose
62
+ @test_options = @cli_override.test_options
58
63
  end
59
64
  # rubocop:enable Metrics/AbcSize
60
65
 
@@ -167,7 +172,7 @@ module FlakeySpecCatcher
167
172
  end
168
173
  end
169
174
 
170
- # rubocop:disable Metrics/CyclomaticComplexity
175
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
171
176
  def override_user_config(env_var, env_value)
172
177
  case env_var
173
178
  when 'FSC_REPEAT_FACTOR'
@@ -180,6 +185,8 @@ module FlakeySpecCatcher
180
185
  @silent_mode = env_var_string_to_bool(env_value)
181
186
  when 'FSC_RERUN_FILE_ONLY'
182
187
  @rerun_file_only = env_var_string_to_bool(env_value)
188
+ when 'FSC_LIST_CHILD_SPECS'
189
+ @list_child_specs = env_var_string_to_bool(env_value)
183
190
  when 'FSC_USAGE_PATTERNS'
184
191
  @rspec_usage_patterns = env_var_string_to_pairs(env_value)
185
192
  when 'FSC_EXCLUDED_TAGS'
@@ -188,6 +195,6 @@ module FlakeySpecCatcher
188
195
  @output_file = env_value
189
196
  end
190
197
  end
191
- # rubocop:enable Metrics/CyclomaticComplexity
198
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength
192
199
  end
193
200
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FlakeySpecCatcher
4
- VERSION = '0.9.7'
4
+ VERSION = '0.11.1'
5
5
  end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flakey_spec_catcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.7
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Watson
8
8
  - Mikey Hargiss
9
9
  - Ben Nelson
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-05-18 00:00:00.000000000 Z
13
+ date: 2021-10-14 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
@@ -18,14 +18,28 @@ dependencies:
18
18
  requirements:
19
19
  - - "~>"
20
20
  - !ruby/object:Gem::Version
21
- version: '3.8'
21
+ version: '3.10'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - "~>"
27
27
  - !ruby/object:Gem::Version
28
- version: '3.8'
28
+ version: '3.10'
29
+ - !ruby/object:Gem::Dependency
30
+ name: byebug
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '11.1'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '11.1'
29
43
  - !ruby/object:Gem::Dependency
30
44
  name: climate_control
31
45
  requirement: !ruby/object:Gem::Requirement
@@ -46,29 +60,43 @@ dependencies:
46
60
  requirements:
47
61
  - - "~>"
48
62
  - !ruby/object:Gem::Version
49
- version: '12.3'
63
+ version: '13.0'
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - "~>"
69
+ - !ruby/object:Gem::Version
70
+ version: '13.0'
71
+ - !ruby/object:Gem::Dependency
72
+ name: rubocop
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - "~>"
76
+ - !ruby/object:Gem::Version
77
+ version: 0.93.1
50
78
  type: :development
51
79
  prerelease: false
52
80
  version_requirements: !ruby/object:Gem::Requirement
53
81
  requirements:
54
82
  - - "~>"
55
83
  - !ruby/object:Gem::Version
56
- version: '12.3'
84
+ version: 0.93.1
57
85
  - !ruby/object:Gem::Dependency
58
86
  name: simplecov
59
87
  requirement: !ruby/object:Gem::Requirement
60
88
  requirements:
61
89
  - - "~>"
62
90
  - !ruby/object:Gem::Version
63
- version: '0.17'
91
+ version: '0.19'
64
92
  type: :development
65
93
  prerelease: false
66
94
  version_requirements: !ruby/object:Gem::Requirement
67
95
  requirements:
68
96
  - - "~>"
69
97
  - !ruby/object:Gem::Version
70
- version: '0.17'
71
- description:
98
+ version: '0.19'
99
+ description:
72
100
  email:
73
101
  - bwatson@instructure.com
74
102
  - mhargiss@instructure.com
@@ -102,12 +130,12 @@ files:
102
130
  - lib/flakey_spec_catcher/version.rb
103
131
  - lib/helpers/colorize.rb
104
132
  - lib/helpers/indent_string.rb
105
- homepage:
133
+ homepage:
106
134
  licenses:
107
135
  - MIT
108
136
  metadata:
109
137
  allowed_push_host: https://rubygems.org
110
- post_install_message:
138
+ post_install_message:
111
139
  rdoc_options: []
112
140
  require_paths:
113
141
  - lib
@@ -115,15 +143,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
115
143
  requirements:
116
144
  - - ">="
117
145
  - !ruby/object:Gem::Version
118
- version: '2.3'
146
+ version: '2.6'
119
147
  required_rubygems_version: !ruby/object:Gem::Requirement
120
148
  requirements:
121
149
  - - ">="
122
150
  - !ruby/object:Gem::Version
123
151
  version: '0'
124
152
  requirements: []
125
- rubygems_version: 3.1.3
126
- signing_key:
153
+ rubygems_version: 3.0.1
154
+ signing_key:
127
155
  specification_version: 4
128
156
  summary: Run new or changed specs many times to prevent unreliable specs
129
157
  test_files: []