awesome_print 1.7.0 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/Appraisals +11 -0
  4. data/CHANGELOG.md +10 -0
  5. data/CONTRIBUTING.md +1 -1
  6. data/README.md +47 -38
  7. data/Rakefile +5 -5
  8. data/lib/ap.rb +2 -2
  9. data/lib/awesome_print.rb +18 -17
  10. data/lib/awesome_print/colorize.rb +1 -1
  11. data/lib/awesome_print/core_ext/{array.rb → awesome_method_array.rb} +16 -18
  12. data/lib/awesome_print/core_ext/class.rb +3 -2
  13. data/lib/awesome_print/core_ext/kernel.rb +1 -1
  14. data/lib/awesome_print/core_ext/logger.rb +1 -1
  15. data/lib/awesome_print/core_ext/method.rb +2 -2
  16. data/lib/awesome_print/core_ext/object.rb +3 -2
  17. data/lib/awesome_print/core_ext/string.rb +3 -3
  18. data/lib/awesome_print/custom_defaults.rb +57 -0
  19. data/lib/awesome_print/ext/action_view.rb +8 -4
  20. data/lib/awesome_print/ext/active_record.rb +19 -11
  21. data/lib/awesome_print/ext/active_support.rb +1 -1
  22. data/lib/awesome_print/ext/mongo_mapper.rb +16 -13
  23. data/lib/awesome_print/ext/mongoid.rb +8 -6
  24. data/lib/awesome_print/ext/nobrainer.rb +8 -5
  25. data/lib/awesome_print/ext/nokogiri.rb +4 -4
  26. data/lib/awesome_print/ext/ostruct.rb +1 -1
  27. data/lib/awesome_print/ext/ripple.rb +5 -6
  28. data/lib/awesome_print/ext/sequel.rb +7 -6
  29. data/lib/awesome_print/formatter.rb +11 -19
  30. data/lib/awesome_print/formatters.rb +15 -0
  31. data/lib/awesome_print/formatters/array_formatter.rb +108 -42
  32. data/lib/awesome_print/formatters/base_formatter.rb +13 -11
  33. data/lib/awesome_print/formatters/class_formatter.rb +2 -1
  34. data/lib/awesome_print/formatters/dir_formatter.rb +1 -1
  35. data/lib/awesome_print/formatters/file_formatter.rb +1 -1
  36. data/lib/awesome_print/formatters/hash_formatter.rb +74 -22
  37. data/lib/awesome_print/formatters/object_formatter.rb +9 -14
  38. data/lib/awesome_print/formatters/struct_formatter.rb +71 -0
  39. data/lib/awesome_print/inspector.rb +77 -93
  40. data/lib/awesome_print/version.rb +2 -2
  41. data/spec/active_record_helper.rb +8 -2
  42. data/spec/colors_spec.rb +30 -30
  43. data/spec/core_ext/logger_spec.rb +43 -0
  44. data/spec/core_ext/string_spec.rb +20 -0
  45. data/spec/ext/action_view_spec.rb +18 -0
  46. data/spec/ext/active_record_spec.rb +252 -0
  47. data/spec/ext/active_support_spec.rb +26 -0
  48. data/spec/ext/mongo_mapper_spec.rb +261 -0
  49. data/spec/ext/mongoid_spec.rb +104 -0
  50. data/spec/ext/nobrainer_spec.rb +59 -0
  51. data/spec/ext/nokogiri_spec.rb +46 -0
  52. data/spec/ext/ostruct_spec.rb +22 -0
  53. data/spec/ext/ripple_spec.rb +48 -0
  54. data/spec/formats_spec.rb +193 -165
  55. data/spec/methods_spec.rb +116 -128
  56. data/spec/misc_spec.rb +104 -108
  57. data/spec/objects_spec.rb +70 -28
  58. data/spec/spec_helper.rb +27 -10
  59. data/spec/support/active_record_data.rb +20 -0
  60. data/spec/support/active_record_data/3_2_diana.txt +24 -0
  61. data/spec/support/active_record_data/3_2_diana_legacy.txt +24 -0
  62. data/spec/support/active_record_data/3_2_multi.txt +50 -0
  63. data/spec/support/active_record_data/3_2_multi_legacy.txt +50 -0
  64. data/spec/support/active_record_data/4_0_diana.txt +98 -0
  65. data/spec/support/active_record_data/4_0_multi.txt +198 -0
  66. data/spec/support/active_record_data/4_1_diana.txt +97 -0
  67. data/spec/support/active_record_data/4_1_multi.txt +196 -0
  68. data/spec/support/active_record_data/4_2_diana.txt +109 -0
  69. data/spec/support/active_record_data/4_2_diana_legacy.txt +109 -0
  70. data/spec/support/active_record_data/4_2_multi.txt +220 -0
  71. data/spec/support/active_record_data/4_2_multi_legacy.txt +220 -0
  72. data/spec/support/active_record_data/5_0_diana.txt +105 -0
  73. data/spec/support/active_record_data/5_0_multi.txt +212 -0
  74. data/spec/support/ext_verifier.rb +42 -0
  75. data/spec/support/mongoid_versions.rb +22 -0
  76. data/spec/support/rails_versions.rb +35 -0
  77. metadata +79 -4
