flakey_spec_catcher 0.10.0 → 0.12.0

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: 9894969be42fdb7dfafa961942ce16b1313ca3cffdc746d9613ebe1398d39069
4
- data.tar.gz: 75238a79f25ddb8cec6fd60064e9f06d5f5651b8bb3c27e423f317f653f65774
3
+ metadata.gz: 306e789630ec567368871033c6334208c08a77e69bf901d76d6a2f0f1135470d
4
+ data.tar.gz: c80514cf76ad55fceda815f217e070f67659feff6bdd6ab923356cd42c722267
5
5
  SHA512:
6
- metadata.gz: d3698a10fd2c5d4ae75f3fe0250d7578a82906eb6ad478c759756911501b8f53125a63f1ced325e51c6115a9f76c7ac2264ae28a42c8b65273376186e8e7aa34
7
- data.tar.gz: 440e5ef180775556f3292548330cf9572db13d82394921fbbca6053b37ed4c088aa5c37b9dcb06ab2fb4049879c7fe2a093a60cf05da649abb950bf01d0af6cf
6
+ metadata.gz: 87c7f748c9577946ab735549729b5695978853225e0b10b01c205ffcbaab28db4140dada4e498eed2d169bcc26e2b940ac169002eda5bc92718159c6201996d2
7
+ data.tar.gz: 1f10d9cd60b5dd635c8e8759a54df20d54e467882c3c5e95ef2dad6ba3530ee99719371162032aa6775d11e3827db02cb2e1139cbf376763faa18006d98a8bd0
@@ -31,6 +31,7 @@ Gem::Specification.new do |gem|
31
31
  gem.required_ruby_version = '>= 2.6'
32
32
 
33
33
  gem.add_dependency 'rspec', '~> 3.10'
34
+ gem.add_dependency 'timecop', '~> 0.9'
34
35
  gem.add_development_dependency 'byebug', '~> 11.1'
35
36
  gem.add_development_dependency 'climate_control', '~> 0.2'
36
37
  gem.add_development_dependency 'rake', '~> 13.0'
@@ -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,24 @@ 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
+
135
+ # Don't build the file level context into spec tree
136
+ return unless parent_scope =~ /:/
137
+
138
+ @spec_tree[parent_scope] = if @spec_tree[parent_scope]
139
+ @spec_tree[parent_scope] << current_scope
140
+ else
141
+ [current_scope]
142
+ end
115
143
  end
116
144
  end
117
145
  end
@@ -9,6 +9,7 @@ module FlakeySpecCatcher
9
9
  class CliOverride
10
10
  attr_reader :rerun_patterns, :rerun_usage, :repeat_factor, :enable_runs, :excluded_tags, :use_parent, :dry_run
11
11
  attr_reader :output_file, :split_nodes, :split_index, :verbose, :test_options, :break_on_first_failure
12
+ attr_reader :list_child_specs, :random_timing
12
13
 
13
14
  def initialize
14
15
  @dry_run = false
@@ -60,6 +61,14 @@ module FlakeySpecCatcher
60
61
  @break_on_first_failure = break_on_first_failure
61
62
  end
62
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
+
68
+ opts.on('--random-timing', 'Run Specs at random times') do |random_timing|
69
+ @random_timing = random_timing
70
+ end
71
+
63
72
  opts.on('-e', '--excluded-tags=EXCLUDED_TAGS',
64
73
  'Specify tags to exclude in a comma separated list') do |tags|
65
74
  @excluded_tags = parse_tags(tags)
@@ -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,34 @@ module FlakeySpecCatcher
171
172
  @rerun_capsules.push(FlakeySpecCatcher::RerunCapsule.new(testcase: testcase, usage: usage))
172
173
  end
173
174
  end
175
+
176
+ def transform_file_level_change(test, tree)
177
+ # Map file level changes to the highest level Example Group in the tree
178
+ if test =~ /:/
179
+ test
180
+ else
181
+ tree.keys.first
182
+ end
183
+ end
184
+
185
+ def transform_parent_specs(tests)
186
+ transformed_tests = []
187
+
188
+ tests.each do |test|
189
+ capsule = @git_controller.capsule_manager.change_capsules.find { |c| c.file_name == test.split(':')[0] }
190
+ spec_tree = capsule.spec_tree
191
+ test = transform_file_level_change(test, spec_tree)
192
+ # If test is a key in the spec_tree, it's an example group, so we queue up its descendant examples
193
+ if spec_tree[test]
194
+ spec_tree[test].each do |child|
195
+ transformed_tests << transform_parent_specs([child]).flatten
196
+ end
197
+ # Else test is just an example
198
+ else
199
+ transformed_tests << test
200
+ end
201
+ end
202
+ transformed_tests
203
+ end
174
204
  end
