ryansch-awesome_print 1.0.2.1
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 +38 -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 +140 -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 +133 -0
@@ -0,0 +1,140 @@
|
|
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
|
+
|
8
|
+
class << self # Class accessors for custom defaults.
|
9
|
+
attr_accessor :defaults, :force_colors
|
10
|
+
|
11
|
+
# Class accessor to force colorized output (ex. forked subprocess where TERM
|
12
|
+
# might be dumb).
|
13
|
+
#------------------------------------------------------------------------------
|
14
|
+
def force_colors!(value = true)
|
15
|
+
@force_colors = value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Inspector
|
20
|
+
attr_accessor :options
|
21
|
+
|
22
|
+
AP = :__awesome_print__
|
23
|
+
|
24
|
+
def initialize(options = {})
|
25
|
+
@options = {
|
26
|
+
:indent => 4, # Indent using 4 spaces.
|
27
|
+
:index => true, # Display array indices.
|
28
|
+
:html => false, # Use ANSI color codes rather than HTML.
|
29
|
+
:multiline => true, # Display in multiple lines.
|
30
|
+
:plain => false, # Use colors.
|
31
|
+
:sort_keys => false, # Do not sort hash keys.
|
32
|
+
:limit => false, # Limit large output for arrays and hashes. Set to a boolean or integer.
|
33
|
+
:color => {
|
34
|
+
:args => :pale,
|
35
|
+
:array => :white,
|
36
|
+
:bigdecimal => :blue,
|
37
|
+
:class => :yellow,
|
38
|
+
:date => :greenish,
|
39
|
+
:falseclass => :red,
|
40
|
+
:fixnum => :blue,
|
41
|
+
:float => :blue,
|
42
|
+
:hash => :pale,
|
43
|
+
:keyword => :cyan,
|
44
|
+
:method => :purpleish,
|
45
|
+
:nilclass => :red,
|
46
|
+
:string => :yellowish,
|
47
|
+
:struct => :pale,
|
48
|
+
:symbol => :cyanish,
|
49
|
+
:time => :greenish,
|
50
|
+
:trueclass => :green,
|
51
|
+
:variable => :cyanish
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
# Merge custom defaults and let explicit options parameter override them.
|
56
|
+
merge_custom_defaults!
|
57
|
+
merge_options!(options)
|
58
|
+
|
59
|
+
@formatter = AwesomePrint::Formatter.new(self)
|
60
|
+
Thread.current[AP] ||= []
|
61
|
+
end
|
62
|
+
|
63
|
+
# Dispatcher that detects data nesting and invokes object-aware formatter.
|
64
|
+
#------------------------------------------------------------------------------
|
65
|
+
def awesome(object)
|
66
|
+
if Thread.current[AP].include?(object.object_id)
|
67
|
+
nested(object)
|
68
|
+
else
|
69
|
+
begin
|
70
|
+
Thread.current[AP] << object.object_id
|
71
|
+
unnested(object)
|
72
|
+
ensure
|
73
|
+
Thread.current[AP].pop
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Return true if we are to colorize the output.
|
79
|
+
#------------------------------------------------------------------------------
|
80
|
+
def colorize?
|
81
|
+
AwesomePrint.force_colors ||= false
|
82
|
+
AwesomePrint.force_colors || (STDOUT.tty? && ((ENV['TERM'] && ENV['TERM'] != 'dumb') || ENV['ANSICON']))
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
# Format nested data, for example:
|
88
|
+
# arr = [1, 2]; arr << arr
|
89
|
+
# => [1,2, [...]]
|
90
|
+
# hash = { :a => 1 }; hash[:b] = hash
|
91
|
+
# => { :a => 1, :b => {...} }
|
92
|
+
#------------------------------------------------------------------------------
|
93
|
+
def nested(object)
|
94
|
+
case printable(object)
|
95
|
+
when :array then @formatter.colorize("[...]", :array)
|
96
|
+
when :hash then @formatter.colorize("{...}", :hash)
|
97
|
+
when :struct then @formatter.colorize("{...}", :struct)
|
98
|
+
else @formatter.colorize("...#{object.class}...", :class)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
#------------------------------------------------------------------------------
|
103
|
+
def unnested(object)
|
104
|
+
@formatter.format(object, printable(object))
|
105
|
+
end
|
106
|
+
|
107
|
+
# Turn class name into symbol, ex: Hello::World => :hello_world. Classes that
|
108
|
+
# inherit from Array, Hash, File, Dir, and Struct are treated as the base class.
|
109
|
+
#------------------------------------------------------------------------------
|
110
|
+
def printable(object)
|
111
|
+
case object
|
112
|
+
when Array then :array
|
113
|
+
when Hash then :hash
|
114
|
+
when File then :file
|
115
|
+
when Dir then :dir
|
116
|
+
when Struct then :struct
|
117
|
+
else object.class.to_s.gsub(/:+/, "_").downcase.to_sym
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Update @options by first merging the :color hash and then the remaining keys.
|
122
|
+
#------------------------------------------------------------------------------
|
123
|
+
def merge_options!(options = {})
|
124
|
+
@options[:color].merge!(options.delete(:color) || {})
|
125
|
+
@options.merge!(options)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Load ~/.aprc file with custom defaults that override default options.
|
129
|
+
#------------------------------------------------------------------------------
|
130
|
+
def merge_custom_defaults!
|
131
|
+
dotfile = File.join(ENV["HOME"], ".aprc")
|
132
|
+
if File.readable?(dotfile)
|
133
|
+
load dotfile
|
134
|
+
merge_options!(AwesomePrint.defaults)
|
135
|
+
end
|
136
|
+
rescue => e
|
137
|
+
$stderr.puts "Could not load #{dotfile}: #{e}"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,10 @@
|
|
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
|
+
def self.version
|
8
|
+
'1.0.2.1'
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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
|
+
#
|
7
|
+
# AwesomePrint might be loaded implicitly through ~/.irbrc so do nothing
|
8
|
+
# for subsequent requires.
|
9
|
+
#
|
10
|
+
unless defined?(AwesomePrint)
|
11
|
+
%w(array string method object class kernel).each do |file|
|
12
|
+
require File.dirname(__FILE__) + "/awesome_print/core_ext/#{file}"
|
13
|
+
end
|
14
|
+
|
15
|
+
require File.dirname(__FILE__) + "/awesome_print/inspector"
|
16
|
+
require File.dirname(__FILE__) + "/awesome_print/formatter"
|
17
|
+
require File.dirname(__FILE__) + "/awesome_print/version"
|
18
|
+
require File.dirname(__FILE__) + "/awesome_print/core_ext/logger" if defined?(Logger)
|
19
|
+
|
20
|
+
# Load the following under normal circumstances as well as in Rails
|
21
|
+
# console when required from ~/.irbrc or ~/.pryrc.
|
22
|
+
require File.dirname(__FILE__) + "/awesome_print/ext/active_record" if defined?(ActiveRecord) || (defined?(Pry) || (defined?(IRB) && ENV['RAILS_ENV']))
|
23
|
+
require File.dirname(__FILE__) + "/awesome_print/ext/active_support" if defined?(ActiveSupport) || (defined?(Pry) || (defined?(IRB) && ENV['RAILS_ENV']))
|
24
|
+
|
25
|
+
# Load remaining extensions.
|
26
|
+
require File.dirname(__FILE__) + "/awesome_print/ext/action_view" if defined?(ActionView::Base)
|
27
|
+
require File.dirname(__FILE__) + "/awesome_print/ext/mongo_mapper" if defined?(MongoMapper)
|
28
|
+
require File.dirname(__FILE__) + "/awesome_print/ext/mongoid" if defined?(Mongoid)
|
29
|
+
require File.dirname(__FILE__) + "/awesome_print/ext/nokogiri" if defined?(Nokogiri)
|
30
|
+
end
|
data/spec/colors_spec.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "AwesomePrint" do
|
4
|
+
def stub_tty!(output = true, stream = STDOUT)
|
5
|
+
if output
|
6
|
+
stream.instance_eval { def tty?; true; end }
|
7
|
+
else
|
8
|
+
stream.instance_eval { def tty?; false; end }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
before do
|
13
|
+
stub_dotfile!
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "colorization" do
|
17
|
+
PLAIN = '[ 1, :two, "three", [ nil, [ true, false ] ] ]'
|
18
|
+
COLORIZED = "[ \e[1;34m1\e[0m, \e[0;36m:two\e[0m, \e[0;33m\"three\"\e[0m, [ \e[1;31mnil\e[0m, [ \e[1;32mtrue\e[0m, \e[1;31mfalse\e[0m ] ] ]"
|
19
|
+
|
20
|
+
before do
|
21
|
+
ENV['TERM'] = "xterm-colors"
|
22
|
+
ENV.delete('ANSICON')
|
23
|
+
@arr = [ 1, :two, "three", [ nil, [ true, false] ] ]
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "default settings (no forced colors)" do
|
27
|
+
before do
|
28
|
+
AwesomePrint.force_colors! false
|
29
|
+
end
|
30
|
+
|
31
|
+
it "colorizes tty processes by default" do
|
32
|
+
stub_tty!
|
33
|
+
@arr.ai(:multiline => false).should == COLORIZED
|
34
|
+
end
|
35
|
+
|
36
|
+
it "colorizes processes with ENV['ANSICON'] by default" do
|
37
|
+
begin
|
38
|
+
stub_tty!
|
39
|
+
term, ENV['ANSICON'] = ENV['ANSICON'], "1"
|
40
|
+
@arr.ai(:multiline => false).should == COLORIZED
|
41
|
+
ensure
|
42
|
+
ENV['ANSICON'] = term
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "does not colorize tty processes running in dumb terminals by default" do
|
47
|
+
begin
|
48
|
+
stub_tty!
|
49
|
+
term, ENV['TERM'] = ENV['TERM'], "dumb"
|
50
|
+
@arr.ai(:multiline => false).should == PLAIN
|
51
|
+
ensure
|
52
|
+
ENV['TERM'] = term
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it "does not colorize subprocesses by default" do
|
57
|
+
begin
|
58
|
+
stub_tty! false
|
59
|
+
@arr.ai(:multiline => false).should == PLAIN
|
60
|
+
ensure
|
61
|
+
stub_tty!
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "forced colors override" do
|
67
|
+
before do
|
68
|
+
AwesomePrint.force_colors!
|
69
|
+
end
|
70
|
+
|
71
|
+
it "still colorizes tty processes" do
|
72
|
+
stub_tty!
|
73
|
+
@arr.ai(:multiline => false).should == COLORIZED
|
74
|
+
end
|
75
|
+
|
76
|
+
it "colorizes processes with ENV['ANSICON'] set to 0" do
|
77
|
+
begin
|
78
|
+
stub_tty!
|
79
|
+
term, ENV['ANSICON'] = ENV['ANSICON'], "1"
|
80
|
+
@arr.ai(:multiline => false).should == COLORIZED
|
81
|
+
ensure
|
82
|
+
ENV['ANSICON'] = term
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it "colorizes dumb terminals" do
|
87
|
+
begin
|
88
|
+
stub_tty!
|
89
|
+
term, ENV['TERM'] = ENV['TERM'], "dumb"
|
90
|
+
@arr.ai(:multiline => false).should == COLORIZED
|
91
|
+
ensure
|
92
|
+
ENV['TERM'] = term
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it "colorizes subprocess" do
|
97
|
+
begin
|
98
|
+
stub_tty! false
|
99
|
+
@arr.ai(:multiline => false).should == COLORIZED
|
100
|
+
ensure
|
101
|
+
stub_tty!
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|