awesome_print 0.1.0 → 0.2.0

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.
data/CHANGELOG ADDED
@@ -0,0 +1,27 @@
1
+ 0.2.0
2
+ - Added support for logger.ap (including Rails logger)
3
+ - Added support for HashWithIndifferentAccess from ActiveSupport
4
+ - ap now works with scripts that use ActiveRecord/ActiveSupport outside Rails
5
+ - ap now correctly shows file and directory names with fancy characters (shell escape)
6
+
7
+ 0.1.4
8
+ - Format BigDecimal and Rational objects as Float scalars
9
+ - Explicit options parameter can override custom defaults
10
+ - Custom defaults are not interfering when running specs
11
+ - Custom defaults now work correctly with Ruby 1.9.x
12
+
13
+ 0.1.3
14
+ - Added support for setting custom defaults in ~/.aprc
15
+
16
+ 0.1.2
17
+ - Correctly handle empty arrays and hashes
18
+ - Use alias_method instead of alias (fixes non-tty method aliasing)
19
+ - Added awesome_inspect method
20
+
21
+ 0.1.1
22
+ - Added support for tableless ActiveRecord models
23
+ - Left align hash keys if @options[:indent] is negative
24
+
25
+ 0.1.0
26
+ - Initial Release.
27
+
data/README.md CHANGED
@@ -1,55 +1,61 @@
1
1
  ## Awesome Print ##
2
- Awesome Print is Ruby library that pretty prints Ruby objects in full color
3
- exposing their internal structure with proper indentation. Rails ActiveRecord
4
- objects are supported via included mixin.
2
+ Awesome Print is Ruby library that pretty prints Ruby objects in full color
3
+ exposing their internal structure with proper indentation. Rails ActiveRecord
4
+ objects are supported via included mixin.
5
5
 
6
6
  ### Installation ###
7
- $ # Installing as Ruby gem
7
+ # Installing as Ruby gem
8
8
  $ gem install awesome_print
9
9
 
10
10
  # Installing as Rails plugin
11
11
  $ ruby script/plugin install http://github.com/michaeldv/awesome_print_.git
12
12
 
13
- $ # Cloning the repository
13
+ # Cloning the repository
14
14
  $ git clone git://github.com/michaeldv/awesome_print_.git
15
15
 
16
16
  ### Usage ###
17
+
17
18
  require "ap"
18
- ap(object, options = {})
19
-
20
- Default options:
21
- :miltiline => true,
22
- :plain => false,
23
- :colors => {
24
- :array => :white,
25
- :bignum => :blue,
26
- :class => :yellow,
27
- :date => :greenish,
28
- :falseclass => :red,
29
- :fixnum => :blue,
30
- :float => :blue,
31
- :hash => :gray,
32
- :nilclass => :red,
33
- :string => :yellowish,
34
- :symbol => :cyanish,
35
- :time => :greenish,
36
- :trueclass => :green
37
- }
19
+ ap object, options = {}
38
20
 
39
- Supported color names:
40
- :gray, :red, :green, :yellow, :blue, :purple, :cyan, :white
41
- :black, :redish, :greenish, :yellowish, :blueish, :purpleish, :cyanish, :pale
21
+ Default options:
22
+
23
+ :multiline => true,
24
+ :plain => false,
25
+ :indent => 4,
26
+ :color => {
27
+ :array => :white,
28
+ :bignum => :blue,
29
+ :class => :yellow,
30
+ :date => :greenish,
31
+ :falseclass => :red,
32
+ :fixnum => :blue,
33
+ :float => :blue,
34
+ :hash => :gray,
35
+ :nilclass => :red,
36
+ :string => :yellowish,
37
+ :symbol => :cyanish,
38
+ :time => :greenish,
39
+ :trueclass => :green
40
+ }
42
41
 
43
- ### Example (IRB) ###
44
- $ irb
45
- irb> require "ap"
46
- irb> data = [ false, 42, %w(fourty two), { :now => Time.now, :class => Time.now.class, :distance => 42e42 } ]
47
- irb> ap data
42
+ Supported color names:
43
+
44
+ :gray, :red, :green, :yellow, :blue, :purple, :cyan, :white
45
+ :black, :redish, :greenish, :yellowish, :blueish, :purpleish, :cyanish, :pale
46
+
47
+ ### Examples ###
48
+ $ cat > 1.rb
49
+ require "ap"
50
+ data = [ false, 42, %w(forty two), { :now => Time.now, :class => Time.now.class, :distance => 42e42 } ]
51
+ ap data
52
+ ^D
53
+ $ ruby 1.rb
48
54
  [
49
55
  [0] false,
50
56
  [1] 42,
51
57
  [2] [
52
- [0] "fourty",
58
+ [0] "forty",
53
59
  [1] "two"
54
60
  ],
55
61
  [3] {
@@ -58,11 +64,29 @@
58
64
  :distance => 4.2e+43
59
65
  }
60
66
  ]
61
- irb> ap data, :multiline => false
62
- [ false, 42, [ "fourty", "two" ], { :class => Time < Object, :distance => 4.2e+43, :now => Fri Apr 02 19:44:52 -0700 2010 } ]
63
- irb>
64
67
 
