command_kit 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +4 -6
  3. data/.rubocop.yml +13 -0
  4. data/ChangeLog.md +18 -0
  5. data/Gemfile +2 -0
  6. data/LICENSE.txt +1 -1
  7. data/README.md +18 -9
  8. data/command_kit.gemspec +0 -1
  9. data/examples/printing/tables.rb +141 -0
  10. data/gemspec.yml +3 -3
  11. data/lib/command_kit/bug_report.rb +105 -0
  12. data/lib/command_kit/colors.rb +4 -4
  13. data/lib/command_kit/edit.rb +54 -0
  14. data/lib/command_kit/env.rb +1 -1
  15. data/lib/command_kit/options/option.rb +5 -1
  16. data/lib/command_kit/options/option_value.rb +2 -2
  17. data/lib/command_kit/options/parser.rb +1 -1
  18. data/lib/command_kit/options/quiet.rb +1 -1
  19. data/lib/command_kit/options/verbose.rb +2 -2
  20. data/lib/command_kit/options/version.rb +10 -0
  21. data/lib/command_kit/options.rb +1 -1
  22. data/lib/command_kit/os.rb +1 -1
  23. data/lib/command_kit/printing/fields.rb +56 -0
  24. data/lib/command_kit/printing/indent.rb +1 -1
  25. data/lib/command_kit/printing/lists.rb +91 -0
  26. data/lib/command_kit/printing/tables/border_style.rb +169 -0
  27. data/lib/command_kit/printing/tables/cell_builder.rb +93 -0
  28. data/lib/command_kit/printing/tables/row_builder.rb +111 -0
  29. data/lib/command_kit/printing/tables/style.rb +198 -0
  30. data/lib/command_kit/printing/tables/table_builder.rb +145 -0
  31. data/lib/command_kit/printing/tables/table_formatter.rb +254 -0
  32. data/lib/command_kit/printing/tables.rb +208 -0
  33. data/lib/command_kit/stdio.rb +5 -1
  34. data/lib/command_kit/version.rb +1 -1
  35. data/spec/bug_report_spec.rb +266 -0
  36. data/spec/colors_spec.rb +6 -0
  37. data/spec/command_name_spec.rb +1 -1
  38. data/spec/edit_spec.rb +72 -0
  39. data/spec/options/option_spec.rb +12 -2
  40. data/spec/options/quiet_spec.rb +51 -0
  41. data/spec/options/verbose_spec.rb +51 -0
  42. data/spec/options/version_spec.rb +146 -0
  43. data/spec/pager_spec.rb +1 -1
  44. data/spec/printing/fields_spec.rb +167 -0
  45. data/spec/printing/lists_spec.rb +99 -0
  46. data/spec/printing/tables/border_style.rb +43 -0
  47. data/spec/printing/tables/cell_builer_spec.rb +135 -0
  48. data/spec/printing/tables/row_builder_spec.rb +165 -0
  49. data/spec/printing/tables/style_spec.rb +377 -0
  50. data/spec/printing/tables/table_builder_spec.rb +252 -0
  51. data/spec/printing/tables/table_formatter_spec.rb +1180 -0
  52. data/spec/printing/tables_spec.rb +1069 -0
  53. metadata +33 -7
