1
0
Fork 0
mirror of https://github.com/awesome-print/awesome_print synced 2023-03-27 23:22:34 -04:00

Make external formatters (Rails, etc) format as expected)

This commit is contained in:
James Cox 2019-01-22 16:04:42 -05:00
parent e2bc9c2a03
commit f0ed2e219a
31 changed files with 553 additions and 467 deletions

View file

@ -2,30 +2,16 @@
# so do nothing for subsequent requires.
#
unless defined?(AwesomePrint::Inspector)
%w(awesome_method_array string object class kernel).each do |file|
%w(active_support awesome_method_array string object class kernel).each do |file|
require "awesome_print/core_ext/#{file}"
end
require 'awesome_print/version'
require 'awesome_print/core_ext/logger' if defined?(Logger)
require 'awesome_print/custom_defaults'
require 'awesome_print/inspector'
require 'awesome_print/formatter'
Dir["./lib/awesome_print/formatters/**/*.rb"].each { |f| require f }
require 'awesome_print/version'
require 'awesome_print/core_ext/logger' if defined?(Logger)
#
# Load the following under normal circumstances as well as in Rails
# console when required from ~/.irbrc or ~/.pryrc.
#
# require 'awesome_print/ext/active_record' if defined?(ActiveRecord) || AwesomePrint.rails_console?
# require 'awesome_print/ext/active_support' if defined?(ActiveSupport) || AwesomePrint.rails_console?
# #
# # Load remaining extensions.
# #
# if defined?(ActiveSupport.on_load)
# ActiveSupport.on_load(:action_view) do
# require 'awesome_print/ext/action_view'
# end
# end
end

View file

@ -0,0 +1,7 @@
#
# Colorize Rails logs.
#
if defined?(ActiveSupport::LogSubscriber)
AwesomePrint.force_colors! ActiveSupport::LogSubscriber.colorize_logging
end

View file

@ -1,17 +0,0 @@
module AwesomePrint
module ActionView
# Use HTML colors and add default "debug_dump" class to the resulting HTML.
def ap_debug(object, options = {})
object.ai(
options.merge(html: true)
).sub(
/^<pre([\s>])/,
'<pre class="debug_dump"\\1'
)
end
alias ap ap_debug
end
end
ActionView::Base.send(:include, AwesomePrint::ActionView)

View file

@ -0,0 +1,44 @@
require_relative '../base_formatter'
module AwesomePrint
module Formatters
class ActiveModelErrorFormatter < BaseFormatter
formatter_for :active_model_error
def self.formattable?(object)
defined?(::ActiveModel) && object.is_a?(::ActiveModel::Errors)
end
def format(object)
if @options[:raw]
return Formatters::ObjectFormatter.new(@inspector).format(object)
end
if !defined?(::ActiveSupport::OrderedHash)
return Formatters::SimpleFormatter.new(@inspector).format(object.inspect)
end
object_dump = object.marshal_dump.first
if object_dump.class.column_names != object_dump.attributes.keys
data = object_dump.attributes
else
data = object_dump.class.column_names.inject(::ActiveSupport::OrderedHash.new) do |hash, name|
if object_dump.has_attribute?(name) || object_dump.new_record?
value = object_dump.respond_to?(name) ? object_dump.send(name) : object_dump.read_attribute(name)
hash[name.to_sym] = value
end
hash
end
end
data.merge!({details: object.details, messages: object.messages})
"#{object} " << Formatters::HashFormatter.new(@inspector).format(data)
end
end
end
end

View file

