awesome_print 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,10 @@
1
+ 1.0.2
2
+ - Added formatting of Mongoid documents (Adam Doppelt)
3
+ - ActiveRecord objects display attributes only. Use :raw => true to display the entire object
4
+ - ActiveSupport::Date objects get formatted as regular Date
5
+ - Rails.logger.ap colorizes output based on ActiveSupport::LogSubscriber.colorize_logging (default is true)
6
+ - Improved formatting of methods array
7
+
1
8
  1.0.1
2
9
  - Updated repo tags for Rubygems.org
3
10
 
data/README.md CHANGED
@@ -229,7 +229,7 @@ Supported color names:
229
229
 
230
230
  ### IRB integration ###
231
231
  To use awesome_print as default formatter in irb and Rails console add the following
232
- lines into your ~/.irbrc file:
232
+ code to your ~/.irbrc file:
233
233
 
234
234
  require "rubygems"
235
235
  require "awesome_print"
@@ -248,6 +248,15 @@ lines into your ~/.irbrc file:
248
248
  end.new
249
249
  end
250
250
 
251
+ ### PRY integration ###
252
+ If you miss awesome_print's way of formatting output, here's how you can use it in place
253
+ of the formatting which comes with pry. Add the following code to your ~/.pryrc:
254
+
255
+ require "rubygems"
256
+ require "awesome_print"
257
+
258
+ Pry.print = proc { |output, value| output.puts value.ai }
259
+
251
260
  ### Logger Convenience Method ###
252
261
  awesome_print adds the 'ap' method to the Logger and ActiveSupport::BufferedLogger classes
253
262
  letting you call:
@@ -266,7 +275,8 @@ in the custom defaults (see below). You can also override on a per call basis wi
266
275
  awesome_print adds the 'ap' method to the ActionView::Base class making it available
267
276
  within Rails templates. For example:
268
277
 
269
- <%= ap @accounts.first %>
278
+ <%= ap @accounts.first %> # ERB
279
+ != ap @accounts.first # HAML
270
280
 
271
281
  With other web frameworks (ex: in Sinatra templates) you can explicitly request HTML
272
282
  formatting:
@@ -23,7 +23,7 @@ unless defined?(AwesomePrint)
23
23
  require File.dirname(__FILE__) + "/awesome_print/ext/active_support" if defined?(ActiveSupport) || (defined?(IRB) && ENV['RAILS_ENV'])
24
24
 
25
25
  # Load remaining extensions.
26
- require File.dirname(__FILE__) + "/awesome_print/ext/action_view" if defined?(ActionView)
26
+ require File.dirname(__FILE__) + "/awesome_print/ext/action_view" if defined?(ActionView::Base)
27
27
  require File.dirname(__FILE__) + "/awesome_print/ext/mongo_mapper" if defined?(MongoMapper)
28
28
  require File.dirname(__FILE__) + "/awesome_print/ext/mongoid" if defined?(Mongoid)
29
29
  require File.dirname(__FILE__) + "/awesome_print/ext/nokogiri" if defined?(Nokogiri)
@@ -4,14 +4,19 @@
4
4
  # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
5
  #------------------------------------------------------------------------------
6
6
  class Class #:nodoc:
7
+ #
8
+ # Intercept methods below to inject @__awesome_print__ instance variable
9
+ # so we know it is the *methods* array when formatting an array.
10
+ #
7
11
  # Remaining public/private etc. '_methods' are handled in core_ext/object.rb.
12
+ #
8
13
  %w(instance_methods private_instance_methods protected_instance_methods public_instance_methods).each do |name|
9
14
  original_method = instance_method(name)
10
15
 
11
16
  define_method name do |*args|
12
17
  methods = original_method.bind(self).call(*args)
13
- methods.instance_variable_set('@__awesome_methods__', self) # Evil?!
14
- methods.sort!
18
+ methods.instance_variable_set('@__awesome_methods__', self)
19
+ methods
15
20
  end
16
21
  end
17
22
  end
@@ -17,4 +17,4 @@ module AwesomePrint
17
17
  end
18
18
 
19
19
  Logger.send(:include, AwesomePrint::Logger)
20
- ActiveSupport::BufferedLogger.send(:include, AwesomePrint::Logger) if defined?(::ActiveSupport::BufferedLogger)
20
+ ActiveSupport::BufferedLogger.send(:include, AwesomePrint::Logger) if defined?(ActiveSupport::BufferedLogger)
@@ -4,14 +4,19 @@
4
4
  # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
5
  #------------------------------------------------------------------------------
6
6
  class Object #:nodoc:
7
+ #
8
+ # Intercept methods below to inject @__awesome_print__ instance variable
9
+ # so we know it is the *methods* array when formatting an array.
10
+ #
7
11
  # Remaining instance '_methods' are handled in core_ext/class.rb.
12
+ #
8
13
  %w(methods private_methods protected_methods public_methods singleton_methods).each do |name|
9
14
  original_method = instance_method(name)
10
15
 
11
16
  define_method name do |*args|
