tty 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -3
  3. data/CHANGELOG.md +8 -0
  4. data/README.md +74 -42
  5. data/lib/tty.rb +7 -9
  6. data/lib/tty/conversion.rb +16 -0
  7. data/lib/tty/conversion/converter/array.rb +35 -0
  8. data/lib/tty/{coercer → conversion/converter}/boolean.rb +20 -7
  9. data/lib/tty/conversion/converter/float.rb +28 -0
  10. data/lib/tty/conversion/converter/integer.rb +28 -0
  11. data/lib/tty/{coercer → conversion/converter}/range.rb +16 -7
  12. data/lib/tty/logger.rb +1 -1
  13. data/lib/tty/shell/question.rb +2 -1
  14. data/lib/tty/shell/response.rb +9 -4
  15. data/lib/tty/shell/statement.rb +3 -2
  16. data/lib/tty/table.rb +3 -3
  17. data/lib/tty/table/border.rb +8 -5
  18. data/lib/tty/table/border/row_line.rb +2 -2
  19. data/lib/tty/table/operation/alignment_set.rb +2 -1
  20. data/lib/tty/table/padder.rb +1 -1
  21. data/lib/tty/table/renderer/basic.rb +1 -1
  22. data/lib/tty/terminal.rb +1 -118
  23. data/lib/tty/text/truncation.rb +4 -1
  24. data/lib/tty/text/wrapping.rb +4 -1
  25. data/lib/tty/vector.rb +4 -3
  26. data/lib/tty/version.rb +2 -2
  27. data/spec/tty/{support/conversion_spec.rb → conversion/converter/array/convert_spec.rb} +4 -5
  28. data/spec/tty/{coercer/boolean/coerce_spec.rb → conversion/converter/boolean/convert_spec.rb} +5 -4
  29. data/spec/tty/{coercer/float/coerce_spec.rb → conversion/converter/float/convert_spec.rb} +3 -2
  30. data/spec/tty/{coercer/integer/coerce_spec.rb → conversion/converter/integer/convert_spec.rb} +4 -2
  31. data/spec/tty/{coercer/range/coerce_spec.rb → conversion/converter/range/convert_spec.rb} +3 -2
  32. data/spec/tty/shell/error_spec.rb +4 -1
  33. data/spec/tty/shell/response/read_bool_spec.rb +1 -1
  34. data/spec/tty/shell/say_spec.rb +3 -0
  35. data/spec/tty/shell/statement/initialize_spec.rb +2 -2
  36. data/spec/tty/shell/warn_spec.rb +3 -0
  37. data/spec/tty/table/field/equality_spec.rb +1 -1
  38. data/spec/tty/table/render_spec.rb +3 -0
  39. data/spec/tty/table/render_with_spec.rb +8 -5
  40. data/spec/tty/table/renderer/basic/coloring_spec.rb +10 -9
  41. data/spec/tty/table/renderer/style_spec.rb +3 -0
  42. data/spec/tty/terminal/color_spec.rb +6 -3
  43. data/tasks/console.rake +1 -1
  44. data/tty.gemspec +7 -1
  45. metadata +88 -30
  46. data/lib/tty/coercer.rb +0 -13
  47. data/lib/tty/coercer/float.rb +0 -20
  48. data/lib/tty/coercer/integer.rb +0 -20
  49. data/lib/tty/support/conversion.rb +0 -35
  50. data/lib/tty/support/equatable.rb +0 -152
  51. data/lib/tty/terminal/color.rb +0 -157
  52. data/spec/tty/support/equatable_spec.rb +0 -201
  53. data/spec/tty/terminal/color/code_spec.rb +0 -19
  54. data/spec/tty/terminal/color/remove_spec.rb +0 -44
  55. data/spec/tty/terminal/color/set_spec.rb +0 -29
  56. data/spec/tty/terminal/size_spec.rb +0 -97
