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