175
205
  end
@@ -13,13 +13,15 @@ module FlakeySpecCatcher
13
13
  # This class will then organize and output the results accordingly.
14
14
  class RspecResult
15
15
  attr_accessor :description, :location, :total_times_run, :total_failures
16
+ attr_reader :spec_start_times, :failures
16
17
 
17
- def initialize(description, location, exception_message = nil)
18
+ def initialize(description, location, spec_start_times, exception_message = nil)
18
19
  @description = description
19
20
  @location = location
20
21
  @total_times_run = 1
21
22
  @total_failures = exception_message ? 1 : 0
22
23
  @failures = []
24
+ @spec_start_times = spec_start_times
23
25
  add_failure(exception_message) if exception_message
24
26
  end
25
27
 
@@ -34,30 +36,47 @@ module FlakeySpecCatcher
34
36
 
35
37
  def add_failure(exception_message)
36
38
  failure = @failures.find { |f| f.exception_message == exception_message }
37
- failure ? failure.add_failure : @failures.push(RSpecFailure.new(exception_message))
39
+ if failure
40
+ failure.add_failure(current_spec_start_time)
41
+ else
42
+ @failures.push(RSpecFailure.new(exception_message, current_spec_start_time))
43
+ end
44
+ end
45
+
46
+ def current_spec_start_time
47
+ @spec_start_times[@total_times_run - 1]
38
48
  end
39
49
 
40
50
  def print_results
41
51
  puts "\n#{@description.yellow} (#{location})
42
52
  \nFAILED #{total_failures} / #{total_times_run} times"
43
53
 
44
- @failures.each do |f|
45
- puts "#{f.count.to_s.indent(2)} times with exception message:"
46
- puts f.exception_message.indent(4).red.to_s
47
- end
54
+ @failures.each { |failure| puts failure.failure_summary }
48
55
  end
49
56
 
50
57
  # Simple class to contain failed example data
51
58
  class RSpecFailure
52
- attr_reader :exception_message, :count
59
+ attr_reader :exception_message, :count, :spec_start_times
53
60
 
54
- def initialize(exception_message)
61
+ def initialize(exception_message, spec_start_time = nil)
55
62
  @exception_message = exception_message
56
63
  @count = 1
64
+ @spec_start_times = [spec_start_time].compact
57
65
  end
58
66
 
59
- def add_failure
67
+ def add_failure(spec_start_time = nil)
60
68
  @count += 1
69
+ @spec_start_times.push(spec_start_time) unless spec_start_time.nil?
70
+ end
71
+
72
+ def failure_summary
73
+ summary = "#{count.to_s.indent(2)} times with exception message:\n"
74
+ summary += exception_message.indent(4).red.to_s
75
+ return summary if spec_start_times.empty?
76
+
77
+ summary += "\n\nFailed at the following times:\n".indent(2)
78
+ summary += spec_start_times.map { |time| time.indent(4).yellow.to_s }.join("\n").to_s
79
+ summary
61
80
  end
62
81
  end
63
82
  end
@@ -12,14 +12,25 @@ module FlakeySpecCatcher
12
12
  # distinct example. It also provides helpers for adding new results,
13
13
  # displaying aggregate results, and checking the state of the collection.
14
14
  class RspecResultManager
15
+ attr_reader :results
16
+
15
17
  def initialize(rspec_result_class)
16
18
  @result_class = rspec_result_class
17
19
  @results = []
20
+ @spec_start_times = []
21
+ end
22
+
23
+ def track_spec_start_times(spec_times)
24
+ @spec_start_times = spec_times
18
25
  end
19
26
 
20
27
  def add_result(desc, location, message = nil)
21
28
  result = @results.find { |r| r.location == location }
22
- result ? result.add_run(message) : @results.push(@result_class.new(desc, location, message))
29
+ if result
30
+ result.add_run(message)
31
+ else
32
+ @results.push(@result_class.new(desc, location, @spec_start_times, message))
33
+ end
23
34
  end
24
35
 
25
36
  def print_results
@@ -7,10 +7,11 @@ require_relative './user_config'
7
7
  require_relative './rerun_manager'
8
8
  require_relative './rspec_result_manager'