65
- ### Example (Rails) ###
68
+ $ cat > 2.rb
69
+ require "ap"
70
+ data = { :now => Time.now, :class => Time.now.class, :distance => 42e42 }
71
+ ap data, :indent => -2 # <-- Left align hash keys.
72
+ ^D
73
+ $ ruby 2.rb
74
+ {
75
+ :class => Time < Object,
76
+ :now => Fri Apr 02 19:55:53 -0700 2010,
77
+ :distance => 4.2e+43
78
+ }
79
+
80
+ $ cat > 3.rb
81
+ require "ap"
82
+ data = [ false, 42, %w(forty two) ]
83
+ data << data # <-- Nested array.
84
+ ap data, :multiline => false
85
+ ^D
86
+ $ ruby 3.rb
87
+ [ false, 42, [ "forty", "two" ], [...] ]
88
+
89
+ ### Example (Rails console) ###
66
90
  $ ruby script/console
67
91
  Loading development environment (Rails 2.3.5)
68
92
  rails> require "ap"
@@ -120,15 +144,61 @@
120
144
  }
121
145
  rails>
122
146
 
147
+ ### IRB integration ###
148
+ To use awesome_print as default formatter in irb and Rails console add the following
149
+ lines into your ~/.irbrc file:
150
+
151
+ require "rubygems"
152
+ require "ap"
153
+ IRB::Irb.class_eval do
154
+ def output_value
155
+ ap @context.last_value
156
+ end
157
+ end
158
+
159
+ ### Logger Convenience Method ###
160
+ awesome_print adds an ap method to the Logger and ActiveSupport::BufferedLogger classes,
161
+ allowing you to call:
162
+
163
+ logger.ap object
164
+
165
+ By default, this logs at the :debug level. You can override that globally with
166
+
167
+ :log_level => :info
168
+
169
+ in the custom defaults (see below), or you can override on a per call basis with
170
+
171
+ logger.ap object, :warn
172
+
173
+ ### Setting Custom Defaults ###
174
+ You can set your own default options by creating ``.aprc`` file in your home
175
+ directory. Within that file assign your defaults to ``AwesomePrint.defaults``.
176
+ For example:
177
+
178
+ # ~/.aprc file.
179
+ AwesomePrint.defaults = {
180
+ :indent => -2,
181
+ :color => {
182
+ :hash => :pale,
183
+ :class => :white
184
+ }
185
+ }
186
+
123
187
  ### Note on Patches/Pull Requests ###
124
- * Fork the project on Github.
125
- * Make your feature addition or bug fix.
126
- * Add specs for it, making sure $ rake spec is all green.
127
- * Commit, do not mess with rakefile, version, or history.
128
- * Send me a pull request.
188
+ * Fork the project on Github.
189
+ * Make your feature addition or bug fix.
190
+ * Add specs for it, making sure $ rake spec is all green.
191
+ * Commit, do not mess with rakefile, version, or history.
192
+ * Send me a pull request.
193
+
194
+ ### Contributors ###
195
+
196
+ * Daniel Bretoi -- http://github.com/danielb2
197
+ * eregon -- http://github.com/eregon
198
+ * Tobias Crawley -- http://github.com/tobias
129
199
 
130
200
  ### License ###
131
- Copyright (c) 2010 Michael Dvorkin
132
- %w(mike dvorkin.net) * "@" || %w(mike fatfreecrm.com) * "@"
201
+ Copyright (c) 2010 Michael Dvorkin
202
+ %w(mike dvorkin.net) * "@" || %w(mike fatfreecrm.com) * "@"
133
203
 
134
- Released under the MIT license. See LICENSE file for details.
204
+ Released under the MIT license. See LICENSE file for details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -3,9 +3,11 @@
3
3
  # Awesome Print is freely distributable under the terms of MIT license.
4
4
  # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
5
  #------------------------------------------------------------------------------
6
+ require "shellwords"
7
+
6
8
  class AwesomePrint
7
9
  AP = :__awesome_print__
8
- CORE = [ :array, :hash, :class, :file, :dir ]
10
+ CORE = [ :array, :hash, :class, :file, :dir, :bigdecimal, :rational ]
9
11
 
10
12
  def initialize(options = {})
11
13
  @options = {
@@ -14,35 +16,36 @@ class AwesomePrint
14
16
  :indent => 4,
15
17
  :color => {
16
18
  :array => :white,
17
- :bignum => :blue,
19
+ :bigdecimal => :blue,
18
20
  :class => :yellow,
19
21
  :date => :greenish,
20
22
  :falseclass => :red,
21
23
  :fixnum => :blue,
22
24
  :float => :blue,
23
- :hash => :gray,
25
+ :hash => :pale,
24
26
  :nilclass => :red,
25
27
  :string => :yellowish,
26
28
  :symbol => :cyanish,
27
29
  :time => :greenish,
28
30
  :trueclass => :green
29
- }.merge(options.delete(:color) || {})
30
- }.merge(options)
31
+ }
32
+ }
31
33
 
32
- @indentation = @options[:indent]
33
- Thread.current[AP] ||= []
34
- end
34
+ # Merge custom defaults and let explicit options parameter override them.
35
+ merge_custom_defaults!
36
+ merge_options!(options)
35
37
 
36
- def puts(object)
37
- Kernel.puts awesome(object)
38
+ @indentation = @options[:indent].abs
39
+ Thread.current[AP] ||= []
38
40
  end
39
-
40
-
41
+
41
42
  private
42
43
 
43
44
  # Format an array.
44
45
  #------------------------------------------------------------------------------
45
46
  def awesome_array(a)
47
+ return "[]" if a == []
48
+
46
49
  if @options[:multiline]
47
50
  width = (a.size - 1).to_s.size
48
51
  data = a.inject([]) do |arr, item|
@@ -58,21 +61,28 @@ class AwesomePrint
58
61
  end
59
62
  end
60
63
 
61
- # Format a hash.
64
+ # Format a hash. If @options[:indent] if negative left align hash keys.
62
65
  #------------------------------------------------------------------------------
