awesome_print 1.2.0 → 1.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -2
  3. data/Appraisals +62 -0
  4. data/CHANGELOG.md +180 -0
  5. data/CONTRIBUTING.md +82 -0
  6. data/Gemfile +3 -2
  7. data/LICENSE +16 -19
  8. data/README.md +112 -87
  9. data/Rakefile +17 -4
  10. data/awesome_print.gemspec +33 -0
  11. data/init.rb +1 -0
  12. data/lib/ap.rb +2 -2
  13. data/lib/awesome_print.rb +22 -16
  14. data/lib/awesome_print/colorize.rb +24 -0
  15. data/lib/awesome_print/core_ext/{array.rb → awesome_method_array.rb} +16 -18
  16. data/lib/awesome_print/core_ext/class.rb +3 -2
  17. data/lib/awesome_print/core_ext/kernel.rb +1 -1
  18. data/lib/awesome_print/core_ext/logger.rb +1 -1
  19. data/lib/awesome_print/core_ext/method.rb +2 -2
  20. data/lib/awesome_print/core_ext/object.rb +3 -2
  21. data/lib/awesome_print/core_ext/string.rb +3 -3
  22. data/lib/awesome_print/custom_defaults.rb +57 -0
  23. data/lib/awesome_print/ext/action_view.rb +8 -4
  24. data/lib/awesome_print/ext/active_record.rb +47 -13
  25. data/lib/awesome_print/ext/active_support.rb +1 -1
  26. data/lib/awesome_print/ext/mongo_mapper.rb +16 -13
  27. data/lib/awesome_print/ext/mongoid.rb +9 -7
  28. data/lib/awesome_print/ext/nobrainer.rb +52 -0
  29. data/lib/awesome_print/ext/nokogiri.rb +4 -4
  30. data/lib/awesome_print/ext/ostruct.rb +27 -0
  31. data/lib/awesome_print/ext/ripple.rb +6 -7
  32. data/lib/awesome_print/ext/sequel.rb +7 -6
  33. data/lib/awesome_print/formatter.rb +54 -327
  34. data/lib/awesome_print/formatters.rb +15 -0
  35. data/lib/awesome_print/formatters/array_formatter.rb +139 -0
  36. data/lib/awesome_print/formatters/base_formatter.rb +140 -0
  37. data/lib/awesome_print/formatters/class_formatter.rb +25 -0
  38. data/lib/awesome_print/formatters/dir_formatter.rb +22 -0
  39. data/lib/awesome_print/formatters/file_formatter.rb +22 -0
  40. data/lib/awesome_print/formatters/hash_formatter.rb +106 -0
  41. data/lib/awesome_print/formatters/method_formatter.rb +22 -0
  42. data/lib/awesome_print/formatters/object_formatter.rb +78 -0
  43. data/lib/awesome_print/formatters/simple_formatter.rb +21 -0
  44. data/lib/awesome_print/formatters/struct_formatter.rb +71 -0
  45. data/lib/awesome_print/indentator.rb +18 -0
  46. data/lib/awesome_print/inspector.rb +92 -94
  47. data/lib/awesome_print/version.rb +2 -2
  48. data/spec/active_record_helper.rb +30 -0
  49. data/spec/colors_spec.rb +31 -31
  50. data/spec/core_ext/logger_spec.rb +43 -0
  51. data/spec/core_ext/string_spec.rb +20 -0
  52. data/spec/ext/action_view_spec.rb +21 -0
  53. data/spec/ext/active_record_spec.rb +260 -0
  54. data/spec/ext/active_support_spec.rb +30 -0
  55. data/spec/ext/mongo_mapper_spec.rb +261 -0
  56. data/spec/ext/mongoid_spec.rb +67 -0
  57. data/spec/ext/nobrainer_spec.rb +59 -0
  58. data/spec/ext/nokogiri_spec.rb +46 -0
  59. data/spec/ext/ostruct_spec.rb +22 -0
  60. data/spec/ext/ripple_spec.rb +48 -0
  61. data/spec/formats_spec.rb +272 -205
  62. data/spec/methods_spec.rb +173 -177
  63. data/spec/misc_spec.rb +129 -105
  64. data/spec/objects_spec.rb +162 -27
  65. data/spec/spec_helper.rb +75 -37
  66. data/spec/support/active_record_data.rb +20 -0
  67. data/spec/support/active_record_data/3_2_diana.txt +24 -0
  68. data/spec/support/active_record_data/3_2_diana_legacy.txt +24 -0
  69. data/spec/support/active_record_data/3_2_multi.txt +50 -0
  70. data/spec/support/active_record_data/3_2_multi_legacy.txt +50 -0
  71. data/spec/support/active_record_data/4_0_diana.txt +98 -0
  72. data/spec/support/active_record_data/4_0_multi.txt +198 -0
  73. data/spec/support/active_record_data/4_1_diana.txt +97 -0
  74. data/spec/support/active_record_data/4_1_multi.txt +196 -0
  75. data/spec/support/active_record_data/4_2_diana.txt +109 -0
  76. data/spec/support/active_record_data/4_2_diana_legacy.txt +109 -0
  77. data/spec/support/active_record_data/4_2_multi.txt +220 -0
  78. data/spec/support/active_record_data/4_2_multi_legacy.txt +220 -0
  79. data/spec/support/active_record_data/5_0_diana.txt +105 -0
  80. data/spec/support/active_record_data/5_0_multi.txt +212 -0
  81. data/spec/support/active_record_data/5_1_diana.txt +104 -0
  82. data/spec/support/active_record_data/5_1_multi.txt +210 -0
  83. data/spec/support/active_record_data/5_2_diana.txt +104 -0
  84. data/spec/support/active_record_data/5_2_multi.txt +210 -0
  85. data/spec/support/active_record_data/6_0_diana.txt +104 -0
  86. data/spec/support/active_record_data/6_0_multi.txt +210 -0
  87. data/spec/support/active_record_data/6_1_diana.txt +109 -0
  88. data/spec/support/active_record_data/6_1_multi.txt +220 -0
  89. data/spec/support/ext_verifier.rb +42 -0
  90. data/spec/support/mongoid_versions.rb +26 -0
  91. data/spec/support/rails_versions.rb +55 -0
  92. metadata +163 -32
  93. data/CHANGELOG +0 -96
  94. data/lib/awesome_print/ext/no_brainer.rb +0 -58
