fat_core 1.6.0 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -141,7 +141,7 @@ module FatCore
141
141
  items: [nil, 'Four', 'score', 'and', nil, '7 years'])
142
142
  end
143
143
 
144
- it 'should be able apply to first to appropriate columns' do
144
+ it 'should be able to apply first to appropriate columns' do
145
145
  expect(@nil_col.first).to eq(nil)
146
146
  expect(@bool_col.first).to eq(false)
147
147
  expect(@date_col.first).to eq(Date.parse('2015-01-21'))
@@ -157,12 +157,12 @@ module FatCore
157
157
  expect(@str_col.last).to eq('7 years')
158
158
  end
159
159
 
160
- it 'should be able to apply rng_s to appropriate columns' do
161
- expect(@nil_col.rng_s).to eq('..')
162
- expect(@bool_col.rng_s).to eq('false..true')
163
- expect(@date_col.rng_s).to eq('2015-01-21..2017-01-25T10:00:00+00:00')
164
- expect(@num_col.rng_s).to eq('20151..45024')
165
- expect(@str_col.rng_s).to eq('Four..7 years')
160
+ it 'should be able to apply rng to appropriate columns' do
161
+ expect(@nil_col.rng).to eq('..')
162
+ expect(@bool_col.rng).to eq('false..true')
163
+ expect(@date_col.rng).to eq('2015-01-21..2017-01-25T10:00:00+00:00')
164
+ expect(@num_col.rng).to eq('20151..45024')
165
+ expect(@str_col.rng).to eq('Four..7 years')
166
166
  end
167
167
 
168
168
  it 'should be able to sum to appropriate columns' do
@@ -194,7 +194,23 @@ module FatCore
194
194
  expect { @bool_col.avg }.to raise_error(/cannot be applied/)
195
195
  expect(@date_col.avg).to eq(DateTime.parse('2014-07-17 12pm'))
196
196
  expect(@num_col.avg).to eq(16295.214967957)
197
- expect{ @str_col.avg }.to raise_error(/cannot be applied/)
197
+ expect { @str_col.avg }.to raise_error(/cannot be applied/)
198
+ end
199
+
200
+ it 'should be able to apply var to appropriate columns' do
201
+ expect { @nil_col.var }.to raise_error(/cannot be applied/)
202
+ expect { @bool_col.var }.to raise_error(/cannot be applied/)
203
+ expect(@date_col.var).to eq(644_564.25)
204
+ expect(@num_col.var.round(5)).to eq(342_771_817.71273)
205
+ expect { @str_col.var }.to raise_error(/cannot be applied/)
206
+ end
207
+
208
+ it 'should be able to apply dev to appropriate columns' do
209
+ expect { @nil_col.dev }.to raise_error(/cannot be applied/)
210
+ expect { @bool_col.dev }.to raise_error(/cannot be applied/)
211
+ expect(@date_col.dev).to eq(802.8475882756328)
212
+ expect(@num_col.dev).to eq(18_514.097809851042)
213
+ expect { @str_col.dev }.to raise_error(/cannot be applied/)
198
214
  end
199
215
 
