tty 0.0.6 → 0.0.7
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.
- data/README.md +78 -12
- data/benchmarks/shell.rb +26 -0
- data/benchmarks/table.rb +35 -0
- data/lib/tty.rb +23 -1
- data/lib/tty/coercer.rb +13 -0
- data/lib/tty/coercer/boolean.rb +39 -0
- data/lib/tty/coercer/float.rb +23 -0
- data/lib/tty/coercer/integer.rb +23 -0
- data/lib/tty/coercer/range.rb +33 -0
- data/lib/tty/shell.rb +6 -2
- data/lib/tty/shell/question.rb +158 -138
- data/lib/tty/shell/reader.rb +92 -0
- data/lib/tty/shell/response.rb +219 -0
- data/lib/tty/shell/response_delegation.rb +53 -0
- data/lib/tty/table.rb +90 -16
- data/lib/tty/table/border.rb +34 -8
- data/lib/tty/table/border/ascii.rb +16 -25
- data/lib/tty/table/border/null.rb +0 -6
- data/lib/tty/table/border/unicode.rb +16 -25
- data/lib/tty/table/column_set.rb +1 -1
- data/lib/tty/table/error.rb +10 -0
- data/lib/tty/table/operation/wrapped.rb +0 -6
- data/lib/tty/table/orientation.rb +57 -0
- data/lib/tty/table/orientation/horizontal.rb +19 -0
- data/lib/tty/table/orientation/vertical.rb +19 -0
- data/lib/tty/table/renderer.rb +7 -0
- data/lib/tty/table/renderer/ascii.rb +1 -1
- data/lib/tty/table/renderer/basic.rb +2 -2
- data/lib/tty/table/renderer/unicode.rb +1 -1
- data/lib/tty/table/validatable.rb +20 -0
- data/lib/tty/terminal.rb +15 -14
- data/lib/tty/terminal/color.rb +1 -1
- data/lib/tty/terminal/echo.rb +41 -0
- data/lib/tty/terminal/home.rb +31 -0
- data/lib/tty/text.rb +85 -0
- data/lib/tty/text/truncation.rb +83 -0
- data/lib/tty/text/wrapping.rb +96 -0
- data/lib/tty/version.rb +1 -1
- data/spec/tty/coercer/boolean/coerce_spec.rb +113 -0
- data/spec/tty/coercer/float/coerce_spec.rb +32 -0
- data/spec/tty/coercer/integer/coerce_spec.rb +39 -0
- data/spec/tty/coercer/range/coerce_spec.rb +73 -0
- data/spec/tty/shell/ask_spec.rb +14 -1
- data/spec/tty/shell/question/argument_spec.rb +30 -0
- data/spec/tty/shell/question/character_spec.rb +16 -0
- data/spec/tty/shell/question/default_spec.rb +25 -0
- data/spec/tty/shell/question/in_spec.rb +23 -0
- data/spec/tty/shell/question/initialize_spec.rb +11 -211
- data/spec/tty/shell/question/modifier/whitespace_spec.rb +1 -1
- data/spec/tty/shell/question/modify_spec.rb +44 -0
- data/spec/tty/shell/question/valid_spec.rb +46 -0
- data/spec/tty/shell/question/validate_spec.rb +30 -0
- data/spec/tty/shell/reader/getc_spec.rb +40 -0
- data/spec/tty/shell/response/read_bool_spec.rb +41 -0
- data/spec/tty/shell/response/read_char_spec.rb +17 -0
- data/spec/tty/shell/response/read_date_spec.rb +20 -0
- data/spec/tty/shell/response/read_email_spec.rb +43 -0
- data/spec/tty/shell/response/read_multiple_spec.rb +24 -0
- data/spec/tty/shell/response/read_number_spec.rb +29 -0
- data/spec/tty/shell/response/read_range_spec.rb +29 -0
- data/spec/tty/shell/response/read_spec.rb +68 -0
- data/spec/tty/shell/response/read_string_spec.rb +19 -0
- data/spec/tty/table/access_spec.rb +6 -0
- data/spec/tty/table/border/new_spec.rb +3 -3
- data/spec/tty/table/initialize_spec.rb +17 -1
- data/spec/tty/table/options_spec.rb +7 -1
- data/spec/tty/table/orientation_spec.rb +98 -0
- data/spec/tty/table/renders_with_spec.rb +76 -0
- data/spec/tty/table/rotate_spec.rb +72 -0
- data/spec/tty/table/to_s_spec.rb +13 -1
- data/spec/tty/table/validatable/validate_options_spec.rb +34 -0
- data/spec/tty/terminal/color/remove_spec.rb +34 -1
- data/spec/tty/terminal/echo_spec.rb +22 -0
- data/spec/tty/text/truncate_spec.rb +13 -0
- data/spec/tty/text/truncation/initialize_spec.rb +29 -0
- data/spec/tty/text/truncation/truncate_spec.rb +73 -0
- data/spec/tty/text/wrap_spec.rb +14 -0
- data/spec/tty/text/wrapping/initialize_spec.rb +25 -0
- data/spec/tty/text/wrapping/wrap_spec.rb +80 -0
- data/tty.gemspec +1 -0
- metadata +101 -8
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe TTY::Shell::Question, '#initialize' do
|
6
|
+
let(:input) { StringIO.new }
|
7
|
+
let(:output) { StringIO.new }
|
8
|
+
let(:shell) { TTY::Shell.new(input, output) }
|
9
|
+
|
10
|
+
it 'reads string' do
|
11
|
+
name = "Piotr"
|
12
|
+
input << name
|
13
|
+
input.rewind
|
14
|
+
q = shell.ask("What is your name?")
|
15
|
+
answer = q.read_string
|
16
|
+
expect(answer).to be_kind_of String
|
17
|
+
expect(answer).to eql name
|
18
|
+
end
|
19
|
+
end
|
@@ -14,6 +14,12 @@ describe TTY::Table, 'access' do
|
|
14
14
|
|
15
15
|
its([0,0]) { should == 'a1'}
|
16
16
|
|
17
|
+
its([0]) { should == rows[0] }
|
18
|
+
|
19
|
+
its([5]) { should be_nil }
|
20
|
+
|
21
|
+
its([-1]) { should == rows[-1] }
|
22
|
+
|
17
23
|
its([5,5]) { should be_nil }
|
18
24
|
|
19
25
|
it 'raises error for negative indices' do
|
@@ -5,13 +5,13 @@ require 'spec_helper'
|
|
5
5
|
describe TTY::Table::Border, '#new' do
|
6
6
|
subject { klass.new }
|
7
7
|
|
8
|
-
context '' do
|
8
|
+
context 'when abstract' do
|
9
9
|
let(:klass) { described_class }
|
10
10
|
|
11
|
-
specify { expect {subject }.to raise_error(NotImplementedError) }
|
11
|
+
specify { expect { subject }.to raise_error(NotImplementedError) }
|
12
12
|
end
|
13
13
|
|
14
|
-
context '' do
|
14
|
+
context 'when concrete' do
|
15
15
|
let(:klass) { Class.new }
|
16
16
|
|
17
17
|
specify { expect {subject }.to_not raise_error(NotImplementedError) }
|
@@ -29,7 +29,7 @@ describe TTY::Table, '#initialize' do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'initializes table rows in a block with param' do
|
32
|
-
table = TTY::Table.new
|
32
|
+
table = TTY::Table.new do |t|
|
33
33
|
t << rows[0]
|
34
34
|
t << rows[1]
|
35
35
|
end
|
@@ -48,6 +48,22 @@ describe TTY::Table, '#initialize' do
|
|
48
48
|
table << rows[0] << rows[1]
|
49
49
|
table.to_a.should == rows
|
50
50
|
end
|
51
|
+
|
52
|
+
context 'with data as hash' do
|
53
|
+
let(:data) { [ {'Header1' => ['a1','a2'], 'Header2' => ['b1', 'b2'] }] }
|
54
|
+
|
55
|
+
it 'extracts rows' do
|
56
|
+
table = TTY::Table.new data
|
57
|
+
expect(table.to_a).to include rows[0]
|
58
|
+
expect(table.to_a).to include rows[1]
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'extracts header' do
|
62
|
+
table = TTY::Table.new data
|
63
|
+
expect(table.header).to include header[0]
|
64
|
+
expect(table.header).to include header[1]
|
65
|
+
end
|
66
|
+
end
|
51
67
|
end
|
52
68
|
|
53
69
|
context 'with header and rows' do
|
@@ -4,7 +4,7 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe TTY::Table, 'options' do
|
6
6
|
let(:rows) { [['a1', 'a2'], ['b1', 'b2']] }
|
7
|
-
let(:widths) {
|
7
|
+
let(:widths) { nil }
|
8
8
|
let(:aligns) { [] }
|
9
9
|
let(:object) {
|
10
10
|
described_class.new rows,
|
@@ -29,6 +29,12 @@ describe TTY::Table, 'options' do
|
|
29
29
|
its(:column_widths) { should == widths }
|
30
30
|
end
|
31
31
|
|
32
|
+
context '#column_widths empty' do
|
33
|
+
let(:widths) { [] }
|
34
|
+
|
35
|
+
it { expect { subject }.to raise_error(TTY::InvalidArgument) }
|
36
|
+
end
|
37
|
+
|
32
38
|
context '#column_aligns' do
|
33
39
|
let(:aligns) { [:center, :center] }
|
34
40
|
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe TTY::Table, 'orientation' do
|
6
|
+
let(:header) { ['h1', 'h2', 'h3'] }
|
7
|
+
let(:rows) { [['a1', 'a2', 'a3'], ['b1', 'b2', 'b3']] }
|
8
|
+
let(:renderer) { :basic }
|
9
|
+
let(:options) { { :orientation => orientation, :renderer => renderer } }
|
10
|
+
|
11
|
+
subject { described_class.new header, rows, options }
|
12
|
+
|
13
|
+
context 'when illegal option' do
|
14
|
+
let(:orientation) { :accross }
|
15
|
+
|
16
|
+
it { expect { subject }.to raise_error(TTY::InvalidOrientationError) }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when horizontal' do
|
20
|
+
let(:orientation) { :horizontal }
|
21
|
+
|
22
|
+
its(:orientation) { should be_kind_of TTY::Table::Orientation }
|
23
|
+
|
24
|
+
it { expect(subject.orientation.name).to eql :horizontal }
|
25
|
+
|
26
|
+
it { expect(subject.header).to eql header }
|
27
|
+
|
28
|
+
it 'preserves original rows' do
|
29
|
+
expect(subject.to_a).to eql rows
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'without border' do
|
33
|
+
it 'displays table' do
|
34
|
+
subject.to_s.should == <<-EOS.normalize
|
35
|
+
h1 h2 h3
|
36
|
+
a1 a2 a3
|
37
|
+
b1 b2 b3
|
38
|
+
EOS
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'with border' do
|
43
|
+
let(:renderer) { :ascii }
|
44
|
+
|
45
|
+
it 'diplays table' do
|
46
|
+
subject.to_s.should == <<-EOS.normalize
|
47
|
+
+--+--+--+
|
48
|
+
|h1|h2|h3|
|
49
|
+
+--+--+--+
|
50
|
+
|a1|a2|a3|
|
51
|
+
|b1|b2|b3|
|
52
|
+
+--+--+--+
|
53
|
+
EOS
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when vertical' do
|
59
|
+
let(:orientation) { :vertical }
|
60
|
+
|
61
|
+
its(:orientation) { should be_kind_of TTY::Table::Orientation }
|
62
|
+
|
63
|
+
it { expect(subject.orientation.name).to eql :vertical }
|
64
|
+
|
65
|
+
it { expect(subject.header).to be_empty }
|
66
|
+
|
67
|
+
it 'rotates original rows' do
|
68
|
+
rotated_rows = []
|
69
|
+
(0..2).each {|n| rotated_rows << [header[n], rows[0][n], rows[1][n]] }
|
70
|
+
expect(subject.to_a).to eql rotated_rows
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'without border' do
|
74
|
+
it 'displays table' do
|
75
|
+
subject.to_s.should == <<-EOS.normalize
|
76
|
+
h1 a1 b1
|
77
|
+
h2 a2 b2
|
78
|
+
h3 a3 b3
|
79
|
+
EOS
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'with border' do
|
84
|
+
let(:renderer) { :ascii }
|
85
|
+
|
86
|
+
it 'diplays table' do
|
87
|
+
subject.to_s.should == <<-EOS.normalize
|
88
|
+
+--+--+--+
|
89
|
+
|h1|a1|b1|
|
90
|
+
|h2|a2|b2|
|
91
|
+
|h3|a3|b3|
|
92
|
+
+--+--+--+
|
93
|
+
EOS
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end # orientation
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe TTY::Table, '#renders_with' do
|
6
|
+
let(:header) { ['h1', 'h2', 'h3'] }
|
7
|
+
let(:rows) { [['a1', 'a2', 'a3'], ['b1', 'b2', 'b3']] }
|
8
|
+
let(:table) { described_class.new header, rows }
|
9
|
+
|
10
|
+
context 'with complete border' do
|
11
|
+
let(:border_class) {
|
12
|
+
class MyBorder < TTY::Table::Border
|
13
|
+
def_border do
|
14
|
+
{
|
15
|
+
'top' => '=',
|
16
|
+
'top_mid' => '*',
|
17
|
+
'top_left' => '*',
|
18
|
+
'top_right' => '*',
|
19
|
+
'bottom' => '=',
|
20
|
+
'bottom_mid' => '*',
|
21
|
+
'bottom_left' => '*',
|
22
|
+
'bottom_right' => '*',
|
23
|
+
'mid' => '=',
|
24
|
+
'mid_mid' => '*',
|
25
|
+
'mid_left' => '*',
|
26
|
+
'mid_right' => '*',
|
27
|
+
'left' => '$',
|
28
|
+
'right' => '$'
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
}
|
33
|
+
|
34
|
+
it 'displays custom border' do
|
35
|
+
border_class
|
36
|
+
table.renders_with MyBorder
|
37
|
+
table.to_s.should == <<-EOS.normalize
|
38
|
+
*==*==*==*
|
39
|
+
$h1$h2$h3$
|
40
|
+
*==*==*==*
|
41
|
+
$a1$a2$a3$
|
42
|
+
$b1$b2$b3$
|
43
|
+
*==*==*==*
|
44
|
+
EOS
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'with incomplete border' do
|
49
|
+
let(:border_class) {
|
50
|
+
class MyBorder < TTY::Table::Border
|
51
|
+
def_border do
|
52
|
+
{
|
53
|
+
'bottom' => ' ',
|
54
|
+
'bottom_mid' => '*',
|
55
|
+
'bottom_left' => '*',
|
56
|
+
'bottom_right' => '*',
|
57
|
+
'left' => '$',
|
58
|
+
'right' => '$'
|
59
|
+
}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
}
|
63
|
+
|
64
|
+
it 'displays border' do
|
65
|
+
border_class
|
66
|
+
table.renders_with MyBorder
|
67
|
+
table.to_s.should == <<-EOS.normalize
|
68
|
+
$h1$h2$h3$
|
69
|
+
$a1$a2$a3$
|
70
|
+
$b1$b2$b3$
|
71
|
+
* * * *
|
72
|
+
EOS
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end # renders_with
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe TTY::Table, '#rotate' do
|
6
|
+
let(:header) { ['h1', 'h2', 'h3'] }
|
7
|
+
let(:rows) { [['a1', 'a2', 'a3'], ['b1', 'b2', 'b3']] }
|
8
|
+
|
9
|
+
subject { described_class.new(header, rows) }
|
10
|
+
|
11
|
+
before { subject.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(subject.header).to be_nil
|
19
|
+
expect(subject.rotate.to_a).to eql rows
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'with header' do
|
24
|
+
it 'preserves orientation' do
|
25
|
+
expect(subject.header).to eql header
|
26
|
+
expect(subject.rotate.to_a).to eql rows
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with no header' do
|
32
|
+
let(:header) { nil }
|
33
|
+
|
34
|
+
it 'rotates the rows' do
|
35
|
+
subject.orientation = :vertical
|
36
|
+
expect(subject.rotate.to_a).to eql [
|
37
|
+
['a1', 'b1'],
|
38
|
+
['a2', 'b2'],
|
39
|
+
['a3', 'b3'],
|
40
|
+
]
|
41
|
+
expect(subject.header).to be_nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'rotates the rows back' do
|
45
|
+
subject.orientation = :vertical
|
46
|
+
subject.rotate
|
47
|
+
subject.orientation = :horizontal
|
48
|
+
expect(subject.rotate.to_a).to eql rows
|
49
|
+
expect(subject.header).to eql header
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'with header' do
|
54
|
+
it 'rotates the rows and merges header' do
|
55
|
+
subject.orientation = :vertical
|
56
|
+
expect(subject.rotate.to_a).to eql [
|
57
|
+
['h1', 'a1', 'b1'],
|
58
|
+
['h2', 'a2', 'b2'],
|
59
|
+
['h3', 'a3', 'b3'],
|
60
|
+
]
|
61
|
+
expect(subject.header).to be_empty
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'rotates the rows and header back' do
|
65
|
+
subject.orientation = :vertical
|
66
|
+
subject.rotate
|
67
|
+
subject.orientation = :horizontal
|
68
|
+
expect(subject.rotate.to_a).to eql rows
|
69
|
+
expect(subject.header).to eql header
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/spec/tty/table/to_s_spec.rb
CHANGED
@@ -9,6 +9,18 @@ describe TTY::Table, '#to_s' do
|
|
9
9
|
|
10
10
|
subject { described_class.new header, rows, :renderer => renderer }
|
11
11
|
|
12
|
+
context 'without renderer' do
|
13
|
+
let(:renderer) { nil }
|
14
|
+
|
15
|
+
it 'displayes basic table' do
|
16
|
+
subject.to_s.should == <<-EOS.normalize
|
17
|
+
h1 h2 h3
|
18
|
+
a1 a2 a3
|
19
|
+
b1 b2 b3
|
20
|
+
EOS
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
12
24
|
context 'without border' do
|
13
25
|
it 'displays table' do
|
14
26
|
subject.to_s.should == <<-EOS.normalize
|
@@ -48,4 +60,4 @@ describe TTY::Table, '#to_s' do
|
|
48
60
|
EOS
|
49
61
|
end
|
50
62
|
end
|
51
|
-
end
|
63
|
+
end # to_s
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe TTY::Table::Validatable, '#validate_options!' do
|
6
|
+
let(:described_class) { Class.new { include TTY::Table::Validatable } }
|
7
|
+
|
8
|
+
subject { described_class.new.validate_options! options }
|
9
|
+
|
10
|
+
context 'with empty rows' do
|
11
|
+
let(:options) { {:rows => []} }
|
12
|
+
|
13
|
+
it { expect { subject }.not_to raise_error(TTY::InvalidArgument) }
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'with invalid rows type' do
|
17
|
+
let(:options) { {:rows => 1 } }
|
18
|
+
|
19
|
+
it { expect { subject }.to raise_error(TTY::InvalidArgument) }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'with empty header' do
|
23
|
+
let(:options) { {:header => []} }
|
24
|
+
|
25
|
+
it { expect { subject }.to raise_error(TTY::InvalidArgument) }
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'with invalid header type' do
|
29
|
+
let(:options) { {:header => 1} }
|
30
|
+
|
31
|
+
it { expect { subject }.to raise_error(TTY::InvalidArgument) }
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -3,10 +3,43 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe TTY::Terminal::Color, '#remove' do
|
6
|
+
let(:instance) { described_class.new }
|
7
|
+
|
6
8
|
let(:string) { "This is a \e[1m\e[34mbold blue text\e[0m" }
|
7
9
|
|
10
|
+
subject { instance.remove string }
|
11
|
+
|
8
12
|
it 'remove color from string' do
|
9
|
-
|
13
|
+
should == "This is a bold blue text"
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'with octal in encapsulating brackets' do
|
17
|
+
let(:string) { "\[\033[01;32m\]u@h \[\033[01;34m\]W $ \[\033[00m\]" }
|
18
|
+
|
19
|
+
it { should == 'u@h W $ '}
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'with octal without brackets' do
|
23
|
+
let(:string) { "\033[01;32mu@h \033[01;34mW $ \033[00m" }
|
24
|
+
|
25
|
+
it { should == 'u@h W $ '}
|
10
26
|
end
|
11
27
|
|
28
|
+
context 'with octal with multiple colors' do
|
29
|
+
let(:string) { "\e[3;0;0;t\e[8;50;0t" }
|
30
|
+
|
31
|
+
it { should == "" }
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with' do
|
35
|
+
let(:string ) { "WARN. \x1b[1m&\x1b[0m ERR. \x1b[7m&\x1b[0m" }
|
36
|
+
|
37
|
+
it { should == 'WARN. & ERR. &' }
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with escape byte' do
|
41
|
+
let(:string) { "This is a \e[1m\e[34mbold blue text\e[0m" }
|
42
|
+
|
43
|
+
it { should == "This is a bold blue text"}
|
44
|
+
end
|
12
45
|
end
|