Class: RSpec::Support::ObjectFormatter Private
Relationships & Source Files | |
Namespace Children | |
Classes:
| |
Inherits: | Object |
Defined in: | rspec-support/lib/rspec/support/object_formatter.rb |
Overview
Provide additional output details beyond what inspect
provides when printing Time, DateTime, or BigDecimal
Constant Summary
-
ELLIPSIS =
# File 'rspec-support/lib/rspec/support/object_formatter.rb', line 11"..."
-
INSPECTOR_CLASSES =
# File 'rspec-support/lib/rspec/support/object_formatter.rb', line 247[ TimeInspector, DateTimeInspector, BigDecimalInspector, UninspectableObjectInspector, DescribableMatcherInspector, DelegatorInspector, InspectableObjectInspector ].tap do |classes| # 2.4 has improved BigDecimal formatting so we do not need # to provide our own. # https://github.com/ruby/bigdecimal/pull/42 classes.delete(BigDecimalInspector) if RUBY_VERSION >= '2.4' end
Class Method Summary
-
.default_instance
Internal use only
Methods are deferred to a default instance of the class to maintain the interface For example, calling
ObjectFormatter
.format is still possible. - .format(object) Internal use only
- .new(max_formatted_output_length = 200) ⇒ ObjectFormatter constructor Internal use only
- .prepare_for_inspection(object) Internal use only
Instance Attribute Summary
- #max_formatted_output_length rw Internal use only
Instance Method Summary
- #format(object) Internal use only
- #prepare_array(array) Internal use only
- #prepare_element(element) Internal use only
-
#prepare_for_inspection(object)
Internal use only
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. - #prepare_hash(input_hash) Internal use only
- #recursive_structure?(object) ⇒ Boolean Internal use only
- #sort_hash_keys(input_hash) Internal use only
- #with_entering_structure(structure) Internal use only
-
#truncate_string(str, start_index, end_index)
private
Internal use only
Returns the substring defined by the start_index and end_index If the string ends with a partial ANSI code code then that will be removed as printing partial ANSI codes to the terminal can lead to corruption.
Class Method Details
.default_instance
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
.format(object)
[ GitHub ]# File 'rspec-support/lib/rspec/support/object_formatter.rb', line 21
def self.format(object) default_instance.format(object) end
.prepare_for_inspection(object)
[ GitHub ]# File 'rspec-support/lib/rspec/support/object_formatter.rb', line 25
def self.prepare_for_inspection(object) default_instance.prepare_for_inspection(object) end
Instance Attribute Details
#max_formatted_output_length (rw)
[ GitHub ]# File 'rspec-support/lib/rspec/support/object_formatter.rb', line 13
attr_accessor :max_formatted_output_length
Instance Method Details
#format(object)
[ GitHub ]# 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
#prepare_array(array)
[ GitHub ]# File 'rspec-support/lib/rspec/support/object_formatter.rb', line 70
def prepare_array(array) with_entering_structure(array) do array.map { |element| prepare_element(element) } end end
#prepare_element(element)
[ GitHub ]# File 'rspec-support/lib/rspec/support/object_formatter.rb', line 94
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
#prepare_for_inspection(object)
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) else inspector_class = INSPECTOR_CLASSES.find { |inspector| inspector.can_inspect?(object) } inspector_class.new(object, self) end end
#prepare_hash(input_hash)
[ GitHub ]# File 'rspec-support/lib/rspec/support/object_formatter.rb', line 76
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
#recursive_structure?(object) ⇒ Boolean
# File 'rspec-support/lib/rspec/support/object_formatter.rb', line 113
def recursive_structure?(object) @current_structure_stack.any? { |seen_structure| seen_structure.equal?(object) } end
#sort_hash_keys(input_hash)
[ GitHub ]# File 'rspec-support/lib/rspec/support/object_formatter.rb', line 86
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
#truncate_string(str, start_index, end_index) (private)
Returns the substring defined by the start_index and end_index If the string ends with a partial ANSI code code then that will be removed as printing partial ANSI codes to the terminal can lead to corruption
# File 'rspec-support/lib/rspec/support/object_formatter.rb', line 268
def truncate_string(str, start_index, end_index) cut_str = str[start_index..end_index] # ANSI color codes are like: \e[33m so anything with \e[ and a # number without a 'm' is an incomplete color code cut_str.sub(/\e\[\d+$/, '') end
#with_entering_structure(structure)
[ GitHub ]# File 'rspec-support/lib/rspec/support/object_formatter.rb', line 106
def with_entering_structure(structure) @current_structure_stack.push(structure) return_value = yield @current_structure_stack.pop return_value end