@@ -0,0 +1,22 @@
1
+ require_relative 'base_formatter'
2
+
3
+ module AwesomePrint
4
+ module Formatters
5
+ class MethodFormatter < BaseFormatter
6
+
7
+ attr_reader :method, :inspector, :options
8
+
9
+ def initialize(method, inspector)
10
+ @method = method
11
+ @inspector = inspector
12
+ @options = inspector.options
13
+ end
14
+
15
+ def format
16
+ name, args, owner = method_tuple(method)
17
+
18
+ "#{colorize(owner, :class)}##{colorize(name, :method)}#{colorize(args, :args)}"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,78 @@
1
+ require_relative 'base_formatter'
2
+
3
+ module AwesomePrint
4
+ module Formatters
5
+ class ObjectFormatter < BaseFormatter
6
+
7
+ attr_reader :object, :variables, :inspector, :options
8
+
9
+ def initialize(object, inspector)
10
+ @object = object
11
+ @variables = object.instance_variables
12
+ @inspector = inspector
13
+ @options = inspector.options
14
+ end
15
+
16
+ def format
17
+ vars = variables.map do |var|
18
+ property = var.to_s[1..-1].to_sym # to_s because of some monkey patching done by Puppet.
19
+ accessor = if object.respond_to?(:"#{property}=")
20
+ object.respond_to?(property) ? :accessor : :writer
21
+ else
22
+ object.respond_to?(property) ? :reader : nil
23
+ end
24
+ if accessor
25
+ [String.new("attr_#{accessor} :#{property}"), var]
26
+ else
27
+ [var.to_s, var]
28
+ end
29
+ end
30
+
31
+ data = (options[:sort_vars] ? vars.sort : vars).map do |declaration, var|
32
+ key = left_aligned do
33
+ align(declaration, declaration.size)
34
+ end
35
+
36
+ unless options[:plain]
37
+ if key =~ /(@\w+)/
38
+ key.sub!($1, colorize($1, :variable))
39
+ else
40
+ key.sub!(/(attr_\w+)\s(\:\w+)/, "#{colorize('\\1', :keyword)} #{colorize('\\2', :method)}")
41
+ end
42
+ end
43
+
44
+ indented do
45
+ key << colorize(' = ', :hash) + inspector.awesome(object.instance_variable_get(var))
46
+ end
47
+ end
48
+
49
+ if options[:multiline]
50
+ "#<#{awesome_instance}\n#{data.join(%Q/,\n/)}\n#{outdent}>"
51
+ else
52
+ "#<#{awesome_instance} #{data.join(', ')}>"
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def valid_instance_var?(variable_name)
59
+ variable_name.to_s.start_with?('@')
60
+ end
61
+
62
+ def awesome_instance
63
+ str = String.new
64
+ str << object.send(options[:class_name]).to_s
65
+ str << ":0x%08x" % (object.__id__ * 2) if options[:object_id]
66
+ str
67
+ end
68
+
69
+ def left_aligned
70
+ current = options[:indent]
71
+ options[:indent] = 0
72
+ yield
73
+ ensure
74
+ options[:indent] = current
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,21 @@
1
+ require_relative 'base_formatter'
2
+
3
+ module AwesomePrint
4
+ module Formatters
5
+ class SimpleFormatter < BaseFormatter
6
+
7
+ attr_reader :string, :type, :inspector, :options
8
+
9
+ def initialize(string, type, inspector)
10
+ @string = string
11
+ @type = type
12
+ @inspector = inspector
13
+ @options = inspector.options
14
+ end
15
+
16
+ def format
17
+ colorize(string, type)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,71 @@
1
+ require_relative 'base_formatter'
2
+
3
+ module AwesomePrint
4
+ module Formatters
5
+ class StructFormatter < BaseFormatter
6
+
7
+ attr_reader :struct, :variables, :inspector, :options
8
+
9
+ def initialize(struct, inspector)
10
+ @struct = struct
11
+ @variables = struct.members
12
+ @inspector = inspector
13
+ @options = inspector.options
14
+ end
15
+
16
+ def format
17
+ vars = variables.map do |var|
18
+ property = var.to_s[1..-1].to_sym # to_s because of some monkey patching done by Puppet.
19
+ accessor = if struct.respond_to?(:"#{property}=")
20
+ struct.respond_to?(property) ? :accessor : :writer
21
+ else
22
+ struct.respond_to?(property) ? :reader : nil
23
+ end
24
+ if accessor
25
+ ["attr_#{accessor} :#{property}", var]
26
+ else
27
+ [var.to_s, var]
28
+ end
29
+ end
30
+
31
+ data = vars.sort.map do |declaration, var|
32
+ key = left_aligned do
33
+ align(declaration, declaration.size)
34
+ end
35
+
36
+ unless options[:plain]
37
+ if key =~ /(@\w+)/
38
+ key.sub!($1, colorize($1, :variable))
39
+ else
40
+ key.sub!(/(attr_\w+)\s(\:\w+)/, "#{colorize('\\1', :keyword)} #{colorize('\\2', :method)}")
41
+ end
42
+ end
43
+
44
+ indented do
45
+ key << colorize(' = ', :hash) + inspector.awesome(struct.send(var))
46
+ end
47
+ end
48
+
49
+ if options[:multiline]
50
+ "#<#{awesome_instance}\n#{data.join(%Q/,\n/)}\n#{outdent}>"
51
+ else
52
+ "#<#{awesome_instance} #{data.join(', ')}>"
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def awesome_instance
59
+ "#{struct.class.superclass}:#{struct.class}:0x%08x" % (struct.__id__ * 2)
60
+ end
61
+
62
+ def left_aligned
63
+ current = options[:indent]
64
+ options[:indent] = 0
65
+ yield
66
+ ensure
67
+ options[:indent] = current
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,18 @@
1
+ module AwesomePrint
2
+ class Indentator
3
+
4
+ attr_reader :shift_width, :indentation
5
+
6
+ def initialize(indentation)
7
+ @indentation = indentation
8
+ @shift_width = indentation.freeze
9
+ end
10
+
11
+ def indent
12
+ @indentation += shift_width
13
+ yield
14
+ ensure
15
+ @indentation -= shift_width
16
+ end
17
+ end
18
+ end
@@ -1,87 +1,51 @@
1
- # Copyright (c) 2010-2013 Michael Dvorkin
1
+ # Copyright (c) 2010-2016 Michael Dvorkin and contributors
2
2
  #
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 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
-
18
- def console?
19
- !!(defined?(IRB) || defined?(Pry))
20
- end
21
-
22
- def rails_console?
23
- console? && !!(defined?(Rails::Console) || ENV["RAILS_ENV"])
24
- end
25
-
26
- def irb!
27
- return unless defined?(IRB)
28
- unless IRB.version.include?("DietRB")
29
- IRB::Irb.class_eval do
30
- def output_value
31
- ap @context.last_value
32
- end
33
- end
34
- else # MacRuby
35
- IRB.formatter = Class.new(IRB::Formatter) do
36
- def inspect_object(object)
37
- object.ai
38
- end
39
- end.new
40
- end
41
- end
42
-
43
- def pry!
44
- if defined?(Pry)
45
- Pry.print = proc { |output, value| output.puts value.ai }
46
- end
47
- end
48
- end
6
+ require_relative 'indentator'
49
7
 
