flakey_spec_catcher 0.8.0 → 0.9.0

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: 15d0a03b7d5147dc7d4ef97bd1868c53a9a279ae767cdc652adbfdfec076ba89
4
- data.tar.gz: a58a1f258d13ab6050275c20e702cd1283598fe8254cf79517a01edd50323fbc
3
+ metadata.gz: 7f845e77fb2900e6e7fca4c3de62b8104dd1c1844fba4b0881d9d9c77d3b65c0
4
+ data.tar.gz: 3611db64df625c5cc1506e400a5cd5d664da15bf254431835f245d6539b9fdaa
5
5
  SHA512:
6
- metadata.gz: ba2cb9723f0f04756c506eaf91608b9fec132f0ba5285d8594e0ec1c67ab1503bb5a87bdcc3e68aa64ab74479791cbcbb2b88d051c9b5faad8a35062448de3d7
7
- data.tar.gz: bc0207b9163c7a07a7398b8694125d503fbd7bda397d84bef7f34c37906a2efdca814ae31d10775ba4893473c7751e6e79c7e20676618a2ec52e31157b4023b8
6
+ metadata.gz: b314f343b5630fab71d1d95eeb0b08f371d7bf314b2b5045e33fbc7eaa6d088c17d86244ee0826cb338f0e74b515f66f2fa1e0b76874fe128cbb0cfac534aedb
7
+ data.tar.gz: 9efea9ff0b95595f1535fdff9ada0bd86822b716c01c7faec2edc48d6600c82a2b6dea07e0fba1a225f63a936720f75e8d74577b8102b3833bc693564e3bcf93
data/README.md CHANGED
@@ -11,7 +11,7 @@ There are two primary usecases for flakey_spec_catcher (FSC):
11
11
  commit many times.
12
12
 
13
13
  2. Manual Re-runs - Specify a test to re-run many times regardless of whether it has
14
- corresponding changes in yuor commit.
14
+ corresponding changes in your commit.
15
15
 
16
16
  FSC detects changes by running the equivalent of a git diff
17
17
  between the current branch's commit and the HEAD of Source Control Management (SCM)
@@ -70,7 +70,7 @@ you'll also need to ensure that FSC has access to any needed gems.
70
70
  It's best to do this by adding flakey_speec_catcher to your Gemfile via bundler
71
71
  and then running it with `bundle exec flakey_spec_catcher`
72
72
 
73
- ### In what cases if FSC not suitable?
73
+ ### In what cases is FSC not suitable?
74
74
 
75
75
  Since FSC by default re-runs tests at the smallest possible level of
76
76
  change (a single test case or example), it is not suitable to allow it to run
@@ -72,7 +72,7 @@ module FlakeySpecCatcher
72
72
  # Not sure if we need to check for description in quotes
73
73
  # spec_scope = /^\s*(#{SCOPE_SPECIFIERS.join("|")})\s*('.*'|".*").*do\s*$/
74
74
 