@@ -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
@@ -1,89 +1,48 @@
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
- require_relative "indentator"
6
+ require_relative 'indentator'
7
7
 
8
8
  module AwesomePrint
9
-
10
- class << self # Class accessors for custom defaults.
11
- attr_accessor :defaults, :force_colors
12
-
13
- # Class accessor to force colorized output (ex. forked subprocess where TERM
14
- # might be dumb).
15
- #------------------------------------------------------------------------------
16
- def force_colors!(value = true)
17
- @force_colors = value
18
- end
19
-
20
- def console?
21
- !!(defined?(IRB) || defined?(Pry))
22
- end
23
-
24
- def rails_console?
25
- console? && !!(defined?(Rails::Console) || ENV["RAILS_ENV"])
26
- end
27
-
28
- def irb!
29
- return unless defined?(IRB)
30
- unless IRB.version.include?("DietRB")
31
- IRB::Irb.class_eval do
32
- def output_value
33
- ap @context.last_value
34
- end
35
- end
36
- else # MacRuby
37
- IRB.formatter = Class.new(IRB::Formatter) do
38
- def inspect_object(object)
39
- object.ai
40
- end
41
- end.new
42
- end
43
- end
44
-
45
- def pry!
46
- if defined?(Pry)
47
- Pry.print = proc { |output, value| output.puts value.ai }
48
- end
49
- end
50
- end
51
-
52
9
  class Inspector
53
10
  attr_accessor :options, :indentator
54
11
 
55
12
  AP = :__awesome_print__
56
13
 
57
14
  def initialize(options = {})