@@ -1,13 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- module TTY
4
-
5
- # Abstract class for type coercions
6
- #
7
- # @abstract
8
- class Coercer
9
- include TTY::Equatable
10
-
11
- end # Coercer
12
-
13
- end # TTY
@@ -1,20 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module TTY
4
- class Coercer
5
- # Coerce values into float number
6
- #
7
- # @api public
8
- class Float
9
- def self.coerce(value, strict = true)
10
- Kernel.send(:Float, value.to_s)
11
- rescue
12
- if strict
13
- raise InvalidArgument, "#{value} could not be coerced into Float"
14
- else
15
- value.to_f
16
- end
17
- end
18
- end # Float
19
- end # Coercer
20
- end # TTY
@@ -1,20 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module TTY
4
- class Coercer
5
- # Coerce value into integer number
6
- #
7
- # @api public
8
- class Integer
9
- def self.coerce(value, strict = true)
10
- Kernel.send(:Integer, value.to_s)
11
- rescue
12
- if strict
13
- raise InvalidArgument, "#{value} could not be coerced into Integer"
14
- else
15
- value.to_i
16
- end
17
- end
18
- end # Integer
19
- end # Coercer
20
- end # TTY
@@ -1,35 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module TTY
4
- # A mixin to allow instances conversion to array type
5
- #
6
- # @api public
7
- module Conversion
8
- # Converts the object into an Array. If copy is set to true
9
- # a copy of object will be made.
10
- #
11
- # @param [Object] object
12
- #
13
- # @param [Boolean] copy
14
- #
15
- # @return [Array]
16
- #
17
- # @api private
18
- def convert_to_array(object, copy = false)
19
- case object
20
- when Array
21
- copy ? object.dup : object
22
- when Hash
23
- Array(object)
24
- else
25
- begin
26
- converted = object.to_ary
27
- rescue Exception => e
28
- raise TTY::TypeError,
29
- "Cannot convert #{object.class} into an Array (#{e.message})"
30
- end
31
- converted
32
- end
33
- end
34
- end # Conversion
35
- end # TTY
@@ -1,152 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- module TTY
4
-
5
- # Make it easy to define equality and hash methods.
6
- module Equatable
7
-
8
- # Hook into module inclusion.
9
- #
10
- # @param [Module] base
11
- # the module or class including Equatable
12
- #
13
- # @return [self]
14
- #
15
- # @api private
16
- def self.included(base)
17
- super
18
- base.extend(self)
19
- base.class_eval do
20
- define_comparison_attrs
21
- include Methods
22
- define_methods
23
- end
24
- self
25
- end
26
-
27
- # Holds all attributes used for comparison.
28
- #
29
- # @return [Array<Symbol>]
30
- #
31
- # @api private
32
- attr_reader :comparison_attrs
33
-
34
- # Objects that include this module are assumed to be value objects.
35
- # It is also assumed that the only values that affect the results of
36
- # equality comparison are the values of the object's attributes.
37
- #
38
- # @param [Array<Symbol>] *args
39
- #
40
- # @return [undefined]
41
- #
42
- # @api public
43
- def attr_reader(*args)
44
- super
45
- @comparison_attrs.concat(args)
46
- end
47
-
48
- # Copy the comparison_attrs into the subclass.
49
- #
50
- # @param [Class] subclass
51
- #
52
- # @api private
53
- def inherited(subclass)
54
- super
55
- subclass.instance_variable_set(:@comparison_attrs, comparison_attrs.dup)
56
- end
57
-
58
- private
59
-
60
- # Define class instance #comparison_attrs as an empty array.
61
- #
62
- # @return [undefined]
63
- #
64
- # @api private
65
- def define_comparison_attrs
66
- instance_variable_set('@comparison_attrs', [])
67
- end
68
-
69
- # Define all methods needed for ensuring object's equality.
70
- #
71
- # @return [undefined]
72
- #
73
- # @api private
74
- def define_methods
75
- define_compare
76
- define_hash
77
- define_inspect
78
- end
79
-
80
- # Define a #compare? method to check if the receiver is the same
81
- # as the other object.
82
- #
83
- # @return [undefined]
84
- #
85
- # @api private
86
- def define_compare
87
- define_method(:compare?) do |comparator, other|
88
- klass = self.class
89
- attrs = klass.comparison_attrs || []
90
- attrs.all? { |attr| send(attr).send(comparator, other.send(attr)) }
91
- end
92
- end
93
-
94
- # Define a hash method that ensures that the hash value is the same for
95
- # the same instance attributes and their corresponding values.
96
- #
97
- # @api private
98
- def define_hash
99
- define_method(:hash) do
100
- klass = self.class
101
- attrs = klass.comparison_attrs || []
102
- ([klass] + attrs.map { |attr| send(attr)}).hash
103
- end
104
- end
105
-
106
- # Define an inspect method that shows the class name and the values for the
107
- # instance's attributes.
108
- #
109
- # @return [undefined]
110
- #
111
- # @api private
112
- def define_inspect
113
- define_method(:inspect) do
114
- klass = self.class
115
- name = klass.name || klass.inspect
116
- attrs = klass.comparison_attrs || []
117
- "#<#{name}#{attrs.map { |attr| " #{attr}=#{send(attr).inspect}" }.join}>"
118
- end
119
- end
120
-
121
- module Methods
122
-
123
- # Compare two objects for equality based on their value
124
- # and being an instance of the given class.
125
- #
126
- # @param [Object] other
127
- # the other object in comparison
128
- #
129
- # @return [Boolean]
130
- #
131
- # @api public
132
- def eql?(other)
133
- instance_of?(other.class) && compare?(__method__, other)
134
- end
135
-
136
- # Compare two objects for equality based on their value
137
- # and being a subclass of the given class.
138
- #
139
- # @param [Object] other
140
- # the other object in comparison
141
- #
142
- # @return [Boolean]
143
- #
144
- # @api public
145
- def ==(other)
146
- kind_of?(other.class) && compare?(__method__, other)
147
- end
148
-
149
- end # Methods
150
-
151
- end # Equatable
152
- end # TTY
@@ -1,157 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module TTY
4
- class Terminal
5
- # A class responsible for coloring strings.
6
- class Color
7
- # Embed in a String to clear all previous ANSI sequences.
8
- CLEAR = "\e[0m"
9
- # The start of an ANSI bold sequence.
10
- BOLD = "\e[1m"
11
- # The start of an ANSI underlined sequence.
12
- UNDERLINE = "\e[4m"
13
-
14
- STYLES = %w( BOLD CLEAR UNDERLINE ).freeze
15
-
16
- # Escape codes for text color.
17
- BLACK = "\e[30m"
18
- RED = "\e[31m"
19
- GREEN = "\e[32m"
20
- YELLOW = "\e[33m"
21
- BLUE = "\e[34m"
22
- MAGENTA = "\e[35m"
23
- CYAN = "\e[36m"
24
- WHITE = "\e[37m"
25
-
26
- LIGHT_BLACK = "\e[90m"
27
- LIGHT_RED = "\e[91m"
28
- LIGHT_GREEN = "\e[92m"
29
- LIGHT_YELLOW = "\e[93m"
30
- LIGHT_BLUE = "\e[94m"
31
- LIGHT_MAGENTA = "\e[95m"
32
- LIGHT_CYAN = "\e[96m"
33
-
34
- TEXT_COLORS = (constants.grep(/^[^ON_]*/) - STYLES).freeze
35
-
36
- # Escape codes for background color.
37
- ON_BLACK = "\e[40m"
38
- ON_RED = "\e[41m"
39
- ON_GREEN = "\e[42m"
40
- ON_YELLOW = "\e[43m"
41
- ON_BLUE = "\e[44m"
42
- ON_MAGENTA = "\e[45m"
43
- ON_CYAN = "\e[46m"
44
- ON_WHITE = "\e[47m"
45
-
46
- ON_LIGHT_BLACK = "\e[100m"
47
- ON_LIGHT_RED = "\e[101m"
48
- ON_LIGHT_GREEN = "\e[102m"
49
- ON_LIGHT_YELLOW = "\e[103m"
50
- ON_LIGHT_BLUE = "\e[104m"
51
- ON_LIGHT_MAGENTA = "\e[105m"
52
- ON_LIGHT_CYAN = "\e[106m"
53
-
54
- BACKGROUND_COLORS = constants.grep(/^ON_*/).freeze
55
-
56
- attr_reader :enabled
57
-
58
- # Initialize a Terminal Color
59
- #
60
- # @api public
61
- def initialize(enabled = false)
62
- @enabled = enabled
63
- end
64
-
65
- # Disable coloring of this terminal session
66
- #
67
- # @api public
68
- def disable!
69
- @enabled = false
70
- end
71
-
72
- # Check if coloring is on
73
- #
74
- # @return [Boolean]
75
- #
76
- # @api public
77
- def enabled?
78
- @enabled
79
- end
80
-
81
- # Apply ANSI color to the given string.
82
- #
83
- # @param [String] string
84
- # text to add ANSI strings
85
- #
86
- # @param [Array[Symbol]] colors
87
- #
88
- # @example
89
- # apply "text", :yellow, :on_green, :underline
90
- #
91
- # @return [String]
92
- #
93
- # @api public
94
- def set(string, *colors)
95
- validate(*colors)
96
- ansi_colors = colors.map { |color| lookup(color) }
97
- "#{ansi_colors.join}#{string}#{CLEAR}"
98
- end
99
-
100
- # Same as instance method.
101
- #
102
- # @return [undefined]
103
- #
104
- # @api public
105
- def self.set(string, *colors)
106
- new.set(string, *colors)
107
- end
108
-
109
- # Remove color codes from a string.
110
- #
111
- # @param [String] string
112
- #
113
- # @return [String]
114
- #
115
- # @api public
116
- def remove(string)
117
- string.to_s.gsub(/(\[)?\033(\[)?[;?\d]*[\dA-Za-z](\])?/, '')
118
- end
119
-
120
- # Return raw color code without embeding it into a string.
121
- #
122
- # @return [Array[String]]
123
- # ANSI escape codes
124
- #
125
- # @api public
126
- def code(*colors)
127
- validate(*colors)
128
- colors.map { |color| lookup(color) }
129
- end
130
-
131
- # All ANSI color names as strings.
132
- #
133
- # @return [Array[String]]
134
- #
135
- # @api public
136
- def names
137
- (STYLES + BACKGROUND_COLORS + TEXT_COLORS).map { |col| col.to_s.downcase }
138
- end
139
-
140
- protected
141
-
142
- # Find color representation.
143
- #
144
- # @api private
145
- def lookup(color)
146
- self.class.const_get(color.to_s.upcase)
147
- end
148
-
149
- # @api private
150
- def validate(*colors)
151
- return if colors.all? { |color| names.include?(color.to_s) }
152
- raise ArgumentError, 'Bad color or unintialized constant, ' \
153
- " valid colors are: #{names.join(', ')}."
154
- end
155
- end # Color
156
- end # Terminal
157
- end # TTY
@@ -1,201 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- describe TTY::Equatable do
6
- let(:name) { 'Value' }
7
-
8
- context 'without attributes' do
9
- let(:klass) { ::Class.new }
10
-
11
- subject { klass.new }
12
-
13
- before {
14
- allow(klass).to receive(:name).and_return('Value')
15
- klass.send :include, described_class
16
- }
17
-
18
- it { is_expected.to respond_to :compare? }
19
-
20
- it { is_expected.to be_instance_of klass }
21
-
22
- describe '#eql?' do
23
- context 'when objects are similar' do
24
- let(:other) { subject.dup }
25
-
26
- it { expect(subject.eql?(other)).to eq(true) }
27
- end
28
-
29
- context 'when objects are different' do
30
- let(:other) { double('other') }
31
-
32
- it { expect(subject.eql?(other)).to eq(false) }
33
- end
34
- end
35
-
36
- describe '#==' do
37
- context 'when objects are similar' do
38
- let(:other) { subject.dup }
39
-
40
- it { expect(subject == other).to eq(true) }
41
- end
42
-
43
- context 'when objects are different' do
44
- let(:other) { double('other') }
45
-
46
- it { expect(subject == other).to eq(false) }
47
- end
48
- end
49
-
50
- describe '#inspect' do
51
- it { expect(subject.inspect).to eql('#<Value>') }
52
- end
53
-
54
- describe '#hash' do
55
- it { expect(subject.hash).to eql([klass].hash) }
56
- end
57
- end
58
-
59
- context 'with attributes' do
60
- let(:value) { 11 }
61
- let(:klass) {
62
- ::Class.new do
63
- include TTY::Equatable
64
-
65
- attr_reader :value
66
-
67
- def initialize(value)
68
- @value = value
69
- end
70
- end
71
- }
72
-
73
- before {
74
- allow(klass).to receive(:name).and_return name
75
- }
76
-
77
- subject { klass.new(value) }
78
-
79
- it 'dynamically defines #hash method' do
80
- expect(klass.method_defined?(:hash)).to eq(true)
81
- end
82
-
83
- it 'dynamically defines #inspect method' do
84
- expect(klass.method_defined?(:inspect)).to eq(true)
85
- end
86
-
87
- it { is_expected.to respond_to :compare? }
88
-
89
- it { is_expected.to respond_to :eql? }
90
-
91
- describe '#eql?' do
92
- context 'when objects are similar' do
93
- let(:other) { subject.dup }
94
-
95
- it { expect(subject.eql?(other)).to eq(true) }
96
- end
97
-
98
- context 'when objects are different' do
99
- let(:other) { double('other') }
100
-
101
- it { expect(subject.eql?(other)).to eq(false) }
102
- end
103
- end
104
-
105
- describe '#==' do
106
- context 'when objects are similar' do
107
- let(:other) { subject.dup }
108
-
109
- it { expect(subject == other).to eq(true) }
110
- end
111
-
112
- context 'when objects are different' do
113
- let(:other) { double('other') }
114
-
115
- it { expect(subject == other).to eq(false) }
116
- end
117
- end
118
-
119
- describe '#inspect' do
120
- it { expect(subject.inspect).to eql('#<Value value=11>') }
121
- end
122
-
123
- describe '#hash' do
124
- it { expect(subject.hash).to eql( ([klass] + [value]).hash) }
125
- end
126
-
127
- context 'equivalence relation' do
128
- let(:other) { subject.dup }
129
-
130
- it 'is not equal to nil reference' do
131
- expect(subject.eql?(nil)).to eq(false)
132
- end
133
-
134
- it 'is reflexive' do
135
- expect(subject.eql?(subject)).to eq(true)
136
- end
137
-
138
- it 'is symmetric' do
139
- expect(subject.eql?(other)).to eql( other.eql?(subject) )
140
- end
141
- end
142
- end
143
-
144
- context 'subclass' do
145
- let(:value) { 11 }
146
- let(:klass) {
147
- ::Class.new do
148
- include TTY::Equatable
149
-
150
- attr_reader :value
151
-
152
- def initialize(value)
153
- @value = value
154
- end
155
- end
156
- }
157
- let(:subclass) { ::Class.new(klass) }
158
-
159
- before {
160
- allow(klass).to receive(:name).and_return name
161
- }
162
-
163
- subject { subclass.new(value) }
164
-
165
- it { expect(subclass.superclass).to eq(klass) }
166
-
167
- it { is_expected.to respond_to :value }
168
-
169
- describe '#inspect' do
170
- it { expect(subject.inspect).to eql('#<Value value=11>') }
171
- end
172
-
173
- describe '#eql?' do
174
- context 'when objects are similar' do
175
- let(:other) { subject.dup }
176
-
177
- it { expect(subject.eql?(other)).to eq(true) }
178
- end
179
-
180
- context 'when objects are different' do
181
- let(:other) { double('other') }
182
-
183
- it { expect(subject.eql?(other)).to eq(false) }
184
- end
185
- end
186
-
187
- describe '#==' do
188
- context 'when objects are similar' do
189
- let(:other) { subject.dup }
190
-
191
- it { expect(subject == other).to eq(true) }
192
- end
193
-
194
- context 'when objects are different' do
195
- let(:other) { double('other') }
196
-
197
- it { expect(subject == other).to eq(false) }
198
- end
199
- end
200
- end
201
- end