Class: TestBisect::BisectTask

Inherits:
Rake::TaskLib
  • Object
show all
Defined in:
lib/test_bisect.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name = :bisect) {|_self| ... } ⇒ BisectTask

Create a test bisect task if the test task which runs the tests is not “test” then specify is as the second arg.

Yields:

  • (_self)

Yield Parameters:



19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/test_bisect.rb', line 19

def initialize(name=:bisect)
  @name = name
  @test_task_name = :test
  # might as well take the last one
  ObjectSpace.each_object(Rake::TestTask) do |obj|
    @test_task = obj if obj != self
  end
  @suspects = @test_task.instance_variable_get(:@test_files) || []
  @suspects += FileList[@test_task.pattern]
  yield self if block_given?
  define
end

Instance Attribute Details

#nameObject

Returns the value of attribute name.



6
7
8
# File 'lib/test_bisect.rb', line 6

def name
  @name
end

#suspectsObject

We try to get the list of suspects from the test task, but they can be manually specified here



14
15
16
# File 'lib/test_bisect.rb', line 14

def suspects
  @suspects
end

#test_task_nameObject

We assume the task used to run the tests is “test” but if not, specify here



10
11
12
# File 'lib/test_bisect.rb', line 10

def test_task_name
  @test_task_name
end

Instance Method Details

#bisect(suspects, victim) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/test_bisect.rb', line 42

def bisect(suspects, victim)
  return suspects[0] if suspects.size == 1

  pivot = suspects.size / 2
  suspects.partition {|file| suspects.index(file) < pivot }.each do |part|
    begin
      @test_task.test_files = part
      Rake::Task[@test_task_name].reenable
      Rake::Task[@test_task_name].invoke
      puts "------ PASSED -------"
      next
    rescue RuntimeError => e
      if e.message =~ /Command failed with status/
        puts "------ FAILED -------"
        return bisect(part, victim)
      else
        raise
      end
    end
  end
end

#defineObject



32
33
34
35
36
37
38
39
40
# File 'lib/test_bisect.rb', line 32

def define
  desc "Bisect test suite files to find file which makes victim fail"
  task @name, [:victim] do |task, args|
    @test_task.pattern = nil
    criminal = bisect(@suspects, args.victim)
    puts "FOUND: #{criminal}"
  end
  self
end