1require 'test/unit/util/backtracefilter' 2 3module Test 4 module Unit 5 class Omission 6 include Util::BacktraceFilter 7 attr_reader :test_name, :location, :message 8 attr_reader :method_name 9 10 SINGLE_CHARACTER = 'O' 11 LABEL = "Omission" 12 13 # Creates a new Omission with the given location and 14 # message. 15 def initialize(test_name, location, message, options={}) 16 @test_name = test_name 17 @location = location 18 @message = message 19 @method_name = options[:method_name] 20 end 21 22 # Returns a single character representation of a omission. 23 def single_character_display 24 SINGLE_CHARACTER 25 end 26 27 def label 28 LABEL 29 end 30 31 # Returns a brief version of the error description. 32 def short_display 33 "#{@test_name}: #{@message.split("\n")[0]}" 34 end 35 36 # Returns a verbose version of the error description. 37 def long_display 38 backtrace = filter_backtrace(location).join("\n") 39 "#{label}: #{@message}\n#{@test_name}\n#{backtrace}" 40 end 41 42 # Overridden to return long_display. 43 def to_s 44 long_display 45 end 46 47 def critical? 48 true 49 end 50 end 51 52 class OmittedError < StandardError 53 end 54 55 56 module TestCaseOmissionSupport 57 class << self 58 def included(base) 59 base.class_eval do 60 include OmissionHandler 61 end 62 end 63 end 64 65 # Omit the test or part of the test. 66 # 67 # Example: 68 # def test_omission 69 # omit 70 # # Not reached here 71 # end 72 # 73 # def test_omission_with_here 74 # omit do 75 # # Not ran here 76 # end 77 # # Reached here 78 # end 79 def omit(message=nil, &block) 80 message ||= "omitted." 81 if block_given? 82 omission = Omission.new(name, filter_backtrace(caller), message, 83 :method_name => @method_name) 84 add_omission(omission) 85 else 86 raise OmittedError.new(message) 87 end 88 end 89 90 # Omit the test or part of the test if _condition_ is 91 # true. 92 # 93 # Example: 94 # def test_omission 95 # omit_if("".empty?) 96 # # Not reached here 97 # end 98 # 99 # def test_omission_with_here 100 # omit_if(true) do 101 # # Not ran here 102 # end 103 # omit_if(false) do 104 # # Reached here 105 # end 106 # # Reached here too 107 # end 108 def omit_if(condition, *args, &block) 109 if condition 110 omit(*args, &block) 111 else 112 block.call if block 113 end 114 end 115 116 # Omit the test or part of the test if _condition_ is 117 # not true. 118 # 119 # Example: 120 # def test_omission 121 # omit_unless("string".empty?) 122 # # Not reached here 123 # end 124 # 125 # def test_omission_with_here 126 # omit_unless(true) do 127 # # Reached here 128 # end 129 # omit_unless(false) do 130 # # Not ran here 131 # end 132 # # Reached here too 133 # end 134 def omit_unless(condition, *args, &block) 135 if condition 136 block.call if block 137 else 138 omit(*args, &block) 139 end 140 end 141 142 private 143 def add_omission(omission) 144 current_result.add_omission(omission) 145 end 146 end 147 148 module OmissionHandler 149 class << self 150 def included(base) 151 base.exception_handler(:handle_omitted_error) 152 end 153 end 154 155 private 156 def handle_omitted_error(exception) 157 return false unless exception.is_a?(OmittedError) 158 omission = Omission.new(name, 159 filter_backtrace(exception.backtrace), 160 exception.message, 161 :method_name => @method_name) 162 add_omission(omission) 163 true 164 end 165 end 166 167 module TestResultOmissionSupport 168 attr_reader :omissions 169 170 # Records a Test::Unit::Omission. 171 def add_omission(omission) 172 @omissions << omission 173 notify_fault(omission) 174 notify_changed 175 end 176 177 # Returns the number of omissions this TestResult has 178 # recorded. 179 def omission_count 180 @omissions.size 181 end 182 183 private 184 def initialize_containers 185 super 186 @omissions = [] 187 @summary_generators << :omission_summary 188 end 189 190 def omission_summary 191 "#{omission_count} omissions" 192 end 193 end 194 end 195end 196