hsume2-hirb 0.6.0.beta.1

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 (53) hide show
  1. data/.gemspec +21 -0
  2. data/CHANGELOG.rdoc +144 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.rdoc +194 -0
  5. data/Rakefile +35 -0
  6. data/lib/bond/completions/hirb.rb +15 -0
  7. data/lib/hirb/console.rb +43 -0
  8. data/lib/hirb/dynamic_view.rb +113 -0
  9. data/lib/hirb/formatter.rb +126 -0
  10. data/lib/hirb/helpers/auto_table.rb +24 -0
  11. data/lib/hirb/helpers/object_table.rb +14 -0
  12. data/lib/hirb/helpers/parent_child_tree.rb +24 -0
  13. data/lib/hirb/helpers/tab_table.rb +24 -0
  14. data/lib/hirb/helpers/table/filters.rb +10 -0
  15. data/lib/hirb/helpers/table/resizer.rb +82 -0
  16. data/lib/hirb/helpers/table.rb +349 -0
  17. data/lib/hirb/helpers/tree.rb +181 -0
  18. data/lib/hirb/helpers/unicode_table.rb +15 -0
  19. data/lib/hirb/helpers/vertical_table.rb +37 -0
  20. data/lib/hirb/helpers.rb +18 -0
  21. data/lib/hirb/import_object.rb +10 -0
  22. data/lib/hirb/menu.rb +238 -0
  23. data/lib/hirb/pager.rb +105 -0
  24. data/lib/hirb/string.rb +44 -0
  25. data/lib/hirb/util.rb +96 -0
  26. data/lib/hirb/version.rb +3 -0
  27. data/lib/hirb/view.rb +270 -0
  28. data/lib/hirb/views/couch_db.rb +11 -0
  29. data/lib/hirb/views/misc_db.rb +15 -0
  30. data/lib/hirb/views/mongo_db.rb +14 -0
  31. data/lib/hirb/views/orm.rb +11 -0
  32. data/lib/hirb/views/rails.rb +19 -0
  33. data/lib/hirb/views.rb +8 -0
  34. data/lib/hirb.rb +82 -0
  35. data/lib/ripl/hirb.rb +15 -0
  36. data/test/auto_table_test.rb +30 -0
  37. data/test/console_test.rb +27 -0
  38. data/test/deps.rip +4 -0
  39. data/test/dynamic_view_test.rb +94 -0
  40. data/test/formatter_test.rb +176 -0
  41. data/test/hirb_test.rb +39 -0
  42. data/test/import_test.rb +9 -0
  43. data/test/menu_test.rb +255 -0
  44. data/test/object_table_test.rb +79 -0
  45. data/test/pager_test.rb +162 -0
  46. data/test/resizer_test.rb +62 -0
  47. data/test/table_test.rb +630 -0
  48. data/test/test_helper.rb +61 -0
  49. data/test/tree_test.rb +184 -0
  50. data/test/util_test.rb +59 -0
  51. data/test/view_test.rb +165 -0
  52. data/test/views_test.rb +13 -0
  53. metadata +184 -0