8
+ module AwesomePrint
50
9
  class Inspector
51
- attr_accessor :options
10
+ attr_accessor :options, :indentator
52
11
 
53
12
  AP = :__awesome_print__
54
13
 
55
14
  def initialize(options = {})
56
- @options = {
57
- :indent => 4, # Indent using 4 spaces.
58
- :index => true, # Display array indices.
59
- :html => false, # Use ANSI color codes rather than HTML.
60
- :multiline => true, # Display in multiple lines.
61
- :plain => false, # Use colors.
62
- :raw => false, # Do not recursively format object instance variables.
63
- :sort_keys => false, # Do not sort hash keys.
64
- :limit => false, # Limit large output for arrays and hashes. Set to a boolean or integer.
65
- :color => {
66
- :args => :pale,
67
- :array => :white,
68
- :bigdecimal => :blue,
69
- :class => :yellow,
70
- :date => :greenish,
71
- :falseclass => :red,
72
- :fixnum => :blue,
73
- :float => :blue,
74
- :hash => :pale,
75
- :keyword => :cyan,
76
- :method => :purpleish,
77
- :nilclass => :red,
78
- :rational => :blue,
79
- :string => :yellowish,
80
- :struct => :pale,
81
- :symbol => :cyanish,
82
- :time => :greenish,
83
- :trueclass => :green,
84
- :variable => :cyanish
15
+ @options = {
16
+ indent: 4, # Number of spaces for indenting.
17
+ index: true, # Display array indices.
18
+ html: false, # Use ANSI color codes rather than HTML.
19
+ multiline: true, # Display in multiple lines.
20
+ plain: false, # Use colors.
21
+ raw: false, # Do not recursively format instance variables.
22
+ sort_keys: false, # Do not sort hash keys.
23
+ sort_vars: true, # Sort instance variables.
24
+ limit: false, # Limit arrays & hashes. Accepts bool or int.
25
+ ruby19_syntax: false, # Use Ruby 1.9 hash syntax in output.
26
+ class_name: :class, # Method used to get Instance class name.
27
+ object_id: true, # Show object_id.
28
+ color: {
29
+ args: :pale,
30
+ array: :white,
31
+ bigdecimal: :blue,
32
+ class: :yellow,
33
+ date: :greenish,
34
+ falseclass: :red,
35
+ fixnum: :blue,
36
+ integer: :blue,
37
+ float: :blue,
38
+ hash: :pale,
39
+ keyword: :cyan,
40
+ method: :purpleish,
41
+ nilclass: :red,
42
+ rational: :blue,
43
+ string: :yellowish,
44
+ struct: :pale,
45
+ symbol: :cyanish,
46
+ time: :greenish,
47
+ trueclass: :green,
48
+ variable: :cyanish
85
49
  }
86
50
  }
87
51
 
@@ -90,11 +54,20 @@ module AwesomePrint
90
54
  merge_options!(options)
91
55
 
92
56
  @formatter = AwesomePrint::Formatter.new(self)
57
+ @indentator = AwesomePrint::Indentator.new(@options[:indent].abs)
93
58
  Thread.current[AP] ||= []
94
59
  end
95
-
60
+
61
+ def current_indentation
62
+ indentator.indentation
63
+ end
64
+
65
+ def increase_indentation(&block)
66
+ indentator.indent(&block)
67
+ end
68
+
96
69
  # Dispatcher that detects data nesting and invokes object-aware formatter.
97
- #------------------------------------------------------------------------------
70
+ #---------------------------------------------------------------------------
98
71
  def awesome(object)
99
72
  if Thread.current[AP].include?(object.object_id)
100
73
  nested(object)
@@ -109,10 +82,18 @@ module AwesomePrint
109
82
  end
110
83
 
111
84
  # Return true if we are to colorize the output.
112
- #------------------------------------------------------------------------------
85
+ #---------------------------------------------------------------------------
113
86
  def colorize?
114
87
  AwesomePrint.force_colors ||= false
115
- AwesomePrint.force_colors || (STDOUT.tty? && ((ENV['TERM'] && ENV['TERM'] != 'dumb') || ENV['ANSICON']))
88
+ AwesomePrint.force_colors || (
89
+ STDOUT.tty? && (
90
+ (
91
+ ENV['TERM'] &&
92
+ ENV['TERM'] != 'dumb'
93
+ ) ||
94
+ ENV['ANSICON']
95
+ )
96
+ )
116
97
  end
117
98
 
118
99
  private
@@ -122,24 +103,25 @@ module AwesomePrint
122
103
  # => [1,2, [...]]
123
104
  # hash = { :a => 1 }; hash[:b] = hash
124
105
  # => { :a => 1, :b => {...} }
125
- #------------------------------------------------------------------------------
106
+ #---------------------------------------------------------------------------
126
107
  def nested(object)
127
108
  case printable(object)
128
- when :array then @formatter.colorize("[...]", :array)
129
- when :hash then @formatter.colorize("{...}", :hash)
130
- when :struct then @formatter.colorize("{...}", :struct)
131
- else @formatter.colorize("...#{object.class}...", :class)
109
+ when :array then @formatter.colorize('[...]', :array)
110
+ when :hash then @formatter.colorize('{...}', :hash)
111
+ when :struct then @formatter.colorize('{...}', :struct)
112
+ else @formatter.colorize("...#{object.class}...", :class)
132
113
  end
133
114
  end
134
115
 
135
- #------------------------------------------------------------------------------
116
+ #---------------------------------------------------------------------------
136
117
  def unnested(object)
137
118
  @formatter.format(object, printable(object))
138
119
  end
139
120
 
140
- # Turn class name into symbol, ex: Hello::World => :hello_world. Classes that
141
- # inherit from Array, Hash, File, Dir, and Struct are treated as the base class.
142
- #------------------------------------------------------------------------------
121
+ # Turn class name into symbol, ex: Hello::World => :hello_world. Classes
122
+ # that inherit from Array, Hash, File, Dir, and Struct are treated as the
123
+ # base class.
124
+ #---------------------------------------------------------------------------
143
125
  def printable(object)
144
126
  case object
145
127
  when Array then :array
@@ -147,25 +129,41 @@ module AwesomePrint
147
129
  when File then :file
148
130
  when Dir then :dir
149
131
  when Struct then :struct
150
- else object.class.to_s.gsub(/:+/, "_").downcase.to_sym
132
+ else object.class.to_s.gsub(/:+/, '_').downcase.to_sym
151
133
  end
152
134
  end
153
135
 
154
- # Update @options by first merging the :color hash and then the remaining keys.
155
- #------------------------------------------------------------------------------
136
+ # Update @options by first merging the :color hash and then the remaining
137
+ # keys.
138
+ #---------------------------------------------------------------------------
156
139
  def merge_options!(options = {})
157
140
  @options[:color].merge!(options.delete(:color) || {})
158
141
  @options.merge!(options)
159
142
  end
160
143
 
144
+ # This method needs to be mocked during testing so that it always loads
145
+ # predictable values
146
+ #---------------------------------------------------------------------------
147
+ def load_dotfile
148
+ dotfile = File.join(ENV['HOME'], '.aprc')
149
+ load dotfile if dotfile_readable?(dotfile)
150
+ end
151
+
152
+ def dotfile_readable? dotfile
153
+ if @@dotfile_readable.nil? || @@dotfile != dotfile
154
+ @@dotfile_readable = File.readable?(@@dotfile = dotfile)
155
+ end
156
+ @@dotfile_readable
157
+ end
158
+ @@dotfile_readable = @@dotfile = nil
159
+
161
160
  # Load ~/.aprc file with custom defaults that override default options.
162
- #------------------------------------------------------------------------------
161
+ #---------------------------------------------------------------------------
163
162
  def merge_custom_defaults!
164
- dotfile = File.join(ENV["HOME"], ".aprc")
165
- load dotfile if File.readable?(dotfile)
163
+ load_dotfile
166
164
  merge_options!(AwesomePrint.defaults) if AwesomePrint.defaults.is_a?(Hash)
167
165
  rescue => e
168
- $stderr.puts "Could not load #{dotfile}: #{e}"
166
+ $stderr.puts "Could not load '.aprc' from ENV['HOME']: #{e}"
169
167
  end
170
168
  end
171
169
  end