63
66
  def awesome_hash(h)
67
+ return "{}" if h == {}
68
+
64
69
  data = h.keys.inject([]) do |arr, key|
65
70
  plain_single_line do
66
71
  arr << [ awesome(key), h[key] ]
67
72
  end
68
73
  end
69
74
 
70
- width = data.map { |key, | key.size }.max + @indentation
75
+ width = data.map { |key, | key.size }.max || 0
76
+ width += @indentation if @options[:indent] > 0
71
77
 
72
78
  data = data.inject([]) do |arr, (key, value)|
73
- formatted_key = (@options[:multiline] ? key.rjust(width) : key) << colorize(" => ", :hash)
79
+ if @options[:multiline]
80
+ formatted_key = (@options[:indent] >= 0 ? key.rjust(width) : indent + key.ljust(width))
81
+ else
82
+ formatted_key = key
83
+ end
74
84
  indented do
75
- arr << (formatted_key << awesome(value))
85
+ arr << (formatted_key << colorize(" => ", :hash) << awesome(value))
76
86
  end
77
87
  end
78
88
  if @options[:multiline]
@@ -95,17 +105,24 @@ class AwesomePrint
95
105
  # Format File object.
96
106
  #------------------------------------------------------------------------------
97
107
  def awesome_file(f)
98
- ls = File.directory?(f) ? `ls -adlF #{f.path}` : `ls -alF #{f.path}`
108
+ ls = File.directory?(f) ? `ls -adlF #{f.path.shellescape}` : `ls -alF #{f.path.shellescape}`
99
109
  awesome_self(f, :with => ls.empty? ? nil : "\n#{ls.chop}")
100
110
  end
101
111
 
102
112
  # Format Dir object.
103
113
  #------------------------------------------------------------------------------
104
114
  def awesome_dir(d)
105
- ls = `ls -alF #{d.path}`
115
+ ls = `ls -alF #{d.path.shellescape}`
106
116
  awesome_self(d, :with => ls.empty? ? nil : "\n#{ls.chop}")
107
117
  end
108
118
 
119
+ # Format BigDecimal and Rational objects by convering them to Float.
120
+ #------------------------------------------------------------------------------
121
+ def awesome_bigdecimal(n)
122
+ awesome_self(n.to_f, :as => :bigdecimal)
123
+ end
124
+ alias :awesome_rational :awesome_bigdecimal
125
+
109
126
  # Catch all method to format an arbitrary object.
110
127
  #------------------------------------------------------------------------------
111
128
  def awesome_self(object, appear = {})
@@ -175,20 +192,47 @@ class AwesomePrint
175
192
 
176
193
  #------------------------------------------------------------------------------
177
194
  def indented
178
- @indentation += @options[:indent]
195
+ @indentation += @options[:indent].abs
179
196
  yield
180
197
  ensure
181
- @indentation -= @options[:indent]
198
+ @indentation -= @options[:indent].abs
182
199
  end
183
200
 
184
- #------------------------------------------------------------------------------
185
201
  def indent
186
- ' ' * @indentation
202
+ @indent = ' ' * @indentation
187
203
  end
188
204
 
189
- #------------------------------------------------------------------------------
190
205
  def outdent
191
- ' ' * (@indentation - @options[:indent])
206
+ @outdent = ' ' * (@indentation - @options[:indent].abs)
207
+ end
208
+
209
+ # Update @options by first merging the :color hash and then the remaining keys.
210
+ #------------------------------------------------------------------------------
211
+ def merge_options!(options = {})
212
+ @options[:color].merge!(options.delete(:color) || {})
213
+ @options.merge!(options)
214
+ end
215
+
216
+ # Load ~/.aprc file with custom defaults that override default options.
217
+ #------------------------------------------------------------------------------
218
+ def merge_custom_defaults!
219
+ dotfile = File.join(ENV["HOME"], ".aprc")
220
+ if File.readable?(dotfile)
221
+ load dotfile
222
+ merge_options!(self.class.defaults)
223
+ end
224
+ rescue => e
225
+ $stderr.puts "Could not load #{dotfile}: #{e}"
226
+ end
227
+
228
+ # Class accessors for custom defaults.
229
+ #------------------------------------------------------------------------------
230
+ def self.defaults
231
+ @@defaults ||= {}
232
+ end
233
+
234
+ def self.defaults=(args = {})
235
+ @@defaults = args
192
236
  end
193
237
 
194
238
  end
@@ -5,10 +5,16 @@
5
5
  #------------------------------------------------------------------------------
6
6
  module Kernel
7
7
 
8
- def ap(object, options = {})
8
+ def ai(options = {})
9
9
  ap = AwesomePrint.new(options)
10
- ap.puts object
10
+ ap.send(:awesome, self)
11
+ end
12
+ alias :awesome_inspect :ai
13
+
14
+ def ap(object, options = {})
15
+ puts object.ai(options)
11
16
  end
17
+ alias :awesome_print :ap
12
18
 
13
19
  module_function :ap
14
20
  end
@@ -0,0 +1,18 @@
1
+ # Copyright (c) 2010 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 AwesomePrintLogger
7
+
8
+ # Add ap method to logger
9
+ #------------------------------------------------------------------------------
10
+ def ap(object, level = nil)
11
+ level ||= AwesomePrint.defaults[:log_level] || :debug
12
+ send level, object.ai
13
+ end
14
+
15
+ end
16
+
17
+ Logger.send(:include, AwesomePrintLogger) if defined?(Logger)
18
+ ActiveSupport::BufferedLogger.send(:include, AwesomePrintLogger) if defined?(::ActiveSupport::BufferedLogger)
@@ -3,7 +3,7 @@
3
3
  # Awesome Print is freely distributable under the terms of MIT license.
