table_print 0.2.3 → 1.0.0.rc3
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.
- data/.rspec +1 -0
- data/.rvmrc +1 -1
- data/.travis.yml +5 -0
- data/Gemfile +11 -10
- data/README.rdoc +85 -32
- data/Rakefile +13 -13
- data/VERSION +1 -1
- data/features/adding_columns.feature +48 -0
- data/features/configuring_output.feature +57 -0
- data/features/excluding_columns.feature +28 -0
- data/features/sensible_defaults.feature +86 -0
- data/features/support/step_definitions/before.rb +3 -0
- data/features/support/step_definitions/steps.rb +77 -0
- data/lib/cattr.rb +46 -0
- data/lib/column.rb +45 -0
- data/lib/config.rb +36 -0
- data/lib/config_resolver.rb +91 -0
- data/lib/fingerprinter.rb +85 -0
- data/lib/formatter.rb +45 -0
- data/lib/hash_extensions.rb +37 -0
- data/lib/kernel_extensions.rb +12 -0
- data/lib/printable.rb +22 -0
- data/lib/returnable.rb +21 -0
- data/lib/row_group.rb +227 -0
- data/lib/table_print.rb +33 -389
- data/spec/column_spec.rb +71 -0
- data/spec/config_resolver_spec.rb +236 -0
- data/spec/config_spec.rb +52 -0
- data/spec/fingerprinter_spec.rb +151 -0
- data/spec/formatter_spec.rb +78 -0
- data/spec/hash_extensions_spec.rb +21 -0
- data/spec/printable_spec.rb +51 -0
- data/spec/returnable_spec.rb +23 -0
- data/spec/row_group_spec.rb +466 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/table_print_spec.rb +59 -0
- data/table_print.gemspec +50 -26
- metadata +147 -68
- data/Gemfile.lock +0 -20
- data/test/helper.rb +0 -56
- data/test/test_column.rb +0 -379
- data/test/test_table_print.rb +0 -162
data/test/helper.rb
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'bundler'
|
3
|
-
begin
|
4
|
-
Bundler.setup(:default, :development)
|
5
|
-
rescue Bundler::BundlerError => e
|
6
|
-
$stderr.puts e.message
|
7
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
-
exit e.status_code
|
9
|
-
end
|
10
|
-
require 'test/unit'
|
11
|
-
require 'shoulda'
|
12
|
-
|
13
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
-
require 'table_print'
|
16
|
-
|
17
|
-
class Test::Unit::TestCase
|
18
|
-
end
|
19
|
-
|
20
|
-
class MyNestedClass
|
21
|
-
attr_accessor :title, :name, :summary, :captions
|
22
|
-
|
23
|
-
def initialize(title, name, summary, captions)
|
24
|
-
self.title = title
|
25
|
-
self.name = name
|
26
|
-
self.summary = summary
|
27
|
-
self.captions = captions.collect{|c| Caption.new(c[:text], c[:photo_url])}
|
28
|
-
end
|
29
|
-
|
30
|
-
class Caption
|
31
|
-
attr_accessor :text, :photo_url
|
32
|
-
|
33
|
-
def initialize(text, photo_url)
|
34
|
-
self.text = text
|
35
|
-
self.photo_url = photo_url
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.setup
|
40
|
-
[["how to", "bert", "bertto", [{:text => "no, really, how to", :photo_url => "http://www.123.com/456.jpg"}]],
|
41
|
-
["enemies", "ernie", "ernieenemies", [{:text => "no, really, enemies", :photo_url => "http://www.234.com/567.jpg"}]],
|
42
|
-
["a walk to forget", "big bird", "bigbirdforget", [{:text => "no, really, a walk to forget", :photo_url => "http://www.345.com/678.jpg"}]],
|
43
|
-
["cookies", "cookie monster", "cookiemonstercookies", [{:text => "no, really, cookies", :photo_url => "http://www.456.com/789.jpg"}]],
|
44
|
-
["your mom", "the count", "thecountmom", [{:text => "no, really, your mom", :photo_url => "http://www.789.com/1011.jpg"}]],
|
45
|
-
["fire!", "elmo", "elmofire!", [{:text => "no, really, fire!", :photo_url => "http://www.8910.com/1112.jpg"}]],
|
46
|
-
["eat your veggies", "michelle obama", "michelleobamaveggies", [{:text => "no, really, eat your veggies", :photo_url => "http://www.91011.com/1213.jpg"}]],
|
47
|
-
["wakka wakka", "ellen degeneres", "ellendegenereswakka", [{:text => "no, really, wakka wakka", :photo_url => "http://www.101112.com/1314.jpg"}]],
|
48
|
-
["peas and carrots", "the hulk", "thehulkcarrots", [{:text => "no, really, peas and carrots", :photo_url => "http://www.abc.com/def.jpg"}]],
|
49
|
-
["juan valdez", "camaro", "camaravaldez", [{:text => "no, really, juan valdez", :photo_url => "http://www.bcd.com/efg.jpg"}]],
|
50
|
-
["fish fish fish", "alaska", "alaskafish", [{:text => "no, really, fish fish fish", :photo_url => "http://www.cde.com/fgh.jpg"}]],
|
51
|
-
["tracks", "sir toppem hat", "sirtoppemhattracks", [{:text => "no, really, tracks", :photo_url => "http://www.def.com/ghi.jpg"}]],
|
52
|
-
["smoking stacked", "thomas", "thomasstacked", [{:text => "no, really, smoking stacked", :photo_url => "http://www.efg.com/hij.jpg"}]],
|
53
|
-
["cannes", "alpo", "alpocannes", [{:text => "no, really, cannes", :photo_url => "http://www.fgh.com/ijk.jpg"}]],
|
54
|
-
].collect { |a| MyNestedClass.new(a[0], a[1], a[2], a[3]) }
|
55
|
-
end
|
56
|
-
end
|
data/test/test_column.rb
DELETED
@@ -1,379 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class TablePrint
|
4
|
-
class ColumnHelper
|
5
|
-
def _truncate(field_value)
|
6
|
-
truncate(field_value)
|
7
|
-
end
|
8
|
-
|
9
|
-
def _get_current_method(method_chain)
|
10
|
-
get_current_method(method_chain)
|
11
|
-
end
|
12
|
-
|
13
|
-
def _add_to_stack?(method_chain, method_hash)
|
14
|
-
add_to_stack?(method_chain, method_hash)
|
15
|
-
end
|
16
|
-
|
17
|
-
def _formatted_cell_value(data_obj, method_chain)
|
18
|
-
formatted_cell_value(data_obj, method_chain)
|
19
|
-
end
|
20
|
-
|
21
|
-
def _find_data_length(data, method_chain, start)
|
22
|
-
find_data_length(data, method_chain, start)
|
23
|
-
end
|
24
|
-
|
25
|
-
def _add_stack_objects(stack, data_obj, method_chain, start)
|
26
|
-
add_stack_objects(stack, data_obj, method_chain, start)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
class TestTablePrint < Test::Unit::TestCase
|
32
|
-
|
33
|
-
# TODO: active record tests if defined?(ActiveRecord)
|
34
|
-
|
35
|
-
# Ordered to match method order in the Column class
|
36
|
-
|
37
|
-
# attr_accessor :field_length, :max_field_length, :method, :name, :options
|
38
|
-
context 'A column object' do
|
39
|
-
setup do
|
40
|
-
@column = TablePrint::ColumnHelper.new([], "to_s")
|
41
|
-
@column.field_length = 0
|
42
|
-
@column.max_field_length = 0
|
43
|
-
@column.method = 0
|
44
|
-
@column.name = 0
|
45
|
-
@column.options = 0
|
46
|
-
end
|
47
|
-
should 'allow writes to and reads from its attributes' do
|
48
|
-
assert_equal 0, @column.field_length
|
49
|
-
assert_equal 0, @column.max_field_length
|
50
|
-
assert_equal 0, @column.method
|
51
|
-
assert_equal 0, @column.name
|
52
|
-
assert_equal 0, @column.options
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# def initialize(data, method, options = {})
|
57
|
-
context 'Instantiating a Column' do
|
58
|
-
context 'with a display_method' do
|
59
|
-
setup do
|
60
|
-
@column = TablePrint::ColumnHelper.new([], "to_s")
|
61
|
-
end
|
62
|
-
should 'remember the display method' do
|
63
|
-
assert_equal "to_s", @column.method
|
64
|
-
end
|
65
|
-
should 'set the name' do
|
66
|
-
assert_equal "to s", @column.name
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
context 'with options including' do
|
71
|
-
context 'name' do
|
72
|
-
setup do
|
73
|
-
@column = TablePrint::ColumnHelper.new([], "first", {:name => "test_tube"})
|
74
|
-
end
|
75
|
-
|
76
|
-
should 'set the name according to the options' do
|
77
|
-
assert_equal "test_tube", @column.name
|
78
|
-
end
|
79
|
-
|
80
|
-
context 'when the method name contains dots' do
|
81
|
-
setup do
|
82
|
-
@column = TablePrint::ColumnHelper.new(["short"], "method1.method2", {:name => "test_tube"})
|
83
|
-
end
|
84
|
-
should 'use the option' do
|
85
|
-
assert_equal "TEST_TUBE", @column.formatted_header
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
context 'a field_length' do
|
91
|
-
context 'that is valid' do
|
92
|
-
setup do
|
93
|
-
@column = TablePrint::ColumnHelper.new(["short"], "first", {:field_length => 20})
|
94
|
-
end
|
95
|
-
|
96
|
-
should 'set the field length according to the options' do
|
97
|
-
assert_equal 20, @column.field_length
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
context 'that is less than 1' do
|
102
|
-
setup do
|
103
|
-
@column = TablePrint::ColumnHelper.new(["short"], "first", {:field_length => 0})
|
104
|
-
end
|
105
|
-
|
106
|
-
should 'ignore the field_length' do
|
107
|
-
assert_equal 5, @column.field_length
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
context 'that is bigger than the max' do
|
112
|
-
setup do
|
113
|
-
@column = TablePrint::ColumnHelper.new(["short"], "first", {:field_length => 20, :max_field_length => 10})
|
114
|
-
end
|
115
|
-
|
116
|
-
should 'respect the max_field_length' do
|
117
|
-
assert_equal 10, @column.field_length
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
# def formatted_header
|
125
|
-
context 'The formatted header function' do
|
126
|
-
context 'when the method name contains no special characters and is shorter than the max field length' do
|
127
|
-
setup do
|
128
|
-
@column = TablePrint::ColumnHelper.new(["short"], "first", {:field_length => 10})
|
129
|
-
end
|
130
|
-
should 'uppercase the method name and pad with spaces' do
|
131
|
-
assert_equal "FIRST ", @column.formatted_header
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
context 'when the method name contains no special characters and is longer than the max field length' do
|
136
|
-
setup do
|
137
|
-
@column = TablePrint::ColumnHelper.new(["short"], "longMethodName", {:field_length => 10})
|
138
|
-
end
|
139
|
-
should 'uppercase and truncate the method name' do
|
140
|
-
assert_equal "LONGMET...", @column.formatted_header
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
context 'when the method name contains underscores' do
|
145
|
-
setup do
|
146
|
-
@column = TablePrint::ColumnHelper.new(["short"], "method_name")
|
147
|
-
end
|
148
|
-
should 'replace underscores with spaces' do
|
149
|
-
assert_equal "METHOD NAME", @column.formatted_header
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
context 'when the method name contains dots' do
|
154
|
-
setup do
|
155
|
-
@column = TablePrint::ColumnHelper.new(["short"], "method1.method2")
|
156
|
-
end
|
157
|
-
should 'replace dots with greater-thans' do
|
158
|
-
assert_equal "METHOD1 > METHOD2", @column.formatted_header
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
context 'when the user passes a name in the column options' do
|
163
|
-
setup do
|
164
|
-
@column = TablePrint::ColumnHelper.new(["short"], "method1.method2", {:name => "whoop"})
|
165
|
-
end
|
166
|
-
should 'use that name instead of the method name' do
|
167
|
-
assert_equal "WHOOP", @column.formatted_header
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
# def formatted_cell_value(data_obj, method_chain)
|
173
|
-
context 'The formatted_cell_value method' do
|
174
|
-
should 'return whitespace if the method chain does not exactly match the column definition method' do
|
175
|
-
assert_equal " ", TablePrint::ColumnHelper.new([], "captions.text")._formatted_cell_value("test", "id")
|
176
|
-
assert_equal " ", TablePrint::ColumnHelper.new([], "captions.text")._formatted_cell_value("test", "captions")
|
177
|
-
end
|
178
|
-
|
179
|
-
should 'return whitespace if the method chain begins the ' do
|
180
|
-
assert_equal "no, really, ...", TablePrint::ColumnHelper.new([], "captions.text")._formatted_cell_value(MyNestedClass.setup.first.captions.first, "captions")
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
# def add_stack_objects(stack, data_obj, method_chain, method_hash)
|
185
|
-
context 'The add_stack_objects method' do
|
186
|
-
context 'when objects need to be added to the stack' do
|
187
|
-
setup do
|
188
|
-
@tp = TablePrint::ColumnHelper.new(MyNestedClass.setup, "captions.text")
|
189
|
-
@stack = [1, 2, 3]
|
190
|
-
@tp._add_stack_objects(@stack, MyNestedClass.setup.first, "", {})
|
191
|
-
end
|
192
|
-
should 'increase stack size' do
|
193
|
-
assert_equal 4, @stack.size
|
194
|
-
end
|
195
|
-
should 'push the new objects on the front of the stack' do
|
196
|
-
assert_equal MyNestedClass::Caption, @stack.first.first.class
|
197
|
-
end
|
198
|
-
should 'include the updated method_chain in the stack' do
|
199
|
-
assert_equal "captions", @stack.first.last
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
|
205
|
-
# def add_to_stack?(method_chain, method_hash = {})
|
206
|
-
context 'The add_to_stack? method' do
|
207
|
-
should 'appropriately respond to its arguments' do
|
208
|
-
|
209
|
-
# our first method produces an array, so yes, stack 'em up
|
210
|
-
assert TablePrint::ColumnHelper.new(MyNestedClass.setup, "captions.text")._add_to_stack?("", {})
|
211
|
-
|
212
|
-
# captions has already been called, so it gets popped off our method chain. text is the final method, so no, don't stack
|
213
|
-
assert !TablePrint::ColumnHelper.new(MyNestedClass.setup, "captions.text")._add_to_stack?("captions", {})
|
214
|
-
|
215
|
-
# the method isn't one of ours, so there's nothing for us to do
|
216
|
-
assert !TablePrint::ColumnHelper.new(MyNestedClass.setup, "captions.text")._add_to_stack?("id", {})
|
217
|
-
|
218
|
-
# another column has already added the captions to the stack, so there's no need for us to do it
|
219
|
-
assert !TablePrint::ColumnHelper.new(MyNestedClass.setup, "captions.text")._add_to_stack?("", {"captions" => {}})
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
# def wrap(object)
|
224
|
-
|
225
|
-
# def truncate(field_value)
|
226
|
-
context 'The truncate function' do
|
227
|
-
should 'let short strings pass through' do
|
228
|
-
assert_equal "asdf", TablePrint::ColumnHelper.new(["a long long long string"], "first")._truncate("asdf")
|
229
|
-
end
|
230
|
-
|
231
|
-
should 'truncate long strings with ellipses' do
|
232
|
-
# have to put long data in the data set to field_length is pushed out to the default max_field_length
|
233
|
-
assert_equal "123456789012345678901234567...", TablePrint::ColumnHelper.new([["1234567890123456789012345678901234567890"]], "first")._truncate("1234567890123456789012345678901234567890")
|
234
|
-
end
|
235
|
-
|
236
|
-
context 'with a non-default field length' do
|
237
|
-
should 'truncate long strings with ellipses' do
|
238
|
-
tp = TablePrint::ColumnHelper.new([], "")
|
239
|
-
tp.field_length = 10
|
240
|
-
assert_equal "1234567...", tp._truncate("1234567890123456789012345678901234567890")
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
context 'when the max length is tiny' do
|
245
|
-
should 'truncate long strings without ellipses' do
|
246
|
-
assert_equal "123456789012345678901234567...", TablePrint::ColumnHelper.new([["1234567890123456789012345678901234567890"]], "first", :field_length => -10)._truncate("1234567890123456789012345678901234567890")
|
247
|
-
assert_equal "123456789012345678901234567...", TablePrint::ColumnHelper.new([["1234567890123456789012345678901234567890"]], "first", :field_length => 0)._truncate("1234567890123456789012345678901234567890")
|
248
|
-
assert_equal "1", TablePrint::ColumnHelper.new([], "", :field_length => 1)._truncate("1234567890123456789012345678901234567890")
|
249
|
-
assert_equal "12", TablePrint::ColumnHelper.new([], "", :field_length => 2)._truncate("1234567890123456789012345678901234567890")
|
250
|
-
assert_equal "123", TablePrint::ColumnHelper.new([], "", :field_length => 3)._truncate("1234567890123456789012345678901234567890")
|
251
|
-
assert_equal "1...", TablePrint::ColumnHelper.new([], "", :field_length => 4)._truncate("1234567890123456789012345678901234567890")
|
252
|
-
end
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
# def initialize_field_length(data)
|
257
|
-
context 'The field length function' do
|
258
|
-
should 'honor the field_length options' do
|
259
|
-
assert_equal 5, TablePrint::ColumnHelper.new(["hello there madam"], "to_s", :field_length => 5).field_length
|
260
|
-
assert_equal 30, TablePrint::ColumnHelper.new(["hello there madam"], "to_s", :field_length => 5).max_field_length
|
261
|
-
end
|
262
|
-
|
263
|
-
should 'honor the max_length option' do
|
264
|
-
assert_equal 5, TablePrint::ColumnHelper.new(["hello there madam"], "to_s", :max_field_length => 5).field_length
|
265
|
-
assert_equal 5, TablePrint::ColumnHelper.new(["hello there madam"], "to_s", :max_field_length => 5).max_field_length
|
266
|
-
end
|
267
|
-
|
268
|
-
should 'honor the max_length option over the field_length option' do
|
269
|
-
assert_equal 5, TablePrint::ColumnHelper.new(["hello there madam"], "to_s", :max_field_length => 5, :field_length => 10).field_length
|
270
|
-
assert_equal 5, TablePrint::ColumnHelper.new(["hello there madam"], "to_s", :max_field_length => 5, :field_length => 10).max_field_length
|
271
|
-
end
|
272
|
-
|
273
|
-
should 'find the maximum width of the data' do
|
274
|
-
assert_equal 11, TablePrint::ColumnHelper.new(["hello there"], "to_s").field_length
|
275
|
-
end
|
276
|
-
|
277
|
-
context 'when the data is longer than the max_field_length' do
|
278
|
-
should 'equal the max field length' do
|
279
|
-
assert_equal 5, TablePrint::ColumnHelper.new(["hello there"], "to_s", :max_field_length => 5).field_length
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
context 'when the column name is longer than the data' do
|
284
|
-
should 'reflect the column name length' do
|
285
|
-
assert_equal 4, TablePrint::ColumnHelper.new(["he"], "to_s", :max_field_length => 5).field_length
|
286
|
-
assert_equal 12, TablePrint::ColumnHelper.new(["hello"], "to_s", :name => "foobar THIS!").field_length
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
context 'when the method is recursive' do
|
291
|
-
should 'find the maximum width of the data' do
|
292
|
-
assert_equal 30, TablePrint::ColumnHelper.new(MyNestedClass.setup, "captions.photo_url", :max_field_length => 50).field_length
|
293
|
-
end
|
294
|
-
end
|
295
|
-
end
|
296
|
-
|
297
|
-
# def find_data_length(data, method, start)
|
298
|
-
context 'The find_data_length method' do
|
299
|
-
context 'when method_chain is a top level method' do
|
300
|
-
setup do
|
301
|
-
@tp = TablePrint::ColumnHelper.new([], "")
|
302
|
-
@tp._find_data_length(MyNestedClass.setup, "title", Time.now)
|
303
|
-
end
|
304
|
-
should 'set field_length to the longest value in the data set' do
|
305
|
-
assert_equal 16, @tp.field_length
|
306
|
-
end
|
307
|
-
end
|
308
|
-
|
309
|
-
context 'when method_chain is not a top level method' do
|
310
|
-
setup do
|
311
|
-
@tp = TablePrint::ColumnHelper.new([], "")
|
312
|
-
@tp._find_data_length(MyNestedClass.setup, "captions.text", Time.now)
|
313
|
-
end
|
314
|
-
should 'set field_length to the longest value in the data set' do
|
315
|
-
assert_equal 28, @tp.field_length
|
316
|
-
end
|
317
|
-
end
|
318
|
-
|
319
|
-
context 'when the data value is longer than max_field_length' do
|
320
|
-
setup do
|
321
|
-
@tp = TablePrint::ColumnHelper.new([], "", :max_field_length => 10)
|
322
|
-
@tp._find_data_length(MyNestedClass.setup, "captions.photo_url", Time.now)
|
323
|
-
end
|
324
|
-
should 'ignore max_field_length (initialize_field_length handles that - this method is just about the data)' do
|
325
|
-
assert_equal 26, @tp.field_length
|
326
|
-
end
|
327
|
-
end
|
328
|
-
end
|
329
|
-
|
330
|
-
# def get_current_method(method_chain)
|
331
|
-
context 'get_current_method' do
|
332
|
-
context 'with a simple method signature' do
|
333
|
-
context 'and no method chain' do
|
334
|
-
should 'return the method itself' do
|
335
|
-
assert_equal "m1", TablePrint::ColumnHelper.new(MyNestedClass.setup, "m1")._get_current_method("")
|
336
|
-
end
|
337
|
-
end
|
338
|
-
context 'and a method chain that does not match' do
|
339
|
-
should 'return nil' do
|
340
|
-
assert_equal nil, TablePrint::ColumnHelper.new(MyNestedClass.setup, "m1")._get_current_method("m2")
|
341
|
-
end
|
342
|
-
end
|
343
|
-
context 'and an overly long method chain' do
|
344
|
-
should 'return nil' do
|
345
|
-
assert_equal nil, TablePrint::ColumnHelper.new(MyNestedClass.setup, "m1")._get_current_method("m1.m2")
|
346
|
-
end
|
347
|
-
end
|
348
|
-
end
|
349
|
-
|
350
|
-
context 'with a compound method signature' do
|
351
|
-
context 'and no method chain' do
|
352
|
-
should 'return the first method in the chain' do
|
353
|
-
assert_equal "m1", TablePrint::ColumnHelper.new(MyNestedClass.setup, "m1.m2.m3")._get_current_method("")
|
354
|
-
end
|
355
|
-
end
|
356
|
-
context 'and a method chain that does not match' do
|
357
|
-
should 'return nil' do
|
358
|
-
assert_equal nil, TablePrint::ColumnHelper.new(MyNestedClass.setup, "m1.m2.m3")._get_current_method("m2")
|
359
|
-
end
|
360
|
-
end
|
361
|
-
context 'and a valid method chain' do
|
362
|
-
should 'return the next method in the chain' do
|
363
|
-
assert_equal "m2", TablePrint::ColumnHelper.new(MyNestedClass.setup, "m1.m2.m3")._get_current_method("m1")
|
364
|
-
assert_equal "m3", TablePrint::ColumnHelper.new(MyNestedClass.setup, "m1.m2.m3")._get_current_method("m1.m2")
|
365
|
-
end
|
366
|
-
end
|
367
|
-
context 'and an overly long method chain' do
|
368
|
-
should 'return nil' do
|
369
|
-
assert_equal nil, TablePrint::ColumnHelper.new(MyNestedClass.setup, "m1.m2.m3")._get_current_method("m1.m2.m3.m4")
|
370
|
-
end
|
371
|
-
end
|
372
|
-
context 'and a method chain matching our method signature' do
|
373
|
-
should 'return nil' do
|
374
|
-
assert_equal nil, TablePrint::ColumnHelper.new(MyNestedClass.setup, "m1.m2.m3")._get_current_method("m1.m2.m3")
|
375
|
-
end
|
376
|
-
end
|
377
|
-
end
|
378
|
-
end
|
379
|
-
end
|
data/test/test_table_print.rb
DELETED
@@ -1,162 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class MyClass
|
4
|
-
attr_accessor :title, :name, :summary
|
5
|
-
|
6
|
-
def initialize(title, name, summary)
|
7
|
-
self.title = title
|
8
|
-
self.name = name
|
9
|
-
self.summary = summary
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.setup
|
13
|
-
[["how to", "bert", "bertto"],
|
14
|
-
["enemies", "ernie", "ernieenemies"],
|
15
|
-
["a walk to forget", "big bird", "bigbirdforget"],
|
16
|
-
["cookies", "cookie monster", "cookiemonstercookies"],
|
17
|
-
["your mom", "the count", "thecountmom"],
|
18
|
-
["fire!", "elmo", "elmofire!"],
|
19
|
-
["eat your veggies", "michelle obama", "michelleobamaveggies"],
|
20
|
-
["wakka wakka", "ellen degeneres", "ellendegenereswakka"],
|
21
|
-
["peas and carrots", "the hulk", "thehulkcarrots"],
|
22
|
-
["juan valdez", "camaro", "camaravaldez"],
|
23
|
-
["fish fish fish", "alaska", "alaskafish"],
|
24
|
-
["tracks", "sir toppem hat", "sirtoppemhattracks"],
|
25
|
-
["smoking stacked", "thomas", "thomasstacked"],
|
26
|
-
["cannes", "alpo", "alpocannes"],
|
27
|
-
].collect { |a| MyClass.new(a[0], a[1], a[2]) }
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
class TablePrint
|
33
|
-
def _get_display_methods(data_obj, options)
|
34
|
-
get_display_methods(data_obj, options)
|
35
|
-
end
|
36
|
-
|
37
|
-
def _get_default_display_methods(data_obj)
|
38
|
-
get_default_display_methods(data_obj)
|
39
|
-
end
|
40
|
-
|
41
|
-
def _sort_display_methods(display_methods)
|
42
|
-
sort_display_methods(display_methods)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
class OneMethod
|
47
|
-
def title
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
class OneAttrAccessor
|
52
|
-
attr_accessor :title
|
53
|
-
end
|
54
|
-
|
55
|
-
class ManyMethods
|
56
|
-
def title
|
57
|
-
end
|
58
|
-
def author
|
59
|
-
end
|
60
|
-
def summary
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
class StringInheritor < String
|
65
|
-
attr_accessor :title
|
66
|
-
end
|
67
|
-
|
68
|
-
class ArrayInheritor < Array
|
69
|
-
attr_accessor :title
|
70
|
-
end
|
71
|
-
|
72
|
-
class HashInheritor < Hash
|
73
|
-
attr_accessor :title
|
74
|
-
end
|
75
|
-
|
76
|
-
class TestTablePrint < Test::Unit::TestCase
|
77
|
-
|
78
|
-
# TODO: active record tests if defined?(ActiveRecord)
|
79
|
-
|
80
|
-
# Vaguely ordered from most to least granular
|
81
|
-
|
82
|
-
context '' do
|
83
|
-
setup do
|
84
|
-
@tp = TablePrint.new
|
85
|
-
end
|
86
|
-
|
87
|
-
context 'The default display methods for ruby base types' do
|
88
|
-
should 'be empty' do
|
89
|
-
#assert_equal [], @tp._get_default_display_methods([])
|
90
|
-
#assert_equal [], @tp._get_default_display_methods("")
|
91
|
-
#assert_equal [], @tp._get_default_display_methods({})
|
92
|
-
#assert_equal [], @tp._get_default_display_methods(10)
|
93
|
-
#assert_equal [], @tp._get_default_display_methods(1.0)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
context 'The default display methods for a custom class with one method' do
|
98
|
-
should 'be that method' do
|
99
|
-
assert_equal ["title"], @tp._get_default_display_methods(OneMethod.new)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
context 'The default display methods for a custom class with one attr_accessor' do
|
104
|
-
should 'only be the attr setter' do
|
105
|
-
assert_equal ["title"], @tp._get_default_display_methods(OneAttrAccessor.new)
|
106
|
-
end
|
107
|
-
|
108
|
-
context 'that subclasses Hash' do
|
109
|
-
should 'only be the attr setter' do
|
110
|
-
assert_equal ["title"], @tp._get_default_display_methods(HashInheritor.new)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
context 'that subclasses Array' do
|
114
|
-
should 'only be the attr setter' do
|
115
|
-
assert_equal ["title"], @tp._get_default_display_methods(ArrayInheritor.new)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
context 'that subclasses String' do
|
119
|
-
should 'only be the attr setter' do
|
120
|
-
assert_equal ["title"], @tp._get_default_display_methods(StringInheritor.new)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
context 'The display methods for a custom class using the :only option' do
|
126
|
-
should 'be an array containing the methods specified in the :only option' do
|
127
|
-
assert_equal ["title"], @tp._get_display_methods(ManyMethods.new, {:only => :title})
|
128
|
-
assert_equal ["title"], @tp._get_display_methods(ManyMethods.new, {:only => "title"})
|
129
|
-
assert_equal ["title"], @tp._get_display_methods(ManyMethods.new, {:only => [:title]})
|
130
|
-
assert_equal ["title"], @tp._get_display_methods(ManyMethods.new, {:only => ["title"]})
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
# The :include option is more for ActiveRecord. It will only affect custom classes once multi-level methods are implemented.
|
135
|
-
context 'The display methods for a custom class using the :include option' do
|
136
|
-
should "be the same as if it weren't used" do
|
137
|
-
assert_equal ["author", "summary", "title"], @tp._get_display_methods(ManyMethods.new, {:include => :title}).sort
|
138
|
-
assert_equal ["author", "summary", "title"], @tp._get_display_methods(ManyMethods.new, {:include => "title"}).sort
|
139
|
-
assert_equal ["author", "summary", "title"], @tp._get_display_methods(ManyMethods.new, {:include => [:title]}).sort
|
140
|
-
assert_equal ["author", "summary", "title"], @tp._get_display_methods(ManyMethods.new, {:include => ["title"]}).sort
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
context 'The display methods for a custom class using the :except option' do
|
145
|
-
should "not include any specified methods" do
|
146
|
-
assert_equal ["author", "summary"], @tp._get_display_methods(ManyMethods.new, {:except => :title}).sort
|
147
|
-
assert_equal ["author", "summary"], @tp._get_display_methods(ManyMethods.new, {:except => "title"}).sort
|
148
|
-
assert_equal ["author", "summary"], @tp._get_display_methods(ManyMethods.new, {:except => [:title]}).sort
|
149
|
-
assert_equal ["summary"], @tp._get_display_methods(ManyMethods.new, {:except => ["title", :author]}).sort
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
context 'An empty input' do
|
154
|
-
should 'say as much in the output' do
|
155
|
-
assert_equal "No data.", @tp.tp(nil)
|
156
|
-
assert_equal "No data.", @tp.tp([])
|
157
|
-
assert_equal "No data.", @tp.tp([nil])
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|