command_line_reporter 1.1.0 → 2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -4,6 +4,9 @@ This gem provides an simple way to add RSpec like formatting of the output of yo
4
4
  eliminates the need to litter your code with *puts* statements instead providing a cleaner, more
5
5
  ruby like way of reporting progress to the user throught the command line interface.
6
6
 
7
+ With the release of Version 2.0, it is now possible to produce tables with and without borders. See
8
+ the section on *Tables* for more examples.
9
+
7
10
  ### Installation
8
11
 
9
12
  It is up on rubygems.org so add it to your bundle or do it the old fashioned way:
@@ -20,7 +23,7 @@ The gem provides a mixin that can be included in your scripts.
20
23
  include CommandLineReporter
21
24
  ```
22
25
 
23
- #### Standard Methods
26
+ ##### Standard Methods
24
27
 
25
28
  There are several methods the mixin provides that do not depend on the formatter used:
26
29
 
@@ -58,6 +61,18 @@ There are several methods the mixin provides that do not depend on the formatter
58
61
  * _text_ - String to display
59
62
  * _:align_ - 'left'|'right'|'center' align the string text. _Default: 'left'_
60
63
  * _:width_ - The width in characters of the string text. _Default: 100_
64
+ * _table(hash) {block}_
65
+ * The first argument is a hash that defines properties of the table.
66
+ * _:border_ - true|false indicates whether to include borders around the table cells
67
+ * The second argument is a block which includes calls the to the _row_ method
68
+ * _row {block}_
69
+ * Only argument is a block with calls to _column_ allowed
70
+ * _column(string, hash)_
71
+ * _text_ - String to display in the table cell
72
+ * _options_ - The options to define the column
73
+ * :width - defines the width of the column
74
+ * :padding - The number of spaces to put on both the left and right of the text.
75
+ * :align - Allowed values are left|right|center
61
76
 
62
77
  ### Progress Formatter
63
78
 
@@ -228,7 +243,108 @@ report(:message => 'running', :complete => 'finished', :type => 'inline', :inden
228
243
  end
229
244
  ```
230
245
 
246
+ ### Tables
247
+
248
+ Examples are always helpful so let's look at the following:
249
+
250
+ ```ruby
251
+ require 'command_line_reporter'
252
+
253
+ class Example
254
+ include CommandLineReporter
255
+
256
+ def run
257
+ table(:border => true) do
258
+ row do
259
+ column('NAME', :width => 20)
260
+ column('ADDRESS', :width => 30, :align => 'right', :padding => 5)
261
+ column('CITY', :width => 15)
262
+ end
263
+ row do
264
+ column('Ceaser')
265
+ column('1 Appian Way')
266
+ column('Rome')
267
+ end
268
+ row do
269
+ column('Richard Feynman')
270
+ column('1 Golden Gate')
271
+ column('Quantum Field')
272
+ end
273
+ end
274
+ end
275
+ end
276
+
277
+ Example.new.run
278
+ ```
279
+
280
+ This produces the very simple output with 2 rows and 3 columns of data:
281
+
282
+ ```bash
283
+ +----------------------+--------------------------------+-----------------+
284
+ | NAME | ADDRESS | CITY |
285
+ +----------------------+--------------------------------+-----------------+
286
+ | Ceaser | 1 Appian Way | Rome |
287
+ +----------------------+--------------------------------+-----------------+
288
+ | Richard Feynman | 1 Golden Gate | Quantum Field |
289
+ +----------------------+--------------------------------+-----------------+
290
+ ```
291
+
292
+ Notice how the properties of the columns for the second and third rows have been inherited from the
293
+ first like in HTML. This makes it a lot easier to write in freeform. What if you have data to
294
+ iterate over and have text that is wider than the column width you have selected? Not a problem as
295
+ the following example demonstrates all of the combinations of the various options:
296
+
297
+ ```ruby
298
+ require 'command_line_reporter'
299
+
300
+ class Example
301
+ include CommandLineReporter
302
+
303
+ def run
304
+ table(:border => true) do
305
+ 3.times do
306
+ row do
307
+ i = 0
308
+ 3.times do
309
+ i += 10
310
+ column('x' * (0 + rand(50)), :align => %w[left right center][rand(3)], :width => i, :padding => rand(5))
311
+ end
312
+ end
313
+ end
314
+ end
315
+ end
316
+ end
317
+ ```
318
+
319
+ This randomly produces a table with a border that has 3 rows and 3 columns. Each column gets wider
320
+ by 10 characters. The alignment of the column is demonstrated and you can see where some data
321
+ elements have padding around them.
322
+
323
+ ```bash
324
+ +------------+----------------------+--------------------------------+
325
+ | xxxxxxxxxx | xxxxxxxxxxxxxx | xxxxxxxxxxxxxxxxxxxxxxxxxx |
326
+ | xxxxxx | xxxxxxxxx | xxxxxx |
327
+ +------------+----------------------+--------------------------------+
328
+ | xxxxxxxxxx | xxxxxxxxxxxxxx | xxxxxxxxxxxxxxxxxxxxxxxxxx |
329
+ | xxxxxxxxxx | xxxxxxxxxxxxxx | xxxxxxxxxxxxxxxxx |
330
+ | xxxxxxxxxx | xxxxxxxxxxxxxx | |
331
+ | xxxxxxx | xxxx | |
332
+ +------------+----------------------+--------------------------------+
333
+ | xxxxxxxxxx | xxxx | xxxxxxxxxxxxxxxxxxx |
334
+ | xxxxxx | | |
335
+ +------------+----------------------+--------------------------------+
336
+ ```
337
+
338
+ This is all generated randomly to illustrate the features but you get the idea of how to use
339
+ alignment, width and padding.
340
+
341
+ The best feature is *wrapping*. If the text you are display in a cell is larger than the width it
342
+ was given, it will automatically wrap it for you. Padding and alignment are preserved. It palso
343
+ properly handles the case where the data in one cell causes the wrapping but other cells my not have
344
+ the same number of lines to wrap.
345
+
231
346
  ### To Do
