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