9
9
  require_relative './event_listener.rb'
10
+ require_relative './timecop_manager.rb'
10
11
 
11
12
  module FlakeySpecCatcher
12
13
  class Runner
13
- attr_reader :user_config, :rerun_manager, :git_controller, :test_run_count
14
+ attr_reader :user_config, :rerun_manager, :git_controller, :test_run_count, :random_dates
14
15
 
15
16
  def initialize(test_mode: false,
16
17
  user_config: FlakeySpecCatcher::UserConfig.new,
@@ -18,17 +19,17 @@ module FlakeySpecCatcher
18
19
  result_manager: FlakeySpecCatcher::RspecResultManager.new(FlakeySpecCatcher::RspecResult),
19
20
  rerun_manager: FlakeySpecCatcher::RerunManager.new(git_controller: git_controller,
20
21
  user_config: user_config))
21
-
22
22
  @git_controller = git_controller
23
23
  @user_config = user_config
24
24
  @rerun_manager = rerun_manager
25
25
  @rspec_result_manager = result_manager
26
26
  @test_run_count = 0
27
27
  @temp_output_file = @user_config.output_file + 'temp' unless @user_config.output_file == File::NULL
28
+ enable_random_timing
28
29
  end
29
30
 
30
31
  # Debug Methods
31
- # rubocop:disable Metrics/AbcSize
32
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
32
33
  def show_settings
33
34
  puts 'Flakey Spec Catcher Settings:'
34
35
  puts " Current Branch: #{@git_controller.branch}" unless @user_config.use_parent
@@ -39,12 +40,13 @@ module FlakeySpecCatcher
39
40
  puts " Break on first failure: #{@user_config.break_on_first_failure}" if @user_config.break_on_first_failure
40
41
  puts " Node Total: #{@user_config.split_nodes}" if @user_config.split_nodes
41
42
  puts " Node Index: #{@user_config.split_index}" if @user_config.split_index
43
+ puts ' Random Timing: Enabled' if @user_config.random_timing
42
44
  puts " Changed Specs Detected: #{@git_controller.changed_examples}"
43
45
  return if @user_config.output_file == File::NULL
44
46
 
45
47
  puts " Verbose Output Path: #{@user_config.output_file}"
46
48
  end
47
- # rubocop:enable Metrics/AbcSize
49
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
48
50
 
49
51
  def rerun_preview
50
52
  puts "\n********************************************"
@@ -73,8 +75,8 @@ module FlakeySpecCatcher
73
75
 
74
76
  status = 0
75
77
  @rerun_manager.rerun_capsules.sort.each do |capsule|
76
- @user_config.repeat_factor.times do
77
- iteration_status = handle_capsule_rerun(capsule)
78
+ @user_config.repeat_factor.times do |iteration|
79
+ iteration_status = timecop_wrapper(capsule, iteration)
78
80
  status = [status, iteration_status].max
79
81
  break if @user_config.break_on_first_failure && !status.zero?
80
82
  end
@@ -127,6 +129,23 @@ module FlakeySpecCatcher
127
129
  end
128
130
  end
129
131
 
132
+ def enable_random_timing
133
+ @random_dates = if @user_config.random_timing
134
+ FlakeySpecCatcher::TimecopManager.generate_dates(@user_config.repeat_factor)
135
+ else
136
+ []
137
+ end
138
+ @rspec_result_manager.track_spec_start_times(@random_dates)
139
+ end
140
+
141
+ def timecop_wrapper(capsule, iteration)
142
+ if @user_config.random_timing
143
+ FlakeySpecCatcher::TimecopManager.randomly_travel_in_time(@random_dates[iteration]) { handle_capsule_rerun(capsule) }
144
+ else
145
+ handle_capsule_rerun(capsule)
146
+ end
147
+ end
148
+
130
149
  def print_flakey_specs_detected_message
131
150
  puts "\n**********************************************".magenta