75
- /\s*(#{SCOPE_SPECIFIERS.join("|")}).*\s+do\s*$/
75
+ /\s*(#{SCOPE_SPECIFIERS.join("|")}).*\s+do.*$/
76
76
  end
77
77
 
78
78
  def line_matches_method_or_block(line)
@@ -37,8 +37,6 @@ module FlakeySpecCatcher
37
37
 
38
38
  opts.on('-r', '--repeat=REPEAT_FACTOR',
39
39
  'Specify a repeat factor for the manual re-run(s)') do |repeat|
40
- raise ArgumentError if @rerun_patterns.nil?
41
-
42
40
  parsed_repeat_factor = remove_formatter_quotes(repeat).to_i
43
41
  @repeat_factor = parsed_repeat_factor if parsed_repeat_factor.positive?
44
42
  end
@@ -20,8 +20,8 @@ module FlakeySpecCatcher
20
20
  attr_reader :capsule_manager
21
21
 
22
22
  def initialize(test_mode: false, capsule_manager: FlakeySpecCatcher::CapsuleManager.new)
23
+ @remote = find_git_remote
23
24
  @branch = find_remote_branch
24
- @remote = `git remote`.gsub(/\s+/, '')
25
25
  @capsule_manager = capsule_manager
26
26
  initialize_git_comparison(test_mode)
27
27
  parse_changes
@@ -34,7 +34,19 @@ module FlakeySpecCatcher
34
34
 
35
35
  private
36
36
 
37
+ # Use 'origin' unless otherwise specified
38
+ def find_git_remote
39
+ if ENV['FSC_GIT_REMOTE'].nil? || ENV['FSC_GIT_REMOTE'].strip.empty?
40
+ remotes = `git remote show`.split
41
+ remotes.empty? ? nil : remotes[0]
42
+ else
43
+ ENV['FSC_GIT_REMOTE']
44
+ end
45
+ end
46
+
37
47
  def find_remote_branch
48
+ return nil if @remote.nil?
49
+
38
50
  working_branch = `git branch | grep '*'`.delete('*').gsub(/\s+/, '')
39
51
  # `git remote show origin` will show us if our branch is configured to push
40
52
  # to a non-master branch. Note that our push destination is what we're interested in
@@ -55,7 +67,7 @@ module FlakeySpecCatcher
55
67
  # dev/reports pushes to dev/reports (up to date)
56
68
  # master pushes to master (up to date)
57
69
 
58
- remote_branches = `git remote show origin`.split("\n")
70
+ remote_branches = `git remote show #{@remote}`.split("\n")
59
71
 
60
72
  # Separate 'dev/reports pushes to dev/reports (up to date)' into
61
73
  # ['dev/reports', 'dev/reports'] or [<LOCAL BRANCH>, <REMOTE BRANCH>]
@@ -78,7 +90,7 @@ module FlakeySpecCatcher
78
90
  end
79
91
 
80
92
  def initialize_git_comparison(test_mode)
81
- if !test_mode
93
+ if !test_mode && !@remote.nil?
82
94
  @working_commit_sha = `git rev-parse @`.gsub(/\s+/, '')
83
95
  @base_commit_sha = `git rev-parse #{@remote}/#{@branch}`.gsub(/\s+/, '')
84
96
  else
@@ -9,7 +9,7 @@ module FlakeySpecCatcher
9
9
  include Comparable
10
10
  attr_reader :usage, :testcase
11
11
 
12
- def initialize(usage: nil, testcase: '')
12
+ def initialize(usage: nil, testcase: [])
13
13
  @usage = initialize_usage(usage)
14
14
  @testcase = initialize_testcase(testcase)
15
15
  end
@@ -30,6 +30,10 @@ module FlakeySpecCatcher
30
30
  @testcase <=> other.testcase
31
31
  end
32
32
 
33
+ def ==(other)
34
+ usage == other.usage && testcase == other.testcase
35
+ end
36
+
33
37
  private
34
38
 
35
39
  def initialize_usage(usage)
@@ -42,9 +46,11 @@ module FlakeySpecCatcher
42
46
 
43
47
  def initialize_testcase(testcase)
44
48
  if testcase.nil? || testcase.empty?
45
- ''
46
- else
49
+ []
50
+ elsif testcase.is_a?(Array)
47
51
  testcase
52
+ else
53
+ raise "Error: expected array for testcase not #{testcase.class}"
48
54
  end
49
55
  end
50
56
  end
@@ -23,7 +23,7 @@ module FlakeySpecCatcher
23
23
  if @user_config.manual_rerun_patterns.nil?
24
24
  pair_reruns_with_usages
25
25
  else
26
- @rerun_capsules.clear
26
+ @rerun_capsules = []
27
27
  inject_manual_reruns(@user_config.manual_rerun_patterns,
28
28
  @user_config.manual_rerun_usage)
29
29
  end
@@ -59,57 +59,52 @@ module FlakeySpecCatcher
59
59
  def pair_reruns_with_usages
60
60
  reruns = tests_for_rerun
61
61
  configured_usage_patterns = @user_config.rspec_usage_patterns
62
-
63
62
  if configured_usage_patterns.count.zero?
64
63
  add_capsules_with_default_usage(reruns)
65
64
  return
66
65
  end
67
66
 
68
- reruns.each do |rerun|
69
- match_found = false
70
- configured_usage_patterns.each do |usage_pattern_pair|
71
- next if match_found
72
-
73
- pattern, usage = usage_pattern_pair
74
- if rerun =~ /#{pattern}/
75
- add_rerun_capsule(testcase: rerun, usage: usage)
76
- match_found = true
77
- end
67
+ configured_usage_patterns.each do |usage_pattern_pair|
68
+ tests = []
69
+ pattern, usage = usage_pattern_pair
70
+ reruns.each do |rerun|
71
+ tests.push rerun if rerun =~ /#{pattern}/
78
72
  end
79
- add_rerun_capsule(testcase: rerun) unless match_found
73
+ reruns -= tests
74
+ add_rerun_capsule(testcase: tests, usage: usage)
80
75
  end
76
+ add_rerun_capsule(testcase: reruns) if reruns.any?
81
77
  end
82
78
 
83
79
  # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
84
80
  def inject_manual_reruns(patterns, usage)
81
+ tests = []
85
82
  patterns.tr(' ', '').split(',').each do |pattern|
86
83
  # Check if file exists first and handle if user supplies testcase:line_number
87
84
  file_name = pattern.split(':')[0]
88
85
  line_number_present = pattern.split(':').count > 1
89
86
  matching_files = Dir.glob(file_name)
90
-
91
87
  # If no file matches are run, don't queue up re-runs
92
88
  if matching_files.count.zero?
93
89
  puts "Specified pattern #{pattern} did not match an existing file"
94
90
  raise ArgumentError
95
91
  end
96
-
97
92
  # It won't make sense to have multiple files to run with one specific line number
98
93
  if line_number_present
99
94
  if matching_files.count > 1
100
95
  puts "Specified pattern #{pattern} matched multiple files but a line number was given"
101
96
  raise ArgumentError
102
97
  else
103
- add_rerun_capsule(testcase: pattern, usage: usage)
98
+ tests.push pattern
104
99
  end
105
-
106
100
  # No line numbers, queue up all matching files
107
101
  else
108
102
  matching_files.each do |file|
109
- add_rerun_capsule(testcase: file, usage: usage)
103
+ tests.push file
110
104
  end
111
105
  end
112
106
  end
107
+ add_rerun_capsule(testcase: tests, usage: usage)
113
108
  end
114
109
  # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
115
110
 
@@ -131,13 +126,18 @@ module FlakeySpecCatcher
131
126
  end
132
127
 
133
128
  def add_capsules_with_default_usage(reruns)
134
- reruns.each do |rerun|
135
- @rerun_capsules.push(FlakeySpecCatcher::RerunCapsule.new(testcase: rerun))
136
- end
129
+ @rerun_capsules.push(FlakeySpecCatcher::RerunCapsule.new(testcase: reruns)) unless reruns.empty?
137
130
  end
138
131
 
139
- def add_rerun_capsule(testcase: '', usage: nil)
140
- @rerun_capsules.push(FlakeySpecCatcher::RerunCapsule.new(testcase: testcase, usage: usage))
132
+ def add_rerun_capsule(testcase: [], usage: nil)
133
+ return if testcase.empty?
134
+
135
+ capsule = @rerun_capsules.find { |cap| cap.usage == usage }
136
+ if capsule
137
+ capsule.testcase.push(testcase)
138
+ else
139
+ @rerun_capsules.push(FlakeySpecCatcher::RerunCapsule.new(testcase: testcase, usage: usage))
140
+ end
141
141
  end
142
142
  end
143
143
  end
@@ -44,10 +44,12 @@ module FlakeySpecCatcher
44
44
  def rerun_preview
45
45
  puts "\n********************************************"
46
46
  puts "Re-run Preview\n"
47
- @rerun_manager.rerun_capsules.sort.each do |capsule|
48
- rerun_msg = " Running #{capsule.testcase} #{@user_config.repeat_factor} times "
49
- rerun_msg += "using `#{capsule.usage}`" unless capsule.default_usage?
50
- puts rerun_msg
47
+ @rerun_manager.rerun_capsules.each do |capsule|
48
+ capsule.testcase.each do |test|
49
+ rerun_msg = " Running #{test} #{@user_config.repeat_factor} times "
50
+ rerun_msg += "using `#{capsule.usage}`" unless capsule.default_usage?
51
+ puts rerun_msg
52
+ end
51
53
  end
52
54
  puts "\n********************************************"
53
55
  end
@@ -55,8 +57,8 @@ module FlakeySpecCatcher
55
57
 
56
58
  def run_specs
57
59
  status = 0
58
- @user_config.repeat_factor.times do
59
- @rerun_manager.rerun_capsules.sort.each do |capsule|
60
+ @rerun_manager.rerun_capsules.sort.each do |capsule|
61
+ @user_config.repeat_factor.times do
60
62
  iteration_status = handle_capsule_rerun(capsule)
61
63
  status = [status, iteration_status].max
62
64
  end
@@ -85,11 +87,9 @@ module FlakeySpecCatcher
85
87
  end
86
88
 
87
89
  def invoke_custom_rspec_runner(usage, testcase)
88
- custom_usage_output = `#{usage} #{testcase}`
90
+ custom_usage_output = `#{usage} #{testcase.join(' ')}`
89
91
 
90
- if @user_config.output_file != '/dev/null'
91
- File.open(@user_config.output_file, 'a') { |f| f.puts custom_usage_output }
92
- end
92
+ File.open(@user_config.output_file, 'a') { |f| f.puts custom_usage_output } if @user_config.output_file != '/dev/null'
93
93
 
94
94
  $?.exitstatus # rubocop:disable Style/SpecialGlobalVars
95
95
  end
@@ -6,7 +6,6 @@ module FlakeySpecCatcher
6
6
  #
7
7
  # Captures user-defined settings to configure RSpec re-run settings.
8
8
 
9
- # rubocop:disable Metrics/ClassLength
10
9
  class UserConfig
11
10
  attr_reader :repeat_factor, :ignore_files, :ignore_branches, :silent_mode
12
11
  attr_reader :rerun_file_only, :rspec_usage_patterns, :excluded_tags
@@ -171,5 +170,4 @@ module FlakeySpecCatcher
171
170
  end
172
171
  # rubocop:enable Metrics/CyclomaticComplexity
173
172
  end
174
- # rubocop:enable Metrics/ClassLength
175
173
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FlakeySpecCatcher
4
- VERSION = '0.8.0'
4
+ VERSION = '0.9.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.8.0
4
+ version: 0.9.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: 2020-01-17 00:00:00.000000000 Z
13
+ date: 2020-02-07 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
@@ -122,8 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
122
  - !ruby/object:Gem::Version
123
123
  version: '0'
124
124
  requirements: []
125
- rubyforge_project:
126
- rubygems_version: 2.7.7
125
+ rubygems_version: 3.0.4
127
126
  signing_key:
128
127
  specification_version: 4
129
128
  summary: Run new or changed specs many times to prevent unreliable specs