ryansch-awesome_print 1.0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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