@ -1,98 +0,0 @@
module AwesomePrint
module ActiveRecord
def self.included(base)
base.send :alias_method, :cast_without_active_record, :cast
base.send :alias_method, :cast, :cast_with_active_record
end
# Add ActiveRecord class names to the dispatcher pipeline.
#------------------------------------------------------------------------------
def cast_with_active_record(object, type)
cast = cast_without_active_record(object, type)
return cast if !defined?(::ActiveRecord::Base)
if object.is_a?(::ActiveRecord::Base)
cast = :active_record_instance
elsif object.is_a?(::ActiveModel::Errors)
cast = :active_model_error
elsif object.is_a?(Class) && object.ancestors.include?(::ActiveRecord::Base)
cast = :active_record_class
elsif type == :activerecord_relation || object.class.ancestors.include?(::ActiveRecord::Relation)
cast = :array
end
cast
end
private
# Format ActiveRecord instance object.
#
# NOTE: by default only instance attributes (i.e. columns) are shown. To format
# ActiveRecord instance as regular object showing its instance variables and
# accessors use :raw => true option:
#
# ap record, :raw => true
#
#------------------------------------------------------------------------------
def awesome_active_record_instance(object)
return object.inspect if !defined?(::ActiveSupport::OrderedHash)
return awesome_object(object) if @options[:raw]
data = if object.class.column_names != object.attributes.keys
object.attributes
else
object.class.column_names.inject(::ActiveSupport::OrderedHash.new) do |hash, name|
if object.has_attribute?(name) || object.new_record?
value = object.respond_to?(name) ? object.send(name) : object.read_attribute(name)
hash[name.to_sym] = value
end
hash
end
end
"#{object} " << awesome_hash(data)
end
# Format ActiveRecord class object.
#------------------------------------------------------------------------------
def awesome_active_record_class(object)
return object.inspect if !defined?(::ActiveSupport::OrderedHash) || !object.respond_to?(:columns) || object.to_s == 'ActiveRecord::Base'
return awesome_class(object) if object.respond_to?(:abstract_class?) && object.abstract_class?
data = object.columns.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
hash[c.name.to_sym] = c.type
hash
end
name = "class #{awesome_simple(object.to_s, :class)}"
base = "< #{awesome_simple(object.superclass.to_s, :class)}"
[name, base, awesome_hash(data)].join(' ')
end
# Format ActiveModel error object.
#------------------------------------------------------------------------------
def awesome_active_model_error(object)
return object.inspect if !defined?(::ActiveSupport::OrderedHash)
return awesome_object(object) if @options[:raw]
object_dump = object.marshal_dump.first
data = if object_dump.class.column_names != object_dump.attributes.keys
object_dump.attributes
else
object_dump.class.column_names.inject(::ActiveSupport::OrderedHash.new) do |hash, name|
if object_dump.has_attribute?(name) || object_dump.new_record?
value = object_dump.respond_to?(name) ? object_dump.send(name) : object_dump.read_attribute(name)
hash[name.to_sym] = value
end
hash
end
end
data.merge!({details: object.details, messages: object.messages})
"#{object} " << awesome_hash(data)
end
end
end
AwesomePrint::Formatter.send(:include, AwesomePrint::ActiveRecord)

View file

@ -0,0 +1,43 @@
require_relative '../base_formatter'
module AwesomePrint
module Formatters
class ActiveRecordClassFormatter < BaseFormatter
formatter_for :active_record_class
def self.formattable?(object)
defined?(::ActiveRecord) &&
(object.is_a?(Class) && object.ancestors.include?(::ActiveRecord::Base))
end
def format(object)
if @options[:raw]
return Formatters::ObjectFormatter.new(@inspector).format(object)
end
if object.respond_to?(:abstract_class?) && object.abstract_class?
return Formatters::ClassFormatter.new(@inspector).format(object)
end
if !defined?(::ActiveSupport::OrderedHash) || !object.respond_to?(:columns)
return Formatters::SimpleFormatter.new(@inspector).format(object.inspect)
end
data = object.columns.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
hash[c.name.to_sym] = c.type
hash
end
[
"class #{colorize(object.to_s, :class)}",
"< #{colorize(object.superclass.to_s, :class)}",
Formatters::HashFormatter.new(@inspector).format(data)
].join(' ')
end
end
end
end

View file

