gardelea-awesome_print 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +22 -0
- data/CHANGELOG +77 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +26 -0
- data/LICENSE +22 -0
- data/README.md +339 -0
- data/Rakefile +2 -0
- data/lib/ap.rb +10 -0
- data/lib/awesome_print/core_ext/array.rb +71 -0
- data/lib/awesome_print/core_ext/class.rb +22 -0
- data/lib/awesome_print/core_ext/kernel.rb +21 -0
- data/lib/awesome_print/core_ext/logger.rb +20 -0
- data/lib/awesome_print/core_ext/method.rb +21 -0
- data/lib/awesome_print/core_ext/object.rb +22 -0
- data/lib/awesome_print/core_ext/string.rb +31 -0
- data/lib/awesome_print/ext/action_view.rb +18 -0
- data/lib/awesome_print/ext/active_record.rb +64 -0
- data/lib/awesome_print/ext/active_support.rb +47 -0
- data/lib/awesome_print/ext/mongo_mapper.rb +110 -0
- data/lib/awesome_print/ext/mongoid.rb +65 -0
- data/lib/awesome_print/ext/nokogiri.rb +45 -0
- data/lib/awesome_print/formatter.rb +384 -0
- data/lib/awesome_print/inspector.rb +145 -0
- data/lib/awesome_print/version.rb +10 -0
- data/lib/awesome_print.rb +30 -0
- data/spec/colors_spec.rb +106 -0
- data/spec/formats_spec.rb +730 -0
- data/spec/methods_spec.rb +458 -0
- data/spec/objects_spec.rb +79 -0
- data/spec/spec_helper.rb +51 -0
- metadata +108 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
# Copyright (c) 2010-2011 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Awesome Print is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
class String
|
7
|
+
#
|
8
|
+
# ANSI color codes:
|
9
|
+
# \e => escape
|
10
|
+
# 30 => color base
|
11
|
+
# 1 => bright
|
12
|
+
# 0 => normal
|
13
|
+
#
|
14
|
+
# For HTML coloring we use <kbd> tag instead of <span> to require monospace
|
15
|
+
# font. Note that beloved <tt> has been removed from HTML5.
|
16
|
+
#
|
17
|
+
%w(gray red green yellow blue purple cyan white).zip(
|
18
|
+
%w(black darkred darkgreen brown navy darkmagenta darkcyan slategray)).each_with_index do |(color, shade), i|
|
19
|
+
define_method color do |*html|
|
20
|
+
html[0] ? %Q|<kbd style="color:#{color}">#{self}</kbd>| : "\e[1;#{30+i}m#{self}\e[0m"
|
21
|
+
end
|
22
|
+
|
23
|
+
define_method "#{color}ish" do |*html|
|
24
|
+
html[0] ? %Q|<kbd style="color:#{shade}">#{self}</kbd>| : "\e[0;#{30+i}m#{self}\e[0m"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
alias :black :grayish
|
29
|
+
alias :pale :whiteish
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Copyright (c) 2010-2011 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Awesome Print is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
module AwesomePrint
|
7
|
+
module ActionView
|
8
|
+
|
9
|
+
# Use HTML colors and add default "debug_dump" class to the resulting HTML.
|
10
|
+
def ap_debug(object, options = {})
|
11
|
+
object.ai(options.merge(:html => true)).sub(/^<pre([\s>])/, '<pre class="debug_dump"\\1')
|
12
|
+
end
|
13
|
+
|
14
|
+
alias_method :ap, :ap_debug
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
ActionView::Base.send(:include, AwesomePrint::ActionView)
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# Copyright (c) 2010-2011 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Awesome Print is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
module AwesomePrint
|
7
|
+
module ActiveRecord
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.send :alias_method, :cast_without_active_record, :cast
|
11
|
+
base.send :alias_method, :cast, :cast_with_active_record
|
12
|
+
end
|
13
|
+
|
14
|
+
# Add ActiveRecord class names to the dispatcher pipeline.
|
15
|
+
#------------------------------------------------------------------------------
|
16
|
+
def cast_with_active_record(object, type)
|
17
|
+
cast = cast_without_active_record(object, type)
|
18
|
+
return cast if !defined?(::ActiveRecord)
|
19
|
+
|
20
|
+
if object.is_a?(::ActiveRecord::Base)
|
21
|
+
cast = :active_record_instance
|
22
|
+
elsif object.is_a?(Class) && object.ancestors.include?(::ActiveRecord::Base)
|
23
|
+
cast = :active_record_class
|
24
|
+
end
|
25
|
+
cast
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Format ActiveRecord instance object.
|
31
|
+
#
|
32
|
+
# NOTE: by default only instance attributes (i.e. columns) are shown. To format
|
33
|
+
# ActiveRecord instance as regular object showing its instance variables and
|
34
|
+
# accessors use :raw => true option:
|
35
|
+
#
|
36
|
+
# ap record, :raw => true
|
37
|
+
#
|
38
|
+
#------------------------------------------------------------------------------
|
39
|
+
def awesome_active_record_instance(object)
|
40
|
+
return object.inspect if !defined?(::ActiveSupport::OrderedHash)
|
41
|
+
return awesome_object(object) if @options[:raw]
|
42
|
+
|
43
|
+
data = object.class.column_names.inject(::ActiveSupport::OrderedHash.new) do |hash, name|
|
44
|
+
hash[name.to_sym] = object.send(name) if object.has_attribute?(name) || object.new_record?
|
45
|
+
hash
|
46
|
+
end
|
47
|
+
"#{object} " << awesome_hash(data)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Format ActiveRecord class object.
|
51
|
+
#------------------------------------------------------------------------------
|
52
|
+
def awesome_active_record_class(object)
|
53
|
+
return object.inspect if !defined?(::ActiveSupport::OrderedHash) || !object.respond_to?(:columns) || object.to_s == "ActiveRecord::Base"
|
54
|
+
|
55
|
+
data = object.columns.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
|
56
|
+
hash[c.name.to_sym] = c.type
|
57
|
+
hash
|
58
|
+
end
|
59
|
+
"class #{object} < #{object.superclass} " << awesome_hash(data)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
AwesomePrint::Formatter.send(:include, AwesomePrint::ActiveRecord)
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# Copyright (c) 2010-2011 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Awesome Print is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
module AwesomePrint
|
7
|
+
module ActiveSupport
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.send :alias_method, :cast_without_active_support, :cast
|
11
|
+
base.send :alias_method, :cast, :cast_with_active_support
|
12
|
+
end
|
13
|
+
|
14
|
+
def cast_with_active_support(object, type)
|
15
|
+
cast = cast_without_active_support(object, type)
|
16
|
+
if defined?(::ActiveSupport) && defined?(::HashWithIndifferentAccess)
|
17
|
+
if object.is_a?(::ActiveSupport::TimeWithZone) || object.is_a?(::Date)
|
18
|
+
cast = :active_support_time
|
19
|
+
elsif object.is_a?(::HashWithIndifferentAccess)
|
20
|
+
cast = :hash_with_indifferent_access
|
21
|
+
end
|
22
|
+
end
|
23
|
+
cast
|
24
|
+
end
|
25
|
+
|
26
|
+
# Format ActiveSupport::TimeWithZone as standard Time.
|
27
|
+
#------------------------------------------------------------------------------
|
28
|
+
def awesome_active_support_time(object)
|
29
|
+
colorize(object.inspect, :time)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Format HashWithIndifferentAccess as standard Hash.
|
33
|
+
#------------------------------------------------------------------------------
|
34
|
+
def awesome_hash_with_indifferent_access(object)
|
35
|
+
awesome_hash(object)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
AwesomePrint::Formatter.send(:include, AwesomePrint::ActiveSupport)
|
41
|
+
#
|
42
|
+
# Colorize Rails logs.
|
43
|
+
#
|
44
|
+
if defined?(ActiveSupport::LogSubscriber)
|
45
|
+
AwesomePrint.force_colors! ActiveSupport::LogSubscriber.colorize_logging
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# Copyright (c) 2010-2011 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Awesome Print is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
module AwesomePrint
|
7
|
+
module MongoMapper
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.send :alias_method, :cast_without_mongo_mapper, :cast
|
11
|
+
base.send :alias_method, :cast, :cast_with_mongo_mapper
|
12
|
+
end
|
13
|
+
|
14
|
+
# Add MongoMapper class names to the dispatcher pipeline.
|
15
|
+
#------------------------------------------------------------------------------
|
16
|
+
def cast_with_mongo_mapper(object, type)
|
17
|
+
cast = cast_without_mongo_mapper(object, type)
|
18
|
+
|
19
|
+
if defined?(::MongoMapper::Document)
|
20
|
+
if object.is_a?(Class) && (object.ancestors & [ ::MongoMapper::Document, ::MongoMapper::EmbeddedDocument ]).size > 0
|
21
|
+
cast = :mongo_mapper_class
|
22
|
+
elsif object.is_a?(::MongoMapper::Document) || object.is_a?(::MongoMapper::EmbeddedDocument)
|
23
|
+
cast = :mongo_mapper_instance
|
24
|
+
elsif object.is_a?(::MongoMapper::Plugins::Associations::Base)
|
25
|
+
cast = :mongo_mapper_association
|
26
|
+
elsif object.is_a?(::BSON::ObjectId)
|
27
|
+
cast = :mongo_mapper_bson_id
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
cast
|
32
|
+
end
|
33
|
+
|
34
|
+
# Format MongoMapper class object.
|
35
|
+
#------------------------------------------------------------------------------
|
36
|
+
def awesome_mongo_mapper_class(object)
|
37
|
+
return object.inspect if !defined?(::ActiveSupport::OrderedHash) || !object.respond_to?(:keys)
|
38
|
+
|
39
|
+
data = object.keys.sort.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
|
40
|
+
hash[c.first] = (c.last.type || "undefined").to_s.underscore.intern
|
41
|
+
hash
|
42
|
+
end
|
43
|
+
|
44
|
+
# Add in associations
|
45
|
+
if @options[:mongo_mapper][:show_associations]
|
46
|
+
object.associations.each do |name, assoc|
|
47
|
+
data[name.to_s] = assoc
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
"class #{object} < #{object.superclass} " << awesome_hash(data)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Format MongoMapper instance object.
|
55
|
+
#
|
56
|
+
# NOTE: by default only instance attributes (i.e. keys) are shown. To format
|
57
|
+
# MongoMapper instance as regular object showing its instance variables and
|
58
|
+
# accessors use :raw => true option:
|
59
|
+
#
|
60
|
+
# ap record, :raw => true
|
61
|
+
#
|
62
|
+
#------------------------------------------------------------------------------
|
63
|
+
def awesome_mongo_mapper_instance(object)
|
64
|
+
return object.inspect if !defined?(::ActiveSupport::OrderedHash)
|
65
|
+
return awesome_object(object) if @options[:raw]
|
66
|
+
|
67
|
+
data = object.keys.keys.sort_by{|k| k}.inject(::ActiveSupport::OrderedHash.new) do |hash, name|
|
68
|
+
hash[name] = object[name]
|
69
|
+
hash
|
70
|
+
end
|
71
|
+
|
72
|
+
# Add in associations
|
73
|
+
if @options[:mongo_mapper][:show_associations]
|
74
|
+
object.associations.each do |name, assoc|
|
75
|
+
if @options[:mongo_mapper][:inline_embedded] and assoc.embeddable?
|
76
|
+
data[name.to_s] = object.send(name)
|
77
|
+
else
|
78
|
+
data[name.to_s] = assoc
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
label = object.to_s
|
84
|
+
label = "#{colorize('embedded', :assoc)} #{label}" if object.is_a?(::MongoMapper::EmbeddedDocument)
|
85
|
+
|
86
|
+
"#{label} " << awesome_hash(data)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Format MongoMapper association object.
|
90
|
+
#------------------------------------------------------------------------------
|
91
|
+
def awesome_mongo_mapper_association(object)
|
92
|
+
return object.inspect if !defined?(::ActiveSupport::OrderedHash)
|
93
|
+
return awesome_object(object) if @options[:raw]
|
94
|
+
|
95
|
+
association = object.class.name.split('::').last.titleize.downcase.sub(/ association$/,'')
|
96
|
+
association = "embeds #{association}" if object.embeddable?
|
97
|
+
class_name = object.class_name
|
98
|
+
|
99
|
+
"#{colorize(association, :assoc)} #{colorize(class_name, :class)}"
|
100
|
+
end
|
101
|
+
|
102
|
+
# Format BSON::ObjectId
|
103
|
+
#------------------------------------------------------------------------------
|
104
|
+
def awesome_mongo_mapper_bson_id(object)
|
105
|
+
object.inspect
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
AwesomePrint::Formatter.send(:include, AwesomePrint::MongoMapper)
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# Copyright (c) 2010-2011 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Awesome Print is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
module AwesomePrint
|
7
|
+
module Mongoid
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.send :alias_method, :cast_without_mongoid, :cast
|
11
|
+
base.send :alias_method, :cast, :cast_with_mongoid
|
12
|
+
end
|
13
|
+
|
14
|
+
# Add Mongoid class names to the dispatcher pipeline.
|
15
|
+
#------------------------------------------------------------------------------
|
16
|
+
def cast_with_mongoid(object, type)
|
17
|
+
cast = cast_without_mongoid(object, type)
|
18
|
+
if defined?(::Mongoid::Document)
|
19
|
+
if object.is_a?(Class) && object.ancestors.include?(::Mongoid::Document)
|
20
|
+
cast = :mongoid_class
|
21
|
+
elsif object.class.ancestors.include?(::Mongoid::Document)
|
22
|
+
cast = :mongoid_document
|
23
|
+
elsif object.is_a?(::BSON::ObjectId)
|
24
|
+
cast = :mongoid_bson_id
|
25
|
+
end
|
26
|
+
end
|
27
|
+
cast
|
28
|
+
end
|
29
|
+
|
30
|
+
# Format Mongoid class object.
|
31
|
+
#------------------------------------------------------------------------------
|
32
|
+
def awesome_mongoid_class(object)
|
33
|
+
return object.inspect if !defined?(::ActiveSupport::OrderedHash) || !object.respond_to?(:fields)
|
34
|
+
|
35
|
+
data = object.fields.sort_by { |key| key }.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
|
36
|
+
hash[c[1].name.to_sym] = (c[1].type || "undefined").to_s.underscore.intern
|
37
|
+
hash
|
38
|
+
end
|
39
|
+
"class #{object} < #{object.superclass} " << awesome_hash(data)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Format Mongoid Document object.
|
43
|
+
#------------------------------------------------------------------------------
|
44
|
+
def awesome_mongoid_document(object)
|
45
|
+
return object.inspect if !defined?(::ActiveSupport::OrderedHash)
|
46
|
+
|
47
|
+
data = object.attributes.sort_by { |key| key }.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
|
48
|
+
hash[c[0].to_sym] = c[1]
|
49
|
+
hash
|
50
|
+
end
|
51
|
+
if !object.errors.empty?
|
52
|
+
data = {:errors => object.errors, :attributes => data}
|
53
|
+
end
|
54
|
+
"#{object} #{awesome_hash(data)}"
|
55
|
+
end
|
56
|
+
|
57
|
+
# Format BSON::ObjectId
|
58
|
+
#------------------------------------------------------------------------------
|
59
|
+
def awesome_mongoid_bson_id(object)
|
60
|
+
object.inspect
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
AwesomePrint::Formatter.send(:include, AwesomePrint::Mongoid)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Copyright (c) 2010-2011 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Awesome Print is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
module AwesomePrint
|
7
|
+
module Nokogiri
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.send :alias_method, :cast_without_nokogiri, :cast
|
11
|
+
base.send :alias_method, :cast, :cast_with_nokogiri
|
12
|
+
end
|
13
|
+
|
14
|
+
# Add Nokogiri XML Node and NodeSet names to the dispatcher pipeline.
|
15
|
+
#------------------------------------------------------------------------------
|
16
|
+
def cast_with_nokogiri(object, type)
|
17
|
+
cast = cast_without_nokogiri(object, type)
|
18
|
+
if (defined?(::Nokogiri::XML::Node) && object.is_a?(::Nokogiri::XML::Node)) ||
|
19
|
+
(defined?(::Nokogiri::XML::NodeSet) && object.is_a?(::Nokogiri::XML::NodeSet))
|
20
|
+
cast = :nokogiri_xml_node
|
21
|
+
end
|
22
|
+
cast
|
23
|
+
end
|
24
|
+
|
25
|
+
#------------------------------------------------------------------------------
|
26
|
+
def awesome_nokogiri_xml_node(object)
|
27
|
+
if object.is_a?(::Nokogiri::XML::NodeSet) && object.empty?
|
28
|
+
return "[]"
|
29
|
+
end
|
30
|
+
xml = object.to_xml(:indent => 2)
|
31
|
+
#
|
32
|
+
# Colorize tag, id/class name, and contents.
|
33
|
+
#
|
34
|
+
xml.gsub!(/(<)(\/?[A-Za-z1-9]+)/) { |tag| "#{$1}#{colorize($2, :keyword)}" }
|
35
|
+
xml.gsub!(/(id|class)="[^"]+"/i) { |id| colorize(id, :class) }
|
36
|
+
xml.gsub!(/>([^<]+)</) do |contents|
|
37
|
+
contents = colorize($1, :trueclass) if contents && !contents.empty?
|
38
|
+
">#{contents}<"
|
39
|
+
end
|
40
|
+
xml
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
AwesomePrint::Formatter.send(:include, AwesomePrint::Nokogiri)
|