12
17
  methods = original_method.bind(self).call(*args)
13
- methods.instance_variable_set('@__awesome_methods__', self) # Evil?!
14
- methods.sort!
18
+ methods.instance_variable_set('@__awesome_methods__', self)
19
+ methods
15
20
  end
16
21
  end
17
22
  end
@@ -15,4 +15,4 @@ module AwesomePrint
15
15
  end
16
16
  end
17
17
 
18
- ActionView::Base.send(:include, AwesomePrint::ActionView) if defined?(ActionView)
18
+ ActionView::Base.send(:include, AwesomePrint::ActionView)
@@ -15,7 +15,11 @@ module AwesomePrint
15
15
  #------------------------------------------------------------------------------
16
16
  def cast_with_active_record(object, type)
17
17
  cast = cast_without_active_record(object, type)
18
- if defined?(::ActiveRecord) && object.is_a?(Class) && object.ancestors.include?(::ActiveRecord::Base)
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)
19
23
  cast = :active_record_class
20
24
  end
21
25
  cast
@@ -23,6 +27,26 @@ module AwesomePrint
23
27
 
24
28
  private
25
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
+
26
50
  # Format ActiveRecord class object.
27
51
  #------------------------------------------------------------------------------
28
52
  def awesome_active_record_class(object)
@@ -14,7 +14,7 @@ module AwesomePrint
14
14
  def cast_with_active_support(object, type)
15
15
  cast = cast_without_active_support(object, type)
16
16
  if defined?(::ActiveSupport) && defined?(::HashWithIndifferentAccess)
17
- if object.is_a?(::ActiveSupport::TimeWithZone)
17
+ if object.is_a?(::ActiveSupport::TimeWithZone) || object.is_a?(::Date)
18
18
  cast = :active_support_time
19
19
  elsif object.is_a?(::HashWithIndifferentAccess)
20
20
  cast = :hash_with_indifferent_access
@@ -38,3 +38,10 @@ module AwesomePrint
38
38
  end
39
39
 
40
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
+
@@ -15,8 +15,14 @@ module AwesomePrint
15
15
  #------------------------------------------------------------------------------
16
16
  def cast_with_mongoid(object, type)
17
17
  cast = cast_without_mongoid(object, type)
18
- if defined?(::Mongoid::Document) && object.is_a?(Class) && object.ancestors.include?(::Mongoid::Document)
19
- cast = :mongoid_class
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
20
26
  end
21
27
  cast
22
28
  end
@@ -26,13 +32,33 @@ module AwesomePrint
26
32
  def awesome_mongoid_class(object)
27
33
  return object.inspect if !defined?(::ActiveSupport::OrderedHash) || !object.respond_to?(:fields)
28
34
 
29
- data = object.fields.inject(::ActiveSupport::OrderedHash.new) do |hash, c|
30
- hash[c[1].name] = (c[1].type || "undefined").to_s.underscore.intern
31
- # hash[c[1].name] = (c[1].type || "undefined").to_s.underscore.intern rescue c[1].type
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
32
37
  hash
33
38
  end
34
39
  "class #{object} < #{object.superclass} " << awesome_hash(data)
35
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
36
62
  end
37
63
  end
38
64
 
@@ -25,12 +25,13 @@ module AwesomePrint
25
25
  awesome = if core_class != :self
26
26
  send(:"awesome_#{core_class}", object) # Core formatters.
27
27
  else
28
- awesome_self(object, type) # Catch all that falls back on object.inspect.
28
+ awesome_self(object, type) # Catch all that falls back to object.inspect.
29
29
  end
30
30
  @options[:html] ? "<pre>#{awesome}</pre>" : awesome
31
31
  end
32
32
 
33
- # Hook this when adding custom formatters.
33
+ # Hook this when adding custom formatters. Check out lib/awesome_print/ext
34
+ # directory for custom formatters that ship with awesome_print.
34
35
  #------------------------------------------------------------------------------
35
36
  def cast(object, type)
36
37
  CORE.grep(type)[0] || :self
@@ -212,17 +213,20 @@ module AwesomePrint
212
213
  # Format object.methods array.
213
214
  #------------------------------------------------------------------------------
214
215
  def methods_array(a)
216
+ a.sort! { |x, y| x.to_s <=> y.to_s } # Can't simply a.sort! because of o.methods << [ :blah ]
215
217
  object = a.instance_variable_get('@__awesome_methods__')
216
218
  tuples = a.map do |name|
217
- tuple = if object.respond_to?(name, true) # Is this a regular method?
218
- the_method = object.method(name) rescue nil # Avoid potential ArgumentError if object#method is overridden.
219
- if the_method && the_method.respond_to?(:arity) # Is this original object#method?
220
- method_tuple(the_method) # Yes, we are good.
219
+ if name.is_a?(Symbol) || name.is_a?(String) # Ignore garbage, ex. 42.methods << [ :blah ]
220
+ tuple = if object.respond_to?(name, true) # Is this a regular method?
221
+ the_method = object.method(name) rescue nil # Avoid potential ArgumentError if object#method is overridden.
222
+ if the_method && the_method.respond_to?(:arity) # Is this original object#method?
223
+ method_tuple(the_method) # Yes, we are good.
224
+ end
225
+ elsif object.respond_to?(:instance_method) # Is this an unbound method?
226
+ method_tuple(object.instance_method(name))
221
227
  end
