amazing_print 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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,22 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'AmazingPrint Ostruct extension' do
4
+ before do
5
+ @ap = AmazingPrint::Inspector.new(plain: true, sort_keys: true)
6
+ end
7
+
8
+ it 'empty hash' do
9
+ struct = OpenStruct.new
10
+ expect(@ap.send(:awesome, struct)).to eq('OpenStruct {}')
11
+ end
12
+
13
+ it 'plain multiline' do
14
+ struct = OpenStruct.new name: 'Foo', address: 'Bar'
15
+ expect(@ap.send(:awesome, struct)).to eq <<~EOS.strip
16
+ OpenStruct {
17
+ :address => "Bar",
18
+ :name => "Foo"
19
+ }
20
+ EOS
21
+ end
22
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'AmazingPrint/Ripple', skip: -> { !ExtVerifier.has_ripple? }.call do
4
+ if ExtVerifier.has_ripple?
5
+ before :all do
6
+ class RippleUser
7
+ include Ripple::Document
8
+
9
+ key_on :_id
10
+ property :_id, String
11
+ property :first_name, String
12
+ property :last_name, String
13
+ end
14
+ end
15
+
16
+ after :all do
17
+ Object.instance_eval { remove_const :RippleUser }
18
+ end
19
+ end
20
+
21
+ before do
22
+ @ap = AmazingPrint::Inspector.new plain: true, sort_keys: true
23
+ end
24
+
25
+ it 'should print class instance' do
26
+ user = RippleUser.new _id: '12345', first_name: 'Al', last_name: 'Capone'
27
+ out = @ap.send :awesome, user
28
+
29
+ expect(out).to be_similar_to <<~EOS.strip
30
+ #<RippleUser:placeholder_id> {
31
+ :_id => "12345",
32
+ :first_name => "Al",
33
+ :last_name => "Capone"
34
+ }
35
+ EOS
36
+ end
37
+
38
+ it 'should print the class' do
39
+ expect(@ap.send(:awesome, RippleUser)).to eq <<~EOS.strip
40
+ class RippleUser < Object {
41
+ :_id => :string,
42
+ :first_name => :string,
43
+ :last_name => :string
44
+ }
45
+ EOS
46
+ end
47
+ end
@@ -0,0 +1,779 @@
1
+ require 'spec_helper'
2
+ require 'bigdecimal'
3
+ require 'set'
4
+
5
+ RSpec.describe 'AmazingPrint' do
6
+ describe 'Array' do
7
+ before do
8
+ @arr = [1, :two, 'three', [nil, [true, false]]]
9
+ end
10
+
11
+ it 'empty array' do
12
+ expect([].ai).to eq('[]')
13
+ end
14
+
15
+ it 'plain multiline' do
16
+ expect(@arr.ai(plain: true)).to eq <<~EOS.strip
17
+ [
18
+ [0] 1,
19
+ [1] :two,
20
+ [2] "three",
21
+ [3] [
22
+ [0] nil,
23
+ [1] [
24
+ [0] true,
25
+ [1] false
26
+ ]
27
+ ]
28
+ ]
29
+ EOS
30
+ end
31
+
32
+ it 'plain multiline without index' do
33
+ expect(@arr.ai(plain: true, index: false)).to eq <<~EOS.strip
34
+ [
35
+ 1,
36
+ :two,
37
+ "three",
38
+ [
39
+ nil,
40
+ [
41
+ true,
42
+ false
43
+ ]
44
+ ]
45
+ ]
46
+ EOS
47
+ end
48
+
49
+ it 'plain multiline indented' do
50
+ expect(@arr.ai(plain: true, indent: 2)).to eq <<~EOS.strip
51
+ [
52
+ [0] 1,
53
+ [1] :two,
54
+ [2] "three",
55
+ [3] [
56
+ [0] nil,
57
+ [1] [
58
+ [0] true,
59
+ [1] false
60
+ ]
61
+ ]
62
+ ]
63
+ EOS
64
+ end
65
+
66
+ it 'plain multiline indented without index' do
67
+ expect(@arr.ai(plain: true, indent: 2, index: false)).to eq <<~EOS.strip
68
+ [
69
+ 1,
70
+ :two,
71
+ "three",
72
+ [
73
+ nil,
74
+ [
75
+ true,
76
+ false
77
+ ]
78
+ ]
79
+ ]
80
+ EOS
81
+ end
82
+
83
+ it 'plain single line' do
84
+ expect(@arr.ai(plain: true, multiline: false)).to eq('[ 1, :two, "three", [ nil, [ true, false ] ] ]')
85
+ end
86
+
87
+ it 'colored multiline (default)' do
88
+ expect(@arr.ai).to eq <<~EOS.strip
89
+ [
90
+ \e[1;37m[0] \e[0m\e[1;34m1\e[0m,
91
+ \e[1;37m[1] \e[0m\e[0;36m:two\e[0m,
92
+ \e[1;37m[2] \e[0m\e[0;33m\"three\"\e[0m,
93
+ \e[1;37m[3] \e[0m[
94
+ \e[1;37m[0] \e[0m\e[1;31mnil\e[0m,
95
+ \e[1;37m[1] \e[0m[
96
+ \e[1;37m[0] \e[0m\e[1;32mtrue\e[0m,
97
+ \e[1;37m[1] \e[0m\e[1;31mfalse\e[0m
98
+ ]
99
+ ]
100
+ ]
101
+ EOS
102
+ end
103
+
104
+ it 'colored multiline indented' do
105
+ expect(@arr.ai(indent: 8)).to eq <<~EOS.strip
106
+ [
107
+ \e[1;37m[0] \e[0m\e[1;34m1\e[0m,
108
+ \e[1;37m[1] \e[0m\e[0;36m:two\e[0m,
109
+ \e[1;37m[2] \e[0m\e[0;33m\"three\"\e[0m,
110
+ \e[1;37m[3] \e[0m[
111
+ \e[1;37m[0] \e[0m\e[1;31mnil\e[0m,
112
+ \e[1;37m[1] \e[0m[
113
+ \e[1;37m[0] \e[0m\e[1;32mtrue\e[0m,
114
+ \e[1;37m[1] \e[0m\e[1;31mfalse\e[0m
115
+ ]
116
+ ]
117
+ ]
118
+ EOS
119
+ end
120
+
121
+ it 'colored single line' do
122
+ expect(@arr.ai(multiline: false)).to eq("[ \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 ] ] ]")
123
+ end
124
+ end
125
+
126
+ #------------------------------------------------------------------------------
127
+ describe 'Nested Array' do
128
+ before do
129
+ @arr = [1, 2]
130
+ @arr << @arr
131
+ end
132
+
133
+ it 'plain multiline' do
134
+ expect(@arr.ai(plain: true)).to eq <<~EOS.strip
135
+ [
136
+ [0] 1,
137
+ [1] 2,
138
+ [2] [...]
139
+ ]
140
+ EOS
141
+ end
142
+
143
+ it 'plain multiline without index' do
144
+ expect(@arr.ai(plain: true, index: false)).to eq <<~EOS.strip
145
+ [
146
+ 1,
147
+ 2,
148
+ [...]
149
+ ]
150
+ EOS
151
+ end
152
+
153
+ it 'plain single line' do
154
+ expect(@arr.ai(plain: true, multiline: false)).to eq('[ 1, 2, [...] ]')
155
+ end
156
+ end
157
+
158
+ #------------------------------------------------------------------------------
159
+ describe 'Limited Output Array' do
160
+ before(:each) do
161
+ @arr = (1..1000).to_a
162
+ end
163
+
164
+ it 'plain limited output large' do
165
+ expect(@arr.ai(plain: true, limit: true)).to eq <<~EOS.strip
166
+ [
167
+ [ 0] 1,
168
+ [ 1] 2,
169
+ [ 2] 3,
170
+ [ 3] .. [996],
171
+ [997] 998,
172
+ [998] 999,
173
+ [999] 1000
174
+ ]
175
+ EOS
176
+ end
177
+
178
+ it 'plain limited output small' do
179
+ @arr = @arr[0..3]
180
+ expect(@arr.ai(plain: true, limit: true)).to eq <<~EOS.strip
181
+ [
182
+ [0] 1,
183
+ [1] 2,
184
+ [2] 3,
185
+ [3] 4
186
+ ]
187
+ EOS
188
+ end
189
+
190
+ it 'plain limited output with 10 lines' do
191
+ expect(@arr.ai(plain: true, limit: 10)).to eq <<~EOS.strip
192
+ [
193
+ [ 0] 1,
194
+ [ 1] 2,
195
+ [ 2] 3,
196
+ [ 3] 4,
197
+ [ 4] 5,
198
+ [ 5] .. [995],
199
+ [996] 997,
200
+ [997] 998,
201
+ [998] 999,
202
+ [999] 1000
203
+ ]
204
+ EOS
205
+ end
206
+
207
+ it 'plain limited output with 11 lines' do
208
+ expect(@arr.ai(plain: true, limit: 11)).to eq <<~EOS.strip
209
+ [
210
+ [ 0] 1,
211
+ [ 1] 2,
212
+ [ 2] 3,
213
+ [ 3] 4,
214
+ [ 4] 5,
215
+ [ 5] .. [994],
216
+ [995] 996,
217
+ [996] 997,
218
+ [997] 998,
219
+ [998] 999,
220
+ [999] 1000
221
+ ]
222
+ EOS
223
+ end
224
+ end
225
+
226
+ #------------------------------------------------------------------------------
227
+ describe 'Limited Output Hash' do
228
+ before(:each) do
229
+ @hash = ('a'..'z').inject({}) { |h, v| h.merge({ v => v.to_sym }) }
230
+ end
231
+
232
+ it 'plain limited output' do
233
+ expect(@hash.ai(sort_keys: true, plain: true, limit: true)).to eq <<~EOS.strip
234
+ {
235
+ "a" => :a,
236
+ "b" => :b,
237
+ "c" => :c,
238
+ "d" => :d .. "w" => :w,
239
+ "x" => :x,
240
+ "y" => :y,
241
+ "z" => :z
242
+ }
243
+ EOS
244
+ end
245
+ end
246
+
247
+ #------------------------------------------------------------------------------
248
+ describe 'Hash' do
249
+ before do
250
+ @hash = { 1 => { sym: { 'str' => { [1, 2, 3] => { { k: :v } => Hash } } } } }
251
+ end
252
+
253
+ it 'empty hash' do
254
+ expect({}.ai).to eq('{}')
255
+ end
256
+
257
+ it 'plain multiline' do
258
+ expect(@hash.ai(plain: true)).to eq <<~EOS.strip
259
+ {
260
+ 1 => {
261
+ :sym => {
262
+ "str" => {
263
+ [ 1, 2, 3 ] => {
264
+ { :k => :v } => Hash < Object
265
+ }
266
+ }
267
+ }
268
+ }
269
+ }
270
+ EOS
271
+ end
272
+
273
+ it 'new hash syntax' do
274
+ expect(@hash.ai(plain: true, ruby19_syntax: true)).to eq <<~EOS.strip
275
+ {
276
+ 1 => {
277
+ sym: {
278
+ "str" => {
279
+ [ 1, 2, 3 ] => {
280
+ { k: :v } => Hash < Object
281
+ }
282
+ }
283
+ }
284
+ }
285
+ }
286
+ EOS
287
+ end
288
+
289
+ it 'plain multiline indented' do
290
+ expect(@hash.ai(plain: true, indent: 1)).to eq <<~EOS.strip
291
+ {
292
+ 1 => {
293
+ :sym => {
294
+ "str" => {
295
+ [ 1, 2, 3 ] => {
296
+ { :k => :v } => Hash < Object
297
+ }
298
+ }
299
+ }
300
+ }
301
+ }
302
+ EOS
303
+ end
304
+
305
+ it 'plain single line' do
306
+ expect(@hash.ai(plain: true, multiline: false)).to eq('{ 1 => { :sym => { "str" => { [ 1, 2, 3 ] => { { :k => :v } => Hash < Object } } } } }')
307
+ end
308
+
309
+ it 'colored multiline (default)' do
310
+ expect(@hash.ai).to eq <<~EOS.strip
311
+ {
312
+ 1\e[0;37m => \e[0m{
313
+ :sym\e[0;37m => \e[0m{
314
+ \"str\"\e[0;37m => \e[0m{
315
+ [ 1, 2, 3 ]\e[0;37m => \e[0m{
316
+ { :k => :v }\e[0;37m => \e[0m\e[1;33mHash < Object\e[0m
317
+ }
318
+ }
319
+ }
320
+ }
321
+ }
322
+ EOS
323
+ end
324
+
325
+ it 'colored with new hash syntax' do
326
+ expect(@hash.ai(ruby19_syntax: true)).to eq <<~EOS.strip
327
+ {
328
+ 1\e[0;37m => \e[0m{
329
+ sym\e[0;37m: \e[0m{
330
+ \"str\"\e[0;37m => \e[0m{
331
+ [ 1, 2, 3 ]\e[0;37m => \e[0m{
332
+ { k: :v }\e[0;37m => \e[0m\e[1;33mHash < Object\e[0m
333
+ }
334
+ }
335
+ }
336
+ }
337
+ }
338
+ EOS
339
+ end
340
+
341
+ it 'colored multiline indented' do
342
+ expect(@hash.ai(indent: 2)).to eq <<~EOS.strip
343
+ {
344
+ 1\e[0;37m => \e[0m{
345
+ :sym\e[0;37m => \e[0m{
346
+ \"str\"\e[0;37m => \e[0m{
347
+ [ 1, 2, 3 ]\e[0;37m => \e[0m{
348
+ { :k => :v }\e[0;37m => \e[0m\e[1;33mHash < Object\e[0m
349
+ }
350
+ }
351
+ }
352
+ }
353
+ }
354
+ EOS
355
+ end
356
+
357
+ it 'colored single line' do
358
+ expect(@hash.ai(multiline: false)).to eq("{ 1\e[0;37m => \e[0m{ :sym\e[0;37m => \e[0m{ \"str\"\e[0;37m => \e[0m{ [ 1, 2, 3 ]\e[0;37m => \e[0m{ { :k => :v }\e[0;37m => \e[0m\e[1;33mHash < Object\e[0m } } } } }")
359
+ end
360
+ end
361
+
362
+ #------------------------------------------------------------------------------
363
+ describe 'Nested Hash' do
364
+ before do
365
+ @hash = {}
366
+ @hash[:a] = @hash
367
+ end
368
+
369
+ it 'plain multiline' do
370
+ expect(@hash.ai(plain: true)).to eq <<~EOS.strip
371
+ {
372
+ :a => {...}
373
+ }
374
+ EOS
375
+ end
376
+
377
+ it 'plain single line' do
378
+ expect(@hash.ai(plain: true, multiline: false)).to eq('{ :a => {...} }')
379
+ end
380
+ end
381
+
382
+ #------------------------------------------------------------------------------
383
+ describe 'Hash with several keys' do
384
+ before do
385
+ @hash = { 'b' => 'b', :a => 'a', :z => 'z', 'alpha' => 'alpha' }
386
+ end
387
+
388
+ it 'plain multiline' do
389
+ out = @hash.ai(plain: true)
390
+ if RUBY_VERSION.to_f < 1.9 # Order of @hash keys is not guaranteed.
391
+ expect(out).to match(/^\{[^\}]+\}/m)
392
+ expect(out).to match(/ "b" => "b",?/)
393
+ expect(out).to match(/ :a => "a",?/)
394
+ expect(out).to match(/ :z => "z",?/)
395
+ expect(out).to match(/ "alpha" => "alpha",?$/)
396
+ else
397
+ expect(out).to eq <<~EOS.strip
398
+ {
399
+ "b" => "b",
400
+ :a => "a",
401
+ :z => "z",
402
+ "alpha" => "alpha"
403
+ }
404
+ EOS
405
+ end
406
+ end
407
+
408
+ it 'plain multiline with sorted keys' do
409
+ expect(@hash.ai(plain: true, sort_keys: true)).to eq <<~EOS.strip
410
+ {
411
+ :a => "a",
412
+ "alpha" => "alpha",
413
+ "b" => "b",
414
+ :z => "z"
415
+ }
416
+ EOS
417
+ end
418
+ end
419
+
420
+ #------------------------------------------------------------------------------
421
+ describe 'Negative options[:indent]' do
422
+ #
423
+ # With Ruby < 1.9 the order of hash keys is not defined so we can't
424
+ # reliably compare the output string.
425
+ #
426
+ it 'hash keys must be left aligned' do
427
+ hash = { [0, 0, 255] => :yellow, :red => 'rgb(255, 0, 0)', 'magenta' => 'rgb(255, 0, 255)' }
428
+ out = hash.ai(plain: true, indent: -4, sort_keys: true)
429
+ expect(out).to eq <<~EOS.strip
430
+ {
431
+ [ 0, 0, 255 ] => :yellow,
432
+ "magenta" => "rgb(255, 0, 255)",
433
+ :red => "rgb(255, 0, 0)"
434
+ }
435
+ EOS
436
+ end
437
+
438
+ it 'nested hash keys should be indented (array of hashes)' do
439
+ arr = [{ a: 1, bb: 22, ccc: 333 }, { 1 => :a, 22 => :bb, 333 => :ccc }]
440
+ out = arr.ai(plain: true, indent: -4, sort_keys: true)
441
+ expect(out).to eq <<~EOS.strip
442
+ [
443
+ [0] {
444
+ :a => 1,
445
+ :bb => 22,
446
+ :ccc => 333
447
+ },
448
+ [1] {
449
+ 1 => :a,
450
+ 22 => :bb,
451
+ 333 => :ccc
452
+ }
453
+ ]
454
+ EOS
455
+ end
456
+
457
+ it 'nested hash keys should be indented (hash of hashes)' do
458
+ arr = { first: { a: 1, bb: 22, ccc: 333 }, second: { 1 => :a, 22 => :bb, 333 => :ccc } }
459
+ out = arr.ai(plain: true, indent: -4, sort_keys: true)
460
+ expect(out).to eq <<~EOS.strip
461
+ {
462
+ :first => {
463
+ :a => 1,
464
+ :bb => 22,
465
+ :ccc => 333
466
+ },
467
+ :second => {
468
+ 1 => :a,
469
+ 22 => :bb,
470
+ 333 => :ccc
471
+ }
472
+ }
473
+ EOS
474
+ end
475
+ end
476
+
477
+ #------------------------------------------------------------------------------
478
+ describe 'Class' do
479
+ it 'should show superclass (plain)' do
480
+ expect(self.class.ai(plain: true)).to eq("#{self.class} < #{self.class.superclass}")
481
+ end
482
+
483
+ it 'should show superclass (color)' do
484
+ expect(self.class.ai).to eq("#{self.class} < #{self.class.superclass}".yellow)
485
+ end
486
+ end
487
+
488
+ #------------------------------------------------------------------------------
489
+ describe 'File' do
490
+ it 'should display a file (plain)' do
491
+ File.open(__FILE__, 'r') do |f|
492
+ expect(f.ai(plain: true)).to eq("#{f.inspect}\n" << `ls -alF #{f.path}`.chop)
493
+ end
494
+ end
495
+ end
496
+
497
+ #------------------------------------------------------------------------------
498
+ describe 'Dir' do
499
+ it 'should display a direcory (plain)' do
500
+ Dir.open(File.dirname(__FILE__)) do |d|
501
+ expect(d.ai(plain: true)).to eq("#{d.inspect}\n" << `ls -alF #{d.path}`.chop)
502
+ end
503
+ end
504
+ end
505
+
506
+ #------------------------------------------------------------------------------
507
+ describe 'BigDecimal and Rational' do
508
+ it 'should present BigDecimal object with arbitrary precision' do
509
+ big = BigDecimal('201020102010201020102010201020102010.4')
510
+ expect(big.ai(plain: true)).to eq('201020102010201020102010201020102010.4')
511
+ end
512
+
513
+ it 'should present Rational object with arbitrary precision' do
514
+ rat = Rational(201_020_102_010_201_020_102_010_201_020_102_010, 2)
515
+ out = rat.ai(plain: true)
516
+ #
517
+ # Ruby 1.9 slightly changed the format of Rational#to_s, see
518
+ # http://techtime.getharvest.com/blog/harvest-is-now-on-ruby-1-dot-9-3 and
519
+ # http://www.ruby-forum.com/topic/189397
520
+ #
521
+ if RUBY_VERSION < '1.9'
522
+ expect(out).to eq('100510051005100510051005100510051005')
523
+ else
524
+ expect(out).to eq('100510051005100510051005100510051005/1')
525
+ end
526
+ end
527
+ end
528
+
529
+ #------------------------------------------------------------------------------
530
+ describe 'Utility methods' do
531
+ it 'should merge options' do
532
+ ap = AmazingPrint::Inspector.new
533
+ ap.send(:merge_options!, { color: { array: :black }, indent: 0 })
534
+ options = ap.instance_variable_get('@options')
535
+ expect(options[:color][:array]).to eq(:black)
536
+ expect(options[:indent]).to eq(0)
537
+ end
538
+ end
539
+
540
+ #------------------------------------------------------------------------------
541
+ describe 'Set' do
542
+ before do
543
+ @arr = [1, :two, 'three']
544
+ @set = Set.new(@arr)
545
+ end
546
+
547
+ it 'empty set' do
548
+ expect(Set.new.ai).to eq([].ai)
549
+ end
550
+
551
+ if RUBY_VERSION > '1.9'
552
+ it 'plain multiline' do
553
+ expect(@set.ai(plain: true)).to eq(@arr.ai(plain: true))
554
+ end
555
+
556
+ it 'plain multiline indented' do
557
+ expect(@set.ai(plain: true, indent: 1)).to eq(@arr.ai(plain: true, indent: 1))
558
+ end
559
+
560
+ it 'plain single line' do
561
+ expect(@set.ai(plain: true, multiline: false)).to eq(@arr.ai(plain: true, multiline: false))
562
+ end
563
+
564
+ it 'colored multiline (default)' do
565
+ expect(@set.ai).to eq(@arr.ai)
566
+ end
567
+ else # Prior to Ruby 1.9 the order of set values is unpredicatble.
568
+ it 'plain multiline' do
569
+ expect(@set.sort_by { |x| x.to_s }.ai(plain: true)).to eq(@arr.sort_by { |x| x.to_s }.ai(plain: true))
570
+ end
571
+
572
+ it 'plain multiline indented' do
573
+ expect(@set.sort_by { |x| x.to_s }.ai(plain: true, indent: 1)).to eq(@arr.sort_by { |x| x.to_s }.ai(plain: true, indent: 1))
574
+ end
575
+
576
+ it 'plain single line' do
577
+ expect(@set.sort_by { |x| x.to_s }.ai(plain: true, multiline: false)).to eq(@arr.sort_by { |x| x.to_s }.ai(plain: true, multiline: false))
578
+ end
579
+
580
+ it 'colored multiline (default)' do
581
+ expect(@set.sort_by { |x| x.to_s }.ai).to eq(@arr.sort_by { |x| x.to_s }.ai)
582
+ end
583
+ end
584
+ end
585
+
586
+ #------------------------------------------------------------------------------
587
+ describe 'Struct' do
588
+ before do
589
+ @struct = if defined?(Struct::SimpleStruct)
590
+ Struct::SimpleStruct.new
591
+ else
592
+ Struct.new('SimpleStruct', :name, :address).new
593
+ end
594
+ @struct.name = 'Herman Munster'
595
+ @struct.address = '1313 Mockingbird Lane'
596
+ end
597
+
598
+ it 'empty struct' do
599
+ expect(Struct.new('EmptyStruct').ai).to eq("\e[1;33mStruct::EmptyStruct < Struct\e[0m")
600
+ end
601
+
602
+ it 'plain multiline' do
603
+ s1 = <<-EOS.strip
604
+ address = \"1313 Mockingbird Lane\",
605
+ name = \"Herman Munster\"
606
+ EOS
607
+ s2 = <<-EOS.strip
608
+ name = \"Herman Munster\",
609
+ address = \"1313 Mockingbird Lane\"
610
+ EOS
611
+ expect(@struct.ai(plain: true)).to satisfy { |out| out.match(s1) || out.match(s2) }
612
+ end
613
+
614
+ it 'plain multiline indented' do
615
+ s1 = <<-EOS.strip
616
+ address = "1313 Mockingbird Lane",
617
+ name = "Herman Munster"
618
+ EOS
619
+ s2 = <<-EOS.strip
620
+ name = "Herman Munster",
621
+ address = "1313 Mockingbird Lane"
622
+ EOS
623
+ expect(@struct.ai(plain: true, indent: 1)).to satisfy { |out| out.match(s1) || out.match(s2) }
624
+ end
625
+
626
+ it 'plain single line' do
627
+ s1 = 'address = "1313 Mockingbird Lane", name = "Herman Munster"'
628
+ s2 = 'name = "Herman Munster", address = "1313 Mockingbird Lane"'
629
+ expect(@struct.ai(plain: true, multiline: false)).to satisfy { |out| out.match(s1) || out.match(s2) }
630
+ end
631
+
632
+ it 'colored multiline (default)' do
633
+ s1 = <<-EOS.strip
634
+ address\e[0;37m = \e[0m\e[0;33m\"1313 Mockingbird Lane\"\e[0m,
635
+ name\e[0;37m = \e[0m\e[0;33m\"Herman Munster\"\e[0m
636
+ EOS
637
+ s2 = <<-EOS.strip
638
+ name\e[0;37m = \e[0m\e[0;33m\"Herman Munster\"\e[0m,
639
+ address\e[0;37m = \e[0m\e[0;33m\"1313 Mockingbird Lane\"\e[0m
640
+ EOS
641
+ expect(@struct.ai).to satisfy { |out| out.include?(s1) || out.include?(s2) }
642
+ end
643
+ end
644
+
645
+ #------------------------------------------------------------------------------
646
+ describe 'Inherited from standard Ruby classes' do
647
+ after do
648
+ Object.instance_eval { remove_const :My } if defined?(My)
649
+ end
650
+
651
+ it 'inherited from Array should be displayed as Array' do
652
+ class My < Array; end
653
+
654
+ my = My.new([1, :two, 'three', [nil, [true, false]]])
655
+ expect(my.ai(plain: true)).to eq <<~EOS.strip
656
+ [
657
+ [0] 1,
658
+ [1] :two,
659
+ [2] "three",
660
+ [3] [
661
+ [0] nil,
662
+ [1] [
663
+ [0] true,
664
+ [1] false
665
+ ]
666
+ ]
667
+ ]
668
+ EOS
669
+ end
670
+
671
+ it 'inherited from Hash should be displayed as Hash' do
672
+ class My < Hash; end
673
+
674
+ my = My[{ 1 => { sym: { 'str' => { [1, 2, 3] => { { k: :v } => Hash } } } } }]
675
+ expect(my.ai(plain: true)).to eq <<~EOS.strip
676
+ {
677
+ 1 => {
678
+ :sym => {
679
+ "str" => {
680
+ [ 1, 2, 3 ] => {
681
+ { :k => :v } => Hash < Object
682
+ }
683
+ }
684
+ }
685
+ }
686
+ }
687
+ EOS
688
+ end
689
+
690
+ it 'inherited from File should be displayed as File' do
691
+ class My < File; end
692
+
693
+ my = begin
694
+ File.new('/dev/null')
695
+ rescue StandardError
696
+ File.new('nul')
697
+ end
698
+ expect(my.ai(plain: true)).to eq("#{my.inspect}\n" << `ls -alF #{my.path}`.chop)
699
+ end
700
+
701
+ it 'inherited from Dir should be displayed as Dir' do
702
+ class My < Dir; end
703
+
704
+ require 'tmpdir'
705
+ my = My.new(Dir.tmpdir)
706
+ expect(my.ai(plain: true)).to eq("#{my.inspect}\n" << `ls -alF #{my.path}`.chop)
707
+ end
708
+
709
+ it 'should handle a class that defines its own #send method' do
710
+ class My
711
+ def send(arg1, arg2, arg3); end
712
+ end
713
+
714
+ my = My.new
715
+ expect { my.methods.ai(plain: true) }.not_to raise_error
716
+ end
717
+
718
+ it 'should handle a class defines its own #method method (ex. request.method)' do
719
+ class My
720
+ def method
721
+ 'POST'
722
+ end
723
+ end
724
+
725
+ my = My.new
726
+ expect { my.methods.ai(plain: true) }.not_to raise_error
727
+ end
728
+
729
+ describe 'should handle a class that defines its own #to_hash method' do
730
+ it 'that takes arguments' do
731
+ class My
732
+ def to_hash(a, b); end
733
+ end
734
+
735
+ my = My.new
736
+ expect { my.ai(plain: true) }.not_to raise_error
737
+ end
738
+
739
+ it 'that returns nil' do
740
+ class My
741
+ def to_hash
742
+ nil
743
+ end
744
+ end
745
+
746
+ my = My.new
747
+ expect { my.ai(plain: true) }.not_to raise_error
748
+ end
749
+
750
+ it "that returns an object that doesn't support #keys" do
751
+ class My
752
+ def to_hash
753
+ object = Object.new
754
+ object.define_singleton_method('[]') { return nil }
755
+
756
+ object
757
+ end
758
+ end
759
+
760
+ my = My.new
761
+ expect { my.ai(plain: true) }.not_to raise_error
762
+ end
763
+
764
+ it "that returns an object that doesn't support subscripting" do
765
+ class My
766
+ def to_hash
767
+ object = Object.new
768
+ object.define_singleton_method(:keys) { return [:foo] }
769
+
770
+ object
771
+ end
772
+ end
773
+
774
+ my = My.new
775
+ expect { my.ai(plain: true) }.not_to raise_error
776
+ end
777
+ end
778
+ end
779
+ end