132
151
  puts ' Flakiness Detected!'.magenta
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+ require 'time'
5
+ require 'timecop'
6
+
7
+ module FlakeySpecCatcher
8
+ class TimecopManager
9
+ def self.randomly_travel_in_time(date)
10
+ status = 0
11
+ Timecop.travel(date) do
12
+ status = yield
13
+ end
14
+ status
15
+ end
16
+
17
+ def self.current_month
18
+ Time.now.month
19
+ end
20
+
21
+ def self.current_year
22
+ Time.now.year
23
+ end
24
+
25
+ def self.random_month
26
+ (current_month..12).to_a.sample
27
+ end
28
+
29
+ def self.random_seconds
30
+ [0, 59].sample
31
+ end
32
+
33
+ def self.random_minutes
34
+ [0, (1..58).to_a.sample, 59].sample
35
+ end
36
+
37
+ def self.random_day(year, month)
38
+ last_day = last_day_of_month(year, month).day
39
+ [1, (1..last_day).to_a.sample, last_day].sample
40
+ end
41
+
42
+ def self.last_day_of_month(year, month)
43
+ day = Date.new(year, month, -1).day
44
+ Time.local(year, month, day, 23, 59, 59)
45
+ end
46
+
47
+ def self.last_day_of_year(year)
48
+ Time.local(year, 12, 31, 11, 59, 59)
49
+ end
50
+
51
+ def self.random_hour
52
+ [0, (1..22).to_a.sample, 23].sample
53
+ end
54
+
55
+ def self.random_date
56
+ year = current_year
57
+ month = random_month
58
+ day = random_day(year, month)
59
+ Time.local(year, month, day, random_hour, random_minutes, random_seconds)
60
+ end
61
+
62
+ def self.prioritized_dates
63
+ [last_day_of_month(current_year, current_month), last_day_of_year(current_year)]
64
+ end
65
+
66
+ def self.generate_dates(count)
67
+ dates = prioritized_dates
68
+ (count - prioritized_dates.count).times { dates << random_date }
69
+ dates.map(&:iso8601).slice(0, count)
70
+ end
71
+ end
72
+ end
@@ -3,20 +3,18 @@
3
3
  require_relative './cli_override'
4
4
  module FlakeySpecCatcher
5
5
  # UserConfig class
6
- #
7
6
  # Captures user-defined settings to configure RSpec re-run settings.
8
7
 
9
8
  class UserConfig
10
- attr_reader :repeat_factor, :ignore_files, :ignore_branches, :silent_mode
11
- attr_reader :rerun_file_only, :rspec_usage_patterns, :excluded_tags
12
- attr_reader :manual_rerun_patterns, :manual_rerun_usage
13
- attr_reader :enable_runs, :output_file, :use_parent, :dry_run
14
- attr_reader :split_nodes, :split_index, :verbose, :test_options
15
- attr_reader :break_on_first_failure
9
+ attr_reader :repeat_factor, :ignore_files, :ignore_branches, :silent_mode, :rerun_file_only, :rspec_usage_patterns
10
+ attr_reader :excluded_tags, :manual_rerun_patterns, :manual_rerun_usage, :enable_runs, :output_file
11
+ attr_reader :use_parent, :dry_run, :split_nodes, :split_index, :verbose, :test_options, :break_on_first_failure
12
+ attr_reader :list_child_specs, :random_timing
16
13
 
17
14
  USER_CONFIG_ENV_VARS = %w[FSC_REPEAT_FACTOR FSC_IGNORE_FILES FSC_IGNORE_BRANCHES
18
15
  FSC_SILENT_MODE FSC_RERUN_FILE_ONLY FSC_USAGE_PATTERNS
19
- FSC_EXCLUDED_TAGS FSC_OUTPUT_FILE].freeze
16
+ FSC_EXCLUDED_TAGS FSC_OUTPUT_FILE FSC_LIST_CHILD_SPECS
17
+ FSC_RANDOM_TIMING].freeze
20
18
 
21
19
  def initialize(cli_override: CliOverride.new)
22
20
  apply_env_var_settings
@@ -26,13 +24,15 @@ module FlakeySpecCatcher
26
24
 
27
25
  private
28
26
 
29
- # rubocop:disable Metrics/AbcSize
27
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
30
28
  def apply_env_var_settings
31
29
  @repeat_factor = initialize_repeat_factor(ENV['FSC_REPEAT_FACTOR'])
32
30
  @ignore_files = env_var_string_to_array(ENV['FSC_IGNORE_FILES'])
33
31
  @ignore_branches = env_var_string_to_array(ENV['FSC_IGNORE_BRANCHES'])
34
32
  @silent_mode = env_var_string_to_bool(ENV['FSC_SILENT_MODE'])
35
33
  @rerun_file_only = env_var_string_to_bool(ENV['FSC_RERUN_FILE_ONLY'])
