class MinitestLog
Constants
- VERSION
Attributes
assertions[RW]
backtrace_filter[RW]
counts[RW]
error_verdict[RW]
file[RW]
file_path[RW]
root_name[RW]
summary[RW]
verdict_ids[RW]
xml_indentation[RW]
Public Class Methods
new(file_path, options=Hash.new) { |self| ... }
click to toggle source
# File lib/minitest_log.rb, line 33 def initialize(file_path, options=Hash.new) raise NoBlockError.new('No block given for MinitestLog#new.') unless (block_given?) self.file_path = file_path handle_options(options) do_log do begin yield self rescue => x handle_exception(x) end end create_xml_log end
Private Class Methods
parse(file_path)
click to toggle source
# File lib/minitest_log.rb, line 418 def self.parse(file_path) document = nil File.open(file_path) do |file| document = REXML::Document.new(file) end document end
timestamp()
click to toggle source
Return a timestamp string. The important property of this string is that it can be incorporated into a legal directory path (i.e., has no colons, etc.).
# File lib/minitest_log.rb, line 396 def self.timestamp now = Time.now ts = now.strftime('%Y-%m-%d-%a-%H.%M.%S') usec_s = (now.usec / 1000).to_s while usec_s.length < 3 do usec_s = '0' + usec_s end "#{ts}.#{usec_s}" end
Public Instance Methods
comment(text)
click to toggle source
# File lib/minitest_log.rb, line 54 def comment(text) if text.match("\n") # Separate text from containing punctuation. put_element('comment') do cdata("\n#{text}\n") end else put_element('comment', text) end nil end
put_data(name, obj)
click to toggle source
# File lib/minitest_log.rb, line 145 def put_data(name, obj) case when obj.kind_of?(String) put_string(name, obj) when obj.respond_to?(:each_pair) put_each_pair(name, obj) when obj.respond_to?(:each_with_index) put_each_with_index(name, obj) when obj.respond_to?(:each) put_each(name, obj) when obj.respond_to?(:to_s) put_to_s(name, obj) when obj.respond_to?(:inspect) put_inspect(name, obj) when obj.respond_to?(:__id__) put_id(name, obj) else message = "Object does not respond to method :__id__: name=#{name}, obj=#{obj}" raise ArgumentError.new(message) end end
put_each(name, obj)
click to toggle source
# File lib/minitest_log.rb, line 94 def put_each(name, obj) lines = [''] obj.each do |item| lines.push(item) end attrs = { :name => name, :class => obj.class, :method => ':each', } add_attr_if(attrs, obj, :size) put_element('data', attrs) do put_pre(lines.join("\n")) end nil end
put_each_pair(name, obj)
click to toggle source
# File lib/minitest_log.rb, line 111 def put_each_pair(name, obj) lines = [''] obj.each_pair do |key, value| lines.push(format('%s => %s', key, value)) end attrs = { :name => name, :class => obj.class, :method => ':each_pair', } add_attr_if(attrs, obj, :size) put_element('data', attrs) do put_pre(lines.join("\n")) end nil end
Also aliased as: put_hash
put_each_with_index(name, obj)
click to toggle source
# File lib/minitest_log.rb, line 75 def put_each_with_index(name, obj) lines = [''] obj.each_with_index do |item, i| lines.push(format('%d: %s', i, item.to_s)) end attrs = { :name => name, :class => obj.class, :method => ':each_with_index', } add_attr_if(attrs, obj, :size) put_element('data', attrs) do put_pre(lines.join("\n")) end nil end
put_element(element_name = 'element', *args)
click to toggle source
# File lib/minitest_log.rb, line 66 def put_element(element_name = 'element', *args) conditioned_element_name = condition_element_name(element_name, caller[0]) if block_given? Element.new(self, conditioned_element_name, *args, &Proc.new) else Element.new(self, conditioned_element_name, *args) end end
put_id(name, obj)
click to toggle source
# File lib/minitest_log.rb, line 141 def put_id(name, obj) put_element('data', :name => name, :class => obj.class, :id => obj.__id__) end
put_inspect(name, obj)
click to toggle source
# File lib/minitest_log.rb, line 137 def put_inspect(name, obj) put_element('data', obj.inspect, :name => name, :class => obj.class, :method => ':inspect') end
put_pre(text, verbatim = false)
click to toggle source
# File lib/minitest_log.rb, line 167 def put_pre(text, verbatim = false) if verbatim put_cdata(text) else t = text.clone until t.start_with?("\n") t = "\n" + t end until t.end_with?("\n\n") t = t + "\n" end put_cdata(t) end end
put_string(name, obj)
click to toggle source
# File lib/minitest_log.rb, line 133 def put_string(name, obj) put_element('data', obj.to_s, :name => name, :class => obj.class, :size => obj.size) end
put_to_s(name, obj)
click to toggle source
# File lib/minitest_log.rb, line 129 def put_to_s(name, obj) put_element('data', obj.to_s, :name => name, :class => obj.class, :method => ':to_s') end
section(name, *args) { || ... }
click to toggle source
# File lib/minitest_log.rb, line 47 def section(name, *args) put_element('section', {:name => name}, *args) do yield if block_given? end nil end
Private Instance Methods
_get_verdict?(verdict_method, verdict_id, message, args_hash) { || ... }
click to toggle source
# File lib/minitest_log.rb, line 280 def _get_verdict?(verdict_method, verdict_id, message, args_hash) assertion_method = assertion_method_for(verdict_method) if block_given? outcome, exception = get_assertion_outcome(verdict_id, assertion_method, *args_hash.values) do yield end else outcome, exception = get_assertion_outcome(verdict_id, assertion_method, *args_hash.values) end element_attributes = { :method => verdict_method, :outcome => outcome, :id => verdict_id, } element_attributes.store(:message, message) unless message.nil? put_element('verdict', element_attributes) do args_hash.each_pair do |k, v| put_element(k.to_s, {:class => v.class, :value => v.inspect}) end if exception self.counts[:failure] += 1 put_element('exception', {:class => exception.class, :message => exception.message}) do put_element('backtrace') do backtrace = filter_backtrace(exception.backtrace) put_pre(backtrace.join("\n")) end end end end outcome == :passed end
add_attr_if(attrs, obj, method)
click to toggle source
# File lib/minitest_log.rb, line 413 def add_attr_if(attrs, obj, method) return unless obj.respond_to?(method) attrs[method] = obj.send(method) end
assertion_method_for(verdict_method)
click to toggle source
# File lib/minitest_log.rb, line 406 def assertion_method_for(verdict_method) # Our verdict method name is just an assertion method name # with prefixed 'verdict_' and suffixed '?'. # Just remove them to form the assertion method name. verdict_method.to_s.sub('verdict_', '').sub('?', '').to_sym end
begin_log()
click to toggle source
# File lib/minitest_log.rb, line 190 def begin_log self.counts = Hash[ :verdict => 0, :failure => 0, :error => 0, ] self.assertions = 0 self.file = File.open(self.file_path, 'w') log_puts("REMARK\tThis text log is the precursor for an XML log.") log_puts("REMARK\tIf the logged process completes, this text will be converted to XML.") log_puts("BEGIN\t#{self.root_name}") end
caller_is_us?(caller_0)
click to toggle source
# File lib/minitest_log.rb, line 438 def caller_is_us?(caller_0) caller_0.match(/minitest_log.rb/) || caller_0.match(/verdict_assertion.rb/) end
condition_element_name(element_name, caller_0)
click to toggle source
# File lib/minitest_log.rb, line 426 def condition_element_name(element_name, caller_0) if caller_is_us?(caller_0) conditioned_element_name = element_name + '_' elsif element_name.end_with?('_') message = "Element name should not end with underscore: #{element_name}" raise IllegalElementNameError.new(message) else conditioned_element_name = element_name end conditioned_element_name end
create_xml_log()
click to toggle source
# File lib/minitest_log.rb, line 211 def create_xml_log document = REXML::Document.new File.open(self.file_path, 'r') do |file| element = document stack = Array.new data_a = Array.new terminator = nil file.each_line do |line| line.chomp! line_type, text = line.split("\t", 2) case line_type when 'REMARK' next when 'BEGIN' element_name = text element = element.add_element(element_name) stack.push(element) if stack.length == 1 && self.summary summary_element = element.add_element('summary_') summary_element.add_attribute('verdicts', self.counts[:verdict].to_s) summary_element.add_attribute('failures', self.counts[:failure].to_s) summary_element.add_attribute('errors', self.counts[:error].to_s) end when 'END' stack.pop element = stack.last when 'ATTRIBUTE' attr_name, attr_value = text.split("\t", 2) element.add_attribute(attr_name, attr_value) when 'CDATA' stack.push(:cdata) data_a = Array.new terminator = text.split('<<', 2).last when 'PCDATA' stack.push(:pcdata) data_a = Array.new terminator = text.split('<<', 2).last when terminator data_s = data_a.join("\n") data_a = Array.new terminator = nil data_type = stack.last case data_type when :cdata cdata = CData.new(data_s) element.add(cdata) when :pcdata element.add_text(data_s) else # Don't want to raise an exception and spoil the run end stack.pop else data_a.push(line) if (terminator) end end document << XMLDecl.default end File.open(self.file_path, 'w') do |file| document.write(file, self.xml_indentation) end # Trailing newline. File.open(self.file_path, 'a') do |file| file.write("\n") end nil end
do_log() { || ... }
click to toggle source
# File lib/minitest_log.rb, line 184 def do_log begin_log yield end_log end
end_log()
click to toggle source
# File lib/minitest_log.rb, line 203 def end_log if self.error_verdict verdict_assert_equal?('error_count', 0, self.counts[:error]) end log_puts("END\t#{self.root_name}") self.file.close end
filter_backtrace(lines)
click to toggle source
Filters lines that are from ruby or log, to make the backtrace more readable.
# File lib/minitest_log.rb, line 382 def filter_backtrace(lines) filtered = [] lines.each do |line| unless line.match(self.backtrace_filter) filtered.push(line) end end filtered end
get_assertion_outcome(verdict_id, assertion_method, *assertion_args) { || ... }
click to toggle source
# File lib/minitest_log.rb, line 364 def get_assertion_outcome(verdict_id, assertion_method, *assertion_args) validate_verdict_id(verdict_id) self.counts[:verdict] += 1 begin if block_given? send(assertion_method, *assertion_args) do yield end else send(assertion_method, *assertion_args) end return :passed, nil rescue Minitest::Assertion => x return :failed, x end end
handle_exception(x)
click to toggle source
# File lib/minitest_log.rb, line 457 def handle_exception(x) put_element('uncaught_exception', :timestamp, :class => x.class) do put_element('message', x.message) put_element('backtrace') do backtrace = filter_backtrace(x.backtrace) put_pre(backtrace.join("\n")) end end end
handle_options(options)
click to toggle source
# File lib/minitest_log.rb, line 442 def handle_options(options) default_options = Hash[ :root_name => 'log', :xml_indentation => 2, :error_verdict => false, :summary => false ] options = default_options.merge(options) self.root_name = options[:root_name] self.xml_indentation = options[:xml_indentation] self.summary = options[:summary] self.error_verdict = options[:error_verdict] || false self.backtrace_filter = options[:backtrace_filter] || /minitest/ end
log_puts(text)
click to toggle source
# File lib/minitest_log.rb, line 327 def log_puts(text) self.file.puts(text) self.file.flush nil end
put_attributes(attributes)
click to toggle source
# File lib/minitest_log.rb, line 312 def put_attributes(attributes) attributes.each_pair do |name, value| value = case when value.is_a?(String) value.gsub("\n", "\\n") when value.is_a?(Symbol) value.to_s else value.inspect end log_puts("ATTRIBUTE\t#{name}\t#{value}") end nil end
put_cdata(text)
click to toggle source
# File lib/minitest_log.rb, line 356 def put_cdata(text) put_cdata_or_pcdata('CDATA', text) end
put_cdata_or_pcdata(token, text)
click to toggle source
# File lib/minitest_log.rb, line 343 def put_cdata_or_pcdata(token, text) # Guard against using a terminator that's a substring of the cdata. s = 'EOT' terminator = s while text.match(terminator) do terminator += s end log_puts("#{token}\t<<#{terminator}") log_puts(text) log_puts(terminator) nil end
put_pcdata(text)
click to toggle source
# File lib/minitest_log.rb, line 360 def put_pcdata(text) put_cdata_or_pcdata('PCDATA', text) end
validate_verdict_id(verdict_id)
click to toggle source
# File lib/minitest_log.rb, line 333 def validate_verdict_id(verdict_id) self.verdict_ids ||= Set.new if self.verdict_ids.include?(verdict_id) message = format('Duplicate verdict id %s; must be unique within its test method', verdict_id.inspect) raise DuplicateVerdictIdError.new(message) end self.verdict_ids.add(verdict_id) nil end