@ -0,0 +1,48 @@
require_relative '../base_formatter'
module AwesomePrint
module Formatters
class ActiveRecordInstanceFormatter < BaseFormatter
formatter_for :active_record_instance
def self.formattable?(object)
defined?(::ActiveRecord) && object.is_a?(::ActiveRecord::Base)
end
# Format ActiveRecord instance object.
#
# NOTE: by default only instance attributes (i.e. columns) are shown. To format
# ActiveRecord instance as regular object showing its instance variables and
# accessors use :raw => true option:
#
# ap record, :raw => true
#
#------------------------------------------------------------------------------
def format(object)
if @options[:raw]
return Formatters::ObjectFormatter.new(@inspector).format(object)
end
if !defined?(::ActiveSupport::OrderedHash)
return Formatters::SimpleFormatter.new(@inspector).format(object.inspect)
end
if object.class.column_names != object.attributes.keys
data = object.attributes
else
data = object.class.column_names.inject(::ActiveSupport::OrderedHash.new) do |hash, name|
if object.has_attribute?(name) || object.new_record?
value = object.respond_to?(name) ? object.send(name) : object.read_attribute(name)
hash[name.to_sym] = value
end
hash
end
end
"#{object} " << Formatters::HashFormatter.new(@inspector).format(data)
end
end
end
end

View file

@ -0,0 +1,19 @@
require_relative '../array_formatter'
module AwesomePrint
module Formatters
class ActiveRecordRelationFormatter < ArrayFormatter
formatter_for :active_record_relation
def self.core?
false
end
def self.formattable?(object)
defined?(::ActiveRecord) && object.class.ancestors.include?(::ActiveRecord::Relation)
end
end
end
end

View file

@ -1,42 +0,0 @@
module AwesomePrint
module ActiveSupport
def self.included(base)
base.send :alias_method, :cast_without_active_support, :cast
base.send :alias_method, :cast, :cast_with_active_support
end
def cast_with_active_support(object, type)
cast = cast_without_active_support(object, type)
if defined?(::ActiveSupport) && defined?(::HashWithIndifferentAccess)
if (defined?(::ActiveSupport::TimeWithZone) && object.is_a?(::ActiveSupport::TimeWithZone)) || object.is_a?(::Date)
cast = :active_support_time
elsif object.is_a?(::HashWithIndifferentAccess)
cast = :hash_with_indifferent_access
end
end
cast
end
# Format ActiveSupport::TimeWithZone as standard Time.
#------------------------------------------------------------------------------
def awesome_active_support_time(object)
colorize(object.inspect, :time)
end
# Format HashWithIndifferentAccess as standard Hash.
#------------------------------------------------------------------------------
def awesome_hash_with_indifferent_access(object)
awesome_hash(object)
end
end
end
AwesomePrint::Formatter.send(:include, AwesomePrint::ActiveSupport)
#
# Colorize Rails logs.
#
if defined?(ActiveSupport::LogSubscriber)
AwesomePrint.force_colors! ActiveSupport::LogSubscriber.colorize_logging
end

View file

@ -0,0 +1,20 @@
require_relative '../base_formatter'
module AwesomePrint
module Formatters
class BsonObjectidFormatter < BaseFormatter
formatter_for :bson_objectid
def self.formattable?(object)
(defined?(::BSON) && object.is_a?(::BSON::ObjectId)) ||
(defined?(::Moped::BSON) && object.is_a?(::Moped::BSON::ObjectId))
end
def format(object)
colorize(object.inspect, self.class.formatted_object_type)
end
end
end
end

View file

@ -0,0 +1,20 @@
require_relative '../hash_formatter'
module AwesomePrint
module Formatters
class HashWithIndifferentAccessFormatter < HashFormatter
formatter_for :hash_with_indifferent_access
def self.core?
false
end
def self.formattable?(object)
defined?(::HashWithIndifferentAccess) &&
object.is_a?(::HashWithIndifferentAccess)
end
end
end
end

View file

