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.
Files changed (81) hide show
  1. data/README.md +78 -12
  2. data/benchmarks/shell.rb +26 -0
  3. data/benchmarks/table.rb +35 -0
  4. data/lib/tty.rb +23 -1
  5. data/lib/tty/coercer.rb +13 -0
  6. data/lib/tty/coercer/boolean.rb +39 -0
  7. data/lib/tty/coercer/float.rb +23 -0
  8. data/lib/tty/coercer/integer.rb +23 -0
  9. data/lib/tty/coercer/range.rb +33 -0
  10. data/lib/tty/shell.rb +6 -2
  11. data/lib/tty/shell/question.rb +158 -138
  12. data/lib/tty/shell/reader.rb +92 -0
  13. data/lib/tty/shell/response.rb +219 -0
  14. data/lib/tty/shell/response_delegation.rb +53 -0
  15. data/lib/tty/table.rb +90 -16
  16. data/lib/tty/table/border.rb +34 -8
  17. data/lib/tty/table/border/ascii.rb +16 -25
  18. data/lib/tty/table/border/null.rb +0 -6
  19. data/lib/tty/table/border/unicode.rb +16 -25
  20. data/lib/tty/table/column_set.rb +1 -1
  21. data/lib/tty/table/error.rb +10 -0
  22. data/lib/tty/table/operation/wrapped.rb +0 -6
  23. data/lib/tty/table/orientation.rb +57 -0
  24. data/lib/tty/table/orientation/horizontal.rb +19 -0
  25. data/lib/tty/table/orientation/vertical.rb +19 -0
  26. data/lib/tty/table/renderer.rb +7 -0
  27. data/lib/tty/table/renderer/ascii.rb +1 -1
  28. data/lib/tty/table/renderer/basic.rb +2 -2
  29. data/lib/tty/table/renderer/unicode.rb +1 -1
  30. data/lib/tty/table/validatable.rb +20 -0
  31. data/lib/tty/terminal.rb +15 -14
  32. data/lib/tty/terminal/color.rb +1 -1
  33. data/lib/tty/terminal/echo.rb +41 -0
  34. data/lib/tty/terminal/home.rb +31 -0
  35. data/lib/tty/text.rb +85 -0
  36. data/lib/tty/text/truncation.rb +83 -0
  37. data/lib/tty/text/wrapping.rb +96 -0
  38. data/lib/tty/version.rb +1 -1
  39. data/spec/tty/coercer/boolean/coerce_spec.rb +113 -0
  40. data/spec/tty/coercer/float/coerce_spec.rb +32 -0
  41. data/spec/tty/coercer/integer/coerce_spec.rb +39 -0
  42. data/spec/tty/coercer/range/coerce_spec.rb +73 -0
  43. data/spec/tty/shell/ask_spec.rb +14 -1
  44. data/spec/tty/shell/question/argument_spec.rb +30 -0
  45. data/spec/tty/shell/question/character_spec.rb +16 -0
  46. data/spec/tty/shell/question/default_spec.rb +25 -0
  47. data/spec/tty/shell/question/in_spec.rb +23 -0
  48. data/spec/tty/shell/question/initialize_spec.rb +11 -211
  49. data/spec/tty/shell/question/modifier/whitespace_spec.rb +1 -1
  50. data/spec/tty/shell/question/modify_spec.rb +44 -0
  51. data/spec/tty/shell/question/valid_spec.rb +46 -0
  52. data/spec/tty/shell/question/validate_spec.rb +30 -0
  53. data/spec/tty/shell/reader/getc_spec.rb +40 -0
  54. data/spec/tty/shell/response/read_bool_spec.rb +41 -0
  55. data/spec/tty/shell/response/read_char_spec.rb +17 -0
  56. data/spec/tty/shell/response/read_date_spec.rb +20 -0
  57. data/spec/tty/shell/response/read_email_spec.rb +43 -0
  58. data/spec/tty/shell/response/read_multiple_spec.rb +24 -0
  59. data/spec/tty/shell/response/read_number_spec.rb +29 -0
  60. data/spec/tty/shell/response/read_range_spec.rb +29 -0
  61. data/spec/tty/shell/response/read_spec.rb +68 -0
  62. data/spec/tty/shell/response/read_string_spec.rb +19 -0
  63. data/spec/tty/table/access_spec.rb +6 -0
  64. data/spec/tty/table/border/new_spec.rb +3 -3
  65. data/spec/tty/table/initialize_spec.rb +17 -1
  66. data/spec/tty/table/options_spec.rb +7 -1
  67. data/spec/tty/table/orientation_spec.rb +98 -0
  68. data/spec/tty/table/renders_with_spec.rb +76 -0
  69. data/spec/tty/table/rotate_spec.rb +72 -0
  70. data/spec/tty/table/to_s_spec.rb +13 -1
  71. data/spec/tty/table/validatable/validate_options_spec.rb +34 -0
  72. data/spec/tty/terminal/color/remove_spec.rb +34 -1
  73. data/spec/tty/terminal/echo_spec.rb +22 -0
  74. data/spec/tty/text/truncate_spec.rb +13 -0
  75. data/spec/tty/text/truncation/initialize_spec.rb +29 -0
  76. data/spec/tty/text/truncation/truncate_spec.rb +73 -0
  77. data/spec/tty/text/wrap_spec.rb +14 -0
  78. data/spec/tty/text/wrapping/initialize_spec.rb +25 -0
  79. data/spec/tty/text/wrapping/wrap_spec.rb +80 -0
  80. data/tty.gemspec +1 -0
  81. 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 do |t|
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
@@ -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
- subject.remove(string).should == "This is a bold blue text"
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