4
4
  # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
5
  #------------------------------------------------------------------------------
6
- class String # :nodoc:
6
+ class String
7
7
 
8
8
  [ :gray, :red, :green, :yellow, :blue, :purple, :cyan, :white ].each_with_index do |color, i|
9
9
  if STDOUT.tty? && ENV['TERM'] && ENV['TERM'] != 'dumb'
@@ -11,7 +11,7 @@ class String # :nodoc:
11
11
  define_method :"#{color}ish" do "\033[0;#{30+i}m#{self}\033[0m" end
12
12
  else
13
13
  define_method color do self end
14
- alias :"#{color}ish" color # <- This break Rdoc: Name or symbol expected (got #<RubyToken::TkDSTRING
14
+ alias_method :"#{color}ish", color
15
15
  end
16
16
  end
17
17
 
@@ -3,23 +3,22 @@
3
3
  # Awesome Print is freely distributable under the terms of MIT license.
4
4
  # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
5
  #------------------------------------------------------------------------------
6
- module AwesomePrintRails
6
+ module AwesomePrintActiveRecord
7
7
 
8
8
  def self.included(base)
9
- base.alias_method_chain :printable, :rails
9
+ base.send :alias_method, :printable_without_active_record, :printable
10
+ base.send :alias_method, :printable, :printable_with_active_record
10
11
  end
11
12
 
12
13
  # Add ActiveRecord class names to the dispatcher pipeline.
13
14
  #------------------------------------------------------------------------------
14
- def printable_with_rails(object)
15
- printable = printable_without_rails(object)
15
+ def printable_with_active_record(object)
16
+ printable = printable_without_active_record(object)
16
17
  if printable == :self
17
18
  if object.is_a?(ActiveRecord::Base)
18
19
  printable = :active_record_instance
19
- elsif object.is_a?(ActiveSupport::TimeWithZone)
20
- printable = :active_support_time
21
20
  end
22
- elsif printable == :class && object.class.is_a?(ActiveRecord::Base.class)
21
+ elsif printable == :class and object.ancestors.include?(ActiveRecord::Base)
23
22
  printable = :active_record_class
24
23
  end
25
24
  printable
@@ -38,7 +37,7 @@ module AwesomePrintRails
38
37
  # Format ActiveRecord class object.
39
38
  #------------------------------------------------------------------------------
40
39
  def awesome_active_record_class(object)
41
- if object.table_exists?
40
+ if object.respond_to?(:columns)
42
41
  data = object.columns.inject(ActiveSupport::OrderedHash.new) do |hash, c|
43
42
  hash[c.name.to_sym] = c.type
44
43
  hash
@@ -48,13 +47,7 @@ module AwesomePrintRails
48
47
  object.inspect
49
48
  end
50
49
  end
51
-
52
- # Format ActiveSupport::TimeWithZone as standard Time.
53
- #------------------------------------------------------------------------------
54
- def awesome_active_support_time(object)
55
- awesome_self(object, :as => :time)
56
- end
57
-
50
+
58
51
  end
59
52
 
60
- AwesomePrint.send(:include, AwesomePrintRails)
53
+ AwesomePrint.send(:include, AwesomePrintActiveRecord)
@@ -0,0 +1,44 @@
1
+ # Copyright (c) 2010 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 AwesomePrintActiveSupport
7
+
8
+ def self.included(base)
9
+ base.send :alias_method, :printable_without_active_support, :printable
10
+ base.send :alias_method, :printable, :printable_with_active_support
11
+ end
12
+
13
+ # Add ActiveSupport class names to the dispatcher pipeline.
14
+ #------------------------------------------------------------------------------
15
+ def printable_with_active_support(object)
16
+ printable = printable_without_active_support(object)
17
+ if printable == :self
18
+ if object.is_a?(ActiveSupport::TimeWithZone)
19
+ printable = :active_support_time
20
+ elsif object.is_a?(HashWithIndifferentAccess)
21
+ printable = :hash_with_indifferent_access
22
+ end
23
+ end
24
+ printable
25
+ end
26
+
27
+ # Format ActiveSupport::TimeWithZone as standard Time.
28
+ #------------------------------------------------------------------------------
29
+ def awesome_active_support_time(object)
30
+ awesome_self(object, :as => :time)
31
+ end
32
+
33
+ # Format HashWithIndifferentAccess as standard Hash.
34
+ #
35
+ # NOTE: can't use awesome_self(object, :as => :hash) since awesome_self uses
36
+ # object.inspect internally, i.e. it would convert hash to string.
37
+ #------------------------------------------------------------------------------
38
+ def awesome_hash_with_indifferent_access(object)
39
+ awesome_hash(object)
40
+ end
41
+
42
+ end
43
+
44
+ AwesomePrint.send(:include, AwesomePrintActiveSupport)
data/lib/ap.rb CHANGED
@@ -7,4 +7,8 @@ require File.dirname(__FILE__) + "/ap/core_ext/string"
7
7
  require File.dirname(__FILE__) + "/ap/core_ext/kernel"
8
8
  require File.dirname(__FILE__) + "/ap/awesome_print"
9
9
 