@ -1,119 +0,0 @@
module AwesomePrint
module MongoMapper
def self.included(base)
base.send :alias_method, :cast_without_mongo_mapper, :cast
base.send :alias_method, :cast, :cast_with_mongo_mapper
end
# Add MongoMapper class names to the dispatcher pipeline.
#------------------------------------------------------------------------------
def cast_with_mongo_mapper(object, type)
apply_default_mongo_mapper_options
cast = cast_without_mongo_mapper(object, type)
if defined?(::MongoMapper::Document)
if object.is_a?(Class) && (object.ancestors & [::MongoMapper::Document, ::MongoMapper::EmbeddedDocument]).size > 0
cast = :mongo_mapper_class
elsif object.is_a?(::MongoMapper::Document) || object.is_a?(::MongoMapper::EmbeddedDocument)
cast = :mongo_mapper_instance
elsif object.is_a?(::MongoMapper::Plugins::Associations::Base)
cast = :mongo_mapper_association
elsif object.is_a?(::BSON::ObjectId)
cast = :mongo_mapper_bson_id
end
end
cast
end
# Format MongoMapper class object.
#------------------------------------------------------------------------------
def awesome_mongo_mapper_class(object)
return object.inspect if !defined?(::ActiveSupport::OrderedHash) || !object.respond_to?(:keys)
data = object.keys.sort.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
hash[c.first] = (c.last.type || 'undefined').to_s.underscore.intern
hash
end
# Add in associations
if @options[:mongo_mapper][:show_associations]
object.associations.each do |name, assoc|
data[name.to_s] = assoc
end
end
name = "class #{awesome_simple(object.to_s, :class)}"
base = "< #{awesome_simple(object.superclass.to_s, :class)}"
[name, base, awesome_hash(data)].join(' ')
end
# Format MongoMapper instance object.
#
# NOTE: by default only instance attributes (i.e. keys) are shown. To format
# MongoMapper instance as regular object showing its instance variables and
# accessors use :raw => true option:
#
# ap record, :raw => true
#
#------------------------------------------------------------------------------
def awesome_mongo_mapper_instance(object)
return object.inspect if !defined?(::ActiveSupport::OrderedHash)
return awesome_object(object) if @options[:raw]
data = object.keys.keys.sort_by { |k| k }.inject(::ActiveSupport::OrderedHash.new) do |hash, name|
hash[name] = object[name]
hash
end
# Add in associations
if @options[:mongo_mapper][:show_associations]
object.associations.each do |name, assoc|
data[name.to_s] = if @options[:mongo_mapper][:inline_embedded] and assoc.embeddable?
object.send(name)
else
assoc
end
end
end
label = object.to_s
label = "#{colorize('embedded', :assoc)} #{label}" if object.is_a?(::MongoMapper::EmbeddedDocument)
"#{label} " << awesome_hash(data)
end
# Format MongoMapper association object.
#------------------------------------------------------------------------------
def awesome_mongo_mapper_association(object)
return object.inspect if !defined?(::ActiveSupport::OrderedHash)
return awesome_object(object) if @options[:raw]
association = object.class.name.split('::').last.titleize.downcase.sub(/ association$/, '')
association = "embeds #{association}" if object.embeddable?
class_name = object.class_name
"#{colorize(association, :assoc)} #{colorize(class_name, :class)}"
end
# Format BSON::ObjectId
#------------------------------------------------------------------------------
def awesome_mongo_mapper_bson_id(object)
object.inspect
end
private
def apply_default_mongo_mapper_options
@options[:color][:assoc] ||= :greenish
@options[:mongo_mapper] ||= {
show_associations: false, # Display association data for MongoMapper documents and classes.
inline_embedded: false # Display embedded associations inline with MongoMapper documents.
}
end
end
end
AwesomePrint::Formatter.send(:include, AwesomePrint::MongoMapper)

View file