@@ -0,0 +1,630 @@
1
+ # encoding: UTF-8
2
+ require File.join(File.dirname(__FILE__), 'test_helper')
3
+
4
+ describe "Table" do
5
+ def table(*args)
6
+ Helpers::Table.render(*args)
7
+ end
8
+ before_all { reset_config }
9
+
10
+ describe "basic table" do
11
+ it "renders" do
12
+ expected_table = <<-TABLE.unindent
13
+ +---+---+
14
+ | a | b |
15
+ +---+---+
16
+ | 1 | 2 |
17
+ | 3 | 4 |
18
+ +---+---+
19
+ 2 rows in set
20
+ TABLE
21
+ table([{:a=>1, :b=>2}, {:a=>3, :b=>4}]).should == expected_table
22
+ end
23
+
24
+ it "with no headers renders" do
25
+ expected_table = <<-TABLE.unindent
26
+ +---+---+
27
+ | 1 | 2 |
28
+ +---+---+
29
+ 1 row in set
30
+ TABLE
31
+ table([{:a=>1, :b=>2}], :headers=>false).should == expected_table
32
+ end
33
+
34
+ it "with no headers and nil fields renders" do
35
+ expected_table = <<-TABLE.unindent
36
+ +---+---+
37
+ | 1 | |
38
+ +---+---+
39
+ 1 row in set
40
+ TABLE
41
+ table([{:a=>1, :b=>nil}], :headers=>false).should == expected_table
42
+ end
43
+
44
+ it "with string keys renders" do
45
+ expected_table = <<-TABLE.unindent
46
+ +---+---+
47
+ | a | b |
48
+ +---+---+
49
+ | 1 | 2 |
50
+ | 3 | 4 |
51
+ +---+---+
52
+ 2 rows in set
53
+ TABLE
54
+ table([{'a'=>1, 'b'=>2}, {'a'=>3, 'b'=>4}]).should == expected_table
55
+ end
56
+
57
+ it "with no keys renders" do
58
+ expected_table = <<-TABLE.unindent
59
+ +--+
60
+ | |
61
+ +--+
62
+ | |
63
+ +--+
64
+ 1 row in set
65
+ TABLE
66
+ table([{}]).should == expected_table
67
+ end
68
+
69
+ it "with array only rows renders" do
70
+ expected_table = <<-TABLE.unindent
71
+ +---+---+
72
+ | 0 | 1 |
73
+ +---+---+
74
+ | 1 | 2 |
75
+ | 3 | 4 |
76
+ +---+---+
77
+ 2 rows in set
78
+ TABLE
79
+ table([[1,2], [3,4]]).should == expected_table
80
+ end
81
+
82
+ it "with too many fields defaults to vertical table" do
83
+ rows = [Array.new(25, "A"* 10)]
84
+ Helpers::VerticalTable.expects(:render).with(rows, anything)
85
+ capture_stderr { table(rows)}.should =~ /Warning:/
86
+ end
87
+
88
+ it "with no rows renders" do
89
+ table([]).should == "0 rows in set"
90
+ end
91
+
92
+ it "with invalid rows raises an argumenterror" do
93
+ lambda { table(:a=>1) }.should.raise(ArgumentError).message.should =~ /Table must/
94
+ end
95
+
96
+ it "renders utf8" do
97
+ expected_table = <<-TABLE.unindent
98
+ +--------------------+
99
+ | name |
100
+ +--------------------+
101
+ | アイウエオカキ |
102
+ | クケコサシスセソタチツテ |
103
+ | Tata l'asticote |
104
+ | toto létoile PAOLI |
105
+ +--------------------+
106
+ 4 rows in set
107
+ TABLE
108
+ table([{:name=>"アイウエオカキ"}, {:name=>"クケコサシスセソタチツテ"}, {:name=>"Tata l'asticote"}, {:name=>"toto létoile PAOLI"}]).should == expected_table
109
+ end
110
+
111
+ it "stringifies newlines and tabs and renders" do
112
+ expected_table = <<-TABLE.unindent
113
+ +-----+---+
114
+ | a | b |
115
+ +-----+---+
116
+ | 1#{'\n'} | 2 |
117
+ | 3#{'\t'} | 4 |
118
+ +-----+---+
119
+ 2 rows in set
120
+ TABLE
121
+ value = [{'a'=>"1\n", 'b'=>2}, {'a'=>"3\t", 'b'=>4}]
122
+ table(value).should == expected_table
123
+ value.should == [{'a'=>"1\n", 'b'=>2}, {'a'=>"3\t", 'b'=>4}]
124
+ end
125
+
126
+ it "with a field of only array values renders values comma joined" do
127
+ expected_table = <<-TABLE.unindent
128
+ +----+------+
129
+ | a | b |
130
+ +----+------+
131
+ | 1 | 1, 2 |
132
+ | ok | 3, 4 |
133
+ +----+------+
134
+ 2 rows in set
135
+ TABLE
136
+ table([{:a=>1, :b=>[1,2]}, {:a=>'ok', :b=>[3,4]}]).should == expected_table
137
+ end
138
+
139
+ it "with filter class default doesn't override explicit filters" do
140
+ expected_table = <<-TABLE.unindent
141
+ +------+-------+
142
+ | name | value |
143
+ +------+-------+
144
+ | a | 1 |
145
+ +------+-------+
146
+ 1 row in set
147
+ TABLE
148
+ table([{:name=>'a', :value=>{:b=>1}}], :filters=>{:value=>:size}).should == expected_table
149
+ end
150
+ end
151
+
152
+ describe "table with" do
153
+ it "fields option renders" do
154
+ expected_table = <<-TABLE.unindent
155
+ +---+---+
156
+ | b | a |
157
+ +---+---+
158
+ | 2 | 1 |
159
+ | 4 | 3 |
160
+ +---+---+
161
+ 2 rows in set
162
+ TABLE
163
+ table([{:a=>1, :b=>2}, {:a=>3, :b=>4}], :fields=>[:b, :a]).should == expected_table
164
+ end
165
+
166
+ it "fields option and array only rows" do
167
+ expected_table = <<-TABLE.unindent
168
+ +---+---+
169
+ | 0 | 2 |
170
+ +---+---+
171
+ | 1 | 3 |
172
+ +---+---+
173
+ 1 row in set
174
+ TABLE
175
+ table([[1,2,3]], :fields=>[0,2]).should == expected_table
176
+ end
177
+
178
+ it "fields and number options copies fields option and does not modify it" do
179
+ options = {:fields=>[:f1], :number=>true}
180
+ table([{:f1=>1, :f2=>2}], options)
181
+ options[:fields].should == [:f1]
182
+ end
183
+
184
+ it "invalid fields option renders empty columns" do
185
+ expected_table = <<-TABLE.unindent
186
+ +---+---+
187
+ | b | c |
188
+ +---+---+
189
+ | 2 | |
190
+ | 4 | |
191
+ +---+---+
192
+ 2 rows in set
193
+ TABLE
194
+ table([{:a=>1, :b=>2}, {:a=>3, :b=>4}], :fields=>[:b, :c]).should == expected_table
195
+ end
196
+
197
+ it "grep_fields option and symbol fields" do
198
+ expected_table = <<-TABLE.unindent
199
+ +----+----+
200
+ | f1 | f2 |
201
+ +----+----+
202
+ | 1 | 2 |
203
+ +----+----+
204
+ 1 row in set
205
+ TABLE
206
+ table([{:f1 => 1, :f2 => 2, :gf1 => 3}], :grep_fields => /^f/).should == expected_table
207
+ end
208
+
209
+ it "grep_fields option and non-symbol fields" do
210
+ expected_table = <<-TABLE.unindent
211
+ +---+
212
+ | 1 |
213
+ +---+
214
+ | 2 |
215
+ +---+
216
+ 1 row in set
217
+ TABLE
218
+ table([[1,2,3]], :grep_fields => /1/).should == expected_table
219
+ end
220
+
221
+ it "invalid field in max_fields option renders" do
222
+ expected_table = <<-TABLE.unindent
223
+ +------------+---+
224
+ | a | b |
225
+ +------------+---+
226
+ | AAAAAAA... | 2 |
227
+ +------------+---+
228
+ 1 row in set
229
+ TABLE
230
+ table([{:a=> "A" * 50, :b=>2}], :max_fields=>{:a=>10,:c=>10}).should == expected_table
231
+ end
232
+
233
+ it "max_fields option with fields less than 3 characters renders" do
234
+ expected_table = <<-TABLE.unindent
235
+ +----+---+
236
+ | a | b |
237
+ +----+---+
238
+ | AA | 2 |
239
+ +----+---+
240
+ 1 row in set
241
+ TABLE
242
+ table([{:a=> "A" * 50, :b=>2}], :max_fields=>{:a=>2}, :resize=>false).should == expected_table
243
+ end
244
+
245
+ it "max_fields option without resize renders" do
246
+ expected_table = <<-TABLE.unindent
247
+ +------------+---+
248
+ | a | b |
249
+ +------------+---+
250
+ | AAAAAAA... | 2 |
251
+ +------------+---+
252
+ 1 row in set
253
+ TABLE
254
+ table([{:a=> "A" * 50, :b=>2}], :max_fields=>{:a=>10}, :resize=>false).should == expected_table
255
+ end
256
+
257
+ it "max_fields option with percentage renders" do
258
+ expected_table = <<-TABLE.unindent
259
+ +------------------+---+
260
+ | a | b |
261
+ +------------------+---+
262
+ | AAAAAAAAAAAAA... | 2 |
263
+ +------------------+---+
264
+ 1 row in set
265
+ TABLE
266
+ table([{:a=> "A" * 50, :b=>2}], :max_fields=>{:a=>'0.15'}).should == expected_table
267
+ end
268
+
269
+ it "max_width option renders" do
270
+ expected_table = <<-TABLE.unindent
271
+ +-----------+---+------------+
272
+ | a | b | c |
273
+ +-----------+---+------------+
274
+ | AAAAAA... | 2 | CCCCCCCCCC |
275
+ +-----------+---+------------+
276
+ 1 row in set
277
+ TABLE
278
+ table([{:a=> "A" * 50, :b=>2, :c=>"C"*10}], :max_width=>30).should == expected_table
279
+ end
280
+
281
+ it "resize option false renders full table" do
282
+ expected_table = <<-TABLE.unindent
283
+ +----------------------------------------------------+---+------------+
284
+ | a | b | c |
285
+ +----------------------------------------------------+---+------------+
286
+ | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | 2 | CCCCCCCCCC |
287
+ +----------------------------------------------------+---+------------+
288
+ 1 row in set
289
+ TABLE
290
+ table([{:a=> "A" * 50, :b=>2, :c=>"C"*10}], :resize=>false).should == expected_table
291
+ end
292
+
293
+ it "global width renders" do
294
+ expected_table = <<-TABLE.unindent
295
+ +-----------+---+------------+
296
+ | a | b | c |
297
+ +-----------+---+------------+
298
+ | AAAAAA... | 2 | CCCCCCCCCC |
299
+ +-----------+---+------------+
300
+ 1 row in set
301
+ TABLE
302
+ View.load_config
303
+ View.resize(30)
304
+ table([{:a=> "A" * 50, :b=>2, :c=>"C"*10}]).should == expected_table
305
+ reset_config
306
+ end
307
+
308
+ it "headers option and headers longer than fields renders" do
309
+ expected_table = <<-TABLE.unindent
310
+ +---+---------+---------+
311
+ | a | field B | field C |
312
+ +---+---------+---------+
313
+ | A | 2 | C |
314
+ +---+---------+---------+
315
+ 1 row in set
316
+ TABLE
317
+ table([{:a=> "A", :b=>2, :c=>"C"}], :headers=>{:b=>"field B", :c=>"field C"}).should == expected_table
318
+ end
319
+
320
+ it "headers option and headers shortened by max_fields renders" do
321
+ expected_table = <<-TABLE.unindent
322
+ +-------+---+
323
+ | fi... | b |
324
+ +-------+---+
325
+ | A | 2 |
326
+ +-------+---+
327
+ 1 row in set
328
+ TABLE
329
+ table([{:a=> "A", :b=>2}], :headers=>{:a=>"field A"}, :max_fields=>{:a=>5}, :resize=>false).should == expected_table
330
+ end
331
+
332
+ it "headers option as an array renders" do
333
+ expected_table = <<-TABLE.unindent
334
+ +---+---+
335
+ | A | B |
336
+ +---+---+
337
+ | 1 | 2 |
338
+ | 3 | 4 |
339
+ +---+---+
340
+ 2 rows in set
341
+ TABLE
342
+ table([[1,2], [3,4]], :headers=>['A', 'B']).should == expected_table
343
+ end
344
+
345
+ it "header_filter option renders" do
346
+ expected_table = <<-TABLE.unindent
347
+ +---+---+
348
+ | A | B |
349
+ +---+---+
350
+ | 2 | 3 |
351
+ +---+---+
352
+ 1 row in set
353
+ TABLE
354
+ table([{:a=> 2, :b=>3}], :header_filter=>:capitalize).should == expected_table
355
+ end
356
+
357
+ it "filters option renders" do
358
+ expected_table = <<-TABLE.unindent
359
+ +-----------+---+
360
+ | 0 | 1 |
361
+ +-----------+---+
362
+ | s,o,m,e | 2 |
363
+ | t,h,i,n,g | 1 |
364
+ +-----------+---+
365
+ 2 rows in set
366
+ TABLE
367
+ table([['some', {:num=>2}], ['thing', {:num=>1}]], :filters=>{0=>lambda {|e| e.split("").join(",")},
368
+ 1=>[:[], :num]}).should == expected_table
369
+ end
370
+
371
+ it "filters option calls Filters method and renders" do
372
+ module ::Hirb::Helpers::Table::Filters
373
+ def semicolon_join(arr); arr.join('; '); end
374
+ end
375
+
376
+ expected_table = <<-TABLE.unindent
377
+ +------+------------------------------+
378
+ | 0 | 1 |
379
+ +------+------------------------------+
380
+ | some | unsightly; unreadable; array |
381
+ +------+------------------------------+
382
+ 1 row in set
383
+ TABLE
384
+ table([[['some'], %w{unsightly unreadable array}]], :filters=>{1=>:semicolon_join}).should == expected_table
385
+ end
386
+
387
+ it "number option renders" do
388
+ expected_table = <<-TABLE.unindent
389
+ +--------+---+---+
390
+ | number | 0 | 1 |
391
+ +--------+---+---+
392
+ | 1 | a | b |
393
+ | 2 | c | d |
394
+ +--------+---+---+
395
+ 2 rows in set
396
+ TABLE
397
+ table([['a','b'], ['c', 'd']], :number=>true).should == expected_table
398
+ end
399
+
400
+ it "number option renders with header that can be overridden" do
401
+ expected_table = <<-TABLE.unindent
402
+ +----+---+---+
403
+ | SR | 0 | 1 |
404
+ +----+---+---+
405
+ | 1 | a | b |
406
+ | 2 | c | d |
407
+ +----+---+---+
408
+ 2 rows in set
409
+ TABLE
410
+ table([['a','b'], ['c', 'd']], :number=>true, :headers => {:hirb_number => "SR"}).should == expected_table
411
+ end
412
+
413
+ it "description option false renders" do
414
+ expected_table = <<-TABLE.unindent
415
+ +---+---+
416
+ | 0 | 1 |
417
+ +---+---+
418
+ | a | b |
419
+ | c | d |
420
+ +---+---+
421
+ TABLE
422
+ table([['a','b'], ['c', 'd']], :description=>false).should == expected_table
423
+ end
424
+
425
+ it "vertical option renders vertical table" do
426
+ expected_table = <<-TABLE.unindent
427
+ *** 1. row ***
428
+ a: 1
429
+ b: 2
430
+ *** 2. row ***
431
+ a: 3
432
+ b: 4
433
+ 2 rows in set
434
+ TABLE
435
+ table([{:a=>1, :b=>2}, {:a=>3, :b=>4}], :vertical=>true).should == expected_table
436
+ end
437
+
438
+ it "vertical option renders vertical table with newlines" do
439
+ expected_table = <<-TABLE.unindent
440
+ *** 1. row ***
441
+ a: 1
442
+ b: 2
443
+ *** 2. row ***
444
+ a: 3
445
+ b: 4
446
+ and one
447
+ 2 rows in set
448
+ TABLE
449
+ table([{:a=>1, :b=>2}, {:a=>3, :b=>"4\nand one"}], :vertical=>true).should == expected_table
450
+ end
451
+
452
+ it "vertical option renders vertical table successively" do
453
+ expected_table = <<-TABLE.unindent
454
+ *** 1. row ***
455
+ a: 1
456
+ b: 2
457
+ *** 2. row ***
458
+ a: 3
459
+ b: 4
460
+ 2 rows in set
461
+ TABLE
462
+ options = {:vertical=>true}
463
+ table([{:a=>1, :b=>2}, {:a=>3, :b=>4}], options).should == expected_table
464
+ table([{:a=>1, :b=>2}, {:a=>3, :b=>4}], options).should == expected_table
465
+ end
466
+
467
+ it "hide_empty and vertical options renders" do
468
+ expected_table = <<-TABLE.unindent
469
+ *** 1. row ***
470
+ b: 2
471
+ *** 2. row ***
472
+ a: 3
473
+ 2 rows in set
474
+ TABLE
475
+ table([{:a=>'', :b=>2}, {:a=>3, :b=>nil}], :hide_empty=>true, :vertical=>true).should == expected_table
476
+ end
477
+
478
+ it "unicode option renders" do
479
+ expected_table = <<-TABLE.unindent
480
+ ┌───┬───┐
481
+ │ a │ b │
482
+ ├───┼───┤
483
+ │ 1 ╎ 2 │
484
+ │ 3 ╎ 4 │
485
+ └───┴───┘
486
+ 2 rows in set
487
+ TABLE
488
+ table([{:a=>1, :b=>2}, {:a=>3, :b=>4}], :unicode => true).should == expected_table
489
+ end
490
+
491
+ it "tab option renders" do
492
+ expected_table = <<-TABLE.unindent
493
+ a b
494
+ 1 2
495
+ 3 4
496
+ TABLE
497
+ table([{:a=>1, :b=>2}, {:a=>3, :b=>4}], :tab => true).should == expected_table
498
+ end
499
+
500
+ it "tab option with no headers renders" do
501
+ expected_table = <<-TABLE.unindent
502
+ 1 2
503
+ 3 4
504
+ TABLE
505
+ table([{:a=>1, :b=>2}, {:a=>3, :b=>4}], :tab => true, :headers => false).
506
+ should == expected_table
507
+ end
508
+
509
+ it "all_fields option renders all fields" do
510
+ expected_table = <<-TABLE.unindent
511
+ +---+---+---+
512
+ | a | b | c |
513
+ +---+---+---+
514
+ | 1 | 2 | |
515
+ | 3 | | 4 |
516
+ +---+---+---+
517
+ 2 rows in set
518
+ TABLE
519
+ table([{:a=>1, :b=>2}, {:a=>3, :c=>4}], :all_fields=>true).should == expected_table
520
+ end
521
+
522
+ it "change_fields option renders" do
523
+ expected_table = <<-TABLE.unindent
524
+ +------+-------+
525
+ | name | value |
526
+ +------+-------+
527
+ | 1 | 2 |
528
+ | 2 | 3 |
529
+ +------+-------+
530
+ 2 rows in set
531
+ TABLE
532
+ table([[1,2],[2,3]], :change_fields=>{0=>'name', 1=>'value'}).should == expected_table
533
+ table([[1,2],[2,3]], :change_fields=>['name', 'value']).should == expected_table
534
+ end
535
+
536
+ it "change_fields and fields option renders" do
537
+ expected_table = <<-TABLE.unindent
538
+ +------+
539
+ | name |
540
+ +------+
541
+ | 1 |
542
+ | 2 |
543
+ +------+
544
+ 2 rows in set
545
+ TABLE
546
+ table([[1,2],[2,3]], :change_fields=>['name', 'value'], :fields=>['name']).should == expected_table
547
+ end
548
+
549
+ it "invalid fields in change_fields options are ignored" do
550
+ expected_table = <<-TABLE.unindent
551
+ +------+-------+
552
+ | name | value |
553
+ +------+-------+
554
+ | 1 | 2 |
555
+ | 2 | 3 |
556
+ +------+-------+
557
+ 2 rows in set
558
+ TABLE
559
+ table([{:a=>1,:b=>2}, {:a=>2,:b=>3}], :change_fields=>{:a=>'name', :b=>'value', :c=>'time'}).should == expected_table
560
+ table([[1,2],[2,3]], :change_fields=>['name', 'value','time']).should == expected_table
561
+ end
562
+
563
+ it "filter_any option filters any value" do
564
+ expected_table = <<-TABLE.unindent
565
+ +---------+
566
+ | a |
567
+ +---------+
568
+ | {:b=>1} |
569
+ | 2 |
570
+ +---------+
571
+ 2 rows in set
572
+ TABLE
573
+ table([{:a=>{:b=>1}}, {:a=>2}], :filter_any=>true).should == expected_table
574
+ end
575
+
576
+ it "filter_classes option overrides class-wide filter_classes" do
577
+ expected_table = <<-TABLE.unindent
578
+ +---+
579
+ | a |
580
+ +---+
581
+ | 1 |
582
+ +---+
583
+ 1 row in set
584
+ TABLE
585
+ table([{:a=>{:b=>1}}], :filter_classes=>{Hash=>:size}).should == expected_table
586
+ end
587
+ end
588
+
589
+ describe "table with callbacks" do
590
+ before_all {
591
+ Helpers::Table.send(:define_method, :and_one_callback) do |obj, opt|
592
+ obj.each {|row| row.each {|k,v| row[k] += opt[:add] } }
593
+ obj
594
+ end
595
+ }
596
+ it "detects and runs them" do
597
+ expected_table = <<-TABLE.unindent
598
+ +---+---+
599
+ | a | b |
600
+ +---+---+
601
+ | 2 | 3 |
602
+ | 4 | 5 |
603
+ +---+---+
604
+ 2 rows in set
605
+ TABLE
606
+ table([{'a'=>1, 'b'=>2}, {'a'=>3, 'b'=>4}], :add=>1).should == expected_table
607
+ end
608
+
609
+ it "doesn't run callbacks in delete_callbacks option" do
610
+ Helpers::Table.send(:define_method, :and_two_callback) do |obj, opt|
611
+ obj.each {|row| row.each {|k,v| row[k] = row[k] * 2 } }
612
+ obj
613
+ end
614
+
615
+ expected_table = <<-TABLE.unindent
616
+ +---+---+
617
+ | a | b |
618
+ +---+---+
619
+ | 2 | 3 |
620
+ | 4 | 5 |
621
+ +---+---+
622
+ 2 rows in set
623
+ TABLE
624
+ table([{'a'=>1, 'b'=>2}, {'a'=>3, 'b'=>4}], :add=>1, :delete_callbacks=>[:and_two]).should == expected_table
625
+
626
+ Helpers::Table.send(:remove_method, :and_two_callback)
627
+ end
628
+ after_all { Helpers::Table.send(:remove_method, :and_one_callback) }
629
+ end
630
+ end
@@ -0,0 +1,61 @@
1
+ require 'bacon'
2
+ require 'bacon/bits'
3
+ require 'mocha'
4
+ require 'mocha-on-bacon'
5
+ require 'hirb'
6
+ include Hirb
7
+
8
+ module TestHelpers
9
+ # set these to avoid invoking stty multiple times which doubles test suite running time
10
+ ENV["LINES"] = ENV["COLUMNS"] = "20"
11
+ def reset_terminal_size
12
+ ENV["LINES"] = ENV["COLUMNS"] = "20"
13
+ end
14
+
15
+ def capture_stdout(&block)
16
+ original_stdout = $stdout
17
+ $stdout = fake = StringIO.new
18
+ begin
19
+ yield
20
+ ensure
21
+ $stdout = original_stdout
22
+ end
23
+ fake.string
24
+ end
25
+
26
+ def capture_stderr(&block)
27
+ original_stderr = $stderr
28
+ $stderr = fake = StringIO.new
29
+ begin
30
+ yield
31
+ ensure
32
+ $stderr = original_stderr
33
+ end
34
+ fake.string
35
+ end
36
+
37
+ def reset_config
38
+ View.instance_eval "@config = nil"
39
+ end
40
+ end
41
+
42
+ class Bacon::Context
43
+ include TestHelpers
44
+ end
45
+
46
+ class String
47
+ def unindent(num=nil)
48
+ regex = num ? /^\s{#{num}}/ : /^\s*/
49
+ gsub(regex, '').chomp
50
+ end
51
+ end
52
+
53
+ # mocks IRB for View + Pager
54
+ module ::IRB
55
+ class Irb
56
+ def initialize(context)
57
+ @context = context
58
+ end
59
+ def output_value; end
60
+ end
61
+ end