58
- @options = {
59
- :indent => 4, # Indent using 4 spaces.
60
- :index => true, # Display array indices.
61
- :html => false, # Use ANSI color codes rather than HTML.
62
- :multiline => true, # Display in multiple lines.
63
- :plain => false, # Use colors.
64
- :raw => false, # Do not recursively format object instance variables.
65
- :sort_keys => false, # Do not sort hash keys.
66
- :limit => false, # Limit large output for arrays and hashes. Set to a boolean or integer.
67
- :color => {
68
- :args => :pale,
69
- :array => :white,
70
- :bigdecimal => :blue,
71
- :class => :yellow,
72
- :date => :greenish,
73
- :falseclass => :red,
74
- :fixnum => :blue,
75
- :float => :blue,
76
- :hash => :pale,
77
- :keyword => :cyan,
78
- :method => :purpleish,
79
- :nilclass => :red,
80
- :rational => :blue,
81
- :string => :yellowish,
82
- :struct => :pale,
83
- :symbol => :cyanish,
84
- :time => :greenish,
85
- :trueclass => :green,
86
- :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
+ color: {
27
+ args: :pale,
28
+ array: :white,
29
+ bigdecimal: :blue,
30
+ class: :yellow,
31
+ date: :greenish,
32
+ falseclass: :red,
33
+ fixnum: :blue,
34
+ float: :blue,
35
+ hash: :pale,
36
+ keyword: :cyan,
37
+ method: :purpleish,
38
+ nilclass: :red,
39
+ rational: :blue,
40
+ string: :yellowish,
41
+ struct: :pale,
42
+ symbol: :cyanish,
43
+ time: :greenish,
44
+ trueclass: :green,
45
+ variable: :cyanish
87
46
  }
88
47
  }
89
48
 
@@ -103,9 +62,9 @@ module AwesomePrint
103
62
  def increase_indentation
104
63
  indentator.indent(&Proc.new)
105
64
  end
106
-
65
+
107
66
  # Dispatcher that detects data nesting and invokes object-aware formatter.
108
- #------------------------------------------------------------------------------
67
+ #---------------------------------------------------------------------------
109
68
  def awesome(object)
110
69
  if Thread.current[AP].include?(object.object_id)
111
70
  nested(object)
@@ -120,10 +79,18 @@ module AwesomePrint
120
79
  end
121
80
 
122
81
  # Return true if we are to colorize the output.
123
- #------------------------------------------------------------------------------
82
+ #---------------------------------------------------------------------------
124
83
  def colorize?
125
84
  AwesomePrint.force_colors ||= false
126
- AwesomePrint.force_colors || (STDOUT.tty? && ((ENV['TERM'] && ENV['TERM'] != 'dumb') || ENV['ANSICON']))
85
+ AwesomePrint.force_colors || (
86
+ STDOUT.tty? && (
87
+ (
88
+ ENV['TERM'] &&
89
+ ENV['TERM'] != 'dumb'
90
+ ) ||
91
+ ENV['ANSICON']
92
+ )
93
+ )
127
94
  end
128
95
 
129
96
  private
@@ -133,24 +100,25 @@ module AwesomePrint
133
100
  # => [1,2, [...]]
134
101
  # hash = { :a => 1 }; hash[:b] = hash
135
102
  # => { :a => 1, :b => {...} }
136
- #------------------------------------------------------------------------------
103
+ #---------------------------------------------------------------------------
137
104
  def nested(object)
138
105
  case printable(object)
139
- when :array then @formatter.colorize("[...]", :array)
140
- when :hash then @formatter.colorize("{...}", :hash)
141
- when :struct then @formatter.colorize("{...}", :struct)
142
- else @formatter.colorize("...#{object.class}...", :class)
106
+ when :array then @formatter.colorize('[...]', :array)
107
+ when :hash then @formatter.colorize('{...}', :hash)
108
+ when :struct then @formatter.colorize('{...}', :struct)
109
+ else @formatter.colorize("...#{object.class}...", :class)
143
110
  end
144
111
  end
145
112
 
146
- #------------------------------------------------------------------------------
113
+ #---------------------------------------------------------------------------
147
114
  def unnested(object)
148
115
  @formatter.format(object, printable(object))
149
116
  end
150
117
 
151
- # Turn class name into symbol, ex: Hello::World => :hello_world. Classes that
152
- # inherit from Array, Hash, File, Dir, and Struct are treated as the base class.
153
- #------------------------------------------------------------------------------
118
+ # Turn class name into symbol, ex: Hello::World => :hello_world. Classes
119
+ # that inherit from Array, Hash, File, Dir, and Struct are treated as the
120
+ # base class.
121
+ #---------------------------------------------------------------------------
154
122
  def printable(object)
155
123
  case object
156
124
  when Array then :array
@@ -158,22 +126,38 @@ module AwesomePrint
158
126
  when File then :file
159
127
  when Dir then :dir
160
128
  when Struct then :struct
161
- else object.class.to_s.gsub(/:+/, "_").downcase.to_sym
129
+ else object.class.to_s.gsub(/:+/, '_').downcase.to_sym
162
130
  end
163
131
  end
164
132
 
165
- # Update @options by first merging the :color hash and then the remaining keys.
166
- #------------------------------------------------------------------------------
133
+ # Update @options by first merging the :color hash and then the remaining
134
+ # keys.
135
+ #---------------------------------------------------------------------------
167
136
  def merge_options!(options = {})
168
137
  @options[:color].merge!(options.delete(:color) || {})
169
138
  @options.merge!(options)
170
139
  end
171
140
 
141
+ # This method needs to be mocked during testing so that it always loads
142
+ # predictable values
143
+ #---------------------------------------------------------------------------
144
+ def load_dotfile
145
+ dotfile = File.join(ENV['HOME'], '.aprc')
146
+ load dotfile if dotfile_readable?(dotfile)
147
+ end
148
+
149
+ def dotfile_readable? dotfile
150
+ if @@dotfile_readable.nil? || @@dotfile != dotfile
151
+ @@dotfile_readable = File.readable?(@@dotfile = dotfile)
152
+ end
153
+ @@dotfile_readable
154
+ end
155
+ @@dotfile_readable = @@dotfile = nil
156
+
172
157
  # Load ~/.aprc file with custom defaults that override default options.
173
- #------------------------------------------------------------------------------
158
+ #---------------------------------------------------------------------------
174
159
  def merge_custom_defaults!
175
- dotfile = File.join(ENV["HOME"], ".aprc")
176
- load dotfile if File.readable?(dotfile)
160
+ load_dotfile
177
161
  merge_options!(AwesomePrint.defaults) if AwesomePrint.defaults.is_a?(Hash)
178
162
  rescue => e
179
163
  $stderr.puts "Could not load #{dotfile}: #{e}"
@@ -1,10 +1,10 @@
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
6
  module AwesomePrint
7
7
  def self.version
8
- '1.7.0'
8
+ '1.8.0'
9
9
  end
10
10
  end
@@ -7,7 +7,7 @@ if ExtVerifier.has_rails?
7
7
  end
8
8
 
9
9
  # Establish connection to in-memory SQLite DB
10
- ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
10
+ ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
11
11
 
12
12
  # Create the users table
13
13
  ActiveRecord::Migration.verbose = false
@@ -18,7 +18,13 @@ if ExtVerifier.has_rails?
18
18
  t.datetime :created_at
19
19
  end
20
20
 
21
+ ActiveRecord::Migration.create_table :emails do |t|
22
+ t.references :user
23
+ t.string :email_address
24
+ end
25
+
21
26
  # Create models
22
- class User < ActiveRecord::Base; end
27
+ class User < ActiveRecord::Base; has_many :emails; end
23
28
  class SubUser < User; end
29
+ class Email < ActiveRecord::Base; belongs_to :user; end
24
30
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- RSpec.describe "AwesomePrint" do
3
+ RSpec.describe 'AwesomePrint' do
4
4
  def stub_tty!(output = true, stream = STDOUT)
5
5
  if output
6
6
  stream.instance_eval { def tty?; true; end }
@@ -9,94 +9,94 @@ RSpec.describe "AwesomePrint" do
9
9
  end
10
10
  end
11
11
 
12
- before do
13
- stub_dotfile!
14
- end
15
-
16
- describe "colorization" do
12
+ describe 'colorization' do
17
13
  PLAIN = '[ 1, :two, "three", [ nil, [ true, false ] ] ]'
18
14
  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
15
 
20
16
  before do
21
- ENV['TERM'] = "xterm-colors"
17
+ ENV['TERM'] = 'xterm-colors'
22
18
  ENV.delete('ANSICON')
23
- @arr = [ 1, :two, "three", [ nil, [ true, false] ] ]
19
+ @arr = [1, :two, 'three', [nil, [true, false]]]
24
20
  end
25
21
 
26
- describe "default settings (no forced colors)" do
22
+ describe 'default settings (no forced colors)' do
27
23
  before do
28
24
  AwesomePrint.force_colors! false
29
25
  end
30
26
 
31
- it "colorizes tty processes by default" do
27
+ it 'colorizes tty processes by default' do
32
28
  stub_tty!
33
- expect(@arr.ai(:multiline => false)).to eq(COLORIZED)
29
+ expect(@arr.ai(multiline: false)).to eq(COLORIZED)
34
30
  end
35
31
 
36
32
  it "colorizes processes with ENV['ANSICON'] by default" do
37
33
  begin
38
34
  stub_tty!
39
- term, ENV['ANSICON'] = ENV['ANSICON'], "1"
40
- expect(@arr.ai(:multiline => false)).to eq(COLORIZED)
35
+ term = ENV['ANSICON']
36
+ ENV['ANSICON'] = '1'
37
+ expect(@arr.ai(multiline: false)).to eq(COLORIZED)
41
38
  ensure
42
39
  ENV['ANSICON'] = term
43
40
  end
44
41
  end
45
42
 
46
- it "does not colorize tty processes running in dumb terminals by default" do
43
+ it 'does not colorize tty processes running in dumb terminals by default' do
47
44
  begin
48
45
  stub_tty!
49
- term, ENV['TERM'] = ENV['TERM'], "dumb"
50
- expect(@arr.ai(:multiline => false)).to eq(PLAIN)
46
+ term = ENV['TERM']
47
+ ENV['TERM'] = 'dumb'
48
+ expect(@arr.ai(multiline: false)).to eq(PLAIN)
51
49
  ensure
52
50
  ENV['TERM'] = term
53
51
  end
54
52
  end
55
53
 
56
- it "does not colorize subprocesses by default" do
54
+ it 'does not colorize subprocesses by default' do
57
55
  begin
58
56
  stub_tty! false
59
- expect(@arr.ai(:multiline => false)).to eq(PLAIN)
57
+ expect(@arr.ai(multiline: false)).to eq(PLAIN)
60
58
  ensure
61
59
  stub_tty!
62
60
  end
63
61
  end
64
62
  end
65
63
 
66
- describe "forced colors override" do
64
+ describe 'forced colors override' do
67
65
  before do
68
66
  AwesomePrint.force_colors!
69
67
  end
70
-
71
- it "still colorizes tty processes" do
68
+
69
+ it 'still colorizes tty processes' do
72
70
  stub_tty!
73
- expect(@arr.ai(:multiline => false)).to eq(COLORIZED)
71
+ expect(@arr.ai(multiline: false)).to eq(COLORIZED)
74
72
  end
75
73
 
76
74
  it "colorizes processes with ENV['ANSICON'] set to 0" do
77
75
  begin
78
76
  stub_tty!
79
- term, ENV['ANSICON'] = ENV['ANSICON'], "1"
80
- expect(@arr.ai(:multiline => false)).to eq(COLORIZED)
77
+ term = ENV['ANSICON']
78
+ ENV['ANSICON'] = '1'
79
+ expect(@arr.ai(multiline: false)).to eq(COLORIZED)
81
80
  ensure
82
81
  ENV['ANSICON'] = term
83
82
  end
84
83
  end
85
-
86
- it "colorizes dumb terminals" do
84
+
85
+ it 'colorizes dumb terminals' do
87
86
  begin
88
87
  stub_tty!
89
- term, ENV['TERM'] = ENV['TERM'], "dumb"
90
- expect(@arr.ai(:multiline => false)).to eq(COLORIZED)
88
+ term = ENV['TERM']
89
+ ENV['TERM'] = 'dumb'
90
+ expect(@arr.ai(multiline: false)).to eq(COLORIZED)
91
91
  ensure
92
92
  ENV['TERM'] = term
93
93
  end
94
94
  end
95
95
 
96
- it "colorizes subprocess" do
96
+ it 'colorizes subprocess' do
97
97
  begin
98
98
  stub_tty! false
99
- expect(@arr.ai(:multiline => false)).to eq(COLORIZED)
99
+ expect(@arr.ai(multiline: false)).to eq(COLORIZED)
100
100
  ensure
101
101
  stub_tty!
102
102
  end