10
- require File.dirname(__FILE__) + "/ap/mixin/rails" if defined?(::Rails)
10
+ require File.dirname(__FILE__) + "/ap/core_ext/logger" if defined?(::Logger) or defined?(::ActiveSupport::BufferedLogger)
11
+
12
+ require File.dirname(__FILE__) + "/ap/mixin/active_record" if defined?(::ActiveRecord)
13
+ require File.dirname(__FILE__) + "/ap/mixin/active_support" if defined?(::ActiveSupport)
14
+
@@ -0,0 +1,118 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ require 'active_record'
4
+ require 'ap/mixin/active_record'
5
+
6
+
7
+ if defined?(::ActiveRecord)
8
+
9
+ # Create tableless ActiveRecord model.
10
+ #------------------------------------------------------------------------------
11
+ class User < ActiveRecord::Base
12
+ def self.columns()
13
+ @columns ||= []
14
+ end
15
+
16
+ def self.column(name, sql_type = nil, default = nil, null = true)
17
+ columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
18
+ end
19
+
20
+ column :id, :integer
21
+ column :name, :string
22
+ column :rank, :integer
23
+ column :admin, :boolean
24
+ column :created_at, :datetime
25
+
26
+ def self.table_exists?
27
+ true
28
+ end
29
+ end
30
+
31
+ class SubUser < User
32
+ def self.columns
33
+ User.columns
34
+ end
35
+ end
36
+
37
+ describe "AwesomePrint/ActiveRecord" do
38
+ before(:each) do
39
+ stub_dotfile!
40
+ end
41
+
42
+ #------------------------------------------------------------------------------
43
+ describe "ActiveRecord instance" do
44
+ before(:each) do
45
+ ActiveRecord::Base.default_timezone = :utc
46
+ @diana = User.new(:name => "Diana", :rank => 1, :admin => false, :created_at => "1992-10-10 12:30:00")
47
+ @laura = User.new(:name => "Laura", :rank => 2, :admin => true, :created_at => "2003-05-26 14:15:00")
48
+ @ap = AwesomePrint.new(:plain => true)
49
+ end
50
+
51
+ it "display single record" do
52
+ out = @ap.send(:awesome, @diana)
53
+ out.gsub(/0x([a-f\d]+)/, "0x01234567").should == <<-EOS.strip
54
+ #<User:0x01234567> {
55
+ :id => nil,
56
+ :name => "Diana",
57
+ :rank => 1,
58
+ :admin => false,
59
+ :created_at => Sat Oct 10 12:30:00 UTC 1992
60
+ }
61
+ EOS
62
+ end
63
+
64
+ it "display multiple records" do
65
+ out = @ap.send(:awesome, [ @diana, @laura ])
66
+ out.gsub(/0x([a-f\d]+)/, "0x01234567").should == <<-EOS.strip
67
+ [
68
+ [0] #<User:0x01234567> {
69
+ :id => nil,
70
+ :name => "Diana",
71
+ :rank => 1,
72
+ :admin => false,
73
+ :created_at => Sat Oct 10 12:30:00 UTC 1992
74
+ },
75
+ [1] #<User:0x01234567> {
76
+ :id => nil,
77
+ :name => "Laura",
78
+ :rank => 2,
79
+ :admin => true,
80
+ :created_at => Mon May 26 14:15:00 UTC 2003
81
+ }
82
+ ]
83
+ EOS
84
+ end
85
+ end
86
+
87
+ #------------------------------------------------------------------------------
88
+ describe "ActiveRecord class" do
89
+ it "should print the class" do
90
+ @ap = AwesomePrint.new(:plain => true)
91
+ @ap.send(:awesome, User).should == <<-EOS.strip
92
+ class User < ActiveRecord::Base {
93
+ :id => :integer,
94
+ :name => :string,
95
+ :rank => :integer,
96
+ :admin => :boolean,
97
+ :created_at => :datetime
98
+ }
99
+ EOS
100
+
101
+ end
102
+
103
+ it "should print the class for non-direct subclasses of AR::Base" do
104
+ @ap = AwesomePrint.new(:plain => true)
105
+ @ap.send(:awesome, SubUser).should == <<-EOS.strip
106
+ class SubUser < User {
107
+ :id => :integer,
108
+ :name => :string,
109
+ :rank => :integer,
110
+ :admin => :boolean,
111
+ :created_at => :datetime
112
+ }
113
+ EOS
114
+
115
+ end
116
+ end
117
+ end
118
+ end
@@ -1,20 +1,23 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require "bigdecimal"
3
+ require "rational"
2
4
 
3
5
  describe "AwesomePrint" do
4
6
  before(:each) do
5
- @color_ap = AwesomePrint.new
6
- @plain_ap = AwesomePrint.new(:plain => true)
7
+ stub_dotfile!
7
8
  end
8
9
 
9
- #------------------------------------------------------------------------------
10
10
  describe "Array" do
11
11
  before(:each) do
12
12
  @arr = [ 1, :two, "three", [ nil, [ true, false] ] ]
13
13
  end
14
14
 
15
+ it "empty array" do
16
+ [].ai.should == "[]"
17
+ end
18
+
15
19
  it "plain multiline" do