34
+ @list_child_specs = env_var_string_to_bool(ENV['FSC_LIST_CHILD_SPECS'])
35
+ @random_timing = env_var_string_to_bool(ENV['FSC_RANDOM_TIMING'])
36
36
  @rspec_usage_patterns = env_var_string_to_pairs(ENV['FSC_USAGE_PATTERNS'])
37
37
  @excluded_tags = env_var_string_to_tags(ENV['FSC_EXCLUDED_TAGS'])
38
38
  @output_file = ENV['FSC_OUTPUT_FILE']
@@ -46,6 +46,8 @@ module FlakeySpecCatcher
46
46
  @use_parent = @cli_override.use_parent
47
47
  @repeat_factor = @cli_override.repeat_factor if @cli_override.repeat_factor.to_i.positive?
48
48
  @break_on_first_failure = @cli_override.break_on_first_failure
49
+ @list_child_specs = @cli_override.list_child_specs unless @cli_override.list_child_specs.nil?
50
+ @random_timing = @cli_override.random_timing unless @cli_override.random_timing.nil?
49
51
  @enable_runs = @cli_override.enable_runs
50
52
  @dry_run = @cli_override.dry_run
51
53
  @split_nodes = @cli_override.split_nodes unless @cli_override.split_nodes.nil?
@@ -59,7 +61,7 @@ module FlakeySpecCatcher
59
61
  @verbose = @cli_override.verbose
60
62
  @test_options = @cli_override.test_options
61
63
  end
62
- # rubocop:enable Metrics/AbcSize
64
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
63
65
 
64
66
  def override_settings
65
67
  apply_cli_override
@@ -107,11 +109,7 @@ module FlakeySpecCatcher
107
109
  end
108
110
 
109
111
  def env_var_string_to_bool(env_var)
110
- if env_var.to_s.casecmp('true').zero?
111
- true
112
- else
113
- false
114
- end
112
+ env_var.to_s.casecmp('true').zero?
115
113
  end
116
114
 
117
115
  def env_var_string_to_pairs(env_var)
@@ -170,7 +168,7 @@ module FlakeySpecCatcher
170
168
  end
171
169
  end
172
170
 
173
- # rubocop:disable Metrics/CyclomaticComplexity
171
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
174
172
  def override_user_config(env_var, env_value)
175
173
  case env_var
176
174
  when 'FSC_REPEAT_FACTOR'
@@ -183,6 +181,10 @@ module FlakeySpecCatcher
183
181
  @silent_mode = env_var_string_to_bool(env_value)
184
182
  when 'FSC_RERUN_FILE_ONLY'
185
183
  @rerun_file_only = env_var_string_to_bool(env_value)
184
+ when 'FSC_LIST_CHILD_SPECS'
185
+ @list_child_specs = env_var_string_to_bool(env_value)
186
+ when 'FSC_RANDOM_TIMING'
187
+ @random_timing = env_var_string_to_bool(env_value)
186
188
  when 'FSC_USAGE_PATTERNS'
187
189
  @rspec_usage_patterns = env_var_string_to_pairs(env_value)
188
190
  when 'FSC_EXCLUDED_TAGS'
@@ -191,6 +193,6 @@ module FlakeySpecCatcher
191
193
  @output_file = env_value
192
194
  end
193
195
  end
194
- # rubocop:enable Metrics/CyclomaticComplexity
196
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength
195
197
  end
196
198
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FlakeySpecCatcher
4
- VERSION = '0.10.0'
4
+ VERSION = '0.12.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flakey_spec_catcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Watson
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2021-07-28 00:00:00.000000000 Z
13
+ date: 2021-11-08 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
@@ -26,6 +26,20 @@ dependencies:
26
26
  - - "~>"
27
27
  - !ruby/object:Gem::Version
28
28
  version: '3.10'
29
+ - !ruby/object:Gem::Dependency
30
+ name: timecop
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '0.9'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '0.9'
29
43
  - !ruby/object:Gem::Dependency
30
44
  name: byebug
31
45
  requirement: !ruby/object:Gem::Requirement
@@ -126,6 +140,7 @@ files:
126
140
  - lib/flakey_spec_catcher/rspec_result.rb
127
141
  - lib/flakey_spec_catcher/rspec_result_manager.rb
128
142
  - lib/flakey_spec_catcher/runner.rb
143
+ - lib/flakey_spec_catcher/timecop_manager.rb
129
144
  - lib/flakey_spec_catcher/user_config.rb
130
145
  - lib/flakey_spec_catcher/version.rb
131
146
  - lib/helpers/colorize.rb