amazing_print 1.0.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.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +35 -0
  3. data/Appraisals +60 -0
  4. data/CHANGELOG.md +2 -0
  5. data/CONTRIBUTING.md +81 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +21 -0
  8. data/README.md +356 -0
  9. data/Rakefile +23 -0
  10. data/lib/amazing_print.rb +46 -0
  11. data/lib/amazing_print/colorize.rb +25 -0
  12. data/lib/amazing_print/core_ext/awesome_method_array.rb +82 -0
  13. data/lib/amazing_print/core_ext/class.rb +23 -0
  14. data/lib/amazing_print/core_ext/kernel.rb +25 -0
  15. data/lib/amazing_print/core_ext/logger.rb +21 -0
  16. data/lib/amazing_print/core_ext/method.rb +21 -0
  17. data/lib/amazing_print/core_ext/object.rb +23 -0
  18. data/lib/amazing_print/core_ext/string.rb +42 -0
  19. data/lib/amazing_print/custom_defaults.rb +57 -0
  20. data/lib/amazing_print/ext/action_view.rb +22 -0
  21. data/lib/amazing_print/ext/active_record.rb +103 -0
  22. data/lib/amazing_print/ext/active_support.rb +45 -0
  23. data/lib/amazing_print/ext/mongo_mapper.rb +125 -0
  24. data/lib/amazing_print/ext/mongoid.rb +68 -0
  25. data/lib/amazing_print/ext/nobrainer.rb +53 -0
  26. data/lib/amazing_print/ext/nokogiri.rb +45 -0
  27. data/lib/amazing_print/ext/ostruct.rb +27 -0
  28. data/lib/amazing_print/ext/ripple.rb +71 -0
  29. data/lib/amazing_print/ext/sequel.rb +55 -0
  30. data/lib/amazing_print/formatter.rb +120 -0
  31. data/lib/amazing_print/formatters.rb +14 -0
  32. data/lib/amazing_print/formatters/array_formatter.rb +139 -0
  33. data/lib/amazing_print/formatters/base_formatter.rb +148 -0
  34. data/lib/amazing_print/formatters/class_formatter.rb +24 -0
  35. data/lib/amazing_print/formatters/dir_formatter.rb +21 -0
  36. data/lib/amazing_print/formatters/file_formatter.rb +21 -0
  37. data/lib/amazing_print/formatters/hash_formatter.rb +106 -0
  38. data/lib/amazing_print/formatters/method_formatter.rb +21 -0
  39. data/lib/amazing_print/formatters/object_formatter.rb +82 -0
  40. data/lib/amazing_print/formatters/simple_formatter.rb +20 -0
  41. data/lib/amazing_print/formatters/struct_formatter.rb +74 -0
  42. data/lib/amazing_print/indentator.rb +17 -0
  43. data/lib/amazing_print/inspector.rb +175 -0
  44. data/lib/amazing_print/version.rb +10 -0
  45. data/lib/ap.rb +10 -0
  46. data/spec/active_record_helper.rb +30 -0
  47. data/spec/colors_spec.rb +114 -0
  48. data/spec/core_ext/logger_spec.rb +44 -0
  49. data/spec/core_ext/string_spec.rb +20 -0
  50. data/spec/ext/action_view_spec.rb +17 -0
  51. data/spec/ext/active_record_spec.rb +297 -0
  52. data/spec/ext/active_support_spec.rb +26 -0
  53. data/spec/ext/mongo_mapper_spec.rb +259 -0
  54. data/spec/ext/mongoid_spec.rb +66 -0
  55. data/spec/ext/nobrainer_spec.rb +58 -0
  56. data/spec/ext/nokogiri_spec.rb +50 -0
  57. data/spec/ext/ostruct_spec.rb +22 -0
  58. data/spec/ext/ripple_spec.rb +47 -0
  59. data/spec/formats_spec.rb +779 -0
  60. data/spec/methods_spec.rb +478 -0
  61. data/spec/misc_spec.rb +245 -0
  62. data/spec/objects_spec.rb +219 -0
  63. data/spec/spec_helper.rb +106 -0
  64. data/spec/support/active_record_data.rb +20 -0
  65. data/spec/support/active_record_data/3_2_diana.txt +24 -0
  66. data/spec/support/active_record_data/3_2_diana_legacy.txt +24 -0
  67. data/spec/support/active_record_data/3_2_multi.txt +50 -0
  68. data/spec/support/active_record_data/3_2_multi_legacy.txt +50 -0
  69. data/spec/support/active_record_data/4_0_diana.txt +98 -0
  70. data/spec/support/active_record_data/4_0_multi.txt +198 -0
  71. data/spec/support/active_record_data/4_1_diana.txt +97 -0
  72. data/spec/support/active_record_data/4_1_multi.txt +196 -0
  73. data/spec/support/active_record_data/4_2_diana.txt +109 -0
  74. data/spec/support/active_record_data/4_2_diana_legacy.txt +109 -0
  75. data/spec/support/active_record_data/4_2_multi.txt +220 -0
  76. data/spec/support/active_record_data/4_2_multi_legacy.txt +220 -0
  77. data/spec/support/active_record_data/5_0_diana.txt +105 -0
  78. data/spec/support/active_record_data/5_0_multi.txt +212 -0
  79. data/spec/support/active_record_data/5_1_diana.txt +104 -0
  80. data/spec/support/active_record_data/5_1_multi.txt +210 -0
  81. data/spec/support/active_record_data/5_2_diana.txt +104 -0
  82. data/spec/support/active_record_data/5_2_multi.txt +210 -0
  83. data/spec/support/active_record_data/6_0_diana.txt +104 -0
  84. data/spec/support/active_record_data/6_0_multi.txt +210 -0
  85. data/spec/support/ext_verifier.rb +41 -0
  86. data/spec/support/mongoid_versions.rb +22 -0
  87. data/spec/support/rails_versions.rb +50 -0
  88. metadata +243 -0