16
- ap = AwesomePrint.new(:plain => true)
17
- ap.send(:awesome, @arr).should == <<-EOS.strip
20
+ @arr.ai(:plain => true).should == <<-EOS.strip
18
21
  [
19
22
  [0] 1,
20
23
  [1] :two,
@@ -31,8 +34,7 @@ EOS
31
34
  end
32
35
 
33
36
  it "plain multiline indented" do
34
- ap = AwesomePrint.new(:plain => true, :indent => 2)
35
- ap.send(:awesome, @arr).should == <<-EOS.strip
37
+ @arr.ai(:plain => true, :indent => 2).should == <<-EOS.strip
36
38
  [
37
39
  [0] 1,
38
40
  [1] :two,
@@ -49,13 +51,11 @@ EOS
49
51
  end
50
52
 
51
53
  it "plain single line" do
52
- ap = AwesomePrint.new(:plain => true, :multiline => false)
53
- ap.send(:awesome, @arr).should == '[ 1, :two, "three", [ nil, [ true, false ] ] ]'
54
+ @arr.ai(:plain => true, :multiline => false).should == '[ 1, :two, "three", [ nil, [ true, false ] ] ]'
54
55
  end
55
56
 
56
- it "colored multiline" do
57
- ap = AwesomePrint.new
58
- ap.send(:awesome, @arr).should == <<-EOS.strip
57
+ it "colored multiline (default)" do
58
+ @arr.ai.should == <<-EOS.strip
59
59
  [
60
60
  \e[1;37m [0] \e[0m\e[1;34m1\e[0m,
61
61
  \e[1;37m [1] \e[0m\e[0;36m:two\e[0m,
@@ -72,8 +72,7 @@ EOS
72
72
  end
73
73
 
74
74
  it "colored multiline indented" do
75
- ap = AwesomePrint.new(:indent => 8)
76
- ap.send(:awesome, @arr).should == <<-EOS.strip
75
+ @arr.ai(:indent => 8).should == <<-EOS.strip
77
76
  [
78
77
  \e[1;37m [0] \e[0m\e[1;34m1\e[0m,
79
78
  \e[1;37m [1] \e[0m\e[0;36m:two\e[0m,
@@ -90,8 +89,7 @@ EOS
90
89
  end
91
90
 
92
91
  it "colored single line" do
93
- ap = AwesomePrint.new(:multiline => false)
94
- ap.send(:awesome, @arr).should == "[ \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 ] ] ]"
92
+ @arr.ai(:multiline => false).should == "[ \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 ] ] ]"
95
93
  end
96
94
  end
97
95
 
@@ -103,8 +101,7 @@ EOS
103
101
  end
104
102
 
105
103
  it "plain multiline" do
106
- ap = AwesomePrint.new(:plain => true)
107
- ap.send(:awesome, @arr).should == <<-EOS.strip
104
+ @arr.ai(:plain => true).should == <<-EOS.strip
108
105
  [
109
106
  [0] 1,
110
107
  [1] 2,
@@ -114,8 +111,7 @@ EOS
114
111
  end
115
112
 
116
113
  it "plain single line" do
117
- ap = AwesomePrint.new(:plain => true, :multiline => false)
118
- ap.send(:awesome, @arr).should == "[ 1, 2, [...] ]"
114
+ @arr.ai(:plain => true, :multiline => false).should == "[ 1, 2, [...] ]"
119
115
  end
120
116
  end
121
117
 
@@ -124,10 +120,13 @@ EOS
124
120
  before(:each) do
125
121
  @hash = { 1 => { :sym => { "str" => { [1, 2, 3] => { { :k => :v } => Hash } } } } }
126
122
  end
127
-
123
+
124
+ it "empty hash" do
125
+ {}.ai.should == "{}"
126
+ end
127
+
128
128
  it "plain multiline" do
129
- ap = AwesomePrint.new(:plain => true)
130
- ap.send(:awesome, @hash).should == <<-EOS.strip
129
+ @hash.ai(:plain => true).should == <<-EOS.strip
131
130
  {
132
131
  1 => {
133
132
  :sym => {
@@ -143,8 +142,7 @@ EOS
143
142
  end
144
143
 
145
144
  it "plain multiline indented" do
146
- ap = AwesomePrint.new(:plain => true, :indent => 1)
147
- ap.send(:awesome, @hash).should == <<-EOS.strip
145
+ @hash.ai(:plain => true, :indent => 1).should == <<-EOS.strip
148
146
  {
149
147
  1 => {
150
148
  :sym => {
@@ -160,13 +158,11 @@ EOS
160
158
  end
161
159
 
162
160
  it "plain single line" do
163
- ap = AwesomePrint.new(:plain => true, :multiline => false)
164
- ap.send(:awesome, @hash).should == '{ 1 => { :sym => { "str" => { [ 1, 2, 3 ] => { { :k => :v } => Hash < Object } } } } }'
161
+ @hash.ai(:plain => true, :multiline => false).should == '{ 1 => { :sym => { "str" => { [ 1, 2, 3 ] => { { :k => :v } => Hash < Object } } } } }'
165
162
  end
166
163
 
167
- it "colored multiline" do
168
- ap = AwesomePrint.new
169
- ap.send(:awesome, @hash).should == <<-EOS.strip
164
+ it "colored multiline (default)" do
165
+ @hash.ai.should == <<-EOS.strip
170
166
  {
171
167
  1\e[1;30m => \e[0m{
172
168
  :sym\e[1;30m => \e[0m{
@@ -182,8 +178,7 @@ EOS
182
178
  end
183
179
 
184
180
  it "colored multiline indented" do
185
- ap = AwesomePrint.new(:indent => 2)
186
- ap.send(:awesome, @hash).should == <<-EOS.strip
181
+ @hash.ai(:indent => 2).should == <<-EOS.strip
187
182
  {
188
183
  1\e[1;30m => \e[0m{
189
184
  :sym\e[1;30m => \e[0m{
@@ -199,8 +194,7 @@ EOS
199
194
  end
200
195
 
201
196
  it "colored single line" do
202
- ap = AwesomePrint.new(:multiline => false)
203
- ap.send(:awesome, @hash).should == "{ 1\e[1;30m => \e[0m{ :sym\e[1;30m => \e[0m{ \"str\"\e[1;30m => \e[0m{ [ 1, 2, 3 ]\e[1;30m => \e[0m{ { :k => :v }\e[1;30m => \e[0m\e[1;33mHash < Object\e[0m } } } } }"
197
+ @hash.ai(:multiline => false).should == "{ 1\e[1;30m => \e[0m{ :sym\e[1;30m => \e[0m{ \"str\"\e[1;30m => \e[0m{ [ 1, 2, 3 ]\e[1;30m => \e[0m{ { :k => :v }\e[1;30m => \e[0m\e[1;33mHash < Object\e[0m } } } } }"
204
198
  end
205
199
 
206
200
  end
@@ -213,8 +207,7 @@ EOS
213
207
  end
214
208
 
215
209
  it "plain multiline" do
216
- ap = AwesomePrint.new(:plain => true)
217
- ap.send(:awesome, @hash).should == <<-EOS.strip
210
+ @hash.ai(:plain => true).should == <<-EOS.strip
218
211
  {
219
212
  :a => {...}
220
213
  }
@@ -222,21 +215,34 @@ EOS
222
215
  end
223
216
 
224
217
  it "plain single line" do
225
- ap = AwesomePrint.new(:plain => true, :multiline => false)
226
- ap.send(:awesome, @hash).should == '{ :a => {...} }'
218
+ @hash.ai(:plain => true, :multiline => false).should == '{ :a => {...} }'
219
+ end
220
+ end
221
+
222
+ #------------------------------------------------------------------------------
223
+ describe "Negative options[:indent]" do
224
+ before(:each) do
225
+ @hash = { [0, 0, 255] => :yellow, :red => "rgb(255, 0, 0)", "magenta" => "rgb(255, 0, 255)" }
226
+ end
227
+
228
+ it "hash keys must be left aligned" do
229
+ out = @hash.ai(:plain => true, :indent => -4)
230
+ out.start_with?("{\n").should == true
231
+ out.include?(' :red => "rgb(255, 0, 0)"').should == true
232
+ out.include?(' "magenta" => "rgb(255, 0, 255)"').should == true
233
+ out.include?(' [ 0, 0, 255 ] => :yellow').should == true
234
+ out.end_with?("\n}").should == true
227
235
  end
228
236
  end
229
237
 
230
238
  #------------------------------------------------------------------------------
231
239
  describe "Class" do
232
240
  it "shoud show superclass (plain)" do
233
- ap = AwesomePrint.new(:plain => true)
234
- ap.send(:awesome, self.class).should == "#{self.class} < #{self.class.superclass}"
241
+ self.class.ai(:plain => true).should == "#{self.class} < #{self.class.superclass}"
235
242
  end
236
243
 
237
244
  it "shoud show superclass (color)" do
238
- ap = AwesomePrint.new
239
- ap.send(:awesome_class, self.class).should == "#{self.class} < #{self.class.superclass}".yellow
245
+ self.class.ai.should == "#{self.class} < #{self.class.superclass}".yellow
240
246
  end
241
247
  end
242
248
 
@@ -244,7 +250,7 @@ EOS
244
250
  describe "File" do
245
251
  it "should display a file (plain)" do
246
252
  File.open(__FILE__, "r") do |f|
247
- @plain_ap.send(:awesome_file, f).should == "#{f.inspect}\n" << `ls -alF #{f.path}`.chop
253
+ f.ai(:plain => true).should == "#{f.inspect}\n" << `ls -alF #{f.path}`.chop
248
254
  end
249
255
  end
250
256
  end
@@ -253,9 +259,33 @@ EOS
253
259
  describe "Dir" do
254
260
  it "should display a direcory (plain)" do
255
261
  Dir.open(File.dirname(__FILE__)) do |d|
256
- @plain_ap.send(:awesome_dir, d).should == "#{d.inspect}\n" << `ls -alF #{d.path}`.chop
262
+ d.ai(:plain => true).should == "#{d.inspect}\n" << `ls -alF #{d.path}`.chop
257
263
  end
258
264
  end
259
265
  end
260
266
 
267
+ #------------------------------------------------------------------------------
268
+ describe "BigDecimal and Rational" do
269
+ it "should present BigDecimal object as Float scalar" do
270
+ big = BigDecimal("2010.4")
271
+ big.ai(:plain => true).should == "2010.4"
272
+ end
273
+
274
+ it "should present Rational object as Float scalar" do
275
+ rat = Rational(2010, 2)
276
+ rat.ai(:plain => true).should == "1005.0"
277
+ end
278
+ end
279
+
280
+ #------------------------------------------------------------------------------
281
+ describe "Utility methods" do
282
+ it "should merge options" do
283
+ ap = AwesomePrint.new
284
+ ap.send(:merge_options!, { :color => { :array => :black }, :indent => 0 })
285
+ options = ap.instance_variable_get("@options")
286
+ options[:color][:array].should == :black
287
+ options[:indent].should == 0
288
+ end
289
+ end
290
+
261
291
  end
@@ -0,0 +1,43 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+
4
+ require 'logger'
5
+ require 'ap/core_ext/logger'
6
+
7
+ describe "AwesomePrint logging extensions" do
8
+ before(:all) do
9
+ @logger = Logger.new('/dev/null')
10
+ end
11
+
12
+ describe "ap method" do
13
+ it "should awesome_inspect the given object" do
14
+ object = mock
15
+ object.should_receive(:ai)
16
+ @logger.ap object
17
+ end
18
+
19
+ describe "the log level" do
20
+ before(:each) do
21
+ AwesomePrint.defaults = { }
22
+ end
23
+
24
+ it "should fallback to the default :debug log level" do
25
+ @logger.should_receive(:debug)
26
+ @logger.ap(nil)
27
+ end
28
+
29
+ it "should use the global user default if no level passed" do
30
+ AwesomePrint.defaults = { :log_level => :info }
31
+ @logger.should_receive(:info)
32
+ @logger.ap(nil)
33
+ end
34
+
35
+ it "should use the passed in level" do
36
+ @logger.should_receive(:warn)
37
+ @logger.ap(nil, :warn)
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+
data/spec/spec_helper.rb CHANGED
@@ -3,7 +3,12 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
3
  require 'ap'
4
4
  require 'spec'
5
5
  require 'spec/autorun'
6
+ require 'rubygems'
6
7
 
7
8
  Spec::Runner.configure do |config|
8
-
9
+ end
10
+
11
+ def stub_dotfile!
12
+ dotfile = File.join(ENV["HOME"], ".aprc")
13
+ File.should_receive(:readable?).at_least(:once).with(dotfile).and_return(false)
9
14
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
7
+ - 2
8
8
  - 0
9
- version: 0.1.0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Michael Dvorkin
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-02 00:00:00 -07:00
17
+ date: 2010-05-05 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -41,6 +41,7 @@ extra_rdoc_files:
41
41
  - LICENSE
42
42
  - README.md
43
43
  files:
44
+ - CHANGELOG
44
45
  - LICENSE
45
46
  - README.md
46
47
  - Rakefile
@@ -49,11 +50,14 @@ files:
49
50
  - lib/ap.rb
50
51
  - lib/ap/awesome_print.rb
51
52
  - lib/ap/core_ext/kernel.rb
53
+ - lib/ap/core_ext/logger.rb
52
54
  - lib/ap/core_ext/string.rb
53
- - lib/ap/mixin/rails.rb
55
+ - lib/ap/mixin/active_record.rb
56
+ - lib/ap/mixin/active_support.rb
54
57
  - rails/init.rb
58
+ - spec/active_record_spec.rb
55
59
  - spec/awesome_print_spec.rb
56
- - spec/rails_spec.rb
60
+ - spec/logger_spec.rb
57
61
  - spec/spec.opts
58
62
  - spec/spec_helper.rb
59
63
  - spec/string_spec.rb
@@ -88,7 +92,8 @@ signing_key:
88
92
  specification_version: 3
89
93
  summary: Pretty print Ruby objects with proper indentation and colors.
90
94
  test_files:
95
+ - spec/active_record_spec.rb
91
96
  - spec/awesome_print_spec.rb
92
- - spec/rails_spec.rb
97
+ - spec/logger_spec.rb
93
98
  - spec/spec_helper.rb
94
99
  - spec/string_spec.rb
data/spec/rails_spec.rb DELETED
@@ -1,87 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- if defined?(::Rails)
4
-
5
- # Create tableless ActiveRecord model.
6
- #------------------------------------------------------------------------------
7
- class User < ActiveRecord::Base
8
- def self.columns()
9
- @columns ||= []
10
- end
11
-
12
- def self.column(name, sql_type = nil, default = nil, null = true)
13
- columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
14
- end
15
-
16
- def self.table_exists?
17
- true
18
- end
19
-
20
- column :id, :integer
21
- column :name, :string
22
- column :rank, :integer
23
- column :admin, :boolean
24
- column :created_at, :datetime
25
- end
26
-
27
- #------------------------------------------------------------------------------
28
- describe "ActiveRecord instance" do
29
- before(:each) do
30
- @diana = User.new(:name => "Diana", :rank => 1, :admin => false, :created_at => "1992-10-10 12:30:00")
31
- @laura = User.new(:name => "Laura", :rank => 2, :admin => true, :created_at => "2003-05-26 14:15:00")
32
- @ap = AwesomePrint.new(:plain => true)
33
- end
34
-
35
- it "display single record" do
36
- out = @ap.send(:awesome, @diana)
37
- out.gsub(/0x([a-f\d]+)/, "0x01234567").should == <<-EOS.strip
38
- #<User:0x01234567> {
39
- :id => nil,
40
- :name => "Diana",
41
- :rank => 1,
42
- :admin => false,
43
- :created_at => Sat, 10 Oct 1992 12:30:00 UTC +00:00
44
- }
45
- EOS
46
- end
47
-
48
- it "display multiple records" do
49
- out = @ap.send(:awesome, [ @diana, @laura ])
50
- out.gsub(/0x([a-f\d]+)/, "0x01234567").should == <<-EOS.strip
51
- [
52
- [0] #<User:0x01234567> {
53
- :id => nil,
54
- :name => "Diana",
55
- :rank => 1,
56
- :admin => false,
57
- :created_at => Sat, 10 Oct 1992 12:30:00 UTC +00:00
58
- },
59
- [1] #<User:0x01234567> {
60
- :id => nil,
61
- :name => "Laura",
62
- :rank => 2,
63
- :admin => true,
64
- :created_at => Mon, 26 May 2003 14:15:00 UTC +00:00
65
- }
66
- ]
67
- EOS
68
- end
69
- end
70
-
71
- #------------------------------------------------------------------------------
72
- describe "ActiveRecord class" do
73
- it "should" do
74
- @ap = AwesomePrint.new(:plain => true)
75
- @ap.send(:awesome, User).should == <<-EOS.strip
76
- class User < ActiveRecord::Base {
77
- :id => :integer,
78
- :name => :string,
79
- :rank => :integer,
80
- :admin => :boolean,
81
- :created_at => :datetime
82
- }
83
- EOS
84
- end
85
- end
86
-
87
- end