ryansch-awesome_print 1.0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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