200
216
  it 'should be able to apply boolean aggregates to boolean columns' do
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ module FatCore
4
+ describe AoaFormatter do
5
+ describe 'table output' do
6
+ before :each do
7
+ @aoa =
8
+ [['Ref', 'Date', 'Code', 'Raw', 'Shares', 'Price', 'Info', 'Bool'],
9
+ nil,
10
+ [1, '2013-05-02', 'P', 795_546.20, 795_546.2, 1.1850, 'ZMPEF1', 'T'],
11
+ [2, '2013-05-02', 'P', 118_186.40, 118_186.4, 11.8500, 'ZMPEF1', 'T'],
12
+ [5, '2013-05-02', 'P', 118_186.40, 118_186.4, 11.8500, 'ZMPEF1\'s "Ent"', 'T'],
13
+ [7, '2013-05-20', 'S', 12_000.00, 5046.00, 28.2804, 'ZMEAC', 'F'],
14
+ [8, '2013-05-20', 'S', 85_000.00, 35_742.50, 28.3224, 'ZMEAC', 'T'],
15
+ [9, '2013-05-20', 'S', 33_302.00, 14_003.49, 28.6383, 'ZMEAC', 'T'],
16
+ [10, '2013-05-23', 'S', 8000.00, 3364.00, 27.1083, 'ZMEAC', 'T'],
17
+ [11, '2013-05-23', 'S', 23_054.00, 9694.21, 26.8015, 'ZMEAC', 'F'],
18
+ [12, '2013-05-23', 'S', 39_906.00, 16_780.47, 25.1749, 'ZMEAC', 'T'],
19
+ [13, '2013-05-29', 'S', 13_459.00, 5659.51, 24.7464, 'ZMEAC', 'T'],
20
+ [14, '2013-05-29', 'S', 15_700.00, 6601.85, 24.7790, 'ZMEAC', 'F'],
21
+ [15, '2013-05-29', 'S', 15_900.00, 6685.95, 24.5802, 'ZMEAC', 'T'],
22
+ [16, '2013-05-30', 'S', 6_679.00, 2808.52, 25.0471, 'ZMEAC', 'T']]
23
+ @tab = Table.from_aoa(@aoa).order_by(:date)
24
+ end
25
+
26
+ it 'should be able to output a table with default formatting instructions' do
27
+ aoa = AoaFormatter.new(@tab).output
28
+ expect(aoa.class).to eq(Array)
29
+ expect(aoa.first.class).to eq(Array)
30
+ end
31
+
32
+ it 'should be able to set format and output by method calls' do
33
+ fmt = AoaFormatter.new(@tab)
34
+ fmt.format(ref: '5.0', code: 'C', raw: ',0.0R', shares: ',0.0R',
35
+ price: '0.3', bool: 'Y')
36
+ fmt.format_for(:header, string: 'CB')
37
+ fmt.sum_gfooter(:price, :raw, :shares)
38
+ fmt.gfooter('Grp Std Dev', price: :dev, shares: :dev, bool: :one?)
39
+ fmt.sum_footer(:price, :raw, :shares)
40
+ fmt.footer('Std Dev', price: :dev, shares: :dev, bool: :all?)
41
+ fmt.footer('Any?', bool: :any?)
42
+ aoa = fmt.output
43
+ expect(aoa.size).to eq(45)
44
+ expect(aoa.first.first).to eq('Ref')
45
+ expect(aoa.first.last).to eq('Bool')
46
+ expect(aoa[1]).to be_nil
47
+ expect(aoa[2][0]).to eq('00001')
48
+ expect(aoa[2][1]).to eq('2013-05-02')
49
+ expect(aoa[2][2]).to eq('P')
50
+ expect(aoa[2][3]).to eq('795,546')
51
+ expect(aoa[2][4]).to eq('795,546')
52
+ expect(aoa[2][5]).to eq('1.185')
53
+ expect(aoa[2][6]).to eq('ZMPEF1')
54
+ expect(aoa[2][7]).to eq('Y')
55
+ expect(aoa[6][0]).to eq('Group Total')
56
+ expect(aoa[6][3]).to eq('1,031,919')
57
+ expect(aoa[6][4]).to eq('1,031,919')
58
+ expect(aoa[6][5]).to eq('24.885')
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ module FatCore
4
+ describe AohFormatter do
5
+ describe 'table output' do
6
+ before :each do
7
+ @aoa =
8
+ [['Ref', 'Date', 'Code', 'Raw', 'Shares', 'Price', 'Info', 'Bool'],
9
+ nil,
10
+ [1, '2013-05-02', 'P', 795_546.20, 795_546.2, 1.1850, 'ZMPEF1', 'T'],
11
+ [2, '2013-05-02', 'P', 118_186.40, 118_186.4, 11.8500, 'ZMPEF1', 'T'],
12
+ [5, '2013-05-02', 'P', 118_186.40, 118_186.4, 11.8500, 'ZMPEF1\'s "Ent"', 'T'],
13
+ [7, '2013-05-20', 'S', 12_000.00, 5046.00, 28.2804, 'ZMEAC', 'F'],
14
+ [8, '2013-05-20', 'S', 85_000.00, 35_742.50, 28.3224, 'ZMEAC', 'T'],
15
+ [9, '2013-05-20', 'S', 33_302.00, 14_003.49, 28.6383, 'ZMEAC', 'T'],
16
+ [10, '2013-05-23', 'S', 8000.00, 3364.00, 27.1083, 'ZMEAC', 'T'],
17
+ [11, '2013-05-23', 'S', 23_054.00, 9694.21, 26.8015, 'ZMEAC', 'F'],
18
+ [12, '2013-05-23', 'S', 39_906.00, 16_780.47, 25.1749, 'ZMEAC', 'T'],
19
+ [13, '2013-05-29', 'S', 13_459.00, 5659.51, 24.7464, 'ZMEAC', 'T'],
20
+ [14, '2013-05-29', 'S', 15_700.00, 6601.85, 24.7790, 'ZMEAC', 'F'],
21
+ [15, '2013-05-29', 'S', 15_900.00, 6685.95, 24.5802, 'ZMEAC', 'T'],
22
+ [16, '2013-05-30', 'S', 6_679.00, 2808.52, 25.0471, 'ZMEAC', 'T']]
23
+ @tab = Table.from_aoa(@aoa).order_by(:date)
24
+ end
25
+
26
+ it 'should be able to output a table with default formatting instructions' do
27
+ aoh = AohFormatter.new(@tab).output
28
+ expect(aoh.class).to eq(Array)
29
+ expect(aoh.first.class).to eq(Hash)
30
+ end
31
+
32
+ it 'should be able to set format and output by method calls' do
33
+ fmt = AohFormatter.new(@tab)
34
+ fmt.format(ref: '5.0', code: 'C', raw: ',0.0R', shares: ',0.0R',
35
+ price: '0.3', bool: 'Y')
36
+ fmt.format_for(:header, string: 'CB')
37
+ fmt.sum_gfooter(:price, :raw, :shares)
38
+ fmt.gfooter('Grp Std Dev', price: :dev, shares: :dev, bool: :one?)
39
+ fmt.sum_footer(:price, :raw, :shares)
40
+ fmt.footer('Std Dev', price: :dev, shares: :dev, bool: :all?)
41
+ fmt.footer('Any?', bool: :any?)
42
+ aoh = fmt.output
43
+ expect(aoh.size).to eq(43)
44
+ expect(aoh.first.keys.first).to eq(:ref)
45
+ expect(aoh.first.keys.last).to eq(:bool)
46
+ expect(aoh[0][:ref]).to eq('00001')
47
+ expect(aoh[0][:date]).to eq('2013-05-02')
48
+ expect(aoh[0][:code]).to eq('P')
49
+ expect(aoh[0][:raw]).to eq('795,546')
50
+ expect(aoh[0][:shares]).to eq('795,546')
51
+ expect(aoh[0][:price]).to eq('1.185')
52
+ expect(aoh[0][:info]).to eq('ZMPEF1')
53
+ expect(aoh[0][:bool]).to eq('Y')
54
+ expect(aoh[4][:ref]).to eq('Group Total')
55
+ expect(aoh[4][:shares]).to eq('1,031,919')
56
+ expect(aoh[4][:raw]).to eq('1,031,919')
57
+ expect(aoh[4][:price]).to eq('24.885')
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,371 @@
1
+ require 'spec_helper'
2
+
3
+ module FatCore
4
+ describe Formatter do
5
+ before :all do
6
+ aoa =
7
+ [['Ref', 'Date', 'Code', 'Raw', 'Shares', 'Price', 'Info', 'Bool'],
8
+ nil,
9
+ [1, '2013-05-02', 'P', 795_546.20, 795_546.2, 1.1850, 'ZMPEF1', 'T'],
10
+ [2, '2013-05-02', 'P', 118_186.40, 118_186.4, 11.8500, 'ZMPEF1', 'T'],
11
+ [7, '2013-05-20', 'S', 12_000.00, 5046.00, 28.2804, 'ZMEAC', 'F'],
12
+ [8, '2013-05-20', 'S', 85_000.00, 35_742.50, 28.3224, 'ZMEAC', 'T'],
13
+ [9, '2013-05-20', 'S', 33_302.00, 14_003.49, 28.6383, 'ZMEAC', 'T'],
14
+ [10, '2013-05-23', 'S', 8000.00, 3364.00, 27.1083, 'ZMEAC', 'T'],
15
+ [11, '2013-05-23', 'S', 23_054.00, 9694.21, 26.8015, 'ZMEAC', 'F'],
16
+ [12, '2013-05-23', 'S', 39_906.00, 16_780.47, 25.1749, 'ZMEAC', 'T'],
17
+ [13, '2013-05-29', 'S', 13_459.00, 5659.51, 24.7464, 'ZMEAC', 'T'],
18
+ [14, '2013-05-29', 'S', 15_700.00, 6601.85, 24.7790, 'ZMEAC', 'F'],
19
+ [15, '2013-05-29', 'S', 15_900.00, 6685.95, 24.5802, 'ZMEAC', 'T'],
20
+ [16, '2013-05-30', 'S', 6_679.00, 2808.52, 25.0471, 'ZMEAC', 'T']]
21
+ @tab = Table.from_aoa(aoa)
22
+ end
23
+
24
+ describe 'parsing and validity' do
25
+ it 'should raise error for invalid location' do
26
+ fmt = Formatter.new(@tab)
27
+ expect {
28
+ fmt.format_for(:trout, string: 'BC')
29
+ }.to raise_error(/unknown format location/)
30
+ end
31
+
32
+ it 'should raise error for invalid format string' do
33
+ fmt = Formatter.new(@tab)
34
+ expect {
35
+ fmt.format_for(:body, string: 'OOIUOIO')
36
+ }.to raise_error(/unrecognized string formatting instruction/)
37
+ end
38
+
39
+ it 'should raise error for inapposite format string' do
40
+ fmt = Formatter.new(@tab)
41
+ expect {
42
+ fmt.format_for(:body, boolean: '7.4,')
43
+ }.to raise_error(/unrecognized boolean formatting instruction/)
44
+ end
45
+
46
+ it 'should be able to set element formats' do
47
+ fmt = Formatter.new(@tab)
48
+ .format_for(:header, string: 'Uc[red]', ref: 'uc[blue]')
49
+ .format_for(:gfooter, string: 'B')
50
+ .format_for(:footer, date: 'Bd[%Y]')
51
+ .format_for(:body, numeric: ',0.2', shares: '0.4', ref: 'B',
52
+ price: '$,',
53
+ bool: ' c[green, red] b[ Yippers, Nah Sir]',
54
+ nil: 'n[ Nothing to see here ]')
55
+ # Header color
56
+ expect(fmt.format_at[:header][:ref].color).to eq('blue')
57
+ expect(fmt.format_at[:header][:date].color).to eq('red')
58
+ expect(fmt.format_at[:header][:code].color).to eq('red')
59
+ expect(fmt.format_at[:header][:raw].color).to eq('red')
60
+ expect(fmt.format_at[:header][:shares].color).to eq('red')
61
+ expect(fmt.format_at[:header][:price].color).to eq('red')
62
+ expect(fmt.format_at[:header][:info].color).to eq('red')
63
+ expect(fmt.format_at[:header][:bool].color).to eq('red')
64
+ # Header case
65
+ expect(fmt.format_at[:header][:ref].case).to eq(:lower)
66
+ expect(fmt.format_at[:header][:date].case).to eq(:upper)
67
+ expect(fmt.format_at[:header][:code].case).to eq(:upper)
68
+ expect(fmt.format_at[:header][:raw].case).to eq(:upper)
69
+ expect(fmt.format_at[:header][:shares].case).to eq(:upper)
70
+ expect(fmt.format_at[:header][:price].case).to eq(:upper)
71
+ expect(fmt.format_at[:header][:info].case).to eq(:upper)
72
+ expect(fmt.format_at[:header][:bool].case).to eq(:upper)
73
+ # Header all others, the default
74
+ @tab.headers.each do |h|
75
+ expect(fmt.format_at[:header][h].true_color).to eq('black')
76
+ expect(fmt.format_at[:header][h].false_color).to eq('black')
77
+ expect(fmt.format_at[:header][h].true_text).to eq('T')
78
+ expect(fmt.format_at[:header][h].false_text).to eq('F')
79
+ expect(fmt.format_at[:header][h].date_fmt).to eq('%F')
80
+ expect(fmt.format_at[:header][h].datetime_fmt).to eq('%F %H:%M:%S')
81
+ expect(fmt.format_at[:header][h].nil_text).to eq('')
82
+ expect(fmt.format_at[:header][h].pre_digits).to eq(-1)
83
+ expect(fmt.format_at[:header][h].post_digits).to eq(-1)
84
+ expect(fmt.format_at[:header][h].bold).to eq(false)
85
+ expect(fmt.format_at[:header][h].italic).to eq(false)
86
+ expect(fmt.format_at[:header][h].alignment).to eq(:left)
87
+ expect(fmt.format_at[:header][h].commas).to eq(false)
88
+ expect(fmt.format_at[:header][h].currency).to eq(false)
89
+ expect(fmt.format_at[:header][h].nil_text).to eq('')
90
+ end
91
+ # Gfooter bold
92
+ @tab.headers.each do |h|
93
+ expect(fmt.format_at[:gfooter][h].bold).to eq(true)
94
+ end
95
+ # Gfooter all others, the default
96
+ @tab.headers.each do |h|
97
+ expect(fmt.format_at[:gfooter][h].true_color).to eq('black')
98
+ expect(fmt.format_at[:gfooter][h].false_color).to eq('black')
99
+ expect(fmt.format_at[:gfooter][h].color).to eq('black')
100
+ expect(fmt.format_at[:gfooter][h].true_text).to eq('T')
101
+ expect(fmt.format_at[:gfooter][h].false_text).to eq('F')
102
+ expect(fmt.format_at[:header][h].date_fmt).to eq('%F')
103
+ expect(fmt.format_at[:header][h].datetime_fmt).to eq('%F %H:%M:%S')
104
+ expect(fmt.format_at[:gfooter][h].nil_text).to eq('')
105
+ expect(fmt.format_at[:gfooter][h].pre_digits).to eq(-1)
106
+ expect(fmt.format_at[:gfooter][h].post_digits).to eq(-1)
107
+ expect(fmt.format_at[:gfooter][h].italic).to eq(false)
108
+ expect(fmt.format_at[:gfooter][h].alignment).to eq(:left)
109
+ expect(fmt.format_at[:gfooter][h].commas).to eq(false)
110
+ expect(fmt.format_at[:gfooter][h].currency).to eq(false)
111
+ expect(fmt.format_at[:gfooter][h].nil_text).to eq('')
112
+ end
113
+ # Footer date_fmt for :date
114
+ expect(fmt.format_at[:footer][:date].date_fmt).to eq('%Y')
115
+ expect(fmt.format_at[:footer][:date].bold).to eq(true)
116
+ # Footer all others, the default
117
+ @tab.headers.each do |h|
118
+ expect(fmt.format_at[:footer][h].true_color).to eq('black')
119
+ expect(fmt.format_at[:footer][h].false_color).to eq('black')
120
+ expect(fmt.format_at[:footer][h].color).to eq('black')
121
+ expect(fmt.format_at[:footer][h].true_text).to eq('T')
122
+ expect(fmt.format_at[:footer][h].false_text).to eq('F')
123
+ expect(fmt.format_at[:header][h].date_fmt).to eq('%F')
124
+ expect(fmt.format_at[:header][h].datetime_fmt).to eq('%F %H:%M:%S')
125
+ expect(fmt.format_at[:footer][h].nil_text).to eq('')
126
+ expect(fmt.format_at[:footer][h].pre_digits).to eq(-1)
127
+ expect(fmt.format_at[:footer][h].post_digits).to eq(-1)
128
+ expect(fmt.format_at[:footer][h].bold).to eq(h == :date)
129
+ expect(fmt.format_at[:footer][h].italic).to eq(false)
130
+ expect(fmt.format_at[:footer][h].alignment).to eq(:left)
131
+ expect(fmt.format_at[:footer][h].commas).to eq(false)
132
+ expect(fmt.format_at[:footer][h].currency).to eq(false)
133
+ expect(fmt.format_at[:footer][h].nil_text).to eq('')
134
+ end
135
+ # .format_for(:body, numeric: ',0.2', shares: '0.4', ref: 'B',
136
+ # bool: ' c[green, red] b[ Yippers, Nah Sir]',
137
+ # nil: 'n[ Nothing to see here ]')
138
+ # Body, numeric columns except :shares
139
+ [:raw, :price].each do |h|
140
+ expect(fmt.format_at[:body][h].commas).to eq(true)
141
+ expect(fmt.format_at[:body][h].pre_digits).to eq(0)
142
+ expect(fmt.format_at[:body][h].post_digits).to eq(2)
143
+ end
144
+ # Body, :shares
145
+ expect(fmt.format_at[:body][:shares].commas).to eq(true)
146
+ expect(fmt.format_at[:body][:shares].pre_digits).to eq(0)
147
+ expect(fmt.format_at[:body][:shares].post_digits).to eq(4)
148
+ # Body, :bool
149
+ expect(fmt.format_at[:body][:bool].true_color).to eq('green')
150
+ expect(fmt.format_at[:body][:bool].false_color).to eq('red')
151
+ expect(fmt.format_at[:body][:bool].true_text).to eq('Yippers')
152
+ expect(fmt.format_at[:body][:bool].false_text).to eq('Nah Sir')
153
+ # Body, :ref
154
+ expect(fmt.format_at[:body][:ref].bold).to eq(true)
155
+ # Body, :price
156
+ expect(fmt.format_at[:body][:price].currency).to eq(true)
157
+ # Body all others, the default
158
+ @tab.headers.each do |h|
159
+ expect(fmt.format_at[:body][h].color).to eq('black')
160
+ unless h == :bool
161
+ expect(fmt.format_at[:body][h].true_color).to eq('black')
162
+ expect(fmt.format_at[:body][h].false_color).to eq('black')
163
+ expect(fmt.format_at[:body][h].true_text).to eq('T')
164
+ expect(fmt.format_at[:body][h].false_text).to eq('F')
165
+ end
166
+ expect(fmt.format_at[:body][h].date_fmt).to eq('%F')
167
+ if @tab.type(h) == 'Numeric'
168
+ expect(fmt.format_at[:body][h].pre_digits).to eq(0)
169
+ expect(fmt.format_at[:body][h].post_digits)
170
+ .to eq(h == :shares ? 4 : 2)
171
+ expect(fmt.format_at[:body][h].commas).to eq(true)
172
+ expect(fmt.format_at[:body][h].bold).to eq(h == :ref)
173
+ expect(fmt.format_at[:body][h].currency).to eq(h == :price)
174
+ else
175
+ expect(fmt.format_at[:body][h].italic).to eq(false)
176
+ expect(fmt.format_at[:body][h].alignment).to eq(:left)
177
+ expect(fmt.format_at[:body][h].currency).to eq(false)
178
+ expect(fmt.format_at[:body][h].nil_text).to eq('Nothing to see here')
179
+ end
180
+ end
181
+ end
182
+ end
183
+
184
+ describe 'cell formatting' do
185
+ it 'should be able to format a string' do
186
+ fmt = Formatter.new
187
+ istruct = OpenStruct.new(Formatter.default_format)
188
+ istruct.case = :upper
189
+ expect(fmt.format_cell('hello world', istruct)).to eq('HELLO WORLD')
190
+ istruct.case = :lower
191
+ expect(fmt.format_cell('HELLO WORLD', istruct)).to eq('hello world')
192
+ istruct.case = :title
193
+ expect(fmt.format_cell('HELLO TO THE WORLD', istruct))
194
+ .to eq('Hello to the World')
195
+ expect(fmt.format_cell(nil, istruct))
196
+ .to eq('')
197
+ end
198
+
199
+ it 'should be able to format a numeric' do
200
+ fmt = Formatter.new
201
+ istruct = OpenStruct.new(Formatter.default_format)
202
+ expect(fmt.format_cell(78546.254, istruct)).to eq('78546.254')
203
+ istruct.commas = true
204
+ expect(fmt.format_cell(78546.254, istruct)).to eq('78,546.254')
205
+ istruct.hms = true
206
+ expect(fmt.format_cell(78546.254, istruct)).to eq('21:49:06.25')
207
+ istruct.hms = false
208
+ istruct.pre_digits = 8
209
+ expect(fmt.format_cell(78546.254, istruct)).to eq('00078546')
210
+ istruct.post_digits = 1
211
+ expect(fmt.format_cell(78546.254, istruct)).to eq('00078546.3')
212
+ istruct.commas = true
213
+ expect(fmt.format_cell(78546.254, istruct)).to eq('00,078,546.3')
214
+ istruct.commas = false
215
+ istruct.pre_digits = -1
216
+ istruct.post_digits = 2
217
+ expect(fmt.format_cell(78546.254, istruct)).to eq('78546.25')
218
+ istruct.currency = true
219
+ istruct.post_digits = 5
220
+ expect(fmt.format_cell(78546.254, istruct)).to eq('$78546.25400')
221
+ istruct.commas = true
222
+ expect(fmt.format_cell(78546.254, istruct)).to eq('$78,546.25400')
223
+ end
224
+
225
+ it 'should be able to format a boolean' do
226
+ fmt = Formatter.new
227
+ istruct = OpenStruct.new(Formatter.default_format)
228
+ expect(fmt.format_cell(true, istruct)).to eq('T')
229
+ expect(fmt.format_cell(false, istruct)).to eq('F')
230
+ istruct.true_text = 'Yippers'
231
+ istruct.false_text = 'Nappers'
232
+ expect(fmt.format_cell(true, istruct)).to eq('Yippers')
233
+ expect(fmt.format_cell(false, istruct)).to eq('Nappers')
234
+ end
235
+
236
+ it 'should be able to format a datetime' do
237
+ fmt = Formatter.new
238
+ istruct = OpenStruct.new(Formatter.default_format)
239
+ val = DateTime.parse('2017-02-23 9pm')
240
+ expect(fmt.format_cell(val, istruct)).to eq('2017-02-23 21:00:00')
241
+ istruct.datetime_fmt = '%Y in %B at %l%P, which was on a %A'
242
+ expect(fmt.format_cell(val, istruct))
243
+ .to eq('2017 in February at 9pm, which was on a Thursday')
244
+ end
245
+ end
246
+
247
+ describe 'footers' do
248
+ before :each do
249
+ aoa =
250
+ [['Ref', 'Date', 'Code', 'Raw', 'Shares', 'Price', 'Info', 'Bool'],
251
+ nil,
252
+ [1, '2013-05-02', 'P', 795_546.20, 795_546.2, 1.1850, 'ZMPEF1', 'T'],
253
+ [2, '2013-05-02', 'P', 118_186.40, 118_186.4, 11.8500, 'ZMPEF1', 'T'],
254
+ [7, '2013-05-20', 'S', 12_000.00, 5046.00, 28.2804, 'ZMEAC', 'F'],
255
+ [8, '2013-05-20', 'S', 85_000.00, 35_742.50, 28.3224, 'ZMEAC', 'T'],
256
+ [9, '2013-05-20', 'S', 33_302.00, 14_003.49, 28.6383, 'ZMEAC', 'T'],
257
+ [10, '2013-05-23', 'S', 8000.00, 3364.00, 27.1083, 'ZMEAC', 'T'],
258
+ [11, '2013-05-23', 'S', 23_054.00, 9694.21, 26.8015, 'ZMEAC', 'F'],
259
+ [12, '2013-05-23', 'S', 39_906.00, 16_780.47, 25.1749, 'ZMEAC', 'T'],
260
+ [13, '2013-05-29', 'S', 13_459.00, 5659.51, 24.7464, 'ZMEAC', 'T'],
261
+ [14, '2013-05-29', 'S', 15_700.00, 6601.85, 24.7790, 'ZMEAC', 'F'],
262
+ [15, '2013-05-29', 'S', 15_900.00, 6685.95, 24.5802, 'ZMEAC', 'T'],
263
+ [16, '2013-05-30', 'S', 6_679.00, 2808.52, 25.0471, 'ZMEAC', 'T']]
264
+ @tab = Table.from_aoa(aoa).order_by(:date)
265
+ end
266
+
267
+ it 'should be able to add a total footer to the output' do
268
+ fmt = Formatter.new(@tab) do |f|
269
+ f.sum_footer(:raw, :shares, :price)
270
+ end
271
+ expect(fmt.footers['Total'][:raw]).to eq(:sum)
272
+ expect(fmt.footers['Total'][:shares]).to eq(:sum)
273
+ expect(fmt.footers['Total'][:price]).to eq(:sum)
274
+ expect(fmt.footers['Total'][:info]).to be_nil
275
+ end
276
+
277
+ it 'should be able to add an average footer to the output' do
278
+ fmt = Formatter.new(@tab) do |f|
279
+ f.avg_footer(:raw, :shares, :price)
280
+ end
281
+ expect(fmt.footers['Average'][:raw]).to eq(:avg)
282
+ expect(fmt.footers['Average'][:shares]).to eq(:avg)
283
+ expect(fmt.footers['Average'][:price]).to eq(:avg)
284
+ expect(fmt.footers['Average'][:info]).to be_nil
285
+ end
286
+
287
+ it 'should be able to add a minimum footer to the output' do
288
+ fmt = Formatter.new(@tab) do |f|
289
+ f.min_footer(:raw, :shares, :price)
290
+ end
291
+ expect(fmt.footers['Minimum'][:raw]).to eq(:min)
292
+ expect(fmt.footers['Minimum'][:shares]).to eq(:min)
293
+ expect(fmt.footers['Minimum'][:price]).to eq(:min)
294
+ expect(fmt.footers['Minimum'][:info]).to be_nil
295
+ end
296
+
297
+ it 'should be able to add a maximum footer to the output' do
298
+ fmt = Formatter.new(@tab) do |f|
299
+ f.max_footer(:raw, :shares, :price)
300
+ end
301
+ expect(fmt.footers['Maximum'][:raw]).to eq(:max)
302
+ expect(fmt.footers['Maximum'][:shares]).to eq(:max)
303
+ expect(fmt.footers['Maximum'][:price]).to eq(:max)
304
+ expect(fmt.footers['Maximum'][:info]).to be_nil
305
+ end
306
+ end
307
+
308
+ describe 'table output' do
309
+ before :each do
310
+ aoa =
311
+ [['Ref', 'Date', 'Code', 'Raw', 'Shares', 'Price', 'Info', 'Bool'],
312
+ nil,
313
+ [1, '2013-05-02', 'P', 795_546.20, 795_546.2, 1.1850, 'ZMPEF1', 'T'],
314
+ [2, '2013-05-02', 'P', 118_186.40, 118_186.4, 11.8500, 'ZMPEF1', 'T'],
315
+ [7, '2013-05-20', 'S', 12_000.00, 5046.00, 28.2804, 'ZMEAC', 'F'],
316
+ [8, '2013-05-20', 'S', 85_000.00, 35_742.50, 28.3224, 'ZMEAC', 'T'],
317
+ [9, '2013-05-20', 'S', 33_302.00, 14_003.49, 28.6383, 'ZMEAC', 'T'],
318
+ [10, '2013-05-23', 'S', 8000.00, 3364.00, 27.1083, 'ZMEAC', 'T'],
319
+ [11, '2013-05-23', 'S', 23_054.00, 9694.21, 26.8015, 'ZMEAC', 'F'],
320
+ [12, '2013-05-23', 'S', 39_906.00, 16_780.47, 25.1749, 'ZMEAC', 'T'],
321
+ [13, '2013-05-29', 'S', 13_459.00, 5659.51, 24.7464, 'ZMEAC', 'T'],
322
+ [14, '2013-05-29', 'S', 15_700.00, 6601.85, 24.7790, 'ZMEAC', 'F'],
323
+ [15, '2013-05-29', 'S', 15_900.00, 6685.95, 24.5802, 'ZMEAC', 'T'],
324
+ [16, '2013-05-30', 'S', 6_679.00, 2808.52, 25.0471, 'ZMEAC', 'T']]
325
+ @tab = Table.from_aoa(aoa).order_by(:date)
326
+ end
327
+
328
+ it 'should be able to output a table with default formatting instructions' do
329
+ str = Formatter.new(@tab).output
330
+ expect(str.length).to be > 10
331
+ end
332
+
333
+ it 'should be able to set format and output by method calls' do
334
+ fmt = Formatter.new(@tab)
335
+ fmt.format(ref: '5.0', code: 'C', raw: ',0.0R', shares: ',0.0R',
336
+ price: '0.3', bool: 'Y')
337
+ fmt.format_for(:header, string: 'CB')
338
+ fmt.sum_gfooter(:price, :raw, :shares)
339
+ fmt.gfooter('Grp Std Dev', price: :dev, shares: :dev, bool: :one?)
340
+ fmt.sum_footer(:price, :raw, :shares)
341
+ fmt.footer('Std Dev', price: :dev, shares: :dev, bool: :all?)
342
+ fmt.footer('Any?', bool: :any?)
343
+ str = fmt.output
344
+ expect(str.length).to be > 10
345
+ expect(str).to match(/^Ref\|.*\|Bool$/)
346
+ expect(str).to match(/^00001\|2013-05-02\|P\|795,546\|795,546\|1.185\|ZMPEF1\|Y$/)
347
+ expect(str).to match(/^Group Total\|\|\|130,302\|54,792\|85.241\|\|$/)
348
+ expect(str).to match(/^Total|||1,166,733|1,020,119|276.514||$/)
349
+ end
350
+
351
+ it 'should be able to set format and output in a block' do
352
+ fmt = Formatter.new(@tab) do |f|
353
+ f.format(ref: '5.0', code: 'C', raw: ',0.0R', shares: ',0.0R',
354
+ price: '0.3', bool: 'Y')
355
+ f.format_for(:header, string: 'CB')
356
+ f.sum_gfooter(:price, :raw, :shares)
357
+ f.gfooter('Grp Std Dev', price: :dev, shares: :dev, bool: :one?)
358
+ f.sum_footer(:price, :raw, :shares)
359
+ f.footer('Std Dev', price: :dev, shares: :dev, bool: :all?)
360
+ f.footer('Any?', bool: :any?)
361
+ end
362
+ str = fmt.output
363
+ expect(str.length).to be > 10
364
+ expect(str).to match(/^Ref\|.*\|Bool$/)
365
+ expect(str).to match(/^00001\|2013-05-02\|P\|795,546\|795,546\|1.185\|ZMPEF1\|Y$/)
366
+ expect(str).to match(/^Group Total\|\|\|130,302\|54,792\|85.241\|\|$/)
367
+ expect(str).to match(/^Total|||1,166,733|1,020,119|276.514||$/)
368
+ end
369
+ end
370
+ end
371
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ module FatCore
4
+ describe OrgFormatter do
5
+ describe 'table output' do
6
+ before :each do
7
+ @aoa =
8
+ [['Ref', 'Date', 'Code', 'Raw', 'Shares', 'Price', 'Info', 'Bool'],
9
+ nil,
10
+ [1, '2013-05-02', 'P', 795_546.20, 795_546.2, 1.1850, 'ZMPEF1', 'T'],
11
+ [2, '2013-05-02', 'P', 118_186.40, 118_186.4, 11.8500, 'ZMPEF1', 'T'],
12
+ [5, '2013-05-02', 'P', 118_186.40, 118_186.4, 11.8500, 'ZMPEF1\'s "Ent"', 'T'],
13
+ [7, '2013-05-20', 'S', 12_000.00, 5046.00, 28.2804, 'ZMEAC', 'F'],
14
+ [8, '2013-05-20', 'S', 85_000.00, 35_742.50, 28.3224, 'ZMEAC', 'T'],
15
+ [9, '2013-05-20', 'S', 33_302.00, 14_003.49, 28.6383, 'ZMEAC', 'T'],
16
+ [10, '2013-05-23', 'S', 8000.00, 3364.00, 27.1083, 'ZMEAC', 'T'],
17
+ [11, '2013-05-23', 'S', 23_054.00, 9694.21, 26.8015, 'ZMEAC', 'F'],
18
+ [12, '2013-05-23', 'S', 39_906.00, 16_780.47, 25.1749, 'ZMEAC', 'T'],
19
+ [13, '2013-05-29', 'S', 13_459.00, 5659.51, 24.7464, 'ZMEAC', 'T'],
20
+ [14, '2013-05-29', 'S', 15_700.00, 6601.85, 24.7790, 'ZMEAC', 'F'],
21
+ [15, '2013-05-29', 'S', 15_900.00, 6685.95, 24.5802, 'ZMEAC', 'T'],
22
+ [16, '2013-05-30', 'S', 6_679.00, 2808.52, 25.0471, 'ZMEAC', 'T']]
23
+ @tab = Table.from_aoa(@aoa).order_by(:date)
24
+ end
25
+
26
+ it 'should be able to output a table with default formatting instructions' do
27
+ org = OrgFormatter.new(@tab).output
28
+ expect(org.class).to eq(String)
29
+ end
30
+
31
+ it 'should be able to set format and output by method calls' do
32
+ fmt = OrgFormatter.new(@tab)
33
+ fmt.format(ref: '5.0', code: 'C', raw: ',0.0', shares: ',0.0',
34
+ price: '0.3R', bool: 'Y', numeric: 'R')
35
+ fmt.format_for(:header, string: 'CB')
36
+ fmt.sum_gfooter(:price, :raw, :shares)
37
+ fmt.gfooter('Grp Std Dev', price: :dev, shares: :dev, bool: :one?)
38
+ fmt.sum_footer(:price, :raw, :shares)
39
+ fmt.footer('Std Dev', price: :dev, shares: :dev, bool: :all?)
40
+ fmt.footer('Any?', bool: :any?)
41
+ org = fmt.output
42
+ expect(org.size).to be > 1000
43
+ expect(org).to match(/\bRef\b/)
44
+ expect(org).to match(/\bBool\b/)
45
+ expect(org).to match(/\[2013-05-02\]/)
46
+ expect(org).to match(/^\|[-+]+\|$/)
47
+ expect(org).to match(/\D795,546\D/)
48
+ expect(org).to match(/\D1,031,919\D/)
49
+ expect(org).to match(/\D1.185\D/)
50
+ expect(org).to match(/\D24.885\D/)
51
+ expect(org).to match(/\D00001\D/)
52
+ expect(org).to match(/\bY\b/)
53
+ expect(org).to match(/\bP\b/)
54
+ expect(org).to match(/\bZMPEF1\b/)
55
+ expect(org).to match(/\bGroup Total\b/)
56
+ expect(org).to match(/\bGrp Std Dev\b/)
57
+ end
58
+ end
59
+ end
60
+ end