tty-table 0.1.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 (148) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +3 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +22 -0
  6. data/Gemfile +19 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +389 -0
  9. data/Rakefile +8 -0
  10. data/benchmarks/speed.rb +36 -0
  11. data/lib/tty/table/border/ascii.rb +32 -0
  12. data/lib/tty/table/border/null.rb +37 -0
  13. data/lib/tty/table/border/row_line.rb +18 -0
  14. data/lib/tty/table/border/unicode.rb +32 -0
  15. data/lib/tty/table/border.rb +219 -0
  16. data/lib/tty/table/border_dsl.rb +251 -0
  17. data/lib/tty/table/border_options.rb +53 -0
  18. data/lib/tty/table/column_set.rb +121 -0
  19. data/lib/tty/table/columns.rb +170 -0
  20. data/lib/tty/table/empty.rb +26 -0
  21. data/lib/tty/table/error.rb +39 -0
  22. data/lib/tty/table/field.rb +139 -0
  23. data/lib/tty/table/header.rb +163 -0
  24. data/lib/tty/table/indentation.rb +52 -0
  25. data/lib/tty/table/operation/alignment_set.rb +103 -0
  26. data/lib/tty/table/operation/escape.rb +30 -0
  27. data/lib/tty/table/operation/filter.rb +34 -0
  28. data/lib/tty/table/operation/padding.rb +95 -0
  29. data/lib/tty/table/operation/truncation.rb +41 -0
  30. data/lib/tty/table/operation/wrapped.rb +43 -0
  31. data/lib/tty/table/operations.rb +69 -0
  32. data/lib/tty/table/options.rb +30 -0
  33. data/lib/tty/table/orientation/horizontal.rb +48 -0
  34. data/lib/tty/table/orientation/vertical.rb +38 -0
  35. data/lib/tty/table/orientation.rb +57 -0
  36. data/lib/tty/table/padder.rb +180 -0
  37. data/lib/tty/table/renderer/ascii.rb +16 -0
  38. data/lib/tty/table/renderer/basic.rb +294 -0
  39. data/lib/tty/table/renderer/color.rb +12 -0
  40. data/lib/tty/table/renderer/unicode.rb +21 -0
  41. data/lib/tty/table/renderer.rb +101 -0
  42. data/lib/tty/table/row.rb +248 -0
  43. data/lib/tty/table/transformation.rb +39 -0
  44. data/lib/tty/table/validatable.rb +64 -0
  45. data/lib/tty/table/version.rb +7 -0
  46. data/lib/tty/table.rb +469 -0
  47. data/lib/tty-table.rb +48 -0
  48. data/spec/spec_helper.rb +51 -0
  49. data/spec/unit/access_spec.rb +86 -0
  50. data/spec/unit/add_row_spec.rb +28 -0
  51. data/spec/unit/border/ascii/rendering_spec.rb +90 -0
  52. data/spec/unit/border/new_spec.rb +27 -0
  53. data/spec/unit/border/null/rendering_spec.rb +130 -0
  54. data/spec/unit/border/options/from_spec.rb +38 -0
  55. data/spec/unit/border/options/new_spec.rb +14 -0
  56. data/spec/unit/border/unicode/rendering_spec.rb +63 -0
  57. data/spec/unit/border_options/new_spec.rb +20 -0
  58. data/spec/unit/border_options/update_spec.rb +18 -0
  59. data/spec/unit/column_set/extract_widths_spec.rb +15 -0
  60. data/spec/unit/column_set/total_width_spec.rb +15 -0
  61. data/spec/unit/column_set/widths_from_spec.rb +51 -0
  62. data/spec/unit/columns/enforce_spec.rb +67 -0
  63. data/spec/unit/columns/widths_spec.rb +35 -0
  64. data/spec/unit/data_spec.rb +14 -0
  65. data/spec/unit/each_spec.rb +41 -0
  66. data/spec/unit/each_with_index_spec.rb +57 -0
  67. data/spec/unit/empty_spec.rb +23 -0
  68. data/spec/unit/eql_spec.rb +34 -0
  69. data/spec/unit/field/equality_spec.rb +51 -0
  70. data/spec/unit/field/length_spec.rb +21 -0
  71. data/spec/unit/field/lines_spec.rb +21 -0
  72. data/spec/unit/field/new_spec.rb +29 -0
  73. data/spec/unit/field/width_spec.rb +23 -0
  74. data/spec/unit/filter_spec.rb +23 -0
  75. data/spec/unit/header/call_spec.rb +30 -0
  76. data/spec/unit/header/color_spec.rb +19 -0
  77. data/spec/unit/header/equality_spec.rb +51 -0
  78. data/spec/unit/header/height_spec.rb +27 -0
  79. data/spec/unit/header/new_spec.rb +25 -0
  80. data/spec/unit/header/set_spec.rb +20 -0
  81. data/spec/unit/header/to_ary_spec.rb +14 -0
  82. data/spec/unit/header_spec.rb +13 -0
  83. data/spec/unit/indentation/insert_indent_spec.rb +27 -0
  84. data/spec/unit/initialize_spec.rb +88 -0
  85. data/spec/unit/operation/alignment_set/call_spec.rb +39 -0
  86. data/spec/unit/operation/alignment_set/each_spec.rb +17 -0
  87. data/spec/unit/operation/alignment_set/new_spec.rb +27 -0
  88. data/spec/unit/operation/alignment_set/to_ary_spec.rb +14 -0
  89. data/spec/unit/operation/escape/call_spec.rb +16 -0
  90. data/spec/unit/operation/filter/call_spec.rb +17 -0
  91. data/spec/unit/operation/truncation/call_spec.rb +32 -0
  92. data/spec/unit/operation/wrapped/call_spec.rb +33 -0
  93. data/spec/unit/operations/new_spec.rb +30 -0
  94. data/spec/unit/options/access_spec.rb +14 -0
  95. data/spec/unit/options_spec.rb +25 -0
  96. data/spec/unit/orientation_spec.rb +145 -0
  97. data/spec/unit/padder/parse_spec.rb +45 -0
  98. data/spec/unit/padder/to_s_spec.rb +14 -0
  99. data/spec/unit/padding_spec.rb +120 -0
  100. data/spec/unit/properties_spec.rb +25 -0
  101. data/spec/unit/render_spec.rb +63 -0
  102. data/spec/unit/render_with_spec.rb +106 -0
  103. data/spec/unit/renderer/ascii/indentation_spec.rb +41 -0
  104. data/spec/unit/renderer/ascii/padding_spec.rb +61 -0
  105. data/spec/unit/renderer/ascii/render_spec.rb +68 -0
  106. data/spec/unit/renderer/ascii/resizing_spec.rb +114 -0
  107. data/spec/unit/renderer/ascii/separator_spec.rb +28 -0
  108. data/spec/unit/renderer/basic/alignment_spec.rb +88 -0
  109. data/spec/unit/renderer/basic/coloring_spec.rb +46 -0
  110. data/spec/unit/renderer/basic/extract_column_widths_spec.rb +28 -0
  111. data/spec/unit/renderer/basic/filter_spec.rb +53 -0
  112. data/spec/unit/renderer/basic/indentation_spec.rb +48 -0
  113. data/spec/unit/renderer/basic/multiline_content_spec.rb +135 -0
  114. data/spec/unit/renderer/basic/new_spec.rb +26 -0
  115. data/spec/unit/renderer/basic/options_spec.rb +52 -0
  116. data/spec/unit/renderer/basic/padding_spec.rb +52 -0
  117. data/spec/unit/renderer/basic/render_spec.rb +57 -0
  118. data/spec/unit/renderer/basic/resizing_spec.rb +96 -0
  119. data/spec/unit/renderer/basic/separator_spec.rb +43 -0
  120. data/spec/unit/renderer/basic/truncation_spec.rb +35 -0
  121. data/spec/unit/renderer/basic/wrapping_spec.rb +40 -0
  122. data/spec/unit/renderer/border_spec.rb +104 -0
  123. data/spec/unit/renderer/render_spec.rb +36 -0
  124. data/spec/unit/renderer/select_spec.rb +22 -0
  125. data/spec/unit/renderer/style_spec.rb +72 -0
  126. data/spec/unit/renderer/unicode/indentation_spec.rb +41 -0
  127. data/spec/unit/renderer/unicode/padding_spec.rb +61 -0
  128. data/spec/unit/renderer/unicode/render_spec.rb +68 -0
  129. data/spec/unit/renderer/unicode/separator_spec.rb +26 -0
  130. data/spec/unit/renderer_spec.rb +19 -0
  131. data/spec/unit/rotate_spec.rb +86 -0
  132. data/spec/unit/row/access_spec.rb +25 -0
  133. data/spec/unit/row/call_spec.rb +45 -0
  134. data/spec/unit/row/data_spec.rb +26 -0
  135. data/spec/unit/row/each_spec.rb +31 -0
  136. data/spec/unit/row/equality_spec.rb +73 -0
  137. data/spec/unit/row/height_spec.rb +27 -0
  138. data/spec/unit/row/new_spec.rb +41 -0
  139. data/spec/unit/row/to_ary_spec.rb +14 -0
  140. data/spec/unit/to_s_spec.rb +63 -0
  141. data/spec/unit/transformation/extract_tuples_spec.rb +35 -0
  142. data/spec/unit/validatable/validate_options_spec.rb +33 -0
  143. data/spec/unit/validatable_spec.rb +32 -0
  144. data/tasks/console.rake +10 -0
  145. data/tasks/coverage.rake +11 -0
  146. data/tasks/spec.rake +29 -0
  147. data/tty-table.gemspec +28 -0
  148. metadata +371 -0
