table_print 0.2.3 → 1.0.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
- 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/spec/column_spec.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'column'
|
3
|
+
|
4
|
+
include TablePrint
|
5
|
+
|
6
|
+
describe Column do
|
7
|
+
let(:c) {Column.new(:data => ["Once upon a time", "there was a dark and stormy night"], :name => :tagline)}
|
8
|
+
|
9
|
+
it "remembers its name as a string" do
|
10
|
+
c.name.should == "tagline"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "exposes the array of data representing the column" do
|
14
|
+
c.data.should == ["Once upon a time", "there was a dark and stormy night"]
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#add_formatter" do
|
18
|
+
it "stores the formatter" do
|
19
|
+
f = {}
|
20
|
+
c.add_formatter(f)
|
21
|
+
c.formatters.should == [f]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#formatter=" do
|
26
|
+
it "adds the formatters individually" do
|
27
|
+
c.should_receive(:add_formatter).twice
|
28
|
+
c.formatters = [{}, {}]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#display_method" do
|
33
|
+
it "stores the column's display method as a string" do
|
34
|
+
c = Column.new(:display_method => :boofar)
|
35
|
+
c.display_method.should == "boofar"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "doesn't turn a lambda display method into a string" do
|
39
|
+
lam = lambda{}
|
40
|
+
c = Column.new(:display_method => lam)
|
41
|
+
c.display_method.should == lam
|
42
|
+
end
|
43
|
+
|
44
|
+
it "defaults to the column name" do
|
45
|
+
c = Column.new(:name => :boofar)
|
46
|
+
c.display_method.should == "boofar"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#data_width" do
|
51
|
+
it "reflects the width of the data set" do
|
52
|
+
c.data_width.should == 33
|
53
|
+
end
|
54
|
+
|
55
|
+
it "includes the title in the calculation" do
|
56
|
+
c.name = "a horse is a horse of course of course"
|
57
|
+
c.data_width.should == 38
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#width" do
|
62
|
+
it "returns the specified width" do
|
63
|
+
c.width = 14
|
64
|
+
c.width.should == 14
|
65
|
+
end
|
66
|
+
|
67
|
+
it "uses the data_width if no width has been set" do
|
68
|
+
c.width.should == 33
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,236 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'config_resolver'
|
3
|
+
|
4
|
+
describe TablePrint::ConfigResolver do
|
5
|
+
|
6
|
+
#it "starts with the specified config" do
|
7
|
+
# Sandbox.add_class("Configged")
|
8
|
+
# TablePrint::Config.set(Sandbox::Configged, [:title, :author])
|
9
|
+
# c = TablePrint::ConfigResolver.new(Object, Object, [:name])
|
10
|
+
# c.columns.length.should == 2
|
11
|
+
# c.columns.first.name.should == 'title'
|
12
|
+
# c.columns.last.name.should == 'author'
|
13
|
+
#end
|
14
|
+
|
15
|
+
describe "#get_and_remove" do
|
16
|
+
it "deletes and returns the :except key from an array" do
|
17
|
+
c = TablePrint::ConfigResolver.new(Object, [])
|
18
|
+
options = [:title, :author, {:except => [:title]}]
|
19
|
+
c.get_and_remove(options, :except).should == [:title]
|
20
|
+
options.should == [:title, :author]
|
21
|
+
end
|
22
|
+
|
23
|
+
it "deletes and returns the :except key from an array with an :include key" do
|
24
|
+
c = TablePrint::ConfigResolver.new(Object, [])
|
25
|
+
options = [:title, {:except => [:title]}, {:include => [:author]}]
|
26
|
+
c.get_and_remove(options, :except).should == [:title]
|
27
|
+
options.should == [:title, {:include => [:author]}]
|
28
|
+
end
|
29
|
+
|
30
|
+
it "deletes and returns the :except key from a hash with an :include key" do
|
31
|
+
c = TablePrint::ConfigResolver.new(Object, [])
|
32
|
+
options = [:title, {:except => [:title], :include => [:author]}]
|
33
|
+
c.get_and_remove(options, :except).should == [:title]
|
34
|
+
options.should == [:title, {:include => [:author]}]
|
35
|
+
end
|
36
|
+
|
37
|
+
it "deletes and returns both the :include and :except keys" do
|
38
|
+
c = TablePrint::ConfigResolver.new(Object, [])
|
39
|
+
options = [:title, {:except => [:title]}, {:include => [:author]}]
|
40
|
+
c.get_and_remove(options, :include).should == [:author]
|
41
|
+
c.get_and_remove(options, :except).should == [:title]
|
42
|
+
options.should == [:title]
|
43
|
+
end
|
44
|
+
|
45
|
+
it "works even if the array doesn't have an exception hash" do
|
46
|
+
c = TablePrint::ConfigResolver.new(Object, [])
|
47
|
+
options = [:title, :author]
|
48
|
+
c.get_and_remove(options, :except).should == []
|
49
|
+
options.should == [:title, :author]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe ":only" do
|
54
|
+
context "with a symbol" do
|
55
|
+
it "returns a column named foo" do
|
56
|
+
c = TablePrint::ConfigResolver.new(Object, [:title], :foo)
|
57
|
+
c.columns.length.should == 1
|
58
|
+
c.columns.first.name.should == 'foo'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
context "with a string" do
|
62
|
+
it "returns a column named foo" do
|
63
|
+
c = TablePrint::ConfigResolver.new(Object, [:title], 'foo')
|
64
|
+
c.columns.length.should == 1
|
65
|
+
c.columns.first.name.should == 'foo'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
context "with an array of symbols and strings" do
|
69
|
+
it "returns columns named foo and bar" do
|
70
|
+
c = TablePrint::ConfigResolver.new(Object, [:title], :foo, 'bar')
|
71
|
+
c.columns.length.should == 2
|
72
|
+
c.columns.first.name.should == 'foo'
|
73
|
+
c.columns.last.name.should == 'bar'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe ":include" do
|
79
|
+
context "with a symbol" do
|
80
|
+
it "adds foo to the list of methods" do
|
81
|
+
c = TablePrint::ConfigResolver.new(Object, [:title], :include => :foo)
|
82
|
+
c.columns.length.should == 2
|
83
|
+
c.columns.first.name.should == 'title'
|
84
|
+
c.columns.last.name.should == 'foo'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context "with an array" do
|
89
|
+
it "adds foo and bar to the list of methods" do
|
90
|
+
c = TablePrint::ConfigResolver.new(Object, [:title], :include => [:foo, :bar])
|
91
|
+
c.columns.length.should == 3
|
92
|
+
c.columns.first.name.should == 'title'
|
93
|
+
c.columns.last.name.should == 'bar'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "with options" do
|
98
|
+
it "adds foo to the list of methods and remembers its options" do
|
99
|
+
c = TablePrint::ConfigResolver.new(Object, [:title], :include => {:foo => {:width => 10}})
|
100
|
+
c.columns.length.should == 2
|
101
|
+
c.columns.first.name.should == 'title'
|
102
|
+
|
103
|
+
c.columns.last.name.should == 'foo'
|
104
|
+
c.columns.last.width.should == 10
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe ":except" do
|
110
|
+
context "with a symbol" do
|
111
|
+
it "removes foo from the list of methods" do
|
112
|
+
c = TablePrint::ConfigResolver.new(Object, [:title, :foo], :except => :foo)
|
113
|
+
c.columns.length.should == 1
|
114
|
+
c.columns.first.name.should == 'title'
|
115
|
+
end
|
116
|
+
end
|
117
|
+
context "with an array" do
|
118
|
+
it "removes foo and bar from the list of methods" do
|
119
|
+
c = TablePrint::ConfigResolver.new(Object, [:title, :foo, :bar], :except => [:foo, 'bar'])
|
120
|
+
c.columns.length.should == 1
|
121
|
+
c.columns.first.name.should == 'title'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "lambdas" do
|
127
|
+
it "uses the key as the name and the lambda as the display method" do
|
128
|
+
lam = lambda {}
|
129
|
+
c = TablePrint::ConfigResolver.new(Object, [:title], :foo => {:display_method => lam})
|
130
|
+
c.columns.length.should == 1
|
131
|
+
c.columns.first.name.should == 'foo'
|
132
|
+
c.columns.first.display_method.should == lam
|
133
|
+
end
|
134
|
+
|
135
|
+
context "without the display_method keyword" do
|
136
|
+
it "uses the key as the name and the lambda as the display method" do
|
137
|
+
lam = lambda {}
|
138
|
+
c = TablePrint::ConfigResolver.new(Object, [:title], :foo => lam)
|
139
|
+
c.columns.length.should == 1
|
140
|
+
c.columns.first.name.should == 'foo'
|
141
|
+
c.columns.first.display_method.should == lam
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "#usable_column_names" do
|
147
|
+
it "returns default columns" do
|
148
|
+
c = TablePrint::ConfigResolver.new(Object, [:title])
|
149
|
+
c.usable_column_names.should == ['title']
|
150
|
+
end
|
151
|
+
|
152
|
+
it "returns specified columns instead of default columns" do
|
153
|
+
c = TablePrint::ConfigResolver.new(Object, [:title], [:author])
|
154
|
+
c.usable_column_names.should == ['author']
|
155
|
+
end
|
156
|
+
|
157
|
+
it "applies includes on top of default columns" do
|
158
|
+
c = TablePrint::ConfigResolver.new(Object, [:title], [:include => :author])
|
159
|
+
c.usable_column_names.should == ['title', 'author']
|
160
|
+
end
|
161
|
+
|
162
|
+
it "applies includes on top of specified columns" do
|
163
|
+
c = TablePrint::ConfigResolver.new(Object, [:title], [:author, {:include => :pub_date}])
|
164
|
+
c.usable_column_names.should == ['author', 'pub_date']
|
165
|
+
end
|
166
|
+
|
167
|
+
it "applies excepts on top of default columns" do
|
168
|
+
c = TablePrint::ConfigResolver.new(Object, [:title, :author], [:except => :author])
|
169
|
+
c.usable_column_names.should == ['title']
|
170
|
+
end
|
171
|
+
|
172
|
+
it "applies excepts on top of specified columns" do
|
173
|
+
c = TablePrint::ConfigResolver.new(Object, [:title, :author], [:pub_date, :length, {:except => :length}])
|
174
|
+
c.usable_column_names.should == ['pub_date']
|
175
|
+
end
|
176
|
+
|
177
|
+
it "applies both includes and excepts on top of specified columns" do
|
178
|
+
c = TablePrint::ConfigResolver.new(Object, [:title, :author], [:pub_date, :length, {:except => :length, :include => :foobar}])
|
179
|
+
c.usable_column_names.should == ['pub_date', 'foobar']
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
describe "column options" do
|
184
|
+
context "display_method" do
|
185
|
+
it "sets the display method on the column" do
|
186
|
+
c = TablePrint::ConfigResolver.new(Object, [:title], :title => {:display_method => :boofar})
|
187
|
+
c.columns.length.should == 1
|
188
|
+
c.columns.first.name.should == 'title'
|
189
|
+
c.columns.first.display_method.should == "boofar"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
context "width" do
|
193
|
+
it "sets the width" do
|
194
|
+
c = TablePrint::ConfigResolver.new(Object, [:title], :title => {:width => 100})
|
195
|
+
c.columns.length.should == 1
|
196
|
+
c.columns.first.name.should == 'title'
|
197
|
+
c.columns.first.width.should == 100
|
198
|
+
end
|
199
|
+
end
|
200
|
+
context "formatters" do
|
201
|
+
it "adds the formatters to the column" do
|
202
|
+
f1 = {}
|
203
|
+
f2 = {}
|
204
|
+
c = TablePrint::ConfigResolver.new(Object, [:title], :title => {:formatters => [f1, f2]})
|
205
|
+
c.columns.length.should == 1
|
206
|
+
c.columns.first.name.should == 'title'
|
207
|
+
c.columns.first.formatters.should == [f1, f2]
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
describe "#option_to_column" do
|
213
|
+
context "with a symbol" do
|
214
|
+
it "returns a column named foo" do
|
215
|
+
c = TablePrint::ConfigResolver.new(Object, [])
|
216
|
+
column = c.option_to_column(:foo)
|
217
|
+
column.name.should == 'foo'
|
218
|
+
end
|
219
|
+
end
|
220
|
+
context "with a string" do
|
221
|
+
it "returns a column named foo" do
|
222
|
+
c = TablePrint::ConfigResolver.new(Object, [])
|
223
|
+
column = c.option_to_column('foo')
|
224
|
+
column.name.should == 'foo'
|
225
|
+
end
|
226
|
+
end
|
227
|
+
context "with a hash" do
|
228
|
+
it "returns a column named foo and the specified options" do
|
229
|
+
c = TablePrint::ConfigResolver.new(Object, [])
|
230
|
+
column = c.option_to_column({:foo => {:width => 10}})
|
231
|
+
column.name.should == 'foo'
|
232
|
+
column.width.should == 10
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'config'
|
3
|
+
|
4
|
+
describe TablePrint::Config do
|
5
|
+
it "defaults max_width to 30" do
|
6
|
+
TablePrint::Config.max_width.should == 30
|
7
|
+
end
|
8
|
+
|
9
|
+
it "defaults time_format to year-month-day-hour-minute-second" do
|
10
|
+
TablePrint::Config.time_format.should == "%Y-%m-%d %H:%M:%S"
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "individual config options" do
|
14
|
+
describe "storing and retrieving" do
|
15
|
+
it "sets the variable" do
|
16
|
+
TablePrint::Config.set(:max_width, [10])
|
17
|
+
TablePrint::Config.max_width.should == 10
|
18
|
+
TablePrint::Config.set(:max_width, [30])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "clearing" do
|
23
|
+
it "resets the variable to its initial value" do
|
24
|
+
TablePrint::Config.set(:max_width, [10])
|
25
|
+
TablePrint::Config.clear(:max_width)
|
26
|
+
TablePrint::Config.max_width.should == 30
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "class-based column config" do
|
32
|
+
before :all do
|
33
|
+
Sandbox.add_class("Blog")
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "storing and retrieving" do
|
37
|
+
it "stores the column hash" do
|
38
|
+
TablePrint::Config.set(Sandbox::Blog, [:title, :author])
|
39
|
+
TablePrint::Config.for(Sandbox::Blog).should == [:title, :author]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "clearing" do
|
44
|
+
it "removes the class from storage" do
|
45
|
+
TablePrint::Config.set(Sandbox::Blog, [:title, :author])
|
46
|
+
TablePrint::Config.clear(Sandbox::Blog)
|
47
|
+
TablePrint::Config.for(Sandbox::Blog).should be_nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ostruct'
|
3
|
+
require 'fingerprinter'
|
4
|
+
require 'column'
|
5
|
+
|
6
|
+
class TablePrint::Row
|
7
|
+
attr_accessor :groups, :cells
|
8
|
+
end
|
9
|
+
|
10
|
+
include TablePrint
|
11
|
+
|
12
|
+
describe Fingerprinter do
|
13
|
+
|
14
|
+
before(:each) do
|
15
|
+
Sandbox.cleanup!
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#lift" do
|
19
|
+
it "turns a single level of columns into a single row" do
|
20
|
+
rows = Fingerprinter.new.lift([Column.new(:name => "name")], OpenStruct.new(:name => "dale carnegie"))
|
21
|
+
rows.length.should == 1
|
22
|
+
row = rows.first
|
23
|
+
row.children.length.should == 0
|
24
|
+
row.cells.should == {'name' => "dale carnegie"}
|
25
|
+
end
|
26
|
+
|
27
|
+
it "uses the display_method to get the data" do
|
28
|
+
rows = Fingerprinter.new.lift([Column.new(:name => "name of work", :display_method => "title")], OpenStruct.new(:title => "of mice and men"))
|
29
|
+
rows.length.should == 1
|
30
|
+
row = rows.first
|
31
|
+
row.children.length.should == 0
|
32
|
+
row.cells.should == {'name of work' => "of mice and men"}
|
33
|
+
end
|
34
|
+
|
35
|
+
it "turns multiple levels of columns into multiple rows" do
|
36
|
+
rows = Fingerprinter.new.lift([Column.new(:name => "name"), Column.new(:name => "books.title")], OpenStruct.new(:name => "dale carnegie", :books => [OpenStruct.new(:title => "how to make influences")]))
|
37
|
+
rows.length.should == 1
|
38
|
+
row = rows.first
|
39
|
+
row.children.length.should == 1
|
40
|
+
row.cells.should == {'name' => "dale carnegie"}
|
41
|
+
row.children.first.children.first.cells.should == {'books.title' => "how to make influences"}
|
42
|
+
end
|
43
|
+
|
44
|
+
it "doesn't choke if an association doesn't exist" do
|
45
|
+
rows = Fingerprinter.new.lift([Column.new(:name => "name"), Column.new(:name => "books.title")], OpenStruct.new(:name => "dale carnegie", :books => []))
|
46
|
+
|
47
|
+
rows.length.should == 1
|
48
|
+
|
49
|
+
row = rows.first
|
50
|
+
row.children.length.should == 0
|
51
|
+
end
|
52
|
+
|
53
|
+
it "allows a lambda as the display_method" do
|
54
|
+
rows = Fingerprinter.new.lift([Column.new(:name => "name", :display_method => lambda { |row| row.name.gsub(/[aeiou]/, "") })], OpenStruct.new(:name => "dale carnegie"))
|
55
|
+
rows.length.should == 1
|
56
|
+
row = rows.first
|
57
|
+
row.children.length.should == 0
|
58
|
+
row.cells.should == {'name' => "dl crng"}
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#hash_to_rows" do
|
63
|
+
it "uses hashes with empty values as column names" do
|
64
|
+
f = Fingerprinter.new
|
65
|
+
f.instance_variable_set("@column_names_by_display_method", {"name" => "name"})
|
66
|
+
rows = f.hash_to_rows("", {'name' => {}}, OpenStruct.new(:name => "dale carnegie"))
|
67
|
+
rows.length.should == 1
|
68
|
+
row = rows.first
|
69
|
+
row.children.length.should == 0
|
70
|
+
row.cells.should == {'name' => 'dale carnegie'}
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'recurses for subsequent levels of hash' do
|
74
|
+
f = Fingerprinter.new
|
75
|
+
f.instance_variable_set("@column_names_by_display_method", {"name" => "name", "books.title" => "books.title"})
|
76
|
+
rows = f.hash_to_rows("", {'name' => {}, 'books' => {'title' => {}}}, [OpenStruct.new(:name => 'dale carnegie', :books => [OpenStruct.new(:title => "hallmark")])])
|
77
|
+
rows.length.should == 1
|
78
|
+
|
79
|
+
top_row = rows.first
|
80
|
+
top_row.cells.should == {'name' => 'dale carnegie'}
|
81
|
+
top_row.children.length.should == 1
|
82
|
+
top_row.children.first.child_count.should == 1
|
83
|
+
|
84
|
+
bottom_row = top_row.children.first.children.first
|
85
|
+
bottom_row.cells.should == {'books.title' => 'hallmark'}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#populate_row" do
|
90
|
+
it "fills a row by calling methods on the target object" do
|
91
|
+
f = Fingerprinter.new
|
92
|
+
f.instance_variable_set("@column_names_by_display_method", {"title" => "title", "author" => "author"})
|
93
|
+
row = f.populate_row("", {'title' => {}, 'author' => {}, 'publisher' => {'address' => {}}}, OpenStruct.new(:title => "foobar", :author => "bobby"))
|
94
|
+
row.cells.should == {'title' => "foobar", 'author' => 'bobby'}
|
95
|
+
end
|
96
|
+
|
97
|
+
it "uses the provided prefix to name the cells" do
|
98
|
+
f = Fingerprinter.new
|
99
|
+
f.instance_variable_set("@column_names_by_display_method", {"bar.title" => "bar.title", "bar.author" => "bar.author"})
|
100
|
+
row = f.populate_row("bar", {'title' => {}, 'author' => {}, 'publisher' => {'address' => {}}}, OpenStruct.new(:title => "foobar", :author => "bobby"))
|
101
|
+
row.cells.should == {'bar.title' => "foobar", 'bar.author' => 'bobby'}
|
102
|
+
end
|
103
|
+
|
104
|
+
it "uses the column name as the cell name but uses the display method to get the value" do
|
105
|
+
f = Fingerprinter.new
|
106
|
+
f.instance_variable_set("@column_names_by_display_method", {"bar.title" => "title", "bar.author" => "bar.author"})
|
107
|
+
row = f.populate_row("bar", {'title' => {}, 'author' => {}, 'publisher' => {'address' => {}}}, OpenStruct.new(:title => "foobar", :author => "bobby"))
|
108
|
+
row.cells.should == {'title' => "foobar", 'bar.author' => 'bobby'}
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "#create_child_group" do
|
113
|
+
it "adds the next level of column information to the prefix" do
|
114
|
+
f = Fingerprinter.new
|
115
|
+
books = []
|
116
|
+
|
117
|
+
f.should_receive(:hash_to_rows).with("author.books", {'title' => {}}, books).and_return([])
|
118
|
+
groups = f.create_child_group("author", {'books' => {'title' => {}}}, OpenStruct.new(:name => "bobby", :books => books))
|
119
|
+
groups.length.should == 1
|
120
|
+
groups.first.should be_a TablePrint::RowGroup
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "#columns_to_handle" do
|
125
|
+
it "returns hash keys that have an empty hash as the value" do
|
126
|
+
Fingerprinter.new.handleable_columns({'name' => {}, 'books' => {'title' => {}}}).should == ["name"]
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "#columns_to_pass" do
|
131
|
+
it "returns hash keys that do not have an empty hash as the value" do
|
132
|
+
Fingerprinter.new.passable_columns({'name' => {}, 'books' => {'title' => {}}}).should == ["books"]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "#chain_to_nested_hash" do
|
137
|
+
it "turns a list of methods into a nested hash" do
|
138
|
+
Fingerprinter.new.display_method_to_nested_hash("books").should == {'books' => {}}
|
139
|
+
Fingerprinter.new.display_method_to_nested_hash("reviews.user").should == {'reviews' => {'user' => {}}}
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "#columns_to_nested_hash" do
|
144
|
+
it "splits the column names into a nested hash" do
|
145
|
+
Fingerprinter.new.display_methods_to_nested_hash(["books.name"]).should == {'books' => {'name' => {}}}
|
146
|
+
Fingerprinter.new.display_methods_to_nested_hash(
|
147
|
+
["books.name", "books.publisher", "reviews.rating", "reviews.user.email", "reviews.user.id"]
|
148
|
+
).should == {'books' => {'name' => {}, 'publisher' => {}}, 'reviews' => {'rating' => {}, 'user' => {'email' => {}, 'id' => {}}}}
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|