class RSpec::Support::ObjectFormatter
Provide additional output details beyond what ‘inspect` provides when printing Time, DateTime, or BigDecimal @api private
Constants
- BaseInspector
- ELLIPSIS
- INSPECTOR_CLASSES
- InspectableItem
Attributes
Public Class Methods
Methods are deferred to a default instance of the class to maintain the interface For example, calling ObjectFormatter.format
is still possible
# File rspec-support/lib/rspec/support/object_formatter.rb, line 17 def self.default_instance @default_instance ||= new end
# File rspec-support/lib/rspec/support/object_formatter.rb, line 21 def self.format(object) default_instance.format(object) end
# File rspec-support/lib/rspec/support/object_formatter.rb, line 29 def initialize(max_formatted_output_length=200) @max_formatted_output_length = max_formatted_output_length @current_structure_stack = [] end
# File rspec-support/lib/rspec/support/object_formatter.rb, line 25 def self.prepare_for_inspection(object) default_instance.prepare_for_inspection(object) end
Public Instance Methods
# File rspec-support/lib/rspec/support/object_formatter.rb, line 34 def format(object) if max_formatted_output_length.nil? prepare_for_inspection(object).inspect else formatted_object = prepare_for_inspection(object).inspect if formatted_object.length < max_formatted_output_length formatted_object else beginning = truncate_string formatted_object, 0, max_formatted_output_length / 2 ending = truncate_string formatted_object, -max_formatted_output_length / 2, -1 beginning + ELLIPSIS + ending end end end
# File rspec-support/lib/rspec/support/object_formatter.rb, line 72 def prepare_array(array) with_entering_structure(array) do array.map { |element| prepare_element(element) } end end
# File rspec-support/lib/rspec/support/object_formatter.rb, line 96 def prepare_element(element) if recursive_structure?(element) case element when Array then InspectableItem.new('[...]') when Hash then InspectableItem.new('{...}') else raise # This won't happen end else prepare_for_inspection(element) end end
Prepares the provided object to be formatted by wrapping it as needed in something that, when ‘inspect` is called on it, will produce the desired output.
This allows us to apply the desired formatting to hash/array data structures at any level of nesting, simply by walking that structure and replacing items with custom items that have ‘inspect` defined to return the desired output for that item. Then we can just use `Array#inspect` or `Hash#inspect` to format the entire thing.
# File rspec-support/lib/rspec/support/object_formatter.rb, line 58 def prepare_for_inspection(object) case object when Array prepare_array(object) when Hash prepare_hash(object) when Symbol object else inspector_class = INSPECTOR_CLASSES.find { |inspector| inspector.can_inspect?(object) } inspector_class.new(object, self) end end
# File rspec-support/lib/rspec/support/object_formatter.rb, line 78 def prepare_hash(input_hash) with_entering_structure(input_hash) do sort_hash_keys(input_hash).inject({}) do |output_hash, key_and_value| key, value = key_and_value.map { |element| prepare_element(element) } output_hash[key] = value output_hash end end end
# File rspec-support/lib/rspec/support/object_formatter.rb, line 115 def recursive_structure?(object) @current_structure_stack.any? { |seen_structure| seen_structure.equal?(object) } end
# File rspec-support/lib/rspec/support/object_formatter.rb, line 88 def sort_hash_keys(input_hash) if input_hash.keys.all? { |k| k.is_a?(String) || k.is_a?(Symbol) } Hash[input_hash.sort_by { |k, _v| k.to_s }] else input_hash end end
# File rspec-support/lib/rspec/support/object_formatter.rb, line 108 def with_entering_structure(structure) @current_structure_stack.push(structure) return_value = yield @current_structure_stack.pop return_value end