@ -0,0 +1,31 @@
require_relative '../base_formatter'
module AwesomePrint
module Formatters
class MongoMapperClassFormatter < BaseFormatter
formatter_for :mongo_mapper_association
def self.formattable?(object)
defined?(::MongoMapper) && object.is_a?(::MongoMapper::Plugins::Associations::Base)
end
def format(object)
if @options[:raw]
return Formatters::ObjectFormatter.new(@inspector).format(object)
end
if !defined?(::ActiveSupport::OrderedHash)
return Formatters::SimpleFormatter.new(@inspector).format(object.inspect.to_s)
end
association = object.class.name.split('::').last.titleize.downcase.sub(/ association$/, '')
association = "embeds #{association}" if object.embeddable?
class_name = object.class_name
"#{colorize(association, :assoc)} #{colorize(class_name, :class)}"
end
end
end
end

View file

@ -0,0 +1,41 @@
require_relative '../base_formatter'
module AwesomePrint
module Formatters
class MongoMapperClassFormatter < BaseFormatter
formatter_for :mongo_mapper_class
def self.formattable?(object)
defined?(::MongoMapper) &&
object.is_a?(Class) &&
(object.ancestors & [::MongoMapper::Document, ::MongoMapper::EmbeddedDocument]).size > 0
end
def format(object)
unless defined?(::ActiveSupport::OrderedHash) && object.respond_to?(:keys)
return Formatters::SimpleFormatter.new(@inspector).format(object.inspect.to_s)
end
data = object.keys.sort.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
hash[c.first] = (c.last.type || 'undefined').to_s.underscore.to_sym
hash
end
# Add in associations
if @options[:mongo_mapper][:show_associations]
object.associations.each { |name, assoc| data[name.to_s] = assoc }
end
sf = Formatters::SimpleFormatter.new(@inspector)
[
"class #{sf.format(object.to_s, :class)}",
"< #{sf.format(object.superclass.to_s, :class)}",
Formatters::HashFormatter.new(@inspector).format(data)
].join(' ')
end
end
end
end

View file

@ -0,0 +1,67 @@
require_relative '../base_formatter'
module AwesomePrint
module Formatters
class MongoMapperInstanceFormatter < BaseFormatter
formatter_for :mongo_mapper_instance
def self.formattable?(object)
defined?(::MongoMapper) &&
(object.is_a?(::MongoMapper::Document) ||
object.is_a?(::MongoMapper::EmbeddedDocument))
end
def initialize(inspector)
super(inspector)
@options[:color][:assoc] ||= :greenish
@options[:mongo_mapper] ||= {
show_associations: false, # Display association data for MongoMapper documents and classes.
inline_embedded: false # Display embedded associations inline with MongoMapper documents.
}
end
# Format MongoMapper instance object.
#
# NOTE: by default only instance attributes (i.e. keys) are shown. To format
# MongoMapper instance as regular object showing its instance variables and
# accessors use :raw => true option:
#
# ap record, :raw => true
#
#------------------------------------------------------------------------------
def format(object)
if @options[:raw]
return Formatters::ObjectFormatter.new(@inspector).format(object)
end
if !defined?(::ActiveSupport::OrderedHash)
return Formatters::SimpleFormatter.new(@inspector).format(object.inspect.to_s)
end
data = object.keys.keys.sort_by { |k| k }.inject(::ActiveSupport::OrderedHash.new) do |hash, name|
hash[name] = object[name]
hash
end
# Add in associations
if @options[:mongo_mapper][:show_associations]
object.associations.each do |name, assoc|
data[name.to_s] = if @options[:mongo_mapper][:inline_embedded] and assoc.embeddable?
object.send(name)
else
assoc
end
end
end
label = object.to_s
label = "#{colorize('embedded', :assoc)} #{label}" if object.is_a?(::MongoMapper::EmbeddedDocument)
"#{label} " << Formatters::HashFormatter.new(@inspector).format(data)
end
end
end
end

View file

