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,165 @@
1
+ require 'spec_helper'
2
+ require 'command_kit/printing/tables/row_builder'
3
+
4
+ describe CommandKit::Printing::Tables::RowBuilder do
5
+ it { expect(described_class).to include(Enumerable) }
6
+
7
+ describe "#initialize" do
8
+ it "must initialize #cells to an empty Array" do
9
+ expect(subject.cells).to eq([])
10
+ end
11
+
12
+ it "must default #height to 0" do
13
+ expect(subject.height).to eq(0)
14
+ end
15
+
16
+ it "must default #width to 0" do
17
+ expect(subject.width).to eq(0)
18
+ end
19
+
20
+ it "must default #columns to 0" do
21
+ expect(subject.columns).to eq(0)
22
+ end
23
+
24
+ context "when given initial cells" do
25
+ let(:cell1) { "foo bar\nbaz qux" }
26
+ let(:cell2) { 'aaaa bbbb' }
27
+ let(:cells) { [cell1, cell2] }
28
+
29
+ subject { described_class.new(cells) }
30
+
31
+ it "must append the cells to the row" do
32
+ expect(subject.cells[0]).to be_kind_of(CommandKit::Printing::Tables::CellBuilder)
33
+ expect(subject.cells[0].lines).to eq(cell1.lines(chomp: true))
34
+
35
+ expect(subject.cells[1]).to be_kind_of(CommandKit::Printing::Tables::CellBuilder)
36
+ expect(subject.cells[1].lines).to eq(cell2.lines(chomp: true))
37
+ end
38
+ end
39
+ end
40
+
41
+ describe "#<<" do
42
+ context "when given a non-nil value" do
43
+ let(:value) { "foo bar\nbaz qux" }
44
+
45
+ it "must append a new CommandKit::Printing::Tables::CellBuilder object to #cells" do
46
+ subject << value
47
+
48
+ expect(subject.cells.last).to be_kind_of(CommandKit::Printing::Tables::CellBuilder)
49
+ expect(subject.cells.last.lines).to eq(value.lines(chomp: true))
50
+ end
51
+
52
+ context "when the new cell's height is greater than the row's current #height" do
53
+ let(:value1) { "foo" }
54
+ let(:value2) { "bar\nbaz\nqux" }
55
+
56
+ it "must update the row's current #height" do
57
+ expect(subject.height).to eq(0)
58
+
59
+ subject << value1
60
+ expect(subject.height).to eq(subject.cells[0].height)
61
+
62
+ subject << value2
63
+ expect(subject.height).to eq(subject.cells[1].height)
64
+ end
65
+ end
66
+
67
+ context "when the new cell's height is not greater than the row's current #height" do
68
+ let(:value1) { "bar\nbaz\nqux" }
69
+ let(:value2) { "foo" }
70
+
71
+ it "must not update the row's current #height" do
72
+ expect(subject.height).to eq(0)
73
+
74
+ subject << value1
75
+ expect(subject.height).to eq(subject.cells[0].height)
76
+
77
+ subject << value2
78
+ expect(subject.height).to eq(subject.cells[0].height)
79
+ end
80
+ end
81
+
82
+ it "must add the cell value's line width to the row's #width" do
83
+ value1 = "foo"
84
+ value1_width = CommandKit::Printing::Tables::CellBuilder.line_width(value1)
85
+
86
+ expect(subject.width).to eq(0)
87
+
88
+ subject << value1
89
+ expect(subject.width).to eq(value1_width)
90
+
91
+ value2 = "\e[32mbar\e[0m"
92
+ value2_width = CommandKit::Printing::Tables::CellBuilder.line_width(value2)
93
+
94
+ subject << value2
95
+ expect(subject.width).to eq(value1_width + value2_width)
96
+ end
97
+
98
+ it "must incrmenet #columns by 1" do
99
+ expect(subject.columns).to eq(0)
100
+
101
+ subject << "foo"
102
+ expect(subject.columns).to eq(1)
103
+
104
+ subject << "bar"
105
+ expect(subject.columns).to eq(2)
106
+ end
107
+
108
+ it "must return self" do
109
+ expect(subject << value).to be(subject)
110
+ end
111
+ end
112
+
113
+ context "when given a nil value" do
114
+ it "must append #{described_class}::EMPTY_CELL to #cells" do
115
+ subject << nil
116
+
117
+ expect(subject.cells.last).to be(described_class::EMPTY_CELL)
118
+ end
119
+
120
+ it "must return self" do
121
+ expect(subject << nil).to be(subject)
122
+ end
123
+ end
124
+ end
125
+
126
+ describe "#[]" do
127
+ before do
128
+ subject << "foo bar"
129
+ subject << "baz qux"
130
+ end
131
+
132
+ context "when the given column index is within the bounds of #cells" do
133
+ it "must return the cell at the given index" do
134
+ expect(subject[1]).to be(subject.cells[1])
135
+ end
136
+ end
137
+
138
+ context "when the given column index is not within the bounds of #cells" do
139
+ it "must return #{described_class}::EMPTY_CELL" do
140
+ expect(subject[2]).to be(described_class::EMPTY_CELL)
141
+ end
142
+ end
143
+ end
144
+
145
+ describe "#each" do
146
+ before do
147
+ subject << "foo bar"
148
+ subject << "baz qux"
149
+ end
150
+
151
+ context "when given a block" do
152
+ it "must yield each cell in #cells" do
153
+ expect { |b|
154
+ subject.each(&b)
155
+ }.to yield_successive_args(*subject.cells)
156
+ end
157
+ end
158
+
159
+ context "when no block is given" do
160
+ it "must return an Enumerator for #cells" do
161
+ expect(subject.each.to_a).to eq(subject.cells)
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,377 @@
1
+ require 'spec_helper'
2
+ require 'command_kit/printing/tables/style'
3
+
4
+ describe CommandKit::Printing::Tables::Style do
5
+ describe "BORDER_STYLES" do
6
+ subject { described_class::BORDER_STYLES }
7
+
8
+ it "must be a Hash" do
9
+ expect(subject).to be_kind_of(Hash)
10
+ end
11
+
12
+ describe ":ascii" do
13
+ subject { super()[:ascii] }
14
+
15
+ it "must be a CommandKit::Printing::Tables::BorderStyle" do
16
+ expect(subject).to be_kind_of(CommandKit::Printing::Tables::BorderStyle)
17
+ end
18
+
19
+ it "must set #top_left_corner to '+'" do
20
+ expect(subject.top_left_corner).to eq('+')
21
+ end
22
+
23
+ it "must set #top_border to '-'" do
24
+ expect(subject.top_border).to eq('-')
25
+ end
26
+
27
+ it "must set #top_joined_border to '+'" do
28
+ expect(subject.top_joined_border).to eq('+')
29
+ end
30
+
31
+ it "must set #top_right_corner to '+'" do
32
+ expect(subject.top_right_corner).to eq('+')
33
+ end
34
+
35
+ it "must set #left_border to '|'" do
36
+ expect(subject.left_border).to eq('|')
37
+ end
38
+
39
+ it "must set #left_joined_border to '+'" do
40
+ expect(subject.left_joined_border).to eq('+')
41
+ end
42
+
43
+ it "must set #horizontal_separator to '-'" do
44
+ expect(subject.horizontal_separator).to eq('-')
45
+ end
46
+
47
+ it "must set #vertical_separator to '|'" do
48
+ expect(subject.vertical_separator).to eq('|')
49
+ end
50
+
51
+ it "must set #inner_joined_border to '+'" do
52
+ expect(subject.inner_joined_border).to eq('+')
53
+ end
54
+
55
+ it "must set #right_border to '|'" do
56
+ expect(subject.right_border).to eq('|')
57
+ end
58
+
59
+ it "must set #right_joined_border to '+'" do
60
+ expect(subject.right_joined_border).to eq('+')
61
+ end
62
+
63
+ it "must set #bottom_border to '-'" do
64
+ expect(subject.bottom_border).to eq('-')
65
+ end
66
+
67
+ it "must set #bottom_left_corner to '+'" do
68
+ expect(subject.bottom_left_corner).to eq('+')
69
+ end
70
+
71
+ it "must set #bottom_joined_border to '+'" do
72
+ expect(subject.bottom_joined_border).to eq('+')
73
+ end
74
+
75
+ it "must set #bottom_right_corner to '+'" do
76
+ expect(subject.bottom_right_corner).to eq('+')
77
+ end
78
+ end
79
+
80
+ describe ":line" do
81
+ subject { super()[:line] }
82
+
83
+ it "must be a CommandKit::Printing::Tables::BorderStyle" do
84
+ expect(subject).to be_kind_of(CommandKit::Printing::Tables::BorderStyle)
85
+ end
86
+
87
+ it "must set #top_left_corner to '┌'" do
88
+ expect(subject.top_left_corner).to eq('┌')
89
+ end
90
+
91
+ it "must set #top_border to '─'" do
92
+ expect(subject.top_border).to eq('─')
93
+ end
94
+
95
+ it "must set #top_joined_border to '┬'" do
96
+ expect(subject.top_joined_border).to eq('┬')
97
+ end
98
+
99
+ it "must set #top_right_corner to '┐'" do
100
+ expect(subject.top_right_corner).to eq('┐')
101
+ end
102
+
103
+ it "must set #left_border to '│'" do
104
+ expect(subject.left_border).to eq('│')
105
+ end
106
+
107
+ it "must set #left_joined_border to '├'" do
108
+ expect(subject.left_joined_border).to eq('├')
109
+ end
110
+
111
+ it "must set #horizontal_separator to '─'" do
112
+ expect(subject.horizontal_separator).to eq('─')
113
+ end
114
+
115
+ it "must set #vertical_separator to '│'" do
116
+ expect(subject.vertical_separator).to eq('│')
117
+ end
118
+
119
+ it "must set #inner_joined_border to '┼'" do
120
+ expect(subject.inner_joined_border).to eq('┼')
121
+ end
122
+
123
+ it "must set #right_border to '│'" do
124
+ expect(subject.right_border).to eq('│')
125
+ end
126
+
127
+ it "must set #right_joined_border to '┤'" do
128
+ expect(subject.right_joined_border).to eq('┤')
129
+ end
130
+
131
+ it "must set #bottom_border to '─'" do
132
+ expect(subject.bottom_border).to eq('─')
133
+ end
134
+
135
+ it "must set #bottom_left_corner to '└'" do
136
+ expect(subject.bottom_left_corner).to eq('└')
137
+ end
138
+
139
+ it "must set #bottom_joined_border to '┴'" do
140
+ expect(subject.bottom_joined_border).to eq('┴')
141
+ end
142
+
143
+ it "must set #bottom_right_corner to '┘'" do
144
+ expect(subject.bottom_right_corner).to eq('┘')
145
+ end
146
+ end
147
+
148
+ describe ":double_line" do
149
+ subject { super()[:double_line] }
150
+
151
+ it "must be a CommandKit::Printing::Tables::BorderStyle" do
152
+ expect(subject).to be_kind_of(CommandKit::Printing::Tables::BorderStyle)
153
+ end
154
+
155
+ it "must set #top_left_corner to '╔'" do
156
+ expect(subject.top_left_corner).to eq('╔')
157
+ end
158
+
159
+ it "must set #top_border to '═'" do
160
+ expect(subject.top_border).to eq('═')
161
+ end
162
+
163
+ it "must set #top_joined_border to '╦'" do
164
+ expect(subject.top_joined_border).to eq('╦')
165
+ end
166
+
167
+ it "must set #top_right_corner to '╗'" do
168
+ expect(subject.top_right_corner).to eq('╗')
169
+ end
170
+
171
+ it "must set #left_border to '║'" do
172
+ expect(subject.left_border).to eq('║')
173
+ end
174
+
175
+ it "must set #left_joined_border to '╠'" do
176
+ expect(subject.left_joined_border).to eq('╠')
177
+ end
178
+
179
+ it "must set #horizontal_separator to '═'" do
180
+ expect(subject.horizontal_separator).to eq('═')
181
+ end
182
+
183
+ it "must set #vertical_separator to '║'" do
184
+ expect(subject.vertical_separator).to eq('║')
185
+ end
186
+
187
+ it "must set #inner_joined_border to '╬'" do
188
+ expect(subject.inner_joined_border).to eq('╬')
189
+ end
190
+
191
+ it "must set #right_border to '║'" do
192
+ expect(subject.right_border).to eq('║')
193
+ end
194
+
195
+ it "must set #right_joined_border to '╣'" do
196
+ expect(subject.right_joined_border).to eq('╣')
197
+ end
198
+
199
+ it "must set #bottom_border to '═'" do
200
+ expect(subject.bottom_border).to eq('═')
201
+ end
202
+
203
+ it "must set #bottom_left_corner to '╚'" do
204
+ expect(subject.bottom_left_corner).to eq('╚')
205
+ end
206
+
207
+ it "must set #bottom_joined_border to '╩'" do
208
+ expect(subject.bottom_joined_border).to eq('╩')
209
+ end
210
+
211
+ it "must set #bottom_right_corner to '╝'" do
212
+ expect(subject.bottom_right_corner).to eq('╝')
213
+ end
214
+ end
215
+ end
216
+
217
+ describe "#initialize" do
218
+ it "must default #border to nil" do
219
+ expect(subject.border).to be(nil)
220
+ end
221
+
222
+ it "must default #padding to 1" do
223
+ expect(subject.padding).to be(1)
224
+ end
225
+
226
+ it "must default #justify to :left" do
227
+ expect(subject.justify).to be(:left)
228
+ end
229
+
230
+ it "must default #justify_header to :center" do
231
+ expect(subject.justify_header).to be(:center)
232
+ end
233
+
234
+ it "must default #separate_rows to false" do
235
+ expect(subject.separate_rows).to eq(false)
236
+ end
237
+
238
+ context "when given the border: keyword argument" do
239
+ context "and it's a Hash" do
240
+ let(:hash) do
241
+ {
242
+ top_left_corner: '=',
243
+ top_border: '=',
244
+ top_joined_border: '=',
245
+ top_right_corner: '=',
246
+ bottom_left_corner: '=',
247
+ bottom_border: '=',
248
+ bottom_joined_border: '=',
249
+ bottom_right_corner: '='
250
+ }
251
+ end
252
+
253
+ subject { described_class.new(border: hash) }
254
+
255
+ it "must initialize #border to a new CommandKit::Printing::Tables::BorderStyle" do
256
+ expect(subject.border).to be_kind_of(CommandKit::Printing::Tables::BorderStyle)
257
+ expect(subject.border.top_left_corner).to eq('=')
258
+ expect(subject.border.top_border).to eq('=')
259
+ expect(subject.border.top_joined_border).to eq('=')
260
+ expect(subject.border.top_right_corner).to eq('=')
261
+ expect(subject.border.bottom_left_corner).to eq('=')
262
+ expect(subject.border.bottom_border).to eq('=')
263
+ expect(subject.border.bottom_joined_border).to eq('=')
264
+ expect(subject.border.bottom_right_corner).to eq('=')
265
+ end
266
+ end
267
+
268
+ context "and it's :ascii" do
269
+ subject { described_class.new(border: :ascii) }
270
+
271
+ it "must set #border to BORDER_STYLES[:ascii]" do
272
+ expect(subject.border).to be(described_class::BORDER_STYLES[:ascii])
273
+ end
274
+ end
275
+
276
+ context "and it's :line" do
277
+ subject { described_class.new(border: :line) }
278
+
279
+ it "must set #border to BORDER_STYLES[:line]" do
280
+ expect(subject.border).to be(described_class::BORDER_STYLES[:line])
281
+ end
282
+ end
283
+
284
+ context "and it's :double_line" do
285
+ subject { described_class.new(border: :double_line) }
286
+
287
+ it "must set #border to BORDER_STYLES[:double_line]" do
288
+ expect(subject.border).to be(described_class::BORDER_STYLES[:double_line])
289
+ end
290
+ end
291
+
292
+ context "but it's an unknwon Symbol" do
293
+ let(:border) { :foo }
294
+
295
+ it do
296
+ expect {
297
+ described_class.new(border: border)
298
+ }.to raise_error(ArgumentError,"unknown border style (#{border.inspect}) must be either :ascii, :line, :double_line")
299
+ end
300
+ end
301
+
302
+ context "and it's nil" do
303
+ subject { described_class.new(border: nil) }
304
+
305
+ it "must set #border to nil" do
306
+ expect(subject.border).to be(nil)
307
+ end
308
+ end
309
+
310
+ context "but it's not a Symbol, Hash, or nil" do
311
+ let(:border) { Object.new }
312
+
313
+ it do
314
+ expect {
315
+ described_class.new(border: border)
316
+ }.to raise_error(ArgumentError,"invalid border value (#{border.inspect}) must be either :ascii, :line, :double_line, Hash, or nil")
317
+ end
318
+ end
319
+ end
320
+
321
+ context "when given the padding: keyword argument" do
322
+ let(:padding) { 2 }
323
+
324
+ subject { described_class.new(padding: padding) }
325
+
326
+ it "must set #padding" do
327
+ expect(subject.padding).to eq(padding)
328
+ end
329
+ end
330
+
331
+ context "when given the justify: keyword argument" do
332
+ let(:justify) { :center }
333
+
334
+ subject { described_class.new(justify: justify) }
335
+
336
+ it "must set #justify" do
337
+ expect(subject.justify).to eq(justify)
338
+ end
339
+ end
340
+
341
+ context "when given the justify: keyword argument" do
342
+ let(:justify_header) { :left }
343
+
344
+ subject { described_class.new(justify_header: justify_header) }
345
+
346
+ it "must set #justify_header" do
347
+ expect(subject.justify_header).to eq(justify_header)
348
+ end
349
+ end
350
+
351
+ context "when given the separate_rows: keyword argument" do
352
+ let(:separate_rows) { true }
353
+
354
+ subject { described_class.new(separate_rows: separate_rows) }
355
+
356
+ it "must set #separate_rows" do
357
+ expect(subject.separate_rows).to eq(separate_rows)
358
+ end
359
+ end
360
+ end
361
+
362
+ describe "#separate_rows?" do
363
+ context "when initialized with separate_rows: true" do
364
+ subject { described_class.new(separate_rows: true) }
365
+
366
+ it "must return true" do
367
+ expect(subject.separate_rows?).to be(true)
368
+ end
369
+ end
370
+
371
+ context "when not initialized with separate_rows: true" do
372
+ it "must return false" do
373
+ expect(subject.separate_rows?).to be(false)
374
+ end
375
+ end
376
+ end
377
+ end