Class: RSpec::Core::Bisect::ExampleMinimizer

Inherits:
Object
  • Object
show all
Defined in:
lib/rspec/core/bisect/example_minimizer.rb

Overview

Contains the core bisect logic. Searches for examples we can ignore by repeatedly running different subsets of the suite.

Defined Under Namespace

Classes: ExampleRange

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(shell_command, runner, notifier) ⇒ ExampleMinimizer

Returns a new instance of ExampleMinimizer



13
14
15
16
17
# File 'lib/rspec/core/bisect/example_minimizer.rb', line 13

def initialize(shell_command, runner, notifier)
  @shell_command = shell_command
  @runner        = runner
  @notifier      = notifier
end

Instance Attribute Details

#all_example_idsObject (readonly)

Returns the value of attribute all_example_ids



10
11
12
# File 'lib/rspec/core/bisect/example_minimizer.rb', line 10

def all_example_ids
  @all_example_ids
end

#failed_example_idsObject (readonly)

Returns the value of attribute failed_example_ids



10
11
12
# File 'lib/rspec/core/bisect/example_minimizer.rb', line 10

def failed_example_ids
  @failed_example_ids
end

#remaining_idsObject

Returns the value of attribute remaining_ids



11
12
13
# File 'lib/rspec/core/bisect/example_minimizer.rb', line 11

def remaining_ids
  @remaining_ids
end

#runnerObject (readonly)

Returns the value of attribute runner



10
11
12
# File 'lib/rspec/core/bisect/example_minimizer.rb', line 10

def runner
  @runner
end

#shell_commandObject (readonly)

Returns the value of attribute shell_command



10
11
12
# File 'lib/rspec/core/bisect/example_minimizer.rb', line 10

def shell_command
  @shell_command
end

Instance Method Details

#bisect(candidate_ids) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
# File 'lib/rspec/core/bisect/example_minimizer.rb', line 33

def bisect(candidate_ids)
  notify(:bisect_dependency_check_started)
  if get_expected_failures_for?([])
    notify(:bisect_dependency_check_failed)
    self.remaining_ids = []
    return
  end
  notify(:bisect_dependency_check_passed)

  bisect_over(candidate_ids)
end

#bisect_over(candidate_ids) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/rspec/core/bisect/example_minimizer.rb', line 45

def bisect_over(candidate_ids)
  return if candidate_ids.one?

  notify(
    :bisect_round_started,
    :candidate_range => example_range(candidate_ids),
    :candidates_count => candidate_ids.size
  )

  slice_size = (candidate_ids.length / 2.0).ceil
  lhs, rhs = candidate_ids.each_slice(slice_size).to_a

  ids_to_ignore, duration = track_duration do
    [lhs, rhs].find do |ids|
      get_expected_failures_for?(remaining_ids - ids)
    end
  end

  if ids_to_ignore
    self.remaining_ids -= ids_to_ignore
    notify(
      :bisect_round_ignoring_ids,
      :ids_to_ignore => ids_to_ignore,
      :ignore_range => example_range(ids_to_ignore),
      :remaining_ids => remaining_ids,
      :duration => duration
    )
    bisect_over(candidate_ids - ids_to_ignore)
  else
    notify(
      :bisect_round_detected_multiple_culprits,
      :duration => duration
    )
    bisect_over(lhs)
    bisect_over(rhs)
  end
end

#currently_needed_idsObject



83
84
85
# File 'lib/rspec/core/bisect/example_minimizer.rb', line 83

def currently_needed_ids
  remaining_ids + failed_example_ids
end

#find_minimal_reproObject



19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/rspec/core/bisect/example_minimizer.rb', line 19

def find_minimal_repro
  prep

  _, duration = track_duration do
    bisect(non_failing_example_ids)
  end

  notify(:bisect_complete, :duration => duration,
                           :original_non_failing_count => non_failing_example_ids.size,
                           :remaining_count => remaining_ids.size)

  remaining_ids + failed_example_ids
end

#repro_command_for_currently_needed_idsObject



87
88
89
90
# File 'lib/rspec/core/bisect/example_minimizer.rb', line 87

def repro_command_for_currently_needed_ids
  return shell_command.repro_command_from(currently_needed_ids) if remaining_ids
  "(Not yet enough information to provide any repro command)"
end