command_kit 0.2.2 → 0.4.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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +4 -5
  3. data/.rubocop.yml +14 -1
  4. data/ChangeLog.md +82 -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/arguments/argument.rb +2 -2
  12. data/lib/command_kit/arguments.rb +27 -2
  13. data/lib/command_kit/bug_report.rb +105 -0
  14. data/lib/command_kit/colors.rb +488 -15
  15. data/lib/command_kit/command.rb +1 -2
  16. data/lib/command_kit/edit.rb +54 -0
  17. data/lib/command_kit/env.rb +1 -1
  18. data/lib/command_kit/file_utils.rb +46 -0
  19. data/lib/command_kit/options/option.rb +45 -22
  20. data/lib/command_kit/options/option_value.rb +2 -2
  21. data/lib/command_kit/options/parser.rb +1 -4
  22. data/lib/command_kit/options/quiet.rb +1 -1
  23. data/lib/command_kit/options/verbose.rb +2 -2
  24. data/lib/command_kit/options/version.rb +10 -0
  25. data/lib/command_kit/options.rb +89 -14
  26. data/lib/command_kit/os.rb +1 -1
  27. data/lib/command_kit/printing/fields.rb +56 -0
  28. data/lib/command_kit/printing/indent.rb +1 -1
  29. data/lib/command_kit/printing/lists.rb +91 -0
  30. data/lib/command_kit/printing/tables/border_style.rb +169 -0
  31. data/lib/command_kit/printing/tables/cell_builder.rb +93 -0
  32. data/lib/command_kit/printing/tables/row_builder.rb +111 -0
  33. data/lib/command_kit/printing/tables/style.rb +198 -0
  34. data/lib/command_kit/printing/tables/table_builder.rb +145 -0
  35. data/lib/command_kit/printing/tables/table_formatter.rb +254 -0
  36. data/lib/command_kit/printing/tables.rb +208 -0
  37. data/lib/command_kit/program_name.rb +9 -0
  38. data/lib/command_kit/stdio.rb +5 -1
  39. data/lib/command_kit/version.rb +1 -1
  40. data/spec/arguments_spec.rb +33 -0
  41. data/spec/bug_report_spec.rb +266 -0
  42. data/spec/colors_spec.rb +232 -195
  43. data/spec/command_name_spec.rb +1 -1
  44. data/spec/command_spec.rb +2 -2
  45. data/spec/edit_spec.rb +72 -0
  46. data/spec/file_utils_spec.rb +59 -0
  47. data/spec/fixtures/template.erb +5 -0
  48. data/spec/options/option_spec.rb +48 -2
  49. data/spec/options/parser_spec.rb +0 -10
  50. data/spec/options/quiet_spec.rb +51 -0
  51. data/spec/options/verbose_spec.rb +51 -0
  52. data/spec/options/version_spec.rb +146 -0
  53. data/spec/options_spec.rb +46 -0
  54. data/spec/pager_spec.rb +1 -1
  55. data/spec/printing/fields_spec.rb +167 -0
  56. data/spec/printing/lists_spec.rb +99 -0
  57. data/spec/printing/tables/border_style.rb +43 -0
  58. data/spec/printing/tables/cell_builer_spec.rb +135 -0
  59. data/spec/printing/tables/row_builder_spec.rb +165 -0
  60. data/spec/printing/tables/style_spec.rb +377 -0
  61. data/spec/printing/tables/table_builder_spec.rb +252 -0
  62. data/spec/printing/tables/table_formatter_spec.rb +1180 -0
  63. data/spec/printing/tables_spec.rb +1069 -0
  64. data/spec/program_name_spec.rb +8 -0
  65. metadata +36 -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