columnist 1.0.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/README.md +150 -0
- data/lib/columnist/column.rb +99 -0
- data/lib/columnist/formatter/nested.rb +70 -0
- data/lib/columnist/formatter/progress.rb +37 -0
- data/lib/columnist/options_validator.rb +5 -0
- data/lib/columnist/row.rb +83 -0
- data/lib/columnist/table.rb +133 -0
- data/lib/columnist.rb +173 -0
- data/spec/column_spec.rb +416 -0
- data/spec/columnist.rb +693 -0
- data/spec/nested_formatter_spec.rb +301 -0
- data/spec/options_validator_spec.rb +24 -0
- data/spec/progress_formatter_spec.rb +89 -0
- data/spec/row_spec.rb +129 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/support/helpers/stdout.rb +8 -0
- data/spec/support/matchers/argument.rb +17 -0
- data/spec/table_spec.rb +154 -0
- metadata +112 -0
data/spec/columnist.rb
ADDED
@@ -0,0 +1,693 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Columnist do
|
4
|
+
let :use_class do
|
5
|
+
Class.new do
|
6
|
+
include Columnist
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:timestamp_regex) { /\d{4}-\d{2}-\d{2} - (\d| )\d:\d{2}:\d{2}[AP]M/ }
|
11
|
+
|
12
|
+
let :controls do
|
13
|
+
{
|
14
|
+
:clear => "\e[0m",
|
15
|
+
:bold => "\e[1m",
|
16
|
+
:red => "\e[31m",
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:linechar) { "\u2501" == 'u2501' ? '-' : "\u2501" }
|
21
|
+
|
22
|
+
subject { use_class.new }
|
23
|
+
|
24
|
+
describe '#formatter=' do
|
25
|
+
it 'only allows allowed formatters' do
|
26
|
+
expect {
|
27
|
+
subject.formatter = 'asfd'
|
28
|
+
}.to raise_error ArgumentError
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'specifies the progress formatter' do
|
32
|
+
subject.formatter = 'progress'
|
33
|
+
expect(subject.formatter.class).to eq(Columnist::ProgressFormatter)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'specifies the nested formatter' do
|
37
|
+
subject.formatter = 'nested'
|
38
|
+
expect(subject.formatter.class).to eq(Columnist::NestedFormatter)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#report' do
|
43
|
+
it 'uses the nested formatter as default' do
|
44
|
+
capture_stdout {
|
45
|
+
subject.report { }
|
46
|
+
}
|
47
|
+
|
48
|
+
expect(subject.formatter.class).to eq(Columnist::NestedFormatter)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'uses the progress formatter' do
|
52
|
+
capture_stdout {
|
53
|
+
subject.formatter = 'progress'
|
54
|
+
subject.report { }
|
55
|
+
}
|
56
|
+
|
57
|
+
expect(subject.formatter.class).to eq(Columnist::ProgressFormatter)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'does not mask other application errors when a formatter is not set' do
|
61
|
+
capture_stdout {
|
62
|
+
subject.report {
|
63
|
+
expect {self.some_method_that_does_not_exist}.to raise_error(NoMethodError)
|
64
|
+
}
|
65
|
+
}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '#header' do
|
70
|
+
context 'argument validation' do
|
71
|
+
|
72
|
+
it 'does not accept an invalid option' do
|
73
|
+
expect {
|
74
|
+
subject.header(:asdf => 'tests')
|
75
|
+
}.to raise_error ArgumentError
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'accepts a title' do
|
79
|
+
expect {
|
80
|
+
allow(subject).to receive(:puts)
|
81
|
+
subject.header(:title => 'test')
|
82
|
+
}.to_not raise_error
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'does not allow a title > width' do
|
86
|
+
expect {
|
87
|
+
subject.header(:title => 'xxxxxxxxxxx', :width => 5)
|
88
|
+
}.to raise_error ArgumentError
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'accepts width' do
|
92
|
+
expect {
|
93
|
+
allow(subject).to receive(:puts)
|
94
|
+
subject.header(:width => 100)
|
95
|
+
}.to_not raise_error
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'ensure width is a number' do
|
99
|
+
expect {
|
100
|
+
subject.header(:width => '100')
|
101
|
+
}.to raise_error ArgumentError
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'accepts align' do
|
105
|
+
expect {
|
106
|
+
allow(subject).to receive(:puts)
|
107
|
+
subject.header(:align => 'center')
|
108
|
+
}.to_not raise_error
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'ensure align is a valid value' do
|
112
|
+
expect {
|
113
|
+
subject.header(:align => :asdf)
|
114
|
+
}.to raise_error ArgumentError
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'accepts spacing' do
|
118
|
+
expect {
|
119
|
+
allow(subject).to receive(:puts)
|
120
|
+
subject.header(:spacing => 2)
|
121
|
+
}.to_not raise_error
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'accepts timestamp' do
|
125
|
+
expect {
|
126
|
+
allow(subject).to receive(:puts)
|
127
|
+
subject.header(:timestamp => true)
|
128
|
+
}.to_not raise_error
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'accepts color' do
|
132
|
+
expect {
|
133
|
+
allow(subject).to receive(:puts)
|
134
|
+
subject.header(:color => 'red')
|
135
|
+
}.to_not raise_error
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'accepts bold' do
|
139
|
+
expect {
|
140
|
+
allow(subject).to receive(:puts)
|
141
|
+
subject.header(:bold => true)
|
142
|
+
}.to_not raise_error
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context 'alignment' do
|
147
|
+
before :each do
|
148
|
+
@title = 'test11test'
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'left aligns title by default' do
|
152
|
+
expect(subject).to receive(:puts).with(@title)
|
153
|
+
expect(subject).to receive(:puts).with("\n")
|
154
|
+
subject.header(:title => @title) { }
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'left aligns title' do
|
158
|
+
expect(subject).to receive(:puts).with(@title)
|
159
|
+
expect(subject).to receive(:puts).with("\n")
|
160
|
+
subject.header(:title => @title, :align => 'left') { }
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'right aligns title using default width' do
|
164
|
+
expect(subject).to receive(:puts).with(' ' * 90 + @title)
|
165
|
+
expect(subject).to receive(:puts).with("\n")
|
166
|
+
subject.header(:title => @title, :align => 'right')
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'right aligns title using specified width' do
|
170
|
+
expect(subject).to receive(:puts).with(' ' * 40 + @title)
|
171
|
+
expect(subject).to receive(:puts).with("\n")
|
172
|
+
subject.header(:title => @title, :align => 'right', :width => 50)
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'center aligns title using default width' do
|
176
|
+
expect(subject).to receive(:puts).with(' ' * 45 + @title)
|
177
|
+
expect(subject).to receive(:puts).with("\n")
|
178
|
+
subject.header(:title => @title, :align => 'center')
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'center aligns title using specified width' do
|
182
|
+
expect(subject).to receive(:puts).with(' ' * 35 + @title)
|
183
|
+
expect(subject).to receive(:puts).with("\n")
|
184
|
+
subject.header(:title => @title, :align => 'center', :width => 80)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context 'spacing' do
|
189
|
+
it 'defaults to a single line of spacing between report' do
|
190
|
+
expect(subject).to receive(:puts).with('title')
|
191
|
+
expect(subject).to receive(:puts).with("\n")
|
192
|
+
subject.header(:title => 'title')
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'uses the defined spacing between report' do
|
196
|
+
expect(subject).to receive(:puts).with('title')
|
197
|
+
expect(subject).to receive(:puts).with("\n" * 3)
|
198
|
+
subject.header(:title => 'title', :spacing => 3)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context 'timestamp subheading' do
|
203
|
+
it 'is added with default alignment' do
|
204
|
+
expect(subject).to receive(:puts).with('title')
|
205
|
+
expect(subject).to receive(:puts).with(/^#{timestamp_regex}/)
|
206
|
+
expect(subject).to receive(:puts).with("\n")
|
207
|
+
subject.header(:title => 'title', :timestamp => true)
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'added with right alignment' do
|
211
|
+
expect(subject).to receive(:puts).with(/^ *title$/)
|
212
|
+
expect(subject).to receive(:puts).with(/^ *#{timestamp_regex}$/)
|
213
|
+
expect(subject).to receive(:puts).with("\n")
|
214
|
+
subject.header(:title => 'title', :align => 'right', :timestamp => true, :width => 80)
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'added with center alignment' do
|
218
|
+
expect(subject).to receive(:puts).with(/^ *title *$/)
|
219
|
+
expect(subject).to receive(:puts).with(/^ *#{timestamp_regex} *$/)
|
220
|
+
expect(subject).to receive(:puts).with("\n")
|
221
|
+
subject.header(:title => 'title', :align => 'center', :timestamp => true, :width => 80)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
context 'horizontal rule' do
|
226
|
+
it 'uses dashes by default' do
|
227
|
+
expect(subject).to receive(:puts)
|
228
|
+
expect(subject).to receive(:puts).with(linechar * 100)
|
229
|
+
expect(subject).to receive(:puts)
|
230
|
+
subject.header(:rule => true)
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'uses = as the rule character' do
|
234
|
+
expect(subject).to receive(:puts)
|
235
|
+
expect(subject).to receive(:puts).with('=' * 100)
|
236
|
+
expect(subject).to receive(:puts)
|
237
|
+
subject.header(:rule => '=')
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
context 'color' do
|
242
|
+
it 'single red line' do
|
243
|
+
expect(subject).to receive(:puts).with(controls[:red] + 'Report' + controls[:clear])
|
244
|
+
expect(subject).to receive(:puts)
|
245
|
+
subject.header(:color => 'red')
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'multimple red lines' do
|
249
|
+
expect(subject).to receive(:puts).with(controls[:red] + 'Report' + controls[:clear])
|
250
|
+
expect(subject).to receive(:puts).with(controls[:red] + linechar * 100 + controls[:clear])
|
251
|
+
expect(subject).to receive(:puts)
|
252
|
+
subject.header(:color => 'red', :rule => true)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
context 'bold' do
|
257
|
+
it 'single line' do
|
258
|
+
expect(subject).to receive(:puts).with(controls[:bold] + 'Report' + controls[:clear])
|
259
|
+
expect(subject).to receive(:puts)
|
260
|
+
subject.header(:bold => true)
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'multimple lines' do
|
264
|
+
expect(subject).to receive(:puts).with(controls[:bold] + 'Report' + controls[:clear])
|
265
|
+
expect(subject).to receive(:puts).with(controls[:bold] + linechar * 100 + controls[:clear])
|
266
|
+
expect(subject).to receive(:puts)
|
267
|
+
subject.header(:bold => true, :rule => true)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
describe '#horizontal_rule' do
|
273
|
+
context 'argument validation' do
|
274
|
+
it 'does not allow invalid options' do
|
275
|
+
expect {
|
276
|
+
subject.horizontal_rule(:asdf => true)
|
277
|
+
}.to raise_error ArgumentError
|
278
|
+
end
|
279
|
+
|
280
|
+
it 'accepts char' do
|
281
|
+
expect {
|
282
|
+
expect(subject).to receive(:puts)
|
283
|
+
subject.horizontal_rule(:char => '*')
|
284
|
+
}.to_not raise_error
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'accepts width' do
|
288
|
+
expect {
|
289
|
+
expect(subject).to receive(:puts)
|
290
|
+
subject.horizontal_rule(:width => 10)
|
291
|
+
}.to_not raise_error
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
context 'drawing' do
|
296
|
+
it 'writes a 100 yard dash by default' do
|
297
|
+
expect(subject).to receive(:puts).with(linechar * 100)
|
298
|
+
subject.horizontal_rule
|
299
|
+
end
|
300
|
+
|
301
|
+
it 'writes a 100 yard asterisk' do
|
302
|
+
expect(subject).to receive(:puts).with('*' * 100)
|
303
|
+
subject.horizontal_rule(:char => '*')
|
304
|
+
end
|
305
|
+
|
306
|
+
it 'writes a 50 yard equals' do
|
307
|
+
expect(subject).to receive(:puts).with('=' * 50)
|
308
|
+
subject.horizontal_rule(:char => '=', :width => 50)
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
it 'outputs color' do
|
313
|
+
expect(subject).to receive(:puts).with(controls[:red] + linechar * 100 + controls[:clear])
|
314
|
+
subject.horizontal_rule(:color => 'red')
|
315
|
+
end
|
316
|
+
|
317
|
+
it 'outputs bold' do
|
318
|
+
expect(subject).to receive(:puts).with(controls[:bold] + linechar * 100 + controls[:clear])
|
319
|
+
subject.horizontal_rule(:bold => true)
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
describe '#vertical_spacing' do
|
324
|
+
it 'accepts a fixnum as a valid argument' do
|
325
|
+
expect {
|
326
|
+
subject.vertical_spacing('asdf')
|
327
|
+
}.to raise_error ArgumentError
|
328
|
+
end
|
329
|
+
|
330
|
+
it 'prints carriage returns for the number of lines' do
|
331
|
+
expect(subject).to receive(:puts).with("\n" * 3)
|
332
|
+
subject.vertical_spacing(3)
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
describe '#datetime' do
|
337
|
+
context 'argument validation' do
|
338
|
+
it 'does not allow invalid options' do
|
339
|
+
expect {
|
340
|
+
subject.datetime(:asdf => true)
|
341
|
+
}.to raise_error ArgumentError
|
342
|
+
end
|
343
|
+
|
344
|
+
it 'accepts align' do
|
345
|
+
expect {
|
346
|
+
expect(subject).to receive(:puts)
|
347
|
+
subject.datetime(:align => 'left')
|
348
|
+
}.to_not raise_error
|
349
|
+
end
|
350
|
+
|
351
|
+
it 'accepts width' do
|
352
|
+
expect {
|
353
|
+
expect(subject).to receive(:puts)
|
354
|
+
subject.datetime(:width => 70)
|
355
|
+
}.to_not raise_error
|
356
|
+
end
|
357
|
+
|
358
|
+
it 'accepts format' do
|
359
|
+
expect {
|
360
|
+
expect(subject).to receive(:puts)
|
361
|
+
subject.datetime(:format => '%m/%d/%Y')
|
362
|
+
}.to_not raise_error
|
363
|
+
end
|
364
|
+
|
365
|
+
it 'does not allow invalid width' do
|
366
|
+
expect {
|
367
|
+
subject.datetime(:align => 'right', :width => 'asdf')
|
368
|
+
}.to raise_error
|
369
|
+
end
|
370
|
+
|
371
|
+
it 'does not allow invalid align' do
|
372
|
+
expect {
|
373
|
+
subject.datetime(:align => 1234)
|
374
|
+
}.to raise_error
|
375
|
+
end
|
376
|
+
|
377
|
+
it 'does not allow a timestamp format larger than the width' do
|
378
|
+
expect {
|
379
|
+
subject.datetime(:width => 8)
|
380
|
+
}.to raise_error
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
context 'display' do
|
385
|
+
it 'a default format - left aligned' do
|
386
|
+
expect(subject).to receive(:puts).with(/^#{timestamp_regex} *$/)
|
387
|
+
subject.datetime
|
388
|
+
end
|
389
|
+
|
390
|
+
it 'a default format - right aligned' do
|
391
|
+
expect(subject).to receive(:puts).with(/^ *#{timestamp_regex}$/)
|
392
|
+
subject.datetime(:align => 'right')
|
393
|
+
end
|
394
|
+
|
395
|
+
it 'a default format - center aligned' do
|
396
|
+
expect(subject).to receive(:puts).with(/^ *#{timestamp_regex} *$/)
|
397
|
+
subject.datetime(:align => 'center')
|
398
|
+
end
|
399
|
+
|
400
|
+
it 'a modified format' do
|
401
|
+
expect(subject).to receive(:puts).with(/^\d{2}\/\d{2}\/\d{2} *$/)
|
402
|
+
subject.datetime(:format => '%y/%m/%d')
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
it 'outputs color' do
|
407
|
+
expect(subject).to receive(:puts).with(/^\e\[31m#{timestamp_regex}\e\[0m/)
|
408
|
+
subject.datetime(:color => 'red')
|
409
|
+
end
|
410
|
+
|
411
|
+
it 'outputs bold' do
|
412
|
+
expect(subject).to receive(:puts).with(/^\e\[1m#{timestamp_regex}\e\[0m/)
|
413
|
+
subject.datetime(:bold => true)
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
describe '#aligned' do
|
418
|
+
context 'argument validation' do
|
419
|
+
it 'accepts align' do
|
420
|
+
expect {
|
421
|
+
allow(subject).to receive(:puts)
|
422
|
+
subject.aligned('test', :align => 'left')
|
423
|
+
}.to_not raise_error
|
424
|
+
end
|
425
|
+
|
426
|
+
it 'does not allow invalid align values' do
|
427
|
+
expect {
|
428
|
+
subject.aligned('test', :align => 1234)
|
429
|
+
}.to raise_error ArgumentError
|
430
|
+
end
|
431
|
+
|
432
|
+
it 'accepts width' do
|
433
|
+
expect {
|
434
|
+
allow(subject).to receive(:puts)
|
435
|
+
subject.aligned('test', :width => 40)
|
436
|
+
}.to_not raise_error
|
437
|
+
end
|
438
|
+
|
439
|
+
it 'does not allow invalid width values' do
|
440
|
+
expect {
|
441
|
+
subject.aligned('test', :align => 'right', :width => 'asdf')
|
442
|
+
}.to raise_error
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
it 'outputs color' do
|
447
|
+
expect(subject).to receive(:puts).with(controls[:red] + 'x' * 10 + controls[:clear])
|
448
|
+
subject.aligned('x' * 10, :color => 'red')
|
449
|
+
end
|
450
|
+
|
451
|
+
it 'outputs bold' do
|
452
|
+
expect(subject).to receive(:puts).with(controls[:bold] + 'x' * 10 + controls[:clear])
|
453
|
+
subject.aligned('x' * 10, :bold => true)
|
454
|
+
end
|
455
|
+
|
456
|
+
end
|
457
|
+
|
458
|
+
describe '#footer' do
|
459
|
+
context 'argument validation' do
|
460
|
+
it 'accepts title' do
|
461
|
+
expect {
|
462
|
+
allow(subject).to receive(:puts)
|
463
|
+
subject.footer(:title => 'test')
|
464
|
+
}.to_not raise_error
|
465
|
+
end
|
466
|
+
|
467
|
+
it 'accepts align' do
|
468
|
+
expect {
|
469
|
+
allow(subject).to receive(:puts)
|
470
|
+
subject.footer(:align => 'right')
|
471
|
+
}.to_not raise_error
|
472
|
+
end
|
473
|
+
|
474
|
+
it 'does not accept invalid align' do
|
475
|
+
expect {
|
476
|
+
subject.header(:align => 1234)
|
477
|
+
}.to raise_error ArgumentError
|
478
|
+
end
|
479
|
+
|
480
|
+
it 'accepts width' do
|
481
|
+
expect {
|
482
|
+
allow(subject).to receive(:puts)
|
483
|
+
subject.footer(:width => 50)
|
484
|
+
}.to_not raise_error
|
485
|
+
end
|
486
|
+
|
487
|
+
it 'does not accept invalid width' do
|
488
|
+
expect {
|
489
|
+
subject.footer(:width => 'asdf')
|
490
|
+
}.to raise_error ArgumentError
|
491
|
+
end
|
492
|
+
|
493
|
+
it 'does not allow title > width' do
|
494
|
+
expect {
|
495
|
+
subject.footer(:title => 'testtesttest', :width => 6)
|
496
|
+
}.to raise_error ArgumentError
|
497
|
+
end
|
498
|
+
|
499
|
+
it 'accepts spacing' do
|
500
|
+
expect {
|
501
|
+
allow(subject).to receive(:puts)
|
502
|
+
subject.footer(:spacing => 3)
|
503
|
+
}.to_not raise_error
|
504
|
+
end
|
505
|
+
end
|
506
|
+
|
507
|
+
context 'alignment' do
|
508
|
+
before :each do
|
509
|
+
@title = 'test12test'
|
510
|
+
end
|
511
|
+
|
512
|
+
it 'left aligns the title by default' do
|
513
|
+
expect(subject).to receive(:puts).with("\n")
|
514
|
+
expect(subject).to receive(:puts).with(@title)
|
515
|
+
subject.footer(:title => @title)
|
516
|
+
end
|
517
|
+
|
518
|
+
it 'left aligns the title' do
|
519
|
+
expect(subject).to receive(:puts).with("\n")
|
520
|
+
expect(subject).to receive(:puts).with(@title)
|
521
|
+
subject.footer(:title => @title, :align => 'left')
|
522
|
+
end
|
523
|
+
|
524
|
+
it 'right aligns the title' do
|
525
|
+
expect(subject).to receive(:puts).with("\n")
|
526
|
+
expect(subject).to receive(:puts).with(' ' * 90 + @title)
|
527
|
+
subject.footer(:title => @title, :align => 'right')
|
528
|
+
end
|
529
|
+
|
530
|
+
it 'right aligns the title using width' do
|
531
|
+
expect(subject).to receive(:puts).with("\n")
|
532
|
+
expect(subject).to receive(:puts).with(' ' * 40 + @title)
|
533
|
+
subject.footer(:title => @title, :align => 'right', :width => 50)
|
534
|
+
end
|
535
|
+
|
536
|
+
it 'center aligns the title' do
|
537
|
+
expect(subject).to receive(:puts).with("\n")
|
538
|
+
expect(subject).to receive(:puts).with(' ' * 45 + @title)
|
539
|
+
subject.footer(:title => @title, :align => 'center')
|
540
|
+
end
|
541
|
+
|
542
|
+
it 'center aligns the title using width' do
|
543
|
+
expect(subject).to receive(:puts).with("\n")
|
544
|
+
expect(subject).to receive(:puts).with(' ' * 35 + @title)
|
545
|
+
subject.footer(:title => @title, :align => 'center', :width => 80)
|
546
|
+
end
|
547
|
+
end
|
548
|
+
|
549
|
+
context 'spacing' do
|
550
|
+
it 'defaults to a single line of spacing between report' do
|
551
|
+
expect(subject).to receive(:puts).with("\n")
|
552
|
+
expect(subject).to receive(:puts).with('title')
|
553
|
+
subject.footer(:title => 'title')
|
554
|
+
end
|
555
|
+
|
556
|
+
it 'uses the defined spacing between report' do
|
557
|
+
expect(subject).to receive(:puts).with("\n" * 3)
|
558
|
+
expect(subject).to receive(:puts).with('title')
|
559
|
+
subject.footer(:title => 'title', :spacing => 3)
|
560
|
+
end
|
561
|
+
end
|
562
|
+
|
563
|
+
context 'timestamp subheading' do
|
564
|
+
it 'is added with default alignment' do
|
565
|
+
expect(subject).to receive(:puts).with("\n")
|
566
|
+
expect(subject).to receive(:puts).with('title')
|
567
|
+
expect(subject).to receive(:puts).with(/^#{timestamp_regex}/)
|
568
|
+
subject.footer(:title => 'title', :timestamp => true)
|
569
|
+
end
|
570
|
+
|
571
|
+
it 'added with right alignment' do
|
572
|
+
expect(subject).to receive(:puts).with("\n")
|
573
|
+
expect(subject).to receive(:puts).with(/^ *title$/)
|
574
|
+
expect(subject).to receive(:puts).with(/^ *#{timestamp_regex}$/)
|
575
|
+
subject.footer(:title => 'title', :align => 'right', :timestamp => true, :width => 80)
|
576
|
+
end
|
577
|
+
|
578
|
+
it 'added with center alignment' do
|
579
|
+
expect(subject).to receive(:puts).with("\n")
|
580
|
+
expect(subject).to receive(:puts).with(/^ *title *$/)
|
581
|
+
expect(subject).to receive(:puts).with(/^ *#{timestamp_regex} *$/)
|
582
|
+
subject.footer(:title => 'title', :align => 'center', :timestamp => true, :width => 80)
|
583
|
+
end
|
584
|
+
end
|
585
|
+
|
586
|
+
context 'horizontal rule' do
|
587
|
+
it 'uses dashes by default' do
|
588
|
+
expect(subject).to receive(:puts)
|
589
|
+
expect(subject).to receive(:puts).with(linechar * 100)
|
590
|
+
expect(subject).to receive(:puts)
|
591
|
+
subject.footer(:rule => true)
|
592
|
+
end
|
593
|
+
|
594
|
+
it 'uses = as the rule character' do
|
595
|
+
expect(subject).to receive(:puts)
|
596
|
+
expect(subject).to receive(:puts).with('=' * 100)
|
597
|
+
expect(subject).to receive(:puts)
|
598
|
+
subject.footer(:rule => '=')
|
599
|
+
end
|
600
|
+
end
|
601
|
+
|
602
|
+
it 'outputs red' do
|
603
|
+
expect(subject).to receive(:puts).with("\n")
|
604
|
+
expect(subject).to receive(:puts).with(controls[:red] + 'title' + controls[:clear])
|
605
|
+
expect(subject).to receive(:puts).with(/^\e\[31m#{timestamp_regex}\e\[0m/)
|
606
|
+
subject.footer(:title => 'title', :timestamp => true, :color => 'red')
|
607
|
+
end
|
608
|
+
|
609
|
+
it 'outputs bold' do
|
610
|
+
expect(subject).to receive(:puts).with("\n")
|
611
|
+
expect(subject).to receive(:puts).with(controls[:bold] + 'title' + controls[:clear])
|
612
|
+
expect(subject).to receive(:puts).with(/^\e\[1m#{timestamp_regex}\e\[0m/)
|
613
|
+
subject.footer(:title => 'title', :timestamp => true, :bold => true)
|
614
|
+
end
|
615
|
+
end
|
616
|
+
|
617
|
+
describe '#table' do
|
618
|
+
it 'instantiates the table class' do
|
619
|
+
allow(subject).to receive(:puts)
|
620
|
+
expect(subject).to receive(:table).once
|
621
|
+
subject.table { }
|
622
|
+
end
|
623
|
+
|
624
|
+
it 'requires a row to be defined' do
|
625
|
+
expect {
|
626
|
+
subject.table
|
627
|
+
}.to raise_error LocalJumpError
|
628
|
+
end
|
629
|
+
|
630
|
+
it 'accepts valid options' do
|
631
|
+
expect {
|
632
|
+
subject.table(:border => true) { }
|
633
|
+
}.to_not raise_error
|
634
|
+
end
|
635
|
+
|
636
|
+
it 'rejects invalid options' do
|
637
|
+
expect {
|
638
|
+
allow(subject).to receive(:puts)
|
639
|
+
subject.table(:asdf => '100') { }
|
640
|
+
}.to raise_error ArgumentError
|
641
|
+
end
|
642
|
+
end
|
643
|
+
|
644
|
+
describe '#row' do
|
645
|
+
it 'instantiates a row class' do
|
646
|
+
expect(subject).to receive(:row).once
|
647
|
+
allow(subject).to receive(:puts)
|
648
|
+
|
649
|
+
subject.table do
|
650
|
+
subject.row do
|
651
|
+
end
|
652
|
+
end
|
653
|
+
end
|
654
|
+
end
|
655
|
+
|
656
|
+
describe '#column' do
|
657
|
+
it 'instantiates multiple columns' do
|
658
|
+
expect(subject).to receive(:column).exactly(3).times
|
659
|
+
allow(subject).to receive(:puts)
|
660
|
+
|
661
|
+
subject.table do
|
662
|
+
subject.row do
|
663
|
+
subject.column('asdf')
|
664
|
+
subject.column('qwer')
|
665
|
+
subject.column('zxcv')
|
666
|
+
end
|
667
|
+
end
|
668
|
+
end
|
669
|
+
|
670
|
+
it 'accepts valid options' do
|
671
|
+
expect(subject).to receive(:column).once
|
672
|
+
allow(subject).to receive(:puts)
|
673
|
+
|
674
|
+
subject.table do
|
675
|
+
subject.row do
|
676
|
+
subject.column('asdf', :width => 30)
|
677
|
+
end
|
678
|
+
end
|
679
|
+
end
|
680
|
+
|
681
|
+
it 'rejects invalid options' do
|
682
|
+
allow(subject).to receive(:puts)
|
683
|
+
expect {
|
684
|
+
subject.table do
|
685
|
+
subject.row do
|
686
|
+
subject.column('asdf', :asdf => 30)
|
687
|
+
end
|
688
|
+
end
|
689
|
+
}.to raise_error ArgumentError
|
690
|
+
end
|
691
|
+
end
|
692
|
+
|
693
|
+
end
|