@ -1,62 +0,0 @@
module AwesomePrint
module Mongoid
def self.included(base)
base.send :alias_method, :cast_without_mongoid, :cast
base.send :alias_method, :cast, :cast_with_mongoid
end
# Add Mongoid class names to the dispatcher pipeline.
#------------------------------------------------------------------------------
def cast_with_mongoid(object, type)
cast = cast_without_mongoid(object, type)
if defined?(::Mongoid::Document)
if object.is_a?(Class) && object.ancestors.include?(::Mongoid::Document)
cast = :mongoid_class
elsif object.class.ancestors.include?(::Mongoid::Document)
cast = :mongoid_document
elsif (defined?(::BSON) && object.is_a?(::BSON::ObjectId)) || (defined?(::Moped::BSON) && object.is_a?(::Moped::BSON::ObjectId))
cast = :mongoid_bson_id
end
end
cast
end
# Format Mongoid class object.
#------------------------------------------------------------------------------
def awesome_mongoid_class(object)
return object.inspect if !defined?(::ActiveSupport::OrderedHash) || !object.respond_to?(:fields)
data = object.fields.sort_by { |key| key }.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
hash[c[1].name.to_sym] = (c[1].type || 'undefined').to_s.underscore.intern
hash
end
name = "class #{awesome_simple(object.to_s, :class)}"
base = "< #{awesome_simple(object.superclass.to_s, :class)}"
[name, base, awesome_hash(data)].join(' ')
end
# Format Mongoid Document object.
#------------------------------------------------------------------------------
def awesome_mongoid_document(object)
return object.inspect if !defined?(::ActiveSupport::OrderedHash)
data = (object.attributes || {}).sort_by { |key| key }.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
hash[c[0].to_sym] = c[1]
hash
end
data = { errors: object.errors, attributes: data } if !object.errors.empty?
"#{object} #{awesome_hash(data)}"
end
# Format BSON::ObjectId
#------------------------------------------------------------------------------
def awesome_mongoid_bson_id(object)
object.inspect
end
end
end
AwesomePrint::Formatter.send(:include, AwesomePrint::Mongoid)

View file

@ -0,0 +1,56 @@
require_relative '../base_formatter'
module AwesomePrint
module Formatters
class MongoidDocument < BaseFormatter
formatter_for :mongoid_document
def self.formattable?(object)
defined?(::Mongoid::Document) &&
object.class.ancestors.include?(::Mongoid::Document)
end
def format(object)
unless defined?(::ActiveSupport::OrderedHash)
return Formatters::SimpleFormatter.new(@inspector).format(object.inspect)
end
if object.respond_to?(:fields)
# mongoid class
format_as_class(object)
else
format_as_instance(object)
end
end
end
private
def format_as_class(object)
data = object.fields.sort_by { |key| key }.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
hash[c[1].name.to_sym] = (c[1].type || 'undefined').to_s.underscore.to_sym
hash
end
[
"class #{colorize(object.to_s, :class)}",
"< #{colorize(object.superclass.to_s, :class)}",
Formatters::HashFormatter.new(@inspector).format(data)
].join(' ')
end
def format_as_instance(object)
data = (object.attributes || {}).sort_by { |key| key }.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
hash[c[0].to_sym] = c[1]
hash
end
data = { errors: object.errors, attributes: data } if !object.errors.empty?
"#{object} #{Formatters::HashFormatter.new(@inspector).format(data)}"
end
end
end

View file