232
347
 
233
- 1. Add the progress method to the top level mixin so that there is no need to invoke through the
234
- formatter.
348
+ * Add the ability for a column to span across others
349
+ * Add the progress method to the top level mixin so that there is no need to invoke through the
350
+ formatter.
data/examples/table.rb ADDED
@@ -0,0 +1,49 @@
1
+ require 'command_line_reporter'
2
+
3
+ class Example
4
+ include CommandLineReporter
5
+
6
+ def run
7
+ header(:title => 'TABLE EXAMPLES - Borders, Wrapping, Alignment and Padding', :align => 'center', :width => 70)
8
+
9
+ 2.times do |j|
10
+ header(:title => "Table #{j}", :align => 'center', :width => 65)
11
+
12
+ table(:border => j % 2 == 0) do
13
+ 3.times do
14
+ row do
15
+ i = 0
16
+ 3.times do
17
+ i += 10
18
+ column('x' * (0 + rand(50)), :align => %w[left right center][rand(3)], :width => i, :padding => rand(5))
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ vertical_spacing(2)
25
+ end
26
+
27
+ header(:title => 'A simple example of how column properties are inhereted from the first row')
28
+
29
+ table(:border => true) do
30
+ row do
31
+ column('NAME', :width => 20)
32
+ column('ADDRESS', :width => 30, :align => 'right', :padding => 5)
33
+ column('CITY', :width => 15)
34
+ end
35
+ row do
36
+ column('Ceaser')
37
+ column('1 Appian Way')
38
+ column('Rome')
39
+ end
40
+ row do
41
+ column('Richard Feynman')
42
+ column('1 Golden Gate')
43
+ column('Quantum Field')
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ Example.new.run
data/lib/column.rb ADDED
@@ -0,0 +1,52 @@
1
+ require 'options_validator'
2
+
3
+ class Column
4
+ include OptionsValidator
5
+
6
+ VALID_OPTIONS = [:width, :padding, :align]
7
+ attr_accessor :text, :size, *VALID_OPTIONS
8
+
9
+ def initialize(text = nil, options = {})
10
+ self.validate_options(options, *VALID_OPTIONS)
11
+
12
+ self.text = text
13
+
14
+ self.width = options[:width] || 10
15
+ self.align = options[:align] || 'left'
16
+ self.padding = options[:padding] || 0
17
+
18
+ raise ArgumentError unless self.width > 0
19
+ raise ArgumentError unless self.padding.to_s.match(/^\d+$/)
20
+
21
+ self.size = self.width - 2 * self.padding
22
+
23
+ # self.freeze
24
+ end
25
+
26
+ def screen_rows
27
+ if self.text.nil? || self.text.empty?
28
+ [' ' * self.width]
29
+ else
30
+ self.text.scan(/.{1,#{self.size}}/m).map {|s| to_cell(s)}
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def to_cell(str)
37
+ cell = if str.empty?
38
+ ' ' * self.size
39
+ else
40
+ case self.align
41
+ when 'left'
42
+ str.ljust(self.size)
43
+ when 'right'
44
+ str.rjust(self.size)
45
+ when 'center'
46
+ str.ljust((self.size - str.size)/2.0 + str.size).rjust(self.size)
47
+ end
48
+ end
49
+
50
+ ' ' * self.padding + cell + ' ' * self.padding
51
+ end
52
+ end
@@ -1,6 +1,10 @@
1
+ require 'table'
2
+
1
3
  Dir[File.join(File.dirname(__FILE__), '*_formatter.rb')].each {|r| require r}
2
4
 
3
5
  module CommandLineReporter
6
+ include OptionsValidator
7
+
4
8
  attr_reader :formatter
5
9
 
6
10
  DEFAULTS = {
@@ -23,10 +27,8 @@ module CommandLineReporter
23
27
  end
24
28
 
25
29
  def report(options = {}, &block)
30
+ self.formatter ||= 'nested'
26
31
  self.formatter.format(options, block)
27
- rescue NoMethodError
28
- self.formatter = 'nested'
29
- retry
30
32
  end
31
33
 
32
34
  def footer(options = {})
@@ -80,12 +82,25 @@ module CommandLineReporter
80
82
  end
81
83
  end
82
84
 
83
- private
85
+ def table(options = {})
86
+ @table = Table.new(options)
87
+ yield
88
+ @table.to_s
89
+ end
84
90
 
85
- def validate_options(options, *allowed_keys)
86
- raise ArgumentError unless (options.keys - allowed_keys).empty?
91
+ def row(options = {})
92
+ @row = Row.new
93
+ yield
94
+ @table.add(@row)
87
95
  end
88
96
 
97
+ def column(text, options = {})
98
+ col = Column.new(text, options)
99
+ @row.add(col)
100
+ end
101
+
102
+ private
103
+
89
104
  def section(type, options)
90
105
  validate_options(options, :title, :width, :align, :spacing, :timestamp, :rule)
91
106
 
@@ -0,0 +1,5 @@
1
+ module OptionsValidator
2
+ def validate_options(provided, *allowed_keys)
3
+ raise(ArgumentError, "Valid options: #{allowed_keys}") unless (provided.keys - allowed_keys).empty?
4
+ end
5
+ end
data/lib/row.rb ADDED
@@ -0,0 +1,60 @@
1
+ require 'column'
2
+ require 'forwardable'
3
+
4
+ class Row
5
+ extend Forwardable
6
+
7
+ attr_accessor :columns, :border
8
+
9
+ def initialize(options = {})
10
+ self.columns = []
11
+ self.border = false
12
+ end
13
+
14
+ def_delegator :@columns, :push, :add
15
+
16
+ def separator
17
+ @sep ||= '+' + self.columns.map {|c| '-' * (c.width + 2)}.join('+') + '+'
18
+ end
19
+
20
+ def to_s
21
+ screen_count.times do |sr|
22
+ line = (self.border) ? '| ' : ''
23
+ self.columns.size.times do |mc|
24
+ col = self.columns[mc]
25
+ # Account for the fact that some columns will have more screen rows than their
26
+ # counterparts in the row. An example being:
27
+ # c1 = Column.new('x' * 50, :width => 10)
28
+ # c2 = Column.new('x' * 20, :width => 10)
29
+ #
30
+ # c1.screen_rows.size == 5
31
+ # c2.screen_rows.size == 2
32
+ #
33
+ # So when we don't have a screen row for c2 we need to fill the screen with the
34
+ # proper number of blanks so the layout looks like (parenthesis on the right just
35
+ # indicate screen row index)
36
+ #
37
+ # +-------------+------------+
38
+ # | xxxxxxxxxxx | xxxxxxxxxx | (0)
39
+ # | xxxxxxxxxxx | xxxxxxxxxx | (1)
40
+ # | xxxxxxxxxxx | | (2)
41
+ # | xxxxxxxxxxx | | (3)
42
+ # | xxxxxxxxxxx | | (4)
43
+ # +-------------+------------+
44
+ if col.screen_rows[sr].nil?
45
+ line << ' ' * col.width
46
+ else
47
+ line << self.columns[mc].screen_rows[sr]
48
+ end
49
+ line << ' ' + ((self.border) ? '| ' : '')
50
+ end
51
+ puts line
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ def screen_count
58
+ @sc ||= self.columns.inject(0) {|max,column| column.screen_rows.size > max ? column.screen_rows.size : max}
59
+ end
60
+ end
data/lib/table.rb ADDED
@@ -0,0 +1,44 @@
1
+ require 'row'
2
+ require 'options_validator'
3
+
4
+ class Table
5
+ include OptionsValidator
6
+
7
+ VALID_OPTIONS = [:border]
8
+ attr_accessor :rows, *VALID_OPTIONS
9
+
10
+ def initialize(options = {})
11
+ self.validate_options(options, *VALID_OPTIONS)
12
+
13
+ self.border = options[:border] || false
14
+
15
+ @rows = []
16
+ end
17
+
18
+ def add(row)
19
+ # Inheritance from the table
20
+ row.border = self.border
21
+
22
+ # Inherit properties from the first row
23
+ if self.rows[0]
24
+ row.columns.each_with_index do |c,i|
25
+ c.align = self.rows[0].columns[i].align
26
+ c.padding = self.rows[0].columns[i].padding
27
+ c.width = self.rows[0].columns[i].width
28
+ c.size = c.width - 2 * c.padding
29
+ end
30
+ end
31
+
32
+ self.rows << row
33
+ end
34
+
35
+ def to_s
36
+ return if self.rows.size == 0 # we got here with nothing to print to the screen
37
+
38
+ puts self.rows[0].separator if self.border
39
+ self.rows.each do |row|
40
+ row.to_s
41
+ puts self.rows[0].separator if self.border
42
+ end
43
+ end
44
+ end
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module CommandLineReporter
2
- VERSION = '1.1.0'
2
+ VERSION = '2.0'
3
3
  end
@@ -0,0 +1,148 @@
1
+ require 'spec_helper'
2
+ require 'column'
3
+
4
+ describe Column do
5
+ context 'creation' do
6
+ it 'rejects invalid options' do
7
+ expect {
8
+ Column.new('test', :asdf => '1234')
9
+ }.to raise_error ArgumentError
10
+ end
11
+
12
+ it 'defaults options hash' do
13
+ expect {
14
+ Column.new('test')
15
+ }.to_not raise_error
16
+ end
17
+
18
+ it 'defaults the width' do
19
+ Column.new('test').width.should == 10
20
+ end
21
+
22
+ it 'accepts the width' do
23
+ Column.new('test', :width => 50).width.should == 50
24
+ end
25
+
26
+ it 'requires valid width' do
27
+ expect {
28
+ Column.new('test', :width => 'asdf')
29
+ }.to raise_error ArgumentError
30
+ end
31
+
32
+ it 'accepts text' do
33
+ Column.new('asdf').text.should == 'asdf'
34
+ end
35
+
36
+ it 'defaults the padding' do
37
+ Column.new('test').padding.should == 0
38
+ end
39
+
40
+ it 'accepts the padding' do
41
+ Column.new('test', :padding => 5).padding.should == 5
42
+ end
43
+
44
+ it 'requires valid width' do
45
+ expect {
46
+ Column.new('test', :padding => 'asdf')
47
+ }.to raise_error ArgumentError
48
+ end
49
+
50
+ # it 'is immutable' do
51
+ # c = Column.new('test')
52
+
53
+ # expect {
54
+ # c.text = 'asdf'
55
+ # }.to raise_error RuntimeError, /frozen object/
56
+
57
+ # expect {
58
+ # c.width = 123
59
+ # }.to raise_error RuntimeError, /frozen object/
60
+
61
+ # expect {
62
+ # c.padding = 123
63
+ # }.to raise_error RuntimeError, /frozen object/
64
+ # end
65
+ end
66
+
67
+ describe '#screen_rows' do
68
+ context 'no wrapping' do
69
+ context 'no padding' do
70
+ it 'gives a single row' do
71
+ c = Column.new('x' * 5)
72
+ c.screen_rows.size == 1
73
+ end
74
+
75
+ it 'handles empty text' do
76
+ c = Column.new
77
+ c.screen_rows[0].should == ' ' * 10
78
+ end
79
+
80
+ it 'left justifies' do
81
+ c = Column.new('x' * 10, :width => 20)
82
+ c.screen_rows[0].should == 'x' * 10 + ' ' * 10
83
+ end
84
+
85
+ it 'right justifies' do
86
+ c = Column.new('x' * 10, :align => 'right', :width => 20)
87
+ c.screen_rows[0].should == ' ' * 10 + 'x' * 10
88
+ end
89
+
90
+ it 'center justifies' do
91
+ c = Column.new('x' * 10, :align => 'center', :width => 20)
92
+ c.screen_rows[0].should == ' ' * 5 + 'x' * 10 + ' ' * 5
93
+ end
94
+ end
95
+
96
+ context 'accounts for padding' do
97
+ it 'left justifies' do
98
+ c = Column.new('x' * 10, :padding => 5, :width => 30)
99
+ c.screen_rows[0].should == ' ' * 5 + 'x' * 10 + ' ' * 15
100
+ end
101
+ it 'right justifies' do
102
+ c = Column.new('x' * 10, :align => 'right', :padding => 5, :width => 30)
103
+ c.screen_rows[0].should == ' ' * 15 + 'x' * 10 + ' ' * 5
104
+ end
105
+ it 'right justifies' do
106
+ c = Column.new('x' * 10, :align => 'center', :padding => 5, :width => 30)
107
+ c.screen_rows[0].should == ' ' * 10 + 'x' * 10 + ' ' * 10
108
+ end
109
+ end
110
+ end
111
+
112
+ context 'with wrapping' do
113
+ context 'no padding' do
114
+ it 'left justifies' do
115
+ c = Column.new('x' * 25, :width => 10)
116
+ c.screen_rows.should == ['x' * 10, 'x' * 10, 'x' * 5 + ' ' * 5]
117
+ end
118
+
119
+ it 'left justifies' do
120
+ c = Column.new('x' * 25, :align => 'right', :width => 10)
121
+ c.screen_rows.should == ['x' * 10, 'x' * 10, ' ' * 5 + 'x' * 5]
122
+ end
123
+
124
+ it 'left justifies' do
125
+ c = Column.new('x' * 25, :align => 'center', :width => 10)
126
+ c.screen_rows.should == ['x' * 10, 'x' * 10, ' ' * 3 + 'x' * 5 + ' ' * 2]
127
+ end
128
+ end
129
+
130
+ context 'account for padding' do
131
+ it 'left justifies' do
132
+ c = Column.new('x' * 25, :padding => 2, :width => 20)
133
+ c.screen_rows.should == [' ' * 2 + 'x' * 16 + ' ' * 2, ' ' * 2 + 'x' * 9 + ' ' * 9]
134
+ end
135
+
136
+ it 'right justifies' do
137
+ c = Column.new('x' * 25, :padding => 2, :align => 'right', :width => 20)
138
+ c.screen_rows.should == [' ' * 2 + 'x' * 16 + ' ' * 2, ' ' * 9 + 'x' * 9 + ' ' * 2]
139
+ end
140
+
141
+ it 'center justifies' do
142
+ c = Column.new('x' * 25, :padding => 2, :align => 'center', :width => 20)
143
+ c.screen_rows.should == [' ' * 2 + 'x' * 16 + ' ' * 2, ' ' * 6 + 'x' * 9 + ' ' * 5]
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
@@ -49,6 +49,14 @@ describe CommandLineReporter do
49
49
 
50
50
  subject.formatter.class.should == CommandLineReporter::ProgressFormatter
51
51
  end
52
+
53
+ it 'does not mask other application errors when a formatter is not set' do
54
+ capture_stdout {
55
+ subject.report {
56
+ lambda {self.some_method_that_does_not_exist}.should raise_error(NoMethodError)
57
+ }
58
+ }
59
+ end
52
60
  end
53
61
 
54
62
  describe '#header' do
@@ -509,4 +517,76 @@ describe CommandLineReporter do
509
517
  end
510
518
  end
511
519
  end
520
+
521
+ describe '#table' do
522
+ it 'instantiates the table class' do
523
+ subject.should_receive(:puts).any_number_of_times
524
+ subject.should_receive(:table).once
525
+ subject.table { }
526
+ # subject.instance_variable_get(:@table).should_not be_nil
527
+ end
528
+
529
+ it 'requires a row to be defined' do
530
+ expect {
531
+ subject.table
532
+ }.to raise_error LocalJumpError
533
+ end
534
+
535
+ it 'accepts valid options' do
536
+ expect {
537
+ subject.table(:border => true) { }
538
+ }.to_not raise_error
539
+ end
540
+
541
+ it 'rejects invalid options' do
542
+ expect {
543
+ subject.table(:asdf => '100') { }
544
+ }.to raise_error ArgumentError
545
+ end
546
+ end
547
+
548
+ describe '#row' do
549
+ it 'instantiates a row class' do
550
+ subject.should_receive(:row).once
551
+ subject.should_receive(:puts).any_number_of_times
552
+
553
+ subject.table do
554
+ subject.row do
555
+ end
556
+ end
557
+ end
558
+ end
559
+
560
+ describe '#column' do
561
+ it 'instantiates multiple columns' do
562
+ subject.should_receive(:column).exactly(3).times
563
+ subject.should_receive(:puts).any_number_of_times
564
+
565
+ subject.table do
566
+ subject.row do
567
+ subject.column('asdf')
568
+ subject.column('qwer')
569
+ subject.column('zxcv')
570
+ end
571
+ end
572
+ end
573
+
574
+ it 'accepts valid options' do
575
+ subject.table do
576
+ subject.row do
577
+ subject.column('asdf', :width => 30)
578
+ end
579
+ end
580
+ end
581
+
582
+ it 'rejects invalid options' do
583
+ expect {
584
+ subject.table do
585
+ subject.row do
586
+ subject.column('asdf', :asdf => 30)
587
+ end
588
+ end
589
+ }.to raise_error ArgumentError
590
+ end
591
+ end
512
592
  end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+ require 'options_validator'
3
+
4
+ describe OptionsValidator do
5
+ subject { Class.new.extend(OptionsValidator) }
6
+
7
+ it 'accepts single key options' do
8
+ expect {
9
+ subject.validate_options({:valid => true}, :valid)
10
+ }.to_not raise_error
11
+ end
12
+
13
+ it 'rejects invalid option hashes' do
14
+ expect {
15
+ subject.validate_options({:wrong => true}, :valid)
16
+ }.to raise_error ArgumentError
17
+ end
18
+
19
+ it 'accepts multi-key options' do
20
+ expect {
21
+ valid = [:valid, :another]
22
+ subject.validate_options({:valid => true, :another => true}, *valid)
23
+ }.to_not raise_error
24
+ end
25
+ end
data/spec/row_spec.rb ADDED
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+ require 'row'
3
+
4
+ describe Row do
5
+ before :each do
6
+ @cols = 10.times.map {|v| Column.new("test#{v}")}
7
+ end
8
+
9
+ describe '#add' do
10
+ subject { Row.new }
11
+
12
+ it 'adds columns' do
13
+ subject.add(@cols[0])
14
+ subject.columns.size.should == 1
15
+ subject.columns[0].should == @cols[0]
16
+ subject.add(@cols[1])
17
+ subject.columns.should == @cols[0,2]
18
+ end
19
+ end
20
+
21
+ describe '#to_s' do
22
+ before :each do
23
+ @cols = [
24
+ Column.new('asdf'),
25
+ Column.new('qwer', :align => 'center'),
26
+ Column.new('zxcv', :align => 'right'),
27
+ Column.new('x' * 25, :align => 'left', :width => 10),
28
+ Column.new('x' * 25, :align => 'center', :width => 10),
29
+ Column.new('x' * 35, :align => 'left', :width => 10),
30
+ ]
31
+ end
32
+
33
+ before :all do
34
+ @one_space = ' '
35
+ @three_spaces = ' {3,3}'
36
+ @six_spaces = ' {6,6}'
37
+ @nine_spaces = ' {9,9}'
38
+ @five_xs = 'x{5,5}'
39
+ @ten_xs = 'x{10,10}'
40
+ end
41
+
42
+ context 'no border' do
43
+ context 'no wrap' do
44
+ it 'prints a single column' do
45
+ subject.add(@cols[0])
46
+ subject.should_receive(:puts).with(/^asdf#{@six_pieces}/)
47
+ subject.to_s
48
+ end
49
+ it 'prints three columns' do
50
+ subject.add(@cols[0])
51
+ subject.add(@cols[1])
52
+ subject.add(@cols[2])
53
+ subject.should_receive(:puts).with(/^asdf#{@six_spaces}#{@one_space}#{@three_spaces}qwer#{@three_spaces}#{@one_space}#{@six_spaces}zxcv $/)
54
+ subject.to_s
55
+ end
56
+ end
57
+
58
+ context 'with wrapping' do
59
+ it 'prints a single column' do
60
+ subject.add(@cols[3])
61
+ subject.should_receive(:puts).with(/^#{@ten_xs}#{@one_space}$/)
62
+ subject.should_receive(:puts).with(/^#{@ten_xs}#{@one_space}$/)
63
+ subject.should_receive(:puts).with(/^#{@five_xs}#{@six_spaces}$/)
64
+ subject.to_s
65
+ end
66
+
67
+ it 'prints multiple columns of the same size' do
68
+ subject.add(@cols[3])
69
+ subject.add(@cols[4])
70
+ subject.should_receive(:puts).with(/^#{@ten_xs}#{@one_space}#{@ten_xs}#{@one_space}$/)
71
+ subject.should_receive(:puts).with(/^#{@ten_xs}#{@one_space}#{@ten_xs}#{@one_space}$/)
72
+ subject.should_receive(:puts).with(/^#{@five_xs}#{@nine_spaces}#{@five_xs}#{@three_spaces}$/)
73
+ subject.to_s
74
+ end
75
+
76
+ it 'prints multiple columns with different size' do
77
+ subject.add(@cols[5])
78
+ subject.add(@cols[3])
79
+ subject.should_receive(:puts).with(/^#{@ten_xs}#{@one_space}#{@ten_xs}#{@one_space}$/)
80
+ subject.should_receive(:puts).with(/^#{@ten_xs}#{@one_space}#{@ten_xs}#{@one_space}$/)
81
+ subject.should_receive(:puts).with(/^#{@ten_xs}#{@one_space}#{@five_xs}#{@six_spaces}$/)
82
+ subject.should_receive(:puts).with(/^#{@five_xs} {5,17}$/)
83
+ subject.to_s
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  $: << File.join(File.dirname(__FILE__), '..', 'lib')
2
2
 
3
+ Dir[File.dirname(__FILE__) + "../lib/*.rb"].each {|f| require f}
3
4
  Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
@@ -0,0 +1,17 @@
1
+ RSpec::Matchers.define :accepts_argument do |expected|
2
+ match do
3
+ expected.call.should raise_exception ArgumentError
4
+ end
5
+
6
+ # failure_message_for_should do |actual|
7
+ # 'should raise an ArgumentError'
8
+ # end
9
+
10
+ # failure_message_for_should_not do |actual|
11
+ # 'should not raise ArgumentError'
12
+ # end
13
+
14
+ # description do
15
+ # 'validates options argument'
16
+ # end
17
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+ require 'table'
3
+
4
+ describe Table do
5
+ context 'creation' do
6
+ it 'defaults options hash' do
7
+ expect {
8
+ Table.new
9
+ }.to_not raise_error
10
+ end
11
+
12
+ it 'defaults the border' do
13
+ Table.new.border.should == false
14
+ end
15
+
16
+ it 'accepts the border' do
17
+ Table.new(:border => true).border.should == true
18
+ end
19
+ end
20
+
21
+ context 'rows' do
22
+ it 'allows addition' do
23
+ cols = [Column.new('test1'), Column.new('test2')]
24
+ row = Row.new
25
+ cols.each {|c| row.add(c)}
26
+ expect {
27
+ Table.new.add(row)
28
+ }.to_not raise_error
29
+ end
30
+
31
+ it 'normalizes all column width and sizes' do
32
+ cols = [Column.new('asdf', :width => 5), Column.new('qwer')]
33
+ row = Row.new
34
+ row.add(cols[0])
35
+ t = Table.new
36
+ t.add(row)
37
+ row = Row.new
38
+ row.add(cols[1])
39
+ t.add(row)
40
+ output = capture_stdout {
41
+ t.to_s
42
+ }
43
+ end
44
+ end
45
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: command_line_reporter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: '2.0'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-12-01 00:00:00.000000000Z
13
+ date: 2012-01-11 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
17
- requirement: &2151943740 !ruby/object:Gem::Requirement
17
+ requirement: &2152892720 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,7 +22,7 @@ dependencies:
22
22
  version: 1.0.0
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *2151943740
25
+ version_requirements: *2152892720
26
26
  description: This gem makes it easy to provide a report while your ruby script is
27
27
  executing
28
28
  email: baywes@gmail.com
@@ -33,16 +33,26 @@ files:
33
33
  - examples/nested.rb
34
34
  - examples/progress.rb
35
35
  - examples/simple.rb
36
+ - examples/table.rb
37
+ - lib/column.rb
36
38
  - lib/command_line_reporter.rb
37
39
  - lib/nested_formatter.rb
40
+ - lib/options_validator.rb
38
41
  - lib/progress_formatter.rb
42
+ - lib/row.rb
43
+ - lib/table.rb
39
44
  - lib/version.rb
40
45
  - README.md
46
+ - spec/column_spec.rb
41
47
  - spec/command_line_reporter_spec.rb
42
48
  - spec/nested_formatter_spec.rb
49
+ - spec/options_validator_spec.rb
43
50
  - spec/progress_formatter_spec.rb
51
+ - spec/row_spec.rb
44
52
  - spec/spec_helper.rb
45
53
  - spec/support/helpers/stdout.rb
54
+ - spec/support/matchers/argument.rb
55
+ - spec/table_spec.rb
46
56
  homepage: http://github.com/wbailey/command_line_reporter
47
57
  licenses: []
48
58
  post_install_message:
@@ -57,7 +67,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
57
67
  version: '0'
58
68
  segments:
59
69
  - 0
60
- hash: -846505284794212082
70
+ hash: 3958532185567160349
61
71
  required_rubygems_version: !ruby/object:Gem::Requirement
62
72
  none: false
63
73
  requirements:
@@ -71,8 +81,13 @@ signing_key:
71
81
  specification_version: 3
72
82
  summary: A tool for providing interactive command line applications
73
83
  test_files:
84
+ - spec/column_spec.rb
74
85
  - spec/command_line_reporter_spec.rb
75
86
  - spec/nested_formatter_spec.rb
87
+ - spec/options_validator_spec.rb
76
88
  - spec/progress_formatter_spec.rb
89
+ - spec/row_spec.rb
77
90
  - spec/spec_helper.rb
78
91
  - spec/support/helpers/stdout.rb
92
+ - spec/support/matchers/argument.rb
93
+ - spec/table_spec.rb