@@ -0,0 +1,1180 @@
1
+ require 'spec_helper'
2
+ require 'command_kit/printing/tables/table_formatter'
3
+ require 'command_kit/printing/tables/table_builder'
4
+ require 'command_kit/printing/tables/style'
5
+
6
+ describe CommandKit::Printing::Tables::TableFormatter do
7
+ let(:header) { ['A', 'B', 'C'] }
8
+ let(:rows) do
9
+ [
10
+ ['AAAA', 'BBBB', 'CCCC'],
11
+ ['DDDD', 'EEEE', 'FFFF'],
12
+ ['GGGG', 'HHHH', 'IIII']
13
+ ]
14
+ end
15
+ let(:multiline_rows) do
16
+ [
17
+ ["AAAA\nAA", "BBBB", "CCCC"],
18
+ ["DDDD", "EEEE\nEE", "FFFF"],
19
+ ["GGGG", "HHHH", "IIII\nII"]
20
+ ]
21
+ end
22
+ let(:rows_with_empty_cells) do
23
+ [
24
+ [nil, 'BBBB', 'CCCC'],
25
+ ['DDDD', nil, 'FFFF'],
26
+ ['GGGG', 'HHHH', nil ]
27
+ ]
28
+ end
29
+ let(:rows_with_diff_row_lengths) do
30
+ [
31
+ ['AAAA'],
32
+ ['DDDD', 'EEEE'],
33
+ ['GGGG', 'HHHH', 'IIII']
34
+ ]
35
+ end
36
+ let(:unjustified_rows) do
37
+ [
38
+ ['AAAA', 'BBBB', 'CCCC'],
39
+ ['DD', 'EE', 'FF' ],
40
+ ['G', 'H', 'I' ]
41
+ ]
42
+ end
43
+
44
+ let(:table) { CommandKit::Printing::Tables::TableBuilder.new(rows) }
45
+ let(:style) { CommandKit::Printing::Tables::Style.new }
46
+
47
+ subject { described_class.new(table,style) }
48
+
49
+ describe "#format" do
50
+ it "must yield each line of the table with 1 space padding and no borders" do
51
+ expect { |b|
52
+ subject.format(&b)
53
+ }.to yield_successive_args(
54
+ " AAAA BBBB CCCC ",
55
+ " DDDD EEEE FFFF ",
56
+ " GGGG HHHH IIII "
57
+ )
58
+ end
59
+
60
+ context "but when the table contains multi-line cells" do
61
+ let(:rows) { multiline_rows }
62
+
63
+ it "must yield each line of each row" do
64
+ expect { |b|
65
+ subject.format(&b)
66
+ }.to yield_successive_args(
67
+ " AAAA BBBB CCCC ",
68
+ " AA ",
69
+ " DDDD EEEE FFFF ",
70
+ " EE ",
71
+ " GGGG HHHH IIII ",
72
+ " II "
73
+ )
74
+ end
75
+ end
76
+
77
+ context "but when the table contains empty cells" do
78
+ let(:rows) { rows_with_empty_cells }
79
+
80
+ it "must replace the empty cells with spaces" do
81
+ expect { |b|
82
+ subject.format(&b)
83
+ }.to yield_successive_args(
84
+ " BBBB CCCC ",
85
+ " DDDD FFFF ",
86
+ " GGGG HHHH "
87
+ )
88
+ end
89
+ end
90
+
91
+ context "but when the table contains empty cells" do
92
+ let(:rows) { rows_with_diff_row_lengths }
93
+
94
+ it "must pad the columns with empty cells" do
95
+ expect { |b|
96
+ subject.format(&b)
97
+ }.to yield_successive_args(
98
+ " AAAA ",
99
+ " DDDD EEEE ",
100
+ " GGGG HHHH IIII "
101
+ )
102
+ end
103
+ end
104
+
105
+ context "when the #style.separate_rows? is true" do
106
+ let(:style) do
107
+ CommandKit::Printing::Tables::Style.new(separate_rows: true)
108
+ end
109
+
110
+ it "must yield the rows with blank lines between each row" do
111
+ expect { |b|
112
+ subject.format(&b)
113
+ }.to yield_successive_args(
114
+ " AAAA BBBB CCCC ",
115
+ "",
116
+ " DDDD EEEE FFFF ",
117
+ "",
118
+ " GGGG HHHH IIII "
119
+ )
120
+ end
121
+ end
122
+
123
+ context "and when #style.justify is :left" do
124
+ let(:rows) { unjustified_rows }
125
+ let(:style) do
126
+ CommandKit::Printing::Tables::Style.new(justify: :left)
127
+ end
128
+
129
+ it "must left justify each cell" do
130
+ expect { |b|
131
+ subject.format(&b)
132
+ }.to yield_successive_args(
133
+ " AAAA BBBB CCCC ",
134
+ " DD EE FF ",
135
+ " G H I "
136
+ )
137
+ end
138
+ end
139
+
140
+ context "and when #style.justify is :right" do
141
+ let(:rows) { unjustified_rows }
142
+ let(:style) do
143
+ CommandKit::Printing::Tables::Style.new(justify: :right)
144
+ end
145
+
146
+ it "must right justify each cell" do
147
+ expect { |b|
148
+ subject.format(&b)
149
+ }.to yield_successive_args(
150
+ " AAAA BBBB CCCC ",
151
+ " DD EE FF ",
152
+ " G H I "
153
+ )
154
+ end
155
+ end
156
+
157
+ context "and when #style.justify is :center" do
158
+ let(:rows) { unjustified_rows }
159
+ let(:style) do
160
+ CommandKit::Printing::Tables::Style.new(justify: :center)
161
+ end
162
+
163
+ it "must center justify each cell" do
164
+ expect { |b|
165
+ subject.format(&b)
166
+ }.to yield_successive_args(
167
+ " AAAA BBBB CCCC ",
168
+ " DD EE FF ",
169
+ " G H I "
170
+ )
171
+ end
172
+ end
173
+
174
+ context "and when #table.header? is true" do
175
+ let(:table) do
176
+ CommandKit::Printing::Tables::TableBuilder.new(rows, header: header)
177
+ end
178
+
179
+ it "must yield the center justified header row, then a blank line, then the rest of the rows" do
180
+ expect { |b|
181
+ subject.format(&b)
182
+ }.to yield_successive_args(
183
+ " A B C ",
184
+ "",
185
+ " AAAA BBBB CCCC ",
186
+ " DDDD EEEE FFFF ",
187
+ " GGGG HHHH IIII "
188
+ )
189
+ end
190
+
191
+ context "and #style.separate_rows? is true" do
192
+ let(:style) do
193
+ CommandKit::Printing::Tables::Style.new(separate_rows: true)
194
+ end
195
+
196
+ it "must yield the header, a blank line, then the rows with blaink lines between each row" do
197
+ expect { |b|
198
+ subject.format(&b)
199
+ }.to yield_successive_args(
200
+ " A B C ",
201
+ "",
202
+ " AAAA BBBB CCCC ",
203
+ "",
204
+ " DDDD EEEE FFFF ",
205
+ "",
206
+ " GGGG HHHH IIII "
207
+ )
208
+ end
209
+ end
210
+
211
+ context "and when #style.justify_header is :left" do
212
+ let(:style) do
213
+ CommandKit::Printing::Tables::Style.new(justify_header: :left)
214
+ end
215
+
216
+ it "must left justify the header cells" do
217
+ expect { |b|
218
+ subject.format(&b)
219
+ }.to yield_successive_args(
220
+ " A B C ",
221
+ "",
222
+ " AAAA BBBB CCCC ",
223
+ " DDDD EEEE FFFF ",
224
+ " GGGG HHHH IIII "
225
+ )
226
+ end
227
+ end
228
+
229
+ context "and when #style.justify_header is :right" do
230
+ let(:style) do
231
+ CommandKit::Printing::Tables::Style.new(justify_header: :right)
232
+ end
233
+
234
+ it "must right justify the header cells" do
235
+ expect { |b|
236
+ subject.format(&b)
237
+ }.to yield_successive_args(
238
+ " A B C ",
239
+ "",
240
+ " AAAA BBBB CCCC ",
241
+ " DDDD EEEE FFFF ",
242
+ " GGGG HHHH IIII "
243
+ )
244
+ end
245
+ end
246
+
247
+ context "and when #style.justify_header is :center" do
248
+ let(:style) do
249
+ CommandKit::Printing::Tables::Style.new(justify_header: :center)
250
+ end
251
+
252
+ it "must center justify the header cells" do
253
+ expect { |b|
254
+ subject.format(&b)
255
+ }.to yield_successive_args(
256
+ " A B C ",
257
+ "",
258
+ " AAAA BBBB CCCC ",
259
+ " DDDD EEEE FFFF ",
260
+ " GGGG HHHH IIII "
261
+ )
262
+ end
263
+ end
264
+
265
+ context "and when #style.justify is :left" do
266
+ let(:rows) { unjustified_rows }
267
+ let(:style) do
268
+ CommandKit::Printing::Tables::Style.new(justify: :left)
269
+ end
270
+
271
+ it "must left justify each cell" do
272
+ expect { |b|
273
+ subject.format(&b)
274
+ }.to yield_successive_args(
275
+ " A B C ",
276
+ "",
277
+ " AAAA BBBB CCCC ",
278
+ " DD EE FF ",
279
+ " G H I "
280
+ )
281
+ end
282
+ end
283
+
284
+ context "and when #style.justify is :right" do
285
+ let(:rows) { unjustified_rows }
286
+ let(:style) do
287
+ CommandKit::Printing::Tables::Style.new(justify: :right)
288
+ end
289
+
290
+ it "must right justify each cell" do
291
+ expect { |b|
292
+ subject.format(&b)
293
+ }.to yield_successive_args(
294
+ " A B C ",
295
+ "",
296
+ " AAAA BBBB CCCC ",
297
+ " DD EE FF ",
298
+ " G H I "
299
+ )
300
+ end
301
+ end
302
+
303
+ context "and when #style.justify is :center" do
304
+ let(:rows) { unjustified_rows }
305
+ let(:style) do
306
+ CommandKit::Printing::Tables::Style.new(justify: :center)
307
+ end
308
+
309
+ it "must center justify each cell" do
310
+ expect { |b|
311
+ subject.format(&b)
312
+ }.to yield_successive_args(
313
+ " A B C ",
314
+ "",
315
+ " AAAA BBBB CCCC ",
316
+ " DD EE FF ",
317
+ " G H I "
318
+ )
319
+ end
320
+ end
321
+ end
322
+
323
+ context "when #style.border is :ascii" do
324
+ let(:style) do
325
+ CommandKit::Printing::Tables::Style.new(border: :ascii)
326
+ end
327
+
328
+ it "must yield each row with an ASCII border" do
329
+ expect { |b|
330
+ subject.format(&b)
331
+ }.to yield_successive_args(
332
+ "+------+------+------+",
333
+ "| AAAA | BBBB | CCCC |",
334
+ "| DDDD | EEEE | FFFF |",
335
+ "| GGGG | HHHH | IIII |",
336
+ "+------+------+------+"
337
+ )
338
+ end
339
+
340
+ context "but when the table contains multi-line cells" do
341
+ let(:rows) { multiline_rows }
342
+
343
+ it "must yield each line of each row" do
344
+ expect { |b|
345
+ subject.format(&b)
346
+ }.to yield_successive_args(
347
+ "+------+------+------+",
348
+ "| AAAA | BBBB | CCCC |",
349
+ "| AA | | |",
350
+ "| DDDD | EEEE | FFFF |",
351
+ "| | EE | |",
352
+ "| GGGG | HHHH | IIII |",
353
+ "| | | II |",
354
+ "+------+------+------+"
355
+ )
356
+ end
357
+ end
358
+
359
+ context "but when the table contains empty cells" do
360
+ let(:rows) { rows_with_empty_cells }
361
+
362
+ it "must replace the empty cells with spaces" do
363
+ expect { |b|
364
+ subject.format(&b)
365
+ }.to yield_successive_args(
366
+ "+------+------+------+",
367
+ "| | BBBB | CCCC |",
368
+ "| DDDD | | FFFF |",
369
+ "| GGGG | HHHH | |",
370
+ "+------+------+------+"
371
+ )
372
+ end
373
+ end
374
+
375
+ context "but when the table contains empty cells" do
376
+ let(:rows) { rows_with_diff_row_lengths }
377
+
378
+ it "must pad the columns with empty cells" do
379
+ expect { |b|
380
+ subject.format(&b)
381
+ }.to yield_successive_args(
382
+ "+------+------+------+",
383
+ "| AAAA | | |",
384
+ "| DDDD | EEEE | |",
385
+ "| GGGG | HHHH | IIII |",
386
+ "+------+------+------+"
387
+ )
388
+ end
389
+ end
390
+
391
+ context "and when #style.separate_rows is true" do
392
+ let(:style) do
393
+ CommandKit::Printing::Tables::Style.new(
394
+ border: :ascii,
395
+ separate_rows: true
396
+ )
397
+ end
398
+
399
+ it "must yield each row with a separator line between each row" do
400
+ expect { |b|
401
+ subject.format(&b)
402
+ }.to yield_successive_args(
403
+ "+------+------+------+",
404
+ "| AAAA | BBBB | CCCC |",
405
+ "+------+------+------+",
406
+ "| DDDD | EEEE | FFFF |",
407
+ "+------+------+------+",
408
+ "| GGGG | HHHH | IIII |",
409
+ "+------+------+------+"
410
+ )
411
+ end
412
+ end
413
+
414
+ context "and when #style.justify is :left" do
415
+ let(:rows) { unjustified_rows }
416
+
417
+ let(:style) do
418
+ CommandKit::Printing::Tables::Style.new(
419
+ border: :ascii,
420
+ justify: :left
421
+ )
422
+ end
423
+
424
+ it "must left justify each cell" do
425
+ expect { |b|
426
+ subject.format(&b)
427
+ }.to yield_successive_args(
428
+ "+------+------+------+",
429
+ "| AAAA | BBBB | CCCC |",
430
+ "| DD | EE | FF |",
431
+ "| G | H | I |",
432
+ "+------+------+------+"
433
+ )
434
+ end
435
+ end
436
+
437
+ context "and when #style.justify is :right" do
438
+ let(:rows) { unjustified_rows }
439
+
440
+ let(:style) do
441
+ CommandKit::Printing::Tables::Style.new(
442
+ border: :ascii,
443
+ justify: :right
444
+ )
445
+ end
446
+
447
+ it "must right justify each cell" do
448
+ expect { |b|
449
+ subject.format(&b)
450
+ }.to yield_successive_args(
451
+ "+------+------+------+",
452
+ "| AAAA | BBBB | CCCC |",
453
+ "| DD | EE | FF |",
454
+ "| G | H | I |",
455
+ "+------+------+------+"
456
+ )
457
+ end
458
+ end
459
+
460
+ context "and when #style.justify is :center" do
461
+ let(:rows) { unjustified_rows }
462
+
463
+ let(:style) do
464
+ CommandKit::Printing::Tables::Style.new(
465
+ border: :ascii,
466
+ justify: :center
467
+ )
468
+ end
469
+
470
+ it "must center justify each cell" do
471
+ expect { |b|
472
+ subject.format(&b)
473
+ }.to yield_successive_args(
474
+ "+------+------+------+",
475
+ "| AAAA | BBBB | CCCC |",
476
+ "| DD | EE | FF |",
477
+ "| G | H | I |",
478
+ "+------+------+------+"
479
+ )
480
+ end
481
+ end
482
+
483
+ context "and when #table.header? is true" do
484
+ let(:table) do
485
+ CommandKit::Printing::Tables::TableBuilder.new(rows, header: header)
486
+ end
487
+
488
+ it "must yield the center justified header row, then a separator line, then the table" do
489
+ expect { |b|
490
+ subject.format(&b)
491
+ }.to yield_successive_args(
492
+ "+------+------+------+",
493
+ "| A | B | C |",
494
+ "+------+------+------+",
495
+ "| AAAA | BBBB | CCCC |",
496
+ "| DDDD | EEEE | FFFF |",
497
+ "| GGGG | HHHH | IIII |",
498
+ "+------+------+------+"
499
+ )
500
+ end
501
+
502
+ context "and when #style.separate_rows? is true" do
503
+ let(:style) do
504
+ CommandKit::Printing::Tables::Style.new(
505
+ border: :ascii,
506
+ separate_rows: true
507
+ )
508
+ end
509
+
510
+ it "must yield the header and rows with separator lines between each row" do
511
+ expect { |b|
512
+ subject.format(&b)
513
+ }.to yield_successive_args(
514
+ "+------+------+------+",
515
+ "| A | B | C |",
516
+ "+------+------+------+",
517
+ "| AAAA | BBBB | CCCC |",
518
+ "+------+------+------+",
519
+ "| DDDD | EEEE | FFFF |",
520
+ "+------+------+------+",
521
+ "| GGGG | HHHH | IIII |",
522
+ "+------+------+------+"
523
+ )
524
+ end
525
+ end
526
+
527
+ context "and when #style.justify_header is :left" do
528
+ let(:style) do
529
+ CommandKit::Printing::Tables::Style.new(
530
+ border: :ascii,
531
+ justify_header: :left
532
+ )
533
+ end
534
+
535
+ it "must left justify the header cells" do
536
+ expect { |b|
537
+ subject.format(&b)
538
+ }.to yield_successive_args(
539
+ "+------+------+------+",
540
+ "| A | B | C |",
541
+ "+------+------+------+",
542
+ "| AAAA | BBBB | CCCC |",
543
+ "| DDDD | EEEE | FFFF |",
544
+ "| GGGG | HHHH | IIII |",
545
+ "+------+------+------+"
546
+ )
547
+ end
548
+ end
549
+
550
+ context "and when #style.justify_header is :right" do
551
+ let(:style) do
552
+ CommandKit::Printing::Tables::Style.new(
553
+ border: :ascii,
554
+ justify_header: :right
555
+ )
556
+ end
557
+
558
+ it "must right justify the header cells" do
559
+ expect { |b|
560
+ subject.format(&b)
561
+ }.to yield_successive_args(
562
+ "+------+------+------+",
563
+ "| A | B | C |",
564
+ "+------+------+------+",
565
+ "| AAAA | BBBB | CCCC |",
566
+ "| DDDD | EEEE | FFFF |",
567
+ "| GGGG | HHHH | IIII |",
568
+ "+------+------+------+"
569
+ )
570
+ end
571
+ end
572
+
573
+ context "and when #style.justify_header is :center" do
574
+ let(:style) do
575
+ CommandKit::Printing::Tables::Style.new(
576
+ border: :ascii,
577
+ justify_header: :center
578
+ )
579
+ end
580
+
581
+ it "must center justify the header cells" do
582
+ expect { |b|
583
+ subject.format(&b)
584
+ }.to yield_successive_args(
585
+ "+------+------+------+",
586
+ "| A | B | C |",
587
+ "+------+------+------+",
588
+ "| AAAA | BBBB | CCCC |",
589
+ "| DDDD | EEEE | FFFF |",
590
+ "| GGGG | HHHH | IIII |",
591
+ "+------+------+------+"
592
+ )
593
+ end
594
+ end
595
+ end
596
+ end
597
+
598
+ context "when #style.border is :line" do
599
+ let(:style) do
600
+ CommandKit::Printing::Tables::Style.new(border: :line)
601
+ end
602
+
603
+ it "must yield the table with an ANSI line border" do
604
+ expect { |b|
605
+ subject.format(&b)
606
+ }.to yield_successive_args(
607
+ "┌──────┬──────┬──────┐",
608
+ "│ AAAA │ BBBB │ CCCC │",
609
+ "│ DDDD │ EEEE │ FFFF │",
610
+ "│ GGGG │ HHHH │ IIII │",
611
+ "└──────┴──────┴──────┘"
612
+ )
613
+ end
614
+
615
+ context "but when the table contains multi-line cells" do
616
+ let(:rows) { multiline_rows }
617
+
618
+ it "must yield each line of each row" do
619
+ expect { |b|
620
+ subject.format(&b)
621
+ }.to yield_successive_args(
622
+ "┌──────┬──────┬──────┐",
623
+ "│ AAAA │ BBBB │ CCCC │",
624
+ "│ AA │ │ │",
625
+ "│ DDDD │ EEEE │ FFFF │",
626
+ "│ │ EE │ │",
627
+ "│ GGGG │ HHHH │ IIII │",
628
+ "│ │ │ II │",
629
+ "└──────┴──────┴──────┘"
630
+ )
631
+ end
632
+ end
633
+
634
+ context "but when the table contains empty cells" do
635
+ let(:rows) { rows_with_empty_cells }
636
+
637
+ it "must replace the empty cells with spaces" do
638
+ expect { |b|
639
+ subject.format(&b)
640
+ }.to yield_successive_args(
641
+ "┌──────┬──────┬──────┐",
642
+ "│ │ BBBB │ CCCC │",
643
+ "│ DDDD │ │ FFFF │",
644
+ "│ GGGG │ HHHH │ │",
645
+ "└──────┴──────┴──────┘"
646
+ )
647
+ end
648
+ end
649
+
650
+ context "but when the table contains empty cells" do
651
+ let(:rows) { rows_with_diff_row_lengths }
652
+
653
+ it "must pad the columns with empty cells" do
654
+ expect { |b|
655
+ subject.format(&b)
656
+ }.to yield_successive_args(
657
+ "┌──────┬──────┬──────┐",
658
+ "│ AAAA │ │ │",
659
+ "│ DDDD │ EEEE │ │",
660
+ "│ GGGG │ HHHH │ IIII │",
661
+ "└──────┴──────┴──────┘"
662
+ )
663
+ end
664
+ end
665
+
666
+ context "and when #style.separate_rows is true" do
667
+ let(:style) do
668
+ CommandKit::Printing::Tables::Style.new(
669
+ border: :line,
670
+ separate_rows: true
671
+ )
672
+ end
673
+
674
+ it "must yield each row with separator lines between each row" do
675
+ expect { |b|
676
+ subject.format(&b)
677
+ }.to yield_successive_args(
678
+ "┌──────┬──────┬──────┐",
679
+ "│ AAAA │ BBBB │ CCCC │",
680
+ "├──────┼──────┼──────┤",
681
+ "│ DDDD │ EEEE │ FFFF │",
682
+ "├──────┼──────┼──────┤",
683
+ "│ GGGG │ HHHH │ IIII │",
684
+ "└──────┴──────┴──────┘"
685
+ )
686
+ end
687
+ end
688
+
689
+ context "and when #style.justify is :left" do
690
+ let(:rows) { unjustified_rows }
691
+
692
+ let(:style) do
693
+ CommandKit::Printing::Tables::Style.new(
694
+ border: :line,
695
+ justify: :left
696
+ )
697
+ end
698
+
699
+ it "must left justify each cell" do
700
+ expect { |b|
701
+ subject.format(&b)
702
+ }.to yield_successive_args(
703
+ "┌──────┬──────┬──────┐",
704
+ "│ AAAA │ BBBB │ CCCC │",
705
+ "│ DD │ EE │ FF │",
706
+ "│ G │ H │ I │",
707
+ "└──────┴──────┴──────┘"
708
+ )
709
+ end
710
+ end
711
+
712
+ context "and when #style.justify is :right" do
713
+ let(:rows) { unjustified_rows }
714
+
715
+ let(:style) do
716
+ CommandKit::Printing::Tables::Style.new(
717
+ border: :line,
718
+ justify: :right
719
+ )
720
+ end
721
+
722
+ it "must right justify each cell" do
723
+ expect { |b|
724
+ subject.format(&b)
725
+ }.to yield_successive_args(
726
+ "┌──────┬──────┬──────┐",
727
+ "│ AAAA │ BBBB │ CCCC │",
728
+ "│ DD │ EE │ FF │",
729
+ "│ G │ H │ I │",
730
+ "└──────┴──────┴──────┘"
731
+ )
732
+ end
733
+ end
734
+
735
+ context "and when #style.justify is :center" do
736
+ let(:rows) { unjustified_rows }
737
+
738
+ let(:style) do
739
+ CommandKit::Printing::Tables::Style.new(
740
+ border: :line,
741
+ justify: :center
742
+ )
743
+ end
744
+
745
+ it "must center justify each cell" do
746
+ expect { |b|
747
+ subject.format(&b)
748
+ }.to yield_successive_args(
749
+ "┌──────┬──────┬──────┐",
750
+ "│ AAAA │ BBBB │ CCCC │",
751
+ "│ DD │ EE │ FF │",
752
+ "│ G │ H │ I │",
753
+ "└──────┴──────┴──────┘"
754
+ )
755
+ end
756
+ end
757
+
758
+ context "and when #style.header is true" do
759
+ let(:table) do
760
+ CommandKit::Printing::Tables::TableBuilder.new(rows, header: header)
761
+ end
762
+
763
+ it "must yield the center justified header row, then a separator line, then the rows" do
764
+ expect { |b|
765
+ subject.format(&b)
766
+ }.to yield_successive_args(
767
+ "┌──────┬──────┬──────┐",
768
+ "│ A │ B │ C │",
769
+ "├──────┼──────┼──────┤",
770
+ "│ AAAA │ BBBB │ CCCC │",
771
+ "│ DDDD │ EEEE │ FFFF │",
772
+ "│ GGGG │ HHHH │ IIII │",
773
+ "└──────┴──────┴──────┘"
774
+ )
775
+ end
776
+
777
+ context "and when #style.separate_rows is true" do
778
+ let(:style) do
779
+ CommandKit::Printing::Tables::Style.new(
780
+ border: :line,
781
+ separate_rows: true
782
+ )
783
+ end
784
+
785
+ it "must yield the header and each row with a separator line between each row" do
786
+ expect { |b|
787
+ subject.format(&b)
788
+ }.to yield_successive_args(
789
+ "┌──────┬──────┬──────┐",
790
+ "│ A │ B │ C │",
791
+ "├──────┼──────┼──────┤",
792
+ "│ AAAA │ BBBB │ CCCC │",
793
+ "├──────┼──────┼──────┤",
794
+ "│ DDDD │ EEEE │ FFFF │",
795
+ "├──────┼──────┼──────┤",
796
+ "│ GGGG │ HHHH │ IIII │",
797
+ "└──────┴──────┴──────┘"
798
+ )
799
+ end
800
+ end
801
+
802
+ context "and when #style.justify_header is :left" do
803
+ let(:style) do
804
+ CommandKit::Printing::Tables::Style.new(
805
+ border: :line,
806
+ justify_header: :left
807
+ )
808
+ end
809
+
810
+ it "must left justify the header cells" do
811
+ expect { |b|
812
+ subject.format(&b)
813
+ }.to yield_successive_args(
814
+ "┌──────┬──────┬──────┐",
815
+ "│ A │ B │ C │",
816
+ "├──────┼──────┼──────┤",
817
+ "│ AAAA │ BBBB │ CCCC │",
818
+ "│ DDDD │ EEEE │ FFFF │",
819
+ "│ GGGG │ HHHH │ IIII │",
820
+ "└──────┴──────┴──────┘"
821
+ )
822
+ end
823
+ end
824
+
825
+ context "and when #style.justify_header is :right" do
826
+ let(:style) do
827
+ CommandKit::Printing::Tables::Style.new(
828
+ border: :line,
829
+ justify_header: :right
830
+ )
831
+ end
832
+
833
+ it "must right justify the header cells" do
834
+ expect { |b|
835
+ subject.format(&b)
836
+ }.to yield_successive_args(
837
+ "┌──────┬──────┬──────┐",
838
+ "│ A │ B │ C │",
839
+ "├──────┼──────┼──────┤",
840
+ "│ AAAA │ BBBB │ CCCC │",
841
+ "│ DDDD │ EEEE │ FFFF │",
842
+ "│ GGGG │ HHHH │ IIII │",
843
+ "└──────┴──────┴──────┘"
844
+ )
845
+ end
846
+ end
847
+
848
+ context "and when #style.justify_header is :center" do
849
+ let(:style) do
850
+ CommandKit::Printing::Tables::Style.new(
851
+ border: :line,
852
+ justify_header: :center
853
+ )
854
+ end
855
+
856
+ it "must center justify the header cells" do
857
+ expect { |b|
858
+ subject.format(&b)
859
+ }.to yield_successive_args(
860
+ "┌──────┬──────┬──────┐",
861
+ "│ A │ B │ C │",
862
+ "├──────┼──────┼──────┤",
863
+ "│ AAAA │ BBBB │ CCCC │",
864
+ "│ DDDD │ EEEE │ FFFF │",
865
+ "│ GGGG │ HHHH │ IIII │",
866
+ "└──────┴──────┴──────┘"
867
+ )
868
+ end
869
+ end
870
+ end
871
+ end
872
+
873
+ context "when #style.border is :double_line" do
874
+ let(:style) do
875
+ CommandKit::Printing::Tables::Style.new(border: :double_line)
876
+ end
877
+
878
+ it "must yield the table with an ANSI double-line border" do
879
+ expect { |b|
880
+ subject.format(&b)
881
+ }.to yield_successive_args(
882
+ "╔══════╦══════╦══════╗",
883
+ "║ AAAA ║ BBBB ║ CCCC ║",
884
+ "║ DDDD ║ EEEE ║ FFFF ║",
885
+ "║ GGGG ║ HHHH ║ IIII ║",
886
+ "╚══════╩══════╩══════╝"
887
+ )
888
+ end
889
+
890
+ context "but when the table contains multi-line cells" do
891
+ let(:rows) { multiline_rows }
892
+
893
+ it "must yield each line of each row" do
894
+ expect { |b|
895
+ subject.format(&b)
896
+ }.to yield_successive_args(
897
+ "╔══════╦══════╦══════╗",
898
+ "║ AAAA ║ BBBB ║ CCCC ║",
899
+ "║ AA ║ ║ ║",
900
+ "║ DDDD ║ EEEE ║ FFFF ║",
901
+ "║ ║ EE ║ ║",
902
+ "║ GGGG ║ HHHH ║ IIII ║",
903
+ "║ ║ ║ II ║",
904
+ "╚══════╩══════╩══════╝"
905
+ )
906
+ end
907
+ end
908
+
909
+ context "but when the table contains empty cells" do
910
+ let(:rows) { rows_with_empty_cells }
911
+
912
+ it "must replace the empty cells with spaces" do
913
+ expect { |b|
914
+ subject.format(&b)
915
+ }.to yield_successive_args(
916
+ "╔══════╦══════╦══════╗",
917
+ "║ ║ BBBB ║ CCCC ║",
918
+ "║ DDDD ║ ║ FFFF ║",
919
+ "║ GGGG ║ HHHH ║ ║",
920
+ "╚══════╩══════╩══════╝"
921
+ )
922
+ end
923
+ end
924
+
925
+ context "but when the table contains empty cells" do
926
+ let(:rows) { rows_with_diff_row_lengths }
927
+
928
+ it "must pad the columns with empty cells" do
929
+ expect { |b|
930
+ subject.format(&b)
931
+ }.to yield_successive_args(
932
+ "╔══════╦══════╦══════╗",
933
+ "║ AAAA ║ ║ ║",
934
+ "║ DDDD ║ EEEE ║ ║",
935
+ "║ GGGG ║ HHHH ║ IIII ║",
936
+ "╚══════╩══════╩══════╝"
937
+ )
938
+ end
939
+ end
940
+
941
+ context "and when #style.separate_rows is true" do
942
+ let(:style) do
943
+ CommandKit::Printing::Tables::Style.new(
944
+ border: :double_line,
945
+ separate_rows: true
946
+ )
947
+ end
948
+
949
+ it "must yield each row with separator lines between each row" do
950
+ expect { |b|
951
+ subject.format(&b)
952
+ }.to yield_successive_args(
953
+ "╔══════╦══════╦══════╗",
954
+ "║ AAAA ║ BBBB ║ CCCC ║",
955
+ "╠══════╬══════╬══════╣",
956
+ "║ DDDD ║ EEEE ║ FFFF ║",
957
+ "╠══════╬══════╬══════╣",
958
+ "║ GGGG ║ HHHH ║ IIII ║",
959
+ "╚══════╩══════╩══════╝"
960
+ )
961
+ end
962
+ end
963
+
964
+ context "and when #style.justify is :left" do
965
+ let(:rows) { unjustified_rows }
966
+
967
+ let(:style) do
968
+ CommandKit::Printing::Tables::Style.new(
969
+ border: :double_line,
970
+ justify: :left
971
+ )
972
+ end
973
+
974
+ it "must left justify each cell" do
975
+ expect { |b|
976
+ subject.format(&b)
977
+ }.to yield_successive_args(
978
+ "╔══════╦══════╦══════╗",
979
+ "║ AAAA ║ BBBB ║ CCCC ║",
980
+ "║ DD ║ EE ║ FF ║",
981
+ "║ G ║ H ║ I ║",
982
+ "╚══════╩══════╩══════╝"
983
+ )
984
+ end
985
+ end
986
+
987
+ context "and when #style.justify is :right" do
988
+ let(:rows) { unjustified_rows }
989
+
990
+ let(:style) do
991
+ CommandKit::Printing::Tables::Style.new(
992
+ border: :double_line,
993
+ justify: :right
994
+ )
995
+ end
996
+
997
+ it "must right justify each cell" do
998
+ expect { |b|
999
+ subject.format(&b)
1000
+ }.to yield_successive_args(
1001
+ "╔══════╦══════╦══════╗",
1002
+ "║ AAAA ║ BBBB ║ CCCC ║",
1003
+ "║ DD ║ EE ║ FF ║",
1004
+ "║ G ║ H ║ I ║",
1005
+ "╚══════╩══════╩══════╝"
1006
+ )
1007
+ end
1008
+ end
1009
+
1010
+ context "and when #style.justify is :center" do
1011
+ let(:rows) { unjustified_rows }
1012
+
1013
+ let(:style) do
1014
+ CommandKit::Printing::Tables::Style.new(
1015
+ border: :double_line,
1016
+ justify: :center
1017
+ )
1018
+ end
1019
+
1020
+ it "must center justify each cell" do
1021
+ expect { |b|
1022
+ subject.format(&b)
1023
+ }.to yield_successive_args(
1024
+ "╔══════╦══════╦══════╗",
1025
+ "║ AAAA ║ BBBB ║ CCCC ║",
1026
+ "║ DD ║ EE ║ FF ║",
1027
+ "║ G ║ H ║ I ║",
1028
+ "╚══════╩══════╩══════╝"
1029
+ )
1030
+ end
1031
+ end
1032
+
1033
+ context "and when #table.header? is true" do
1034
+ let(:table) do
1035
+ CommandKit::Printing::Tables::TableBuilder.new(rows, header: header)
1036
+ end
1037
+
1038
+ it "must yield the center justified header row, then a separator line, then each row" do
1039
+ expect { |b|
1040
+ subject.format(&b)
1041
+ }.to yield_successive_args(
1042
+ "╔══════╦══════╦══════╗",
1043
+ "║ A ║ B ║ C ║",
1044
+ "╠══════╬══════╬══════╣",
1045
+ "║ AAAA ║ BBBB ║ CCCC ║",
1046
+ "║ DDDD ║ EEEE ║ FFFF ║",
1047
+ "║ GGGG ║ HHHH ║ IIII ║",
1048
+ "╚══════╩══════╩══════╝"
1049
+ )
1050
+ end
1051
+
1052
+ context "and when #style.separate_rows? is true" do
1053
+ let(:style) do
1054
+ CommandKit::Printing::Tables::Style.new(
1055
+ border: :double_line,
1056
+ separate_rows: true
1057
+ )
1058
+ end
1059
+
1060
+ it "must yield the header and each row with separator lines between them" do
1061
+ expect { |b|
1062
+ subject.format(&b)
1063
+ }.to yield_successive_args(
1064
+ "╔══════╦══════╦══════╗",
1065
+ "║ A ║ B ║ C ║",
1066
+ "╠══════╬══════╬══════╣",
1067
+ "║ AAAA ║ BBBB ║ CCCC ║",
1068
+ "╠══════╬══════╬══════╣",
1069
+ "║ DDDD ║ EEEE ║ FFFF ║",
1070
+ "╠══════╬══════╬══════╣",
1071
+ "║ GGGG ║ HHHH ║ IIII ║",
1072
+ "╚══════╩══════╩══════╝"
1073
+ )
1074
+ end
1075
+ end
1076
+
1077
+ context "and when #style.justify_header is :left" do
1078
+ let(:style) do
1079
+ CommandKit::Printing::Tables::Style.new(
1080
+ border: :double_line,
1081
+ justify_header: :left
1082
+ )
1083
+ end
1084
+
1085
+ it "must left justify the header cells" do
1086
+ expect { |b|
1087
+ subject.format(&b)
1088
+ }.to yield_successive_args(
1089
+ "╔══════╦══════╦══════╗",
1090
+ "║ A ║ B ║ C ║",
1091
+ "╠══════╬══════╬══════╣",
1092
+ "║ AAAA ║ BBBB ║ CCCC ║",
1093
+ "║ DDDD ║ EEEE ║ FFFF ║",
1094
+ "║ GGGG ║ HHHH ║ IIII ║",
1095
+ "╚══════╩══════╩══════╝"
1096
+ )
1097
+ end
1098
+ end
1099
+
1100
+ context "and when #style.justify_header is :right" do
1101
+ let(:style) do
1102
+ CommandKit::Printing::Tables::Style.new(
1103
+ border: :double_line,
1104
+ justify_header: :right
1105
+ )
1106
+ end
1107
+
1108
+ it "must right justify the header cells" do
1109
+ expect { |b|
1110
+ subject.format(&b)
1111
+ }.to yield_successive_args(
1112
+ "╔══════╦══════╦══════╗",
1113
+ "║ A ║ B ║ C ║",
1114
+ "╠══════╬══════╬══════╣",
1115
+ "║ AAAA ║ BBBB ║ CCCC ║",
1116
+ "║ DDDD ║ EEEE ║ FFFF ║",
1117
+ "║ GGGG ║ HHHH ║ IIII ║",
1118
+ "╚══════╩══════╩══════╝"
1119
+ )
1120
+ end
1121
+ end
1122
+
1123
+ context "and when #style.justify_header is :center" do
1124
+ let(:style) do
1125
+ CommandKit::Printing::Tables::Style.new(
1126
+ border: :double_line,
1127
+ justify_header: :center
1128
+ )
1129
+ end
1130
+
1131
+ it "must center justify the header cells" do
1132
+ expect { |b|
1133
+ subject.format(&b)
1134
+ }.to yield_successive_args(
1135
+ "╔══════╦══════╦══════╗",
1136
+ "║ A ║ B ║ C ║",
1137
+ "╠══════╬══════╬══════╣",
1138
+ "║ AAAA ║ BBBB ║ CCCC ║",
1139
+ "║ DDDD ║ EEEE ║ FFFF ║",
1140
+ "║ GGGG ║ HHHH ║ IIII ║",
1141
+ "╚══════╩══════╩══════╝"
1142
+ )
1143
+ end
1144
+ end
1145
+ end
1146
+ end
1147
+
1148
+ context "when given an invalid justify_header: value" do
1149
+ let(:justify) { :foo }
1150
+
1151
+ let(:table) do
1152
+ CommandKit::Printing::Tables::TableBuilder.new(rows, header: header)
1153
+ end
1154
+
1155
+ let(:style) do
1156
+ CommandKit::Printing::Tables::Style.new(justify_header: justify)
1157
+ end
1158
+
1159
+ it do
1160
+ expect { |b|
1161
+ subject.format(&b)
1162
+ }.to raise_error(ArgumentError,"invalid justify value (#{justify.inspect}), must be :left, :right, or :center")
1163
+ end
1164
+ end
1165
+
1166
+ context "when given an invalid justify: value" do
1167
+ let(:justify) { :foo }
1168
+
1169
+ let(:style) do
1170
+ CommandKit::Printing::Tables::Style.new(justify: justify)
1171
+ end
1172
+
1173
+ it do
1174
+ expect { |b|
1175
+ subject.format(&b)
1176
+ }.to raise_error(ArgumentError,"invalid justify value (#{justify.inspect}), must be :left, :right, or :center")
1177
+ end
1178
+ end
1179
+ end
1180
+ end