@ -1,40 +0,0 @@
module AwesomePrint
module Nokogiri
def self.included(base)
base.send :alias_method, :cast_without_nokogiri, :cast
base.send :alias_method, :cast, :cast_with_nokogiri
end
# Add Nokogiri XML Node and NodeSet names to the dispatcher pipeline.
#------------------------------------------------------------------------------
def cast_with_nokogiri(object, type)
cast = cast_without_nokogiri(object, type)
if (defined?(::Nokogiri::XML::Node) && object.is_a?(::Nokogiri::XML::Node)) ||
(defined?(::Nokogiri::XML::NodeSet) && object.is_a?(::Nokogiri::XML::NodeSet))
cast = :nokogiri_xml_node
end
cast
end
#------------------------------------------------------------------------------
def awesome_nokogiri_xml_node(object)
if object.is_a?(::Nokogiri::XML::NodeSet) && object.empty?
return '[]'
end
xml = object.to_xml(indent: 2)
#
# Colorize tag, id/class name, and contents.
#
xml.gsub!(/(<)(\/?[A-Za-z1-9]+)/) { |tag| "#{$1}#{colorize($2, :keyword)}" }
xml.gsub!(/(id|class)="[^"]+"/i) { |id| colorize(id, :class) }
xml.gsub!(/>([^<]+)</) do |contents|
contents = colorize($1, :trueclass) if contents && !contents.empty?
">#{contents}<"
end
xml
end
end
end
AwesomePrint::Formatter.send(:include, AwesomePrint::Nokogiri)

View file

@ -0,0 +1,29 @@
require_relative '../base_formatter'
module AwesomePrint
module Formatters
class NokogiriNodeFormatter < BaseFormatter
formatter_for :nokogiri_xml_node
def self.formattable?(object)
defined?(::Nokogiri) && object.is_a?(::Nokogiri::XML::Node)
end
def format(object)
xml = object.to_xml(indent: 2)
#
# Colorize tag, id/class name, and contents.
#
xml.gsub!(/(<)(\/?[A-Za-z1-9]+)/) { |tag| "#{$1}#{colorize($2, :keyword)}" }
xml.gsub!(/(id|class)="[^"]+"/i) { |id| colorize(id, :class) }
xml.gsub!(/>([^<]+)</) do |contents|
contents = colorize($1, :trueclass) if contents && !contents.empty?
">#{contents}<"
end
xml
end
end
end
end

View file

@ -0,0 +1,32 @@
require_relative '../base_formatter'
module AwesomePrint
module Formatters
class NokogiriNodeFormatter < BaseFormatter
formatter_for :nokogiri_xml_nodeset
def self.formattable?(object)
defined?(::Nokogiri) && object.is_a?(::Nokogiri::XML::NodeSet)
end
def format(object)
return '[]' if object.empty?
xml = object.to_xml(indent: 2)
#
# Colorize tag, id/class name, and contents.
#
xml.gsub!(/(<)(\/?[A-Za-z1-9]+)/) { |tag| "#{$1}#{colorize($2, :keyword)}" }
xml.gsub!(/(id|class)="[^"]+"/i) { |id| colorize(id, :class) }
xml.gsub!(/>([^<]+)</) do |contents|
contents = colorize($1, :trueclass) if contents && !contents.empty?
">#{contents}<"
end
xml
end
end
end
end

View file

@ -1,53 +0,0 @@
module AwesomePrint
module Sequel
def self.included(base)
base.send :alias_method, :cast_without_sequel, :cast
base.send :alias_method, :cast, :cast_with_sequel
end
# Add Sequel class names to the dispatcher pipeline.
#------------------------------------------------------------------------------
def cast_with_sequel(object, type)
cast = cast_without_sequel(object, type)
if defined?(::Sequel::Model) && object.is_a?(::Sequel::Model)
cast = :sequel_document
elsif defined?(::Sequel::Model) && object.is_a?(Class) && object.ancestors.include?(::Sequel::Model)
cast = :sequel_model_class
elsif defined?(::Sequel::Mysql2::Dataset) && object.class.ancestors.include?(::Sequel::Mysql2::Dataset)
cast = :sequel_dataset
end
cast
end
# Format Sequel Document object.
#------------------------------------------------------------------------------
def awesome_sequel_document(object)
data = object.values.sort_by { |key| key.to_s }.inject({}) do |hash, c|
hash[c[0].to_sym] = c[1]
hash
end
data = { errors: object.errors, values: data } if !object.errors.empty?
"#{object} #{awesome_hash(data)}"
end
# Format Sequel Dataset object.
#------------------------------------------------------------------------------
def awesome_sequel_dataset(dataset)
[awesome_array(dataset.to_a), awesome_print(dataset.sql)].join("\n")
end
# Format Sequel Model class.
#------------------------------------------------------------------------------
def awesome_sequel_model_class(object)
data = object.db_schema.inject({}) { |h, (prop, defn)| h.merge(prop => defn[:db_type]) }
name = "class #{awesome_simple(object.to_s, :class)}"
base = "< #{awesome_simple(object.superclass.to_s, :class)}"
[name, base, awesome_hash(data)].join(' ')
end
end
end
AwesomePrint::Formatter.send(:include, AwesomePrint::Sequel)

View file

@ -0,0 +1,20 @@
require_relative '../base_formatter'
module AwesomePrint
module Formatters
class SequelDatasetFormatter < BaseFormatter
formatter_for :sequel_dataset
def self.formattable?(object)
defined?(::Sequel::Mysql2::Dataset) && object.class.ancestors.include?(::Sequel::Mysql2::Dataset)
end
def format(object)
af = Formatters::ArrayFormatter.new(@inspector)
[af.format(dataset.to_a), colorize(dataset.sql, :string)].join("\n")
end
end
end
end

View file

@ -0,0 +1,25 @@
require_relative '../base_formatter'
module AwesomePrint
module Formatters
class SequelModelClassFormatter < BaseFormatter
formatter_for :sequel_model_class
def self.formattable?(object)
defined?(::Sequel::Model) && object.is_a?(Class) && object.ancestors.include?(::Sequel::Model)
end
def format(object)
data = object.db_schema.inject({}) { |h, (prop, defn)| h.merge(prop => defn[:db_type]) }
[
"class #{colorize(object.to_s, :class)}",
"< #{colorize(object.superclass.to_s, :class)}",
Formatters::HashFormatter.new(@inspector).format(data)
].join(' ')
end
end
end
end

View file

@ -0,0 +1,26 @@
require_relative '../base_formatter'
module AwesomePrint
module Formatters
class SequelModelFormatter < BaseFormatter
formatter_for :sequel_model
def self.formattable?(object)
defined?(::Sequel::Model) && object.is_a?(::Sequel::Model)
end
def format(object)
data = object.values.sort_by { |key| key.to_s }.inject({}) do |hash, c|
hash[c[0].to_sym] = c[1]
hash
end
data = { errors: object.errors, values: data } if !object.errors.empty?
hf = Formatters::HashFormatter.new(@inspector)
"#{colorize(object.to_s, :sequel)} #{hf.format(data)}"
end
end
end
end

View file

@ -0,0 +1,21 @@
require_relative '../base_formatter'
require 'date'
module AwesomePrint
module Formatters
class TimeWithZoneFormatter < BaseFormatter
formatter_for :time_with_zone
def self.formattable?(object)
(defined?(::ActiveSupport::TimeWithZone) && object.is_a?(::ActiveSupport::TimeWithZone)) ||
object.is_a?(::DateTime) || Object.is_a?(::Time)
end
def format(object)
colorize(object.inspect, :time)
end
end
end
end

View file

@ -1,18 +0,0 @@
require 'spec_helper'
RSpec.describe 'AwesomePrint ActionView extensions', skip: -> { !ExtVerifier.has_rails? }.call do
before do
@view = ActionView::Base.new
end
it "uses HTML and adds 'debug_dump' class to plain <pre> tag" do
markup = rand
expect(@view.ap(markup, plain: true)).to eq(%Q|<pre class="debug_dump">#{markup}</pre>|)
end
it "uses HTML and adds 'debug_dump' class to colorized <pre> tag" do
markup = ' &<hello>'
expect(@view.ap(markup)).to eq('<pre class="debug_dump"><kbd style="color:brown">&quot; &amp;&lt;hello&gt;&quot;</kbd></pre>')
end
end