@@ -0,0 +1,104 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Table::Renderer, '#border' do
6
+ let(:header) { ['h1', 'h2', 'h3'] }
7
+ let(:rows) { [['a1', 'a2', 'a3'], ['b1', 'b2', 'b3']] }
8
+ let(:border) { nil }
9
+
10
+ let(:table) { TTY::Table.new(header, rows) }
11
+
12
+ subject(:renderer) { described_class.select(type).new(table) }
13
+
14
+ context 'when basic renderer' do
15
+ let(:type) { :basic }
16
+ let(:border) { {characters: {'top' => '-'}, style: :red} }
17
+
18
+ it 'specifies border in hash' do
19
+ renderer.border(border)
20
+ expect(renderer.border.characters['top']).to eql('-')
21
+ end
22
+
23
+ it 'specifies border in characters attribute' do
24
+ renderer.border.characters = {'top' => '*'}
25
+ expect(renderer.border.characters['top']).to eql('*')
26
+ end
27
+
28
+ it 'specifies border in block' do
29
+ renderer.border do
30
+ mid '='
31
+ mid_mid ' '
32
+ end
33
+
34
+ expect(renderer.render).to eq <<-EOS.normalize
35
+ h1 h2 h3
36
+ == == ==
37
+ a1 a2 a3
38
+ b1 b2 b3
39
+ EOS
40
+ end
41
+ end
42
+
43
+ context 'when ascii renderer' do
44
+ let(:type) { :ascii }
45
+
46
+ it 'specifies border in block' do
47
+ renderer.border do
48
+ mid '='
49
+ mid_mid '='
50
+ mid_left '='
51
+ mid_right '='
52
+ end
53
+
54
+ expect(renderer.render).to eq <<-EOS.normalize
55
+ +--+--+--+
56
+ |h1|h2|h3|
57
+ ==========
58
+ |a1|a2|a3|
59
+ |b1|b2|b3|
60
+ +--+--+--+
61
+ EOS
62
+ end
63
+
64
+ it 'specifies border as hash' do
65
+ renderer.border({characters: {
66
+ 'mid' => '=',
67
+ 'mid_mid' => '=',
68
+ 'mid_left' => '=',
69
+ 'mid_right' => '=',
70
+ }})
71
+
72
+ expect(renderer.render).to eq <<-EOS.normalize
73
+ +--+--+--+
74
+ |h1|h2|h3|
75
+ ==========
76
+ |a1|a2|a3|
77
+ |b1|b2|b3|
78
+ +--+--+--+
79
+ EOS
80
+ end
81
+ end
82
+
83
+ context 'when unicode renderer' do
84
+ let(:type) { :unicode }
85
+
86
+ it 'specifies border in block' do
87
+ renderer.border do
88
+ mid '='
89
+ mid_mid '='
90
+ mid_left '='
91
+ mid_right '='
92
+ end
93
+
94
+ expect(renderer.render).to eq <<-EOS.normalize
95
+ ┌──┬──┬──┐
96
+ │h1│h2│h3│
97
+ ==========
98
+ │a1│a2│a3│
99
+ │b1│b2│b3│
100
+ └──┴──┴──┘
101
+ EOS
102
+ end
103
+ end
104
+ end # border
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Table::Renderer, '#render' do
6
+ let(:header) { ['h1', 'h2', 'h3'] }
7
+ let(:rows) { [['a1', 'a2', 'a3'], ['b1', 'b2', 'b3']] }
8
+ let(:table) { TTY::Table.new(header, rows) }
9
+
10
+ subject { described_class.render(table, {}, &block) }
11
+
12
+ context 'when default' do
13
+ let(:renderer) { double(:renderer).as_null_object }
14
+ let(:renderer_class) { double(:renderer_class).as_null_object }
15
+ let(:yielded) { [] }
16
+ let(:block) { proc { |render| yielded << render } }
17
+
18
+ before { allow(described_class).to receive(:select).and_return(renderer_class) }
19
+
20
+ it 'creates renderer' do
21
+ subject
22
+ expect(renderer_class).to have_received(:new).with(table, {})
23
+ end
24
+
25
+ it 'yields renderer' do
26
+ allow(renderer_class).to receive(:new).and_return(renderer)
27
+ expect { subject }.to change { yielded}.from([]).to([renderer])
28
+ end
29
+
30
+ it 'calls render' do
31
+ allow(renderer_class).to receive(:new).and_return(renderer)
32
+ subject
33
+ expect(renderer).to have_received(:render)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Table::Renderer, '#select' do
6
+ let(:klass) { ::Class.new }
7
+ let(:instance) { described_class }
8
+
9
+ subject { instance.select(renderer) }
10
+
11
+ context 'with basic' do
12
+ let(:renderer) { :basic }
13
+
14
+ it { is_expected.to be(TTY::Table::Renderer::Basic) }
15
+ end
16
+
17
+ context 'with unicode' do
18
+ let(:renderer) { :unicode }
19
+
20
+ it { is_expected.to be(TTY::Table::Renderer::Unicode) }
21
+ end
22
+ end
@@ -0,0 +1,72 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Table::Renderer, 'with style' do
6
+ let(:header) { ['h1', 'h2', 'h3'] }
7
+ let(:rows) { [['a1', 'a2', 'a3'], ['b1', 'b2', 'b3']] }
8
+ let(:table) { TTY::Table.new(header, rows) }
9
+ let(:color) { Pastel.new(enabled: true) }
10
+
11
+ subject(:renderer) { described_class.select(type).new(table) }
12
+
13
+ before { allow(Pastel).to receive(:new).and_return(color) }
14
+
15
+ context 'when basic renderer' do
16
+ let(:type) { :basic }
17
+
18
+ it "sets through hash" do
19
+ renderer.border(style: :red)
20
+ expect(renderer.border.style).to eql(:red)
21
+ end
22
+
23
+ it "sets through attribute" do
24
+ renderer.border.style = :red
25
+ expect(renderer.border.style).to eql :red
26
+ end
27
+
28
+ it "renders without color" do
29
+ expect(renderer.render).to eq <<-EOS.normalize
30
+ h1 h2 h3
31
+ a1 a2 a3
32
+ b1 b2 b3
33
+ EOS
34
+ end
35
+ end
36
+
37
+ context 'when ascii renderer' do
38
+ let(:type) { :ascii }
39
+ let(:red) { "\e[31m" }
40
+ let(:clear) { "\e[0m" }
41
+
42
+ it "renders border in color" do
43
+ renderer.border.style= :red
44
+ expect(renderer.render).to eq <<-EOS.normalize
45
+ #{red}+--+--+--+#{clear}
46
+ #{red}|#{clear}h1#{red}|#{clear}h2#{red}|#{clear}h3#{red}|#{clear}
47
+ #{red}+--+--+--+#{clear}
48
+ #{red}|#{clear}a1#{red}|#{clear}a2#{red}|#{clear}a3#{red}|#{clear}
49
+ #{red}|#{clear}b1#{red}|#{clear}b2#{red}|#{clear}b3#{red}|#{clear}
50
+ #{red}+--+--+--+#{clear}
51
+ EOS
52
+ end
53
+ end
54
+
55
+ context 'when unicode renderer' do
56
+ let(:type) { :unicode }
57
+ let(:red) { "\e[31m" }
58
+ let(:clear) { "\e[0m" }
59
+
60
+ it "renders each row" do
61
+ renderer.border.style= :red
62
+ expect(renderer.render).to eq <<-EOS.normalize
63
+ #{red}┌──┬──┬──┐#{clear}
64
+ #{red}│#{clear}h1#{red}│#{clear}h2#{red}│#{clear}h3#{red}│#{clear}
65
+ #{red}├──┼──┼──┤#{clear}
66
+ #{red}│#{clear}a1#{red}│#{clear}a2#{red}│#{clear}a3#{red}│#{clear}
67
+ #{red}│#{clear}b1#{red}│#{clear}b2#{red}│#{clear}b3#{red}│#{clear}
68
+ #{red}└──┴──┴──┘#{clear}
69
+ EOS
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,41 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Table::Renderer::Unicode, 'indentation' do
6
+ let(:header) { ['h1', 'h2', 'h3'] }
7
+ let(:rows) { [['a1', 'a2', 'a3'], ['b1', 'b2', 'b3']] }
8
+ let(:table) { TTY::Table.new(header, rows) }
9
+ let(:indent) { 2 }
10
+ let(:options) { {indent: indent } }
11
+
12
+ subject(:renderer) { described_class.new(table, options)}
13
+
14
+ context 'when default' do
15
+ it 'indents by value' do
16
+ expect(renderer.render).to eql <<-EOS.chomp
17
+ ┌──┬──┬──┐
18
+ │h1│h2│h3│
19
+ ├──┼──┼──┤
20
+ │a1│a2│a3│
21
+ │b1│b2│b3│
22
+ └──┴──┴──┘
23
+ EOS
24
+ end
25
+ end
26
+
27
+ context 'when each row' do
28
+ it 'indents by value' do
29
+ renderer.border.separator = :each_row
30
+ expect(renderer.render).to eql <<-EOS.chomp
31
+ ┌──┬──┬──┐
32
+ │h1│h2│h3│
33
+ ├──┼──┼──┤
34
+ │a1│a2│a3│
35
+ ├──┼──┼──┤
36
+ │b1│b2│b3│
37
+ └──┴──┴──┘
38
+ EOS
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,61 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Table::Renderer::Unicode, 'padding' do
6
+ let(:header) { ['Field', 'Type', 'Null', 'Key', 'Default', 'Extra'] }
7
+ let(:rows) { [['id', 'int(11)', 'YES', 'nil', 'NULL', '']] }
8
+ let(:table) { TTY::Table.new(header, rows) }
9
+
10
+ subject(:renderer) { described_class.new(table, options) }
11
+
12
+ context 'with left & right padding' do
13
+ let(:options) { {padding: [0,1,0,1]} }
14
+
15
+ it 'pads each field' do
16
+ expect(renderer.render).to eql <<-EOS.chomp
17
+ ┌───────┬─────────┬──────┬─────┬─────────┬───────┐
18
+ │ Field │ Type │ Null │ Key │ Default │ Extra │
19
+ ├───────┼─────────┼──────┼─────┼─────────┼───────┤
20
+ │ id │ int(11) │ YES │ nil │ NULL │ │
21
+ └───────┴─────────┴──────┴─────┴─────────┴───────┘
22
+ EOS
23
+ end
24
+ end
25
+
26
+ context 'with top & bottom padding' do
27
+ let(:options) { {padding: [1,0,1,0], multiline: true} }
28
+
29
+ it 'pads each field' do
30
+ expect(renderer.render).to eql <<-EOS.chomp
31
+ ┌─────┬───────┬────┬───┬───────┬─────┐
32
+ │ │ │ │ │ │ │
33
+ │Field│Type │Null│Key│Default│Extra│
34
+ │ │ │ │ │ │ │
35
+ ├─────┼───────┼────┼───┼───────┼─────┤
36
+ │ │ │ │ │ │ │
37
+ │id │int(11)│YES │nil│NULL │ │
38
+ │ │ │ │ │ │ │
39
+ └─────┴───────┴────┴───┴───────┴─────┘
40
+ EOS
41
+ end
42
+ end
43
+
44
+ context 'with full padding' do
45
+ let(:options) { {padding: [1,1,1,1], multiline: true} }
46
+
47
+ it 'pads each field' do
48
+ expect(renderer.render).to eql <<-EOS.chomp
49
+ ┌───────┬─────────┬──────┬─────┬─────────┬───────┐
50
+ │ │ │ │ │ │ │
51
+ │ Field │ Type │ Null │ Key │ Default │ Extra │
52
+ │ │ │ │ │ │ │
53
+ ├───────┼─────────┼──────┼─────┼─────────┼───────┤
54
+ │ │ │ │ │ │ │
55
+ │ id │ int(11) │ YES │ nil │ NULL │ │
56
+ │ │ │ │ │ │ │
57
+ └───────┴─────────┴──────┴─────┴─────────┴───────┘
58
+ EOS
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,68 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Table::Renderer::Unicode, '#render' do
6
+ let(:header) { ['h1', 'h2', 'h3'] }
7
+ let(:rows) { [['a1', 'a2', 'a3'], ['b1', 'b2', 'b3']] }
8
+ let(:table) { TTY::Table.new header, rows }
9
+
10
+ subject(:renderer) { described_class.new(table) }
11
+
12
+ context 'with rows only' do
13
+ let(:table) { TTY::Table.new rows }
14
+
15
+ it 'display table rows' do
16
+ expect(renderer.render).to eq <<-EOS.normalize
17
+ ┌──┬──┬──┐
18
+ │a1│a2│a3│
19
+ │b1│b2│b3│
20
+ └──┴──┴──┘
21
+ EOS
22
+ end
23
+ end
24
+
25
+ context 'with header' do
26
+ it 'displays table with header' do
27
+ expect(renderer.render).to eq <<-EOS.normalize
28
+ ┌──┬──┬──┐
29
+ │h1│h2│h3│
30
+ ├──┼──┼──┤
31
+ │a1│a2│a3│
32
+ │b1│b2│b3│
33
+ └──┴──┴──┘
34
+ EOS
35
+ end
36
+ end
37
+
38
+ context 'with short header' do
39
+ let(:header) { ['h1', 'h2'] }
40
+ let(:rows) { [['aaa1', 'a2'], ['b1', 'bb1']] }
41
+
42
+ it 'displays table according to widths' do
43
+ expect(renderer.render).to eq <<-EOS.normalize
44
+ ┌────┬───┐
45
+ │h1 │h2 │
46
+ ├────┼───┤
47
+ │aaa1│a2 │
48
+ │b1 │bb1│
49
+ └────┴───┘
50
+ EOS
51
+ end
52
+ end
53
+
54
+ context 'with long header' do
55
+ let(:header) { ['header1', 'header2', 'header3'] }
56
+
57
+ it 'header greater than row sizes' do
58
+ expect(renderer.render).to eq <<-EOS.normalize
59
+ ┌───────┬───────┬───────┐
60
+ │header1│header2│header3│
61
+ ├───────┼───────┼───────┤
62
+ │a1 │a2 │a3 │
63
+ │b1 │b2 │b3 │
64
+ └───────┴───────┴───────┘
65
+ EOS
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Table::Renderer::Unicode, 'with separator' do
6
+ let(:header) { ['h1', 'h2', 'h3'] }
7
+ let(:rows) { [['a1', 'a2', 'a3'], ['b1', 'b2', 'b3']] }
8
+ let(:table) { TTY::Table.new(header, rows) }
9
+
10
+ let(:object) { described_class.new table }
11
+
12
+ subject(:renderer) { object }
13
+
14
+ it "renders each row" do
15
+ renderer.border.separator= :each_row
16
+ expect(renderer.render).to eq <<-EOS.normalize
17
+ ┌──┬──┬──┐
18
+ │h1│h2│h3│
19
+ ├──┼──┼──┤
20
+ │a1│a2│a3│
21
+ ├──┼──┼──┤
22
+ │b1│b2│b3│
23
+ └──┴──┴──┘
24
+ EOS
25
+ end
26
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Table, '#renderer' do
6
+ let(:object) { described_class }
7
+ let(:header) { ['h1', 'h2'] }
8
+ let(:rows) { [['a1', 'a2'], ['b1', 'b2']] }
9
+
10
+ subject(:table) { object.new(header, rows).renderer }
11
+
12
+ it 'creates new renderer' do
13
+ expect(subject).to be_kind_of(TTY::Table::Renderer::Basic)
14
+ end
15
+
16
+ it 'chains calls on renderer' do
17
+ expect(subject.render).to eql("h1 h2\na1 a2\nb1 b2")
18
+ end
19
+ end
@@ -0,0 +1,86 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Table, '#rotate' do
6
+ let(:header) { ['h1', 'h2', 'h3'] }
7
+ let(:rows) { [['a1', 'a2', 'a3'], ['b1', 'b2', 'b3']] }
8
+
9
+ subject(:table) { described_class.new(header, rows) }
10
+
11
+ before { table.orientation = :horizontal }
12
+
13
+ context 'with default' do
14
+ context 'without header' do
15
+ let(:header) { nil }
16
+
17
+ it 'preserves orientation' do
18
+ expect(table.header).to be_nil
19
+ expect(table.rotate.to_a).to eql rows
20
+ end
21
+ end
22
+
23
+ context 'with header' do
24
+ it 'preserves orientation' do
25
+ expect(table.rotate.to_a).to eql [header] + rows
26
+ end
27
+ end
28
+ end
29
+
30
+ context 'with no header' do
31
+ let(:header) { nil }
32
+
33
+ it 'rotates the rows' do
34
+ table.orientation = :vertical
35
+ expect(table.rotate.to_a).to eql [
36
+ ['1', 'a1'],
37
+ ['2', 'a2'],
38
+ ['3', 'a3'],
39
+ ['1', 'b1'],
40
+ ['2', 'b2'],
41
+ ['3', 'b3'],
42
+ ]
43
+ expect(table.header).to be_nil
44
+ end
45
+
46
+ it 'rotates the rows back' do
47
+ table.orientation = :vertical
48
+ table.rotate
49
+ table.orientation = :horizontal
50
+ expect(table.rotate.to_a).to eql rows
51
+ expect(table.header).to eql header
52
+ end
53
+
54
+ it 'roates the output' do
55
+ expect(table.to_s).to eq("a1 a2 a3\nb1 b2 b3")
56
+ table.orientation = :vertical
57
+ table.rotate
58
+ expect(table.to_s).to eq("1 a1\n2 a2\n3 a3\n1 b1\n2 b2\n3 b3")
59
+ end
60
+ end
61
+
62
+ context 'with header' do
63
+ it 'rotates the rows and merges header' do
64
+ table.orientation = :vertical
65
+ expect(table.rotate.to_a).to eql [
66
+ ['h1', 'a1'],
67
+ ['h2', 'a2'],
68
+ ['h3', 'a3'],
69
+ ['h1', 'b1'],
70
+ ['h2', 'b2'],
71
+ ['h3', 'b3'],
72
+ ]
73
+ expect(table.header).to be_empty
74
+ end
75
+
76
+ it 'rotates the rows and header back' do
77
+ table.orientation = :vertical
78
+ table.rotate
79
+ expect(table.orientation).to be_a TTY::Table::Orientation::Vertical
80
+
81
+ table.orientation = :horizontal
82
+ expect(table.rotate.to_a).to eql [header] + rows
83
+ expect(table.header).to eql header
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Table::Row, '#access' do
6
+ let(:object) { described_class.new [] }
7
+
8
+ before { object[attribute] = value}
9
+
10
+ subject { object[attribute] }
11
+
12
+ context 'when integer' do
13
+ let(:attribute) { 0 }
14
+ let(:value) { 1 }
15
+
16
+ it { is_expected.to eq(1) }
17
+ end
18
+
19
+ context 'when symbol' do
20
+ let(:attribute) { :id }
21
+ let(:value) { 1 }
22
+
23
+ it { is_expected.to eq(1) }
24
+ end
25
+ end
@@ -0,0 +1,45 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Table::Row, '#call' do
6
+ let(:object) { described_class.new(data) }
7
+
8
+ subject { object[attribute] }
9
+
10
+ context 'when integer' do
11
+ let(:data) { ['a', 'b'] }
12
+
13
+ let(:attribute) { 1 }
14
+
15
+ it { is_expected.to eql('b') }
16
+ end
17
+
18
+ context 'when symbol' do
19
+ let(:data) { {:id => 1} }
20
+
21
+ context 'when hash access' do
22
+ let(:attribute) { :id }
23
+
24
+ it { is_expected.to eql(1) }
25
+ end
26
+
27
+ context 'when array access' do
28
+ let(:attribute) { 0 }
29
+
30
+ it { is_expected.to eql(1) }
31
+ end
32
+ end
33
+
34
+ context 'when unkown attribute' do
35
+ let(:data) { {:id => 1} }
36
+
37
+ let(:attribute) { :other }
38
+
39
+ specify {
40
+ expect {
41
+ subject
42
+ }.to raise_error(TTY::Table::UnknownAttributeError)
43
+ }
44
+ end
45
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Table::Row, '#data' do
6
+ let(:object) { described_class.new data, header }
7
+ let(:data) { ['a'] }
8
+
9
+ subject { object.to_hash }
10
+
11
+ context 'without attributes' do
12
+ let(:header) { nil }
13
+
14
+ it { is_expected.to be_instance_of(Hash) }
15
+
16
+ it { is_expected.to eql(0 => 'a') }
17
+ end
18
+
19
+ context 'with attributes' do
20
+ let(:header) { [:id] }
21
+
22
+ it { is_expected.to be_instance_of(Hash) }
23
+
24
+ it { is_expected.to eql(id: 'a') }
25
+ end
26
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Table::Row, '#new' do
6
+ let(:yields) { [] }
7
+ let(:value) { 'a1' }
8
+ let(:header) { ['Header1']}
9
+ let(:row) { [ value ] }
10
+ let(:object) { described_class.new row, header }
11
+
12
+ context 'with block' do
13
+ subject { object.each { |field| yields << field } }
14
+
15
+ it 'yields only fields' do
16
+ subject
17
+ yields.each { |field| expect(field).to be_instance_of(value.class) }
18
+ end
19
+
20
+ it 'yields rows with expected attributes' do
21
+ subject
22
+ yields.each { |field| expect(field).to eql(value) }
23
+ end
24
+
25
+ it 'yields each row' do
26
+ expect { subject }.to change { yields }.
27
+ from( [] ).
28
+ to( yields )
29
+ end
30
+ end
31
+ end