File: test-fault-location-detector.rb

package info (click to toggle)
ruby-test-unit 3.7.7-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,348 kB
  • sloc: ruby: 16,403; makefile: 9
file content (188 lines) | stat: -rw-r--r-- 4,793 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# Copyright (C) 2012  Kouhei Sutou <kou@clear-code.com>
#
# License: Ruby's

require "test-unit"
require "test/unit/fault-location-detector"
require_relative "testunit-test-util"

class TestFaultLocationDetector < Test::Unit::TestCase
  include TestUnitTestUtil

  def setup
    @fetcher = Test::Unit::CodeSnippetFetcher.new
  end

  private
  def run_test_case(test_case)
    suite = test_case.suite
    result = Test::Unit::TestResult.new
    worker_context = Test::Unit::WorkerContext.new(nil, nil, result)
    suite.run(worker_context) {}
    result.faults[0]
  end

  def assert_detect(fault, target_line_number)
    detector = Test::Unit::FaultLocationDetector.new(fault, @fetcher)

    expected_backtrace_entries_until_detected = []
    fault.location.each do |backtrace_entry|
      expected_backtrace_entries_until_detected << backtrace_entry
      _, line_number, = detector.split_backtrace_entry(backtrace_entry)
      break if target_line_number == line_number
    end

    actual_backtrace_entries_until_detected = []
    fault.location.each do |backtrace_entry|
      actual_backtrace_entries_until_detected << backtrace_entry
      break if detector.target?(backtrace_entry)
    end

    assert_equal(expected_backtrace_entries_until_detected,
                 actual_backtrace_entries_until_detected)
  end

  module AlwaysFailAssertion
    private
    def assert_always_failed
      assert_true(false)
    end
  end

  class TestSourceLocation < self
    setup
    def setup_check_source_location(&_)
      unless lambda {}.respond_to?(:source_location)
        omit("Need Proc#source_location")
      end
    end

    def test_detected
      target_line_number = nil
      test_case = Class.new(Test::Unit::TestCase) do
        include AlwaysFailAssertion

        test "failed" do
          target_line_number = __LINE__; assert_always_failed
        end
      end

      fault = run_test_case(test_case)
      assert_detect(fault, target_line_number)
    end

    class TestOneLine < self
      def test_brace
        target_line_number = nil
        test_case = Class.new(Test::Unit::TestCase) do
          include AlwaysFailAssertion

          test("failed") {target_line_number = __LINE__; assert_always_failed}

          def other_method
            # body
          end
        end

        fault = run_test_case(test_case)
        assert_detect(fault, target_line_number)
      end

      def test_do_end
        target_line_number = nil
        test_case = Class.new(Test::Unit::TestCase) do
          include AlwaysFailAssertion

          test "failed" do target_line_number = __LINE__; assert_always_failed; end

          def other_method
            # body
          end
        end

        fault = run_test_case(test_case)
        assert_detect(fault, target_line_number)
      end
    end
  end

  class TestMethodName < self
    def test_in_anonymous_test_case
      test_case = Class.new(Test::Unit::TestCase) do
        include AlwaysFailAssertion

        class << self
          def target_line_number
            @target_line_number
          end

          def target_line_number=(line_number)
            @target_line_number = line_number
          end
        end

        def test_failed
          self.class.target_line_number = __LINE__; assert_always_failed
        end
      end

      fault = run_test_case(test_case)
      assert_detect(fault, test_case.target_line_number)
    end

    class NamedTestCase < Test::Unit::TestCase
      include AlwaysFailAssertion

      class << self
        def target_line_number
          @target_line_number
        end

        def target_line_number=(line_number)
          @target_line_number = line_number
        end
      end
    end

    def test_in_named_test_case
      # Define test method dynamically to avoid running this failed
      # test in the main test suite.
      NamedTestCase.class_eval do
        def test_failed
          self.class.target_line_number = __LINE__; assert_always_failed
        end
      end
      fault = run_test_case(NamedTestCase)
      assert_detect(fault, NamedTestCase.target_line_number)
    end

    def test_in_block
      test_case = Class.new(Test::Unit::TestCase) do
        include AlwaysFailAssertion

        class << self
          def target_line_number
            @target_line_number
          end

          def target_line_number=(line_number)
            @target_line_number = line_number
          end
        end

        def run_yield
          yield
        end

        def test_failed
          run_yield do
            self.class.target_line_number = __LINE__; assert_always_failed
          end
        end
      end

      fault = run_test_case(test_case)
      assert_detect(fault, test_case.target_line_number)
    end
  end
end