@@ -0,0 +1,245 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'AmazingPrint' do
4
+ describe 'Misc' do
5
+ it 'handle weird objects that return nil on inspect' do
6
+ weird = Class.new do
7
+ def inspect
8
+ nil
9
+ end
10
+ end
11
+ expect(weird.new.ai(plain: true)).to eq('')
12
+ end
13
+
14
+ it 'handle frozen object.inspect' do
15
+ weird = Class.new do
16
+ def inspect
17
+ 'ice'.freeze
18
+ end
19
+ end
20
+ expect(weird.new.ai(plain: false)).to eq('ice')
21
+ end
22
+
23
+ # See https://github.com/awesome-print/awesome_print/issues/35
24
+ it 'handle array grep when pattern contains / chapacter' do
25
+ hash = { '1/x' => 1, '2//x' => :"2" }
26
+ grepped = hash.keys.sort.grep(%r{^(\d+)/}) { Regexp.last_match(1) }
27
+ expect(grepped.ai(plain: true, multiline: false)).to eq('[ "1", "2" ]')
28
+ end
29
+
30
+ # See https://github.com/awesome-print/awesome_print/issues/85
31
+ if RUBY_VERSION >= '1.8.7'
32
+ it "handle array grep when a method is defined in C and thus doesn't have a binding" do
33
+ arr = (0..6).to_a
34
+ grepped = arr.grep(1..4, &:succ)
35
+ expect(grepped.ai(plain: true, multiline: false)).to eq('[ 2, 3, 4, 5 ]')
36
+ end
37
+ end
38
+
39
+ it 'returns value passed as a parameter' do
40
+ object = rand
41
+ allow(self).to receive(:puts)
42
+ expect(ap(object)).to eq(object)
43
+ end
44
+
45
+ # Require different file name this time (lib/ap.rb vs. lib/amazing_print).
46
+ it "several require 'amazing_print' should do no harm" do
47
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/ap')
48
+ expect { rand.ai }.not_to raise_error
49
+ end
50
+
51
+ it 'format ENV as hash' do
52
+ expect(ENV.ai(plain: true)).to eq(ENV.to_hash.ai(plain: true))
53
+ expect(ENV.ai).to eq(ENV.to_hash.ai)
54
+ end
55
+
56
+ # See https://github.com/awesome-print/awesome_print/issues/134
57
+ it 'IPAddr workaround' do
58
+ require 'ipaddr'
59
+ ipaddr = IPAddr.new('3ffe:505:2::1')
60
+ expect(ipaddr.ai).to eq('#<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff>')
61
+ end
62
+
63
+ # See https://github.com/awesome-print/awesome_print/issues/139
64
+ it 'Object that overrides == and expects the :id method' do
65
+ weird = Class.new do
66
+ # Raises NoMethodError: undefined method `id' when "other" is nil or ENV.
67
+ def ==(other)
68
+ id == other.id
69
+ end
70
+ alias_method :eql?, :==
71
+ end
72
+ expect { weird.new.ai }.not_to raise_error
73
+ end
74
+ end
75
+
76
+ #------------------------------------------------------------------------------
77
+ describe 'HTML output' do
78
+ it 'wraps ap output with plain <pre> tag' do
79
+ markup = rand
80
+ expect(markup.ai(html: true, plain: true)).to eq("<pre>#{markup}</pre>")
81
+ end
82
+
83
+ it 'wraps ap output with <pre> tag with colorized <kbd>' do
84
+ markup = rand
85
+ expect(markup.ai(html: true)).to eq(%(<pre><kbd style="color:blue">#{markup}</kbd></pre>))
86
+ end
87
+
88
+ it 'wraps multiline ap output with <pre> tag with colorized <kbd>' do
89
+ markup = [1, :two, 'three']
90
+ expect(markup.ai(html: true)).to eq <<~EOS.strip
91
+ <pre>[
92
+ <kbd style="color:white">[0] </kbd><kbd style="color:blue">1</kbd>,
93
+ <kbd style="color:white">[1] </kbd><kbd style="color:darkcyan">:two</kbd>,
94
+ <kbd style="color:white">[2] </kbd><kbd style="color:brown">&quot;three&quot;</kbd>
95
+ ]</pre>
96
+ EOS
97
+ end
98
+
99
+ it 'wraps hash ap output with only an outer <pre> tag' do
100
+ markup = [{ 'hello' => 'world' }]
101
+ expect(markup.ai(html: true)).to eq <<~EOS.strip
102
+ <pre>[
103
+ <kbd style="color:white">[0] </kbd>{
104
+ &quot;hello&quot;<kbd style="color:slategray"> =&gt; </kbd><kbd style="color:brown">&quot;world&quot;</kbd>
105
+ }
106
+ ]</pre>
107
+ EOS
108
+ end
109
+
110
+ it 'encodes HTML entities (plain)' do
111
+ markup = ' &<hello>'
112
+ expect(markup.ai(html: true, plain: true)).to eq('<pre>&quot; &amp;&lt;hello&gt;&quot;</pre>')
113
+ end
114
+
115
+ it 'encodes HTML entities (color)' do
116
+ markup = ' &<hello>'
117
+ expect(markup.ai(html: true)).to eq('<pre><kbd style="color:brown">&quot; &amp;&lt;hello&gt;&quot;</kbd></pre>')
118
+ end
119
+ end
120
+
121
+ #------------------------------------------------------------------------------
122
+ describe 'AmazingPrint.defaults' do
123
+ after do
124
+ AmazingPrint.defaults = nil
125
+ end
126
+
127
+ # See https://github.com/awesome-print/awesome_print/issues/98
128
+ it 'should properly merge the defaults' do
129
+ AmazingPrint.defaults = { indent: -2, sort_keys: true }
130
+ hash = { [0, 0, 255] => :yellow, :red => 'rgb(255, 0, 0)', 'magenta' => 'rgb(255, 0, 255)' }
131
+ out = hash.ai(plain: true)
132
+ expect(out).to eq <<~EOS.strip
133
+ {
134
+ [ 0, 0, 255 ] => :yellow,
135
+ "magenta" => "rgb(255, 0, 255)",
136
+ :red => "rgb(255, 0, 0)"
137
+ }
138
+ EOS
139
+ end
140
+ end
141
+
142
+ #------------------------------------------------------------------------------
143
+ describe 'Coexistence with the colorize gem' do
144
+ before do # Redefine String#red just like colorize gem does it.
145
+ @awesome_method = ''.method(:red)
146
+
147
+ String.instance_eval do
148
+ define_method :red do # Method arity is now 0 in Ruby 1.9+.
149
+ "[red]#{self}[/red]"
150
+ end
151
+ end
152
+ end
153
+
154
+ after do # Restore String#red method.
155
+ awesome_method = @awesome_method
156
+ String.instance_eval do
157
+ define_method :red, awesome_method
158
+ end
159
+ end
160
+
161
+ it 'shoud not raise ArgumentError when formatting HTML' do
162
+ out = 'hello'.ai(color: { string: :red }, html: true)
163
+ if RUBY_VERSION >= '1.9'
164
+ expect(out).to eq(%(<pre>[red]<kbd style="color:red">&quot;hello&quot;</kbd>[/red]</pre>))
165
+ else
166
+ expect(out).to eq(%(<pre>[red]&quot;hello&quot;[/red]</pre>))
167
+ end
168
+ end
169
+
170
+ it 'shoud not raise ArgumentError when formatting HTML (shade color)' do
171
+ out = 'hello'.ai(color: { string: :redish }, html: true)
172
+ expect(out).to eq(%(<pre><kbd style="color:darkred">&quot;hello&quot;</kbd></pre>))
173
+ end
174
+
175
+ it 'shoud not raise ArgumentError when formatting non-HTML' do
176
+ out = 'hello'.ai(color: { string: :red }, html: false)
177
+ expect(out).to eq(%([red]"hello"[/red]))
178
+ end
179
+
180
+ it 'shoud not raise ArgumentError when formatting non-HTML (shade color)' do
181
+ out = 'hello'.ai(color: { string: :redish }, html: false)
182
+ expect(out).to eq(%(\e[0;31m"hello"\e[0m))
183
+ end
184
+ end
185
+
186
+ #------------------------------------------------------------------------------
187
+ describe 'Console' do
188
+ it 'should detect IRB' do
189
+ class IRB; end
190
+ ENV.delete('RAILS_ENV')
191
+ expect(AmazingPrint.console?).to eq(true)
192
+ expect(AmazingPrint.rails_console?).to eq(false)
193
+ Object.instance_eval { remove_const :IRB }
194
+ end
195
+
196
+ it 'should detect Pry' do
197
+ class Pry; end
198
+ ENV.delete('RAILS_ENV')
199
+ expect(AmazingPrint.console?).to eq(true)
200
+ expect(AmazingPrint.rails_console?).to eq(false)
201
+ Object.instance_eval { remove_const :Pry }
202
+ end
203
+
204
+ it 'should detect Rails::Console' do
205
+ class IRB; end
206
+ module Rails; class Console; end; end
207
+ expect(AmazingPrint.console?).to eq(true)
208
+ expect(AmazingPrint.rails_console?).to eq(true)
209
+ Object.instance_eval { remove_const :IRB }
210
+ Object.instance_eval { remove_const :Rails }
211
+ end
212
+
213
+ it "should detect ENV['RAILS_ENV']" do
214
+ class Pry; end
215
+ ENV['RAILS_ENV'] = 'development'
216
+ expect(AmazingPrint.console?).to eq(true)
217
+ expect(AmazingPrint.rails_console?).to eq(true)
218
+ Object.instance_eval { remove_const :Pry }
219
+ end
220
+
221
+ it 'should return the actual object when *not* running under console' do
222
+ expect(capture! { ap([1, 2, 3]) }).to eq([1, 2, 3])
223
+ expect(capture! { ap({ a: 1 }) }).to eq({ a: 1 })
224
+ end
225
+
226
+ it 'should return nil when running under console' do
227
+ class IRB; end
228
+ expect(capture! { ap([1, 2, 3]) }).to eq(nil)
229
+ expect(capture! { ap({ a: 1 }) }).to eq(nil)
230
+ Object.instance_eval { remove_const :IRB }
231
+ end
232
+
233
+ it 'handles NoMethodError on IRB implicit #ai' do
234
+ module IRB; class Irb; end; end
235
+ irb_context = double('irb_context', last_value: BasicObject.new)
236
+ IRB.define_singleton_method :version, -> { 'test_version' }
237
+ irb = IRB::Irb.new
238
+ irb.instance_eval { @context = irb_context }
239
+ AmazingPrint.irb!
240
+ expect(irb).to receive(:puts).with("(Object doesn't support #ai)")
241
+ expect { irb.output_value }.to_not raise_error
242
+ Object.instance_eval { remove_const :IRB }
243
+ end
244
+ end
245
+ end
@@ -0,0 +1,219 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'Objects' do
4
+ after do
5
+ Object.instance_eval { remove_const :Hello } if defined?(Hello)
6
+ end
7
+
8
+ describe 'Formatting an object' do
9
+ it 'attributes' do
10
+ class Hello
11
+ attr_reader :abra
12
+ attr_writer :ca
13
+ attr_accessor :dabra
14
+
15
+ def initialize
16
+ @abra = 1
17
+ @ca = 2
18
+ @dabra = 3
19
+ end
20
+ end
21
+
22
+ hello = Hello.new
23
+ out = hello.ai(plain: true, raw: true)
24
+ str = <<~EOS.strip
25
+ #<Hello:placeholder_id
26
+ attr_accessor :dabra = 3,
27
+ attr_reader :abra = 1,
28
+ attr_writer :ca = 2
29
+ >
30
+ EOS
31
+ expect(out).to be_similar_to(str)
32
+ expect(hello.ai(plain: true, raw: false)).to eq(hello.inspect)
33
+ end
34
+
35
+ it 'instance variables' do
36
+ class Hello
37
+ def initialize
38
+ @abra = 1
39
+ @ca = 2
40
+ @dabra = 3
41
+ end
42
+ end
43
+
44
+ hello = Hello.new
45
+ out = hello.ai(plain: true, raw: true)
46
+ str = <<~EOS.strip
47
+ #<Hello:placeholder_id
48
+ @abra = 1,
49
+ @ca = 2,
50
+ @dabra = 3
51
+ >
52
+ EOS
53
+ expect(out).to be_similar_to(str)
54
+ expect(hello.ai(plain: true, raw: false)).to eq(hello.inspect)
55
+ end
56
+
57
+ it 'attributes and instance variables' do
58
+ class Hello
59
+ attr_reader :abra
60
+ attr_writer :ca
61
+ attr_accessor :dabra
62
+
63
+ def initialize
64
+ @abra = 1
65
+ @ca = 2
66
+ @dabra = 3
67
+ @scooby = 3
68
+ @dooby = 2
69
+ @doo = 1
70
+ end
71
+ end
72
+
73
+ hello = Hello.new
74
+ out = hello.ai(plain: true, raw: true)
75
+ str = <<~EOS.strip
76
+ #<Hello:placeholder_id
77
+ @doo = 1,
78
+ @dooby = 2,
79
+ @scooby = 3,
80
+ attr_accessor :dabra = 3,
81
+ attr_reader :abra = 1,
82
+ attr_writer :ca = 2
83
+ >
84
+ EOS
85
+ expect(out).to be_similar_to(str)
86
+ expect(hello.ai(plain: true, raw: false)).to eq(hello.inspect)
87
+ end
88
+
89
+ it 'without the plain options print the colorized values' do
90
+ class Hello
91
+ attr_reader :abra
92
+ attr_writer :ca
93
+
94
+ def initialize
95
+ @abra = 1
96
+ @ca = 2
97
+ @dabra = 3
98
+ end
99
+ end
100
+
101
+ hello = Hello.new
102
+ out = hello.ai(raw: true)
103
+ str = <<~EOS.strip
104
+ #<Hello:placeholder_id
105
+ \e[0;36m@dabra\e[0m\e[0;37m = \e[0m\e[1;34m3\e[0m,
106
+ \e[1;36mattr_reader\e[0m \e[0;35m:abra\e[0m\e[0;37m = \e[0m\e[1;34m1\e[0m,
107
+ \e[1;36mattr_writer\e[0m \e[0;35m:ca\e[0m\e[0;37m = \e[0m\e[1;34m2\e[0m
108
+ >
109
+ EOS
110
+ expect(out).to be_similar_to(str)
111
+ expect(hello.ai(plain: true, raw: false)).to eq(hello.inspect)
112
+ end
113
+
114
+ it 'with multine as false show inline values' do
115
+ class Hello
116
+ attr_reader :abra
117
+ attr_writer :ca
118
+
119
+ def initialize
120
+ @abra = 1
121
+ @ca = 2
122
+ @dabra = 3
123
+ end
124
+ end
125
+
126
+ hello = Hello.new
127
+ out = hello.ai(multiline: false, plain: true, raw: true)
128
+ str = <<~EOS.strip
129
+ #<Hello:placeholder_id @dabra = 3, attr_reader :abra = 1, attr_writer :ca = 2>
130
+ EOS
131
+ expect(out).to be_similar_to(str)
132
+ expect(hello.ai(plain: true, raw: false)).to eq(hello.inspect)
133
+ end
134
+
135
+ it 'without the sort_vars option does not sort instance variables' do
136
+ class Hello
137
+ attr_reader :abra
138
+ attr_writer :ca
139
+ attr_accessor :dabra
140
+
141
+ def initialize
142
+ @abra = 1
143
+ @ca = 2
144
+ @dabra = 3
145
+ @scooby = 3
146
+ @dooby = 2
147
+ @doo = 1
148
+ end
149
+
150
+ def instance_variables
151
+ %i[@scooby @dooby @doo @abra @ca @dabra]
152
+ end
153
+ end
154
+
155
+ hello = Hello.new
156
+ out = hello.ai(plain: true, raw: true, sort_vars: false)
157
+ str = <<~EOS.strip
158
+ #<Hello:placeholder_id
159
+ @scooby = 3,
160
+ @dooby = 2,
161
+ @doo = 1,
162
+ attr_reader :abra = 1,
163
+ attr_writer :ca = 2,
164
+ attr_accessor :dabra = 3
165
+ >
166
+ EOS
167
+ expect(out).to be_similar_to(str)
168
+ expect(hello.ai(plain: true, raw: false)).to eq(hello.inspect)
169
+ end
170
+
171
+ it 'object_id' do
172
+ class Hello
173
+ def initialize
174
+ @abra = 1
175
+ @ca = 2
176
+ @dabra = 3
177
+ end
178
+ end
179
+
180
+ hello = Hello.new
181
+ out = hello.ai(plain: true, raw: true, object_id: false)
182
+ str = <<~EOS.strip
183
+ #<Hello
184
+ @abra = 1,
185
+ @ca = 2,
186
+ @dabra = 3
187
+ >
188
+ EOS
189
+ expect(out).to be_similar_to(str)
190
+ expect(hello.ai(plain: true, raw: false)).to eq(hello.inspect)
191
+ end
192
+
193
+ it 'class_name' do
194
+ class Hello
195
+ def initialize
196
+ @abra = 1
197
+ @ca = 2
198
+ @dabra = 3
199
+ end
200
+
201
+ def to_s
202
+ 'CustomizedHello'
203
+ end
204
+ end
205
+
206
+ hello = Hello.new
207
+ out = hello.ai(plain: true, raw: true, class_name: :to_s)
208
+ str = <<~EOS.strip
209
+ #<CustomizedHello:placeholder_id
210
+ @abra = 1,
211
+ @ca = 2,
212
+ @dabra = 3
213
+ >
214
+ EOS
215
+ expect(out).to be_similar_to(str)
216
+ expect(hello.ai(plain: true, raw: false)).to eq(hello.inspect)
217
+ end
218
+ end
219
+ end