222
- elsif object.respond_to?(:instance_method) # Is this an unbound method?
223
- method_tuple(object.instance_method(name))
224
228
  end
225
- tuple || [ name.to_s, '(?)', '' ] # Return WTF default if all the above fails.
229
+ tuple || [ name.to_s, '(?)', '?' ] # Return WTF default if all the above fails.
226
230
  end
227
231
 
228
232
  width = (tuples.size - 1).to_s.size
@@ -259,14 +263,27 @@ module AwesomePrint
259
263
  args[-1] = "*#{args[-1]}" if method.arity < 0
260
264
  end
261
265
 
262
- if method.to_s =~ /(Unbound)*Method: (.*?)[#\.]/
263
- owner = "#{$2}#{$1 ? '(unbound)' : ''}".gsub('(', ' (')
266
+ # method.to_s formats to handle:
267
+ #
268
+ # #<Method: Fixnum#zero?>
269
+ # #<Method: Fixnum(Integer)#years>
270
+ # #<Method: User(#<Module:0x00000103207c00>)#_username>
271
+ # #<Method: User(id: integer, username: string).table_name>
272
+ # #<Method: User(id: integer, username: string)(ActiveRecord::Base).current>
273
+ # #<UnboundMethod: Hello#world>
274
+ #
275
+ if method.to_s =~ /(Unbound)*Method: (.*)[#\.]/
276
+ unbound, klass = $1 && '(unbound)', $2
277
+ if klass && klass =~ /(\(\w+:\s.*?\))/ # Is this ActiveRecord-style class?
278
+ klass.sub!($1, '') # Yes, strip the fields leaving class name only.
279
+ end
280
+ owner = "#{klass}#{unbound}".gsub('(', ' (')
264
281
  end
265
282
 
266
283
  [ method.name.to_s, "(#{args.join(', ')})", owner.to_s ]
267
284
  end
268
285
 
269
- # Format hash keys as plain string regardless of underlying data type.
286
+ # Format hash keys as plain strings regardless of underlying data type.
270
287
  #------------------------------------------------------------------------------
271
288
  def plain_single_line
272
289
  plain, multiline = @options[:plain], @options[:multiline]
@@ -314,7 +331,25 @@ module AwesomePrint
314
331
  ' ' * (@indentation - @options[:indent].abs)
315
332
  end
316
333
 
317
- # To support limited output.
334
+ # To support limited output, for example:
335
+ #
336
+ # ap ('a'..'z').to_a, :limit => 3
337
+ # [
338
+ # [ 0] "a",
339
+ # [ 1] .. [24],
340
+ # [25] "z"
341
+ # ]
342
+ #
343
+ # ap (1..100).to_a, :limit => true # Default limit is 7.
344
+ # [
345
+ # [ 0] 1,
346
+ # [ 1] 2,
347
+ # [ 2] 3,
348
+ # [ 3] .. [96],
349
+ # [97] 98,
350
+ # [98] 99,
351
+ # [99] 100
352
+ # ]
318
353
  #------------------------------------------------------------------------------
319
354
  def should_be_limited?
320
355
  @options[:limit] == true or (@options[:limit].is_a?(Fixnum) and @options[:limit] > 0)
@@ -345,6 +380,5 @@ module AwesomePrint
345
380
  temp
346
381
  end
347
382
  end
348
-
349
383
  end
350
384
  end
@@ -5,6 +5,6 @@
5
5
  #------------------------------------------------------------------------------
6
6
  module AwesomePrint
7
7
  def self.version
8
- '1.0.1'
8
+ '1.0.2'
9
9
  end
10
10
  end
@@ -445,4 +445,14 @@ describe "Methods arrays" do
445
445
  hello = Hello.new
446
446
  (hello.send(:his) - hello.send(:her)).sort_by { |x| x.to_s }.should == [ :him, :his ]
447
447
  end
448
+
449
+ it "appending garbage to methods array should not raise error" do
450
+ arr = 42.methods << [ :wtf ]
451
+ arr.ai(:plain => true).should_not raise_error(TypeError)
452
+ if RUBY_VERSION < '1.9.2'
453
+ arr.ai(:plain => true).should =~ /\s+wtf\(\?\)\s+\?/ # [ :wtf ].to_s => "wtf"
454
+ else
455
+ arr.ai(:plain => true).should =~ /\s+\[:wtf\]\(\?\)\s+\?/ # [ :wtf ].to_s => [:wtf]
456
+ end
457
+ end
448
458
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: awesome_print
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.0.1
5
+ version: 1.0.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Michael Dvorkin
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-11-08 00:00:00 Z
13
+ date: 2011-12-20 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec