tty 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -5
- data/CHANGELOG.md +7 -0
- data/README.md +1 -0
- data/lib/tty.rb +2 -1
- data/lib/tty/shell/question.rb +19 -2
- data/lib/tty/shell/reader.rb +9 -0
- data/lib/tty/shell/response.rb +37 -16
- data/lib/tty/shell/response_delegation.rb +2 -0
- data/lib/tty/table.rb +2 -2
- data/lib/tty/table/operation/alignment_set.rb +2 -2
- data/lib/tty/terminal.rb +24 -0
- data/lib/tty/terminal/raw.rb +38 -0
- data/lib/tty/vector.rb +2 -2
- data/lib/tty/version.rb +1 -1
- data/spec/tty/shell/response/read_bool_spec.rb +1 -2
- data/spec/tty/shell/response/read_range_spec.rb +3 -1
- data/spec/tty/vector/new_spec.rb +4 -3
- data/tty.gemspec +1 -0
- metadata +17 -18
- data/lib/tty/conversion.rb +0 -16
- data/lib/tty/conversion/converter/array.rb +0 -35
- data/lib/tty/conversion/converter/boolean.rb +0 -49
- data/lib/tty/conversion/converter/float.rb +0 -28
- data/lib/tty/conversion/converter/integer.rb +0 -28
- data/lib/tty/conversion/converter/range.rb +0 -41
- data/spec/tty/conversion/converter/array/convert_spec.rb +0 -37
- data/spec/tty/conversion/converter/boolean/convert_spec.rb +0 -117
- data/spec/tty/conversion/converter/float/convert_spec.rb +0 -35
- data/spec/tty/conversion/converter/integer/convert_spec.rb +0 -42
- data/spec/tty/conversion/converter/range/convert_spec.rb +0 -75
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e81389b3c20540a552a4677e80c55307fb8964c
|
4
|
+
data.tar.gz: 10b70aa565b3bd550cbb7177826e3075ff47b9f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 07691cae6416ce1edee73949c2088ce1be07ab2f764b8ca1c59af6e5d2c98a03efaad09a64171a87eba9152c507277bdc01ba91a024edfd28cecfad92f68aa7d
|
7
|
+
data.tar.gz: 4be98f8a15d2cf8a363b56c27d101c901a8f4091c24fe470a17350ec952d2b0ce1b2b143d2e887392f83d290a6ddfd6e2b5437e87307012a5f59e951d1a61601
|
data/.travis.yml
CHANGED
@@ -7,15 +7,11 @@ rvm:
|
|
7
7
|
- 2.1.0
|
8
8
|
- ruby-head
|
9
9
|
- rbx-2
|
10
|
+
- jruby-19mode
|
10
11
|
matrix:
|
11
12
|
include:
|
12
|
-
- rvm: jruby-19mode
|
13
|
-
- rvm: jruby-20mode
|
14
|
-
- rvm: jruby-21mode
|
15
13
|
- rvm: jruby-head
|
16
14
|
allow_failures:
|
17
|
-
- rvm: jruby-20mode
|
18
|
-
- rvm: jruby-21mode
|
19
15
|
- rvm: ruby-head
|
20
16
|
- rvm: jruby-head
|
21
17
|
fast_finish: true
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -527,6 +527,7 @@ read_regex # return regex expression
|
|
527
527
|
read_string # return string
|
528
528
|
read_symbol # return symbol
|
529
529
|
read_text # return multiline string
|
530
|
+
read_keypress # return the key pressed
|
530
531
|
```
|
531
532
|
|
532
533
|
For example, if we wanted to ask a user for a single digit in given range
|
data/lib/tty.rb
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
require 'equatable'
|
4
4
|
require 'pastel'
|
5
|
+
require 'necromancer'
|
5
6
|
require 'tty-screen'
|
6
7
|
require 'tty-spinner'
|
7
8
|
require 'tty-progressbar'
|
8
9
|
|
9
10
|
require 'tty/version'
|
10
11
|
|
11
|
-
require 'tty/conversion'
|
12
12
|
require 'tty/support/utils'
|
13
13
|
require 'tty/support/delegatable'
|
14
14
|
require 'tty/support/coercion'
|
@@ -35,6 +35,7 @@ require 'tty/shell/reader'
|
|
35
35
|
require 'tty/shell/response'
|
36
36
|
|
37
37
|
require 'tty/terminal/echo'
|
38
|
+
require 'tty/terminal/raw'
|
38
39
|
require 'tty/terminal/home'
|
39
40
|
require 'tty/terminal/pager'
|
40
41
|
require 'tty/terminal/pager/basic'
|
data/lib/tty/shell/question.rb
CHANGED
@@ -56,6 +56,7 @@ module TTY
|
|
56
56
|
@shell = shell || Shell.new
|
57
57
|
@required = options.fetch(:required) { false }
|
58
58
|
@echo = options.fetch(:echo) { true }
|
59
|
+
@raw = options.fetch(:raw) { false }
|
59
60
|
@mask = options.fetch(:mask) { false }
|
60
61
|
@character = options.fetch(:character) { false }
|
61
62
|
@in = options.fetch(:in) { false }
|
@@ -64,7 +65,7 @@ module TTY
|
|
64
65
|
@validation = Validation.new options.fetch(:validation) { nil }
|
65
66
|
@default_value = nil
|
66
67
|
@error = false
|
67
|
-
@
|
68
|
+
@converter = Necromancer.new
|
68
69
|
end
|
69
70
|
|
70
71
|
# Set a new prompt
|
@@ -198,6 +199,22 @@ module TTY
|
|
198
199
|
!!@echo
|
199
200
|
end
|
200
201
|
|
202
|
+
# Turn raw mode on or off. This enables character-based input.
|
203
|
+
#
|
204
|
+
# @api public
|
205
|
+
def raw(value = nil)
|
206
|
+
return @raw if value.nil?
|
207
|
+
@raw = value
|
208
|
+
self
|
209
|
+
end
|
210
|
+
|
211
|
+
# Check if raw mode is set
|
212
|
+
#
|
213
|
+
# @api public
|
214
|
+
def raw?
|
215
|
+
!!@raw
|
216
|
+
end
|
217
|
+
|
201
218
|
# Set character for masking the STDIN input
|
202
219
|
#
|
203
220
|
# @param [String] character
|
@@ -249,7 +266,7 @@ module TTY
|
|
249
266
|
# @api public
|
250
267
|
def in(value = nil)
|
251
268
|
return @in if value.nil?
|
252
|
-
@in = @
|
269
|
+
@in = @converter.convert(value).to(:range, strict: true)
|
253
270
|
self
|
254
271
|
end
|
255
272
|
|
data/lib/tty/shell/reader.rb
CHANGED
@@ -75,6 +75,15 @@ module TTY
|
|
75
75
|
shell.input.gets
|
76
76
|
end
|
77
77
|
|
78
|
+
# Reads at maximum +maxlen+ characters.
|
79
|
+
#
|
80
|
+
# @param [Integer] maxlen
|
81
|
+
#
|
82
|
+
# @api public
|
83
|
+
def readpartial(maxlen)
|
84
|
+
shell.input.readpartial(maxlen)
|
85
|
+
end
|
86
|
+
|
78
87
|
private
|
79
88
|
|
80
89
|
# Handle single character by appending to or removing from output
|
data/lib/tty/shell/response.rb
CHANGED
@@ -30,14 +30,10 @@ module TTY
|
|
30
30
|
#
|
31
31
|
# @api public
|
32
32
|
def initialize(question, shell = Shell.new)
|
33
|
-
@
|
34
|
-
@
|
35
|
-
@
|
36
|
-
@
|
37
|
-
|
38
|
-
@question = question
|
39
|
-
@shell = shell
|
40
|
-
@reader = Reader.new(shell)
|
33
|
+
@question = question
|
34
|
+
@shell = shell
|
35
|
+
@converter = Necromancer.new
|
36
|
+
@reader = Reader.new(shell)
|
41
37
|
end
|
42
38
|
|
43
39
|
# Read input from STDIN either character or line
|
@@ -59,7 +55,15 @@ module TTY
|
|
59
55
|
reader.getc(question.mask)
|
60
56
|
else
|
61
57
|
TTY.terminal.echo(question.echo) do
|
62
|
-
|
58
|
+
TTY.terminal.raw(question.raw) do
|
59
|
+
if question.raw?
|
60
|
+
reader.readpartial(10)
|
61
|
+
elsif question.character?
|
62
|
+
reader.getc(question.mask)
|
63
|
+
else
|
64
|
+
reader.gets
|
65
|
+
end
|
66
|
+
end
|
63
67
|
end
|
64
68
|
end
|
65
69
|
end
|
@@ -93,7 +97,7 @@ module TTY
|
|
93
97
|
#
|
94
98
|
# @api public
|
95
99
|
def read_symbol(error = nil)
|
96
|
-
question.evaluate_response
|
100
|
+
question.evaluate_response(read_input.to_sym)
|
97
101
|
end
|
98
102
|
|
99
103
|
# Read answer from predifined choicse
|
@@ -108,14 +112,16 @@ module TTY
|
|
108
112
|
#
|
109
113
|
# @api public
|
110
114
|
def read_int(error = nil)
|
111
|
-
|
115
|
+
response = @converter.convert(read_input).to(:integer)
|
116
|
+
question.evaluate_response(response)
|
112
117
|
end
|
113
118
|
|
114
119
|
# Read float value
|
115
120
|
#
|
116
121
|
# @api public
|
117
122
|
def read_float(error = nil)
|
118
|
-
|
123
|
+
response = @converter.convert(read_input).to(:float)
|
124
|
+
question.evaluate_response(response)
|
119
125
|
end
|
120
126
|
|
121
127
|
# Read regular expression
|
@@ -129,28 +135,32 @@ module TTY
|
|
129
135
|
#
|
130
136
|
# @api public
|
131
137
|
def read_range
|
132
|
-
|
138
|
+
response = @converter.convert(read_input).to(:range, strict: true)
|
139
|
+
question.evaluate_response(response)
|
133
140
|
end
|
134
141
|
|
135
142
|
# Read date
|
136
143
|
#
|
137
144
|
# @api public
|
138
145
|
def read_date
|
139
|
-
|
146
|
+
response = @converter.convert(read_input).to(:date)
|
147
|
+
question.evaluate_response(response)
|
140
148
|
end
|
141
149
|
|
142
150
|
# Read datetime
|
143
151
|
#
|
144
152
|
# @api public
|
145
153
|
def read_datetime
|
146
|
-
|
154
|
+
response = @converter.convert(read_input).to(:datetime)
|
155
|
+
question.evaluate_response(response)
|
147
156
|
end
|
148
157
|
|
149
158
|
# Read boolean
|
150
159
|
#
|
151
160
|
# @api public
|
152
161
|
def read_bool(error = nil)
|
153
|
-
|
162
|
+
response = @converter.convert(read_input).to(:boolean, strict: true)
|
163
|
+
question.evaluate_response(response)
|
154
164
|
end
|
155
165
|
|
156
166
|
# Read file contents
|
@@ -193,6 +203,17 @@ module TTY
|
|
193
203
|
question.evaluate_response read_input
|
194
204
|
end
|
195
205
|
|
206
|
+
# Read a single keypress
|
207
|
+
#
|
208
|
+
# @api public
|
209
|
+
def read_keypress
|
210
|
+
question.echo false
|
211
|
+
question.raw true
|
212
|
+
question.evaluate_response(read_input).tap do |key|
|
213
|
+
raise Interrupt if key == "\x03" # Ctrl-C
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
196
217
|
private
|
197
218
|
|
198
219
|
# Ignore exception
|
data/lib/tty/table.rb
CHANGED
@@ -110,7 +110,7 @@ module TTY
|
|
110
110
|
# @api private
|
111
111
|
def initialize(options = {}, &block)
|
112
112
|
validate_options! options
|
113
|
-
@
|
113
|
+
@converter = Necromancer.new
|
114
114
|
@header = (value = options[:header]) ? Header.new(value) : nil
|
115
115
|
@rows = coerce(options.fetch(:rows) { Row.new([]) })
|
116
116
|
@rotated = false
|
@@ -457,7 +457,7 @@ module TTY
|
|
457
457
|
#
|
458
458
|
# @api public
|
459
459
|
def coerce(rows)
|
460
|
-
rows = @
|
460
|
+
rows = @converter.convert(rows).to(:array)
|
461
461
|
rows.map { |row| to_row(row, header) }
|
462
462
|
end
|
463
463
|
|
@@ -12,8 +12,8 @@ module TTY
|
|
12
12
|
#
|
13
13
|
# @api private
|
14
14
|
def initialize(aligns, widths = nil)
|
15
|
-
@
|
16
|
-
@elements = @
|
15
|
+
@converter = Necromancer.new
|
16
|
+
@elements = @converter.convert(aligns).to(:array)
|
17
17
|
@widths = widths
|
18
18
|
end
|
19
19
|
|
data/lib/tty/terminal.rb
CHANGED
@@ -22,6 +22,7 @@ module TTY
|
|
22
22
|
def initialize(options = {})
|
23
23
|
@color = Pastel.new
|
24
24
|
@echo = TTY::Terminal::Echo.new
|
25
|
+
@raw = TTY::Terminal::Raw.new
|
25
26
|
@pager = TTY::Terminal::Pager
|
26
27
|
@home = Home.new
|
27
28
|
end
|
@@ -49,6 +50,29 @@ module TTY
|
|
49
50
|
@echo.echo(is_on, &block)
|
50
51
|
end
|
51
52
|
|
53
|
+
# Switch raw mode on
|
54
|
+
#
|
55
|
+
# @api public
|
56
|
+
def raw_on
|
57
|
+
@raw.on
|
58
|
+
end
|
59
|
+
|
60
|
+
# Switch raw mode off
|
61
|
+
#
|
62
|
+
# @api public
|
63
|
+
def raw_off
|
64
|
+
@raw.off
|
65
|
+
end
|
66
|
+
|
67
|
+
# Use raw mode in the given block
|
68
|
+
#
|
69
|
+
# @param [Boolean] is_on
|
70
|
+
#
|
71
|
+
# @api public
|
72
|
+
def raw(is_on = true, &block)
|
73
|
+
@raw.raw(is_on, &block)
|
74
|
+
end
|
75
|
+
|
52
76
|
# Find user home directory
|
53
77
|
#
|
54
78
|
# @return [String]
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class Terminal
|
5
|
+
# A class responsible for toggling raw mode.
|
6
|
+
class Raw
|
7
|
+
# Turn raw mode on
|
8
|
+
#
|
9
|
+
# @api public
|
10
|
+
def on
|
11
|
+
%x{stty raw} if TTY::System.unix?
|
12
|
+
end
|
13
|
+
|
14
|
+
# Turn raw mode off
|
15
|
+
#
|
16
|
+
# @api public
|
17
|
+
def off
|
18
|
+
%x{stty -raw} if TTY::System.unix?
|
19
|
+
end
|
20
|
+
|
21
|
+
# Wrap code block inside raw mode
|
22
|
+
#
|
23
|
+
# @api public
|
24
|
+
def raw(is_on=true, &block)
|
25
|
+
value = nil
|
26
|
+
begin
|
27
|
+
on if is_on
|
28
|
+
value = block.call if block_given?
|
29
|
+
off
|
30
|
+
return value
|
31
|
+
rescue NoMethodError, Interrupt
|
32
|
+
off
|
33
|
+
exit
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end # Echo
|
37
|
+
end # Terminal
|
38
|
+
end # TTY
|
data/lib/tty/vector.rb
CHANGED
@@ -27,8 +27,8 @@ module TTY
|
|
27
27
|
#
|
28
28
|
# @api public
|
29
29
|
def initialize(array = [])
|
30
|
-
@
|
31
|
-
@elements = @
|
30
|
+
@converter = Necromancer.new
|
31
|
+
@elements = @converter.convert(array).to(:array, strict: true)
|
32
32
|
end
|
33
33
|
|
34
34
|
# Return element at index.
|
data/lib/tty/version.rb
CHANGED
@@ -11,7 +11,7 @@ describe TTY::Shell::Question, '#read_bool' do
|
|
11
11
|
input << 'invalid'
|
12
12
|
input.rewind
|
13
13
|
q = shell.ask("Do you read books?")
|
14
|
-
expect { q.read_bool }.to raise_error(
|
14
|
+
expect { q.read_bool }.to raise_error(Necromancer::ConversionTypeError)
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'reads negative boolean' do
|
@@ -37,5 +37,4 @@ describe TTY::Shell::Question, '#read_bool' do
|
|
37
37
|
answer = q.read_bool
|
38
38
|
expect(answer).to eql true
|
39
39
|
end
|
40
|
-
|
41
40
|
end
|
@@ -24,6 +24,8 @@ describe TTY::Shell::Question, '#read_range' do
|
|
24
24
|
context 'with invalid range' do
|
25
25
|
let(:value) { "abcd" }
|
26
26
|
|
27
|
-
it
|
27
|
+
it "fails to convert to range" do
|
28
|
+
expect { subject }.to raise_error(Necromancer::ConversionTypeError)
|
29
|
+
end
|
28
30
|
end
|
29
31
|
end # read_range
|
data/spec/tty/vector/new_spec.rb
CHANGED
@@ -19,7 +19,7 @@ describe TTY::Vector, '#new' do
|
|
19
19
|
let(:argument) { nil }
|
20
20
|
|
21
21
|
it 'throws type error' do
|
22
|
-
expect
|
22
|
+
expect(vector.to_a).to eq([])
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -33,11 +33,12 @@ describe TTY::Vector, '#new' do
|
|
33
33
|
|
34
34
|
context 'with an argument that respond to #to_ary' do
|
35
35
|
let(:argument) {
|
36
|
-
Class.new do
|
36
|
+
Custom = Class.new do
|
37
37
|
def to_ary
|
38
38
|
['Piotr']
|
39
39
|
end
|
40
|
-
end
|
40
|
+
end
|
41
|
+
Custom.new
|
41
42
|
}
|
42
43
|
|
43
44
|
it 'sets elements' do
|
data/tty.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
20
20
|
gem.add_dependency 'equatable', '~> 0.5.0'
|
21
|
+
gem.add_dependency 'necromancer', '~> 0.3.0'
|
21
22
|
gem.add_dependency 'pastel', '~> 0.4.0'
|
22
23
|
gem.add_dependency 'tty-screen', '~> 0.1.0'
|
23
24
|
gem.add_dependency 'tty-spinner', '~> 0.1.0'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Murach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: equatable
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.5.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: necromancer
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.3.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.3.0
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: pastel
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -116,12 +130,6 @@ files:
|
|
116
130
|
- benchmarks/table.rb
|
117
131
|
- images/tty.png
|
118
132
|
- lib/tty.rb
|
119
|
-
- lib/tty/conversion.rb
|
120
|
-
- lib/tty/conversion/converter/array.rb
|
121
|
-
- lib/tty/conversion/converter/boolean.rb
|
122
|
-
- lib/tty/conversion/converter/float.rb
|
123
|
-
- lib/tty/conversion/converter/integer.rb
|
124
|
-
- lib/tty/conversion/converter/range.rb
|
125
133
|
- lib/tty/logger.rb
|
126
134
|
- lib/tty/plugins.rb
|
127
135
|
- lib/tty/plugins/plugin.rb
|
@@ -181,6 +189,7 @@ files:
|
|
181
189
|
- lib/tty/terminal/pager.rb
|
182
190
|
- lib/tty/terminal/pager/basic.rb
|
183
191
|
- lib/tty/terminal/pager/system.rb
|
192
|
+
- lib/tty/terminal/raw.rb
|
184
193
|
- lib/tty/text.rb
|
185
194
|
- lib/tty/text/distance.rb
|
186
195
|
- lib/tty/text/truncation.rb
|
@@ -188,11 +197,6 @@ files:
|
|
188
197
|
- lib/tty/vector.rb
|
189
198
|
- lib/tty/version.rb
|
190
199
|
- spec/spec_helper.rb
|
191
|
-
- spec/tty/conversion/converter/array/convert_spec.rb
|
192
|
-
- spec/tty/conversion/converter/boolean/convert_spec.rb
|
193
|
-
- spec/tty/conversion/converter/float/convert_spec.rb
|
194
|
-
- spec/tty/conversion/converter/integer/convert_spec.rb
|
195
|
-
- spec/tty/conversion/converter/range/convert_spec.rb
|
196
200
|
- spec/tty/logger/log_spec.rb
|
197
201
|
- spec/tty/logger/new_spec.rb
|
198
202
|
- spec/tty/logger/valid_level_spec.rb
|
@@ -395,11 +399,6 @@ summary: A toolbox for developing beautiful command line clients. It provides a
|
|
395
399
|
information back.
|
396
400
|
test_files:
|
397
401
|
- spec/spec_helper.rb
|
398
|
-
- spec/tty/conversion/converter/array/convert_spec.rb
|
399
|
-
- spec/tty/conversion/converter/boolean/convert_spec.rb
|
400
|
-
- spec/tty/conversion/converter/float/convert_spec.rb
|
401
|
-
- spec/tty/conversion/converter/integer/convert_spec.rb
|
402
|
-
- spec/tty/conversion/converter/range/convert_spec.rb
|
403
402
|
- spec/tty/logger/log_spec.rb
|
404
403
|
- spec/tty/logger/new_spec.rb
|
405
404
|
- spec/tty/logger/valid_level_spec.rb
|
data/lib/tty/conversion.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module TTY
|
4
|
-
module Conversion
|
5
|
-
TypeError = Class.new(StandardError)
|
6
|
-
|
7
|
-
# Raised when cannot conver to a given type
|
8
|
-
NoTypeConversionAvailable = Class.new(StandardError)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
require 'tty/conversion/converter/array'
|
13
|
-
require 'tty/conversion/converter/boolean'
|
14
|
-
require 'tty/conversion/converter/float'
|
15
|
-
require 'tty/conversion/converter/integer'
|
16
|
-
require 'tty/conversion/converter/range'
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module TTY
|
4
|
-
module Conversion
|
5
|
-
class ArrayConverter
|
6
|
-
|
7
|
-
attr_reader :target
|
8
|
-
|
9
|
-
attr_reader :source
|
10
|
-
|
11
|
-
def initialize(source = String)
|
12
|
-
@source = source
|
13
|
-
@target = Array
|
14
|
-
end
|
15
|
-
|
16
|
-
# @api public
|
17
|
-
def convert(value, copy = false)
|
18
|
-
case value
|
19
|
-
when Array
|
20
|
-
copy ? value.dup : value
|
21
|
-
when Hash
|
22
|
-
Array(value)
|
23
|
-
else
|
24
|
-
begin
|
25
|
-
converted = value.to_ary
|
26
|
-
rescue Exception => e
|
27
|
-
raise TTY::TypeError,
|
28
|
-
"Cannot convert #{value.class} into an Array (#{e.message})"
|
29
|
-
end
|
30
|
-
converted
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end # ArrayConverter
|
34
|
-
end # Conversion
|
35
|
-
end # TTY
|
@@ -1,49 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module TTY
|
4
|
-
module Conversion
|
5
|
-
class BooleanConverter
|
6
|
-
|
7
|
-
attr_reader :target
|
8
|
-
|
9
|
-
attr_reader :source
|
10
|
-
|
11
|
-
def initialize(source = String)
|
12
|
-
@source = source
|
13
|
-
@target = [TrueClass, FalseClass]
|
14
|
-
end
|
15
|
-
|
16
|
-
def boolean?(value)
|
17
|
-
target.any? { |klass| value.is_a?(klass) }
|
18
|
-
end
|
19
|
-
|
20
|
-
# Convert value to boolean type including range of strings such as
|
21
|
-
#
|
22
|
-
# @param [Object] value
|
23
|
-
#
|
24
|
-
# @example
|
25
|
-
# coerce("True") # => true
|
26
|
-
#
|
27
|
-
# other values coerced to true are:
|
28
|
-
# 1, t, T, TRUE, true, True, y, Y, YES, yes, Yes
|
29
|
-
#
|
30
|
-
# @example
|
31
|
-
# coerce("False") # => false
|
32
|
-
#
|
33
|
-
# other values coerced to false are:
|
34
|
-
# 0, f, F, FALSE, false, False, n, N, No, no, No
|
35
|
-
#
|
36
|
-
# @api public
|
37
|
-
def convert(value)
|
38
|
-
case value.to_s
|
39
|
-
when /^(yes|y|t(rue)?|1)$/i
|
40
|
-
return true
|
41
|
-
when /^(no|n|f(alse)?|0)$/i
|
42
|
-
return false
|
43
|
-
else
|
44
|
-
fail TypeError, "Expected boolean type, got #{value}"
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end # BooleanConverter
|
48
|
-
end # Conversion
|
49
|
-
end # TTY
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module TTY
|
4
|
-
module Conversion
|
5
|
-
class FloatConverter
|
6
|
-
|
7
|
-
attr_reader :target
|
8
|
-
|
9
|
-
attr_reader :source
|
10
|
-
|
11
|
-
def initialize(source = String)
|
12
|
-
@source = source
|
13
|
-
@target = Float
|
14
|
-
end
|
15
|
-
|
16
|
-
# @api public
|
17
|
-
def convert(value, strict = false)
|
18
|
-
Kernel.send(target.name.to_sym, value.to_s)
|
19
|
-
rescue
|
20
|
-
if strict
|
21
|
-
raise InvalidArgument, "#{value} could not be coerced into #{target.name}"
|
22
|
-
else
|
23
|
-
value.to_f
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end # IntegerConverter
|
27
|
-
end # Conversion
|
28
|
-
end # TTY
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module TTY
|
4
|
-
module Conversion
|
5
|
-
class IntegerConverter
|
6
|
-
|
7
|
-
attr_reader :target
|
8
|
-
|
9
|
-
attr_reader :source
|
10
|
-
|
11
|
-
def initialize(source = String)
|
12
|
-
@source = source
|
13
|
-
@target = Integer
|
14
|
-
end
|
15
|
-
|
16
|
-
# @api public
|
17
|
-
def convert(value, strict = false)
|
18
|
-
Kernel.send(target.name.to_sym, value.to_s)
|
19
|
-
rescue
|
20
|
-
if strict
|
21
|
-
raise InvalidArgument, "#{value} could not be coerced into #{target.name}"
|
22
|
-
else
|
23
|
-
value.to_i
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end # IntegerConverter
|
27
|
-
end # Conversion
|
28
|
-
end # TTY
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module TTY
|
4
|
-
module Conversion
|
5
|
-
class RangeConverter
|
6
|
-
|
7
|
-
attr_reader :target
|
8
|
-
|
9
|
-
attr_reader :source
|
10
|
-
|
11
|
-
def initialize(source = String)
|
12
|
-
@source = source
|
13
|
-
@target = Range
|
14
|
-
end
|
15
|
-
|
16
|
-
# Convert value to Range type with possible ranges
|
17
|
-
#
|
18
|
-
# @param [Object] value
|
19
|
-
#
|
20
|
-
# @example
|
21
|
-
# coerce('0,9') # => (0..9)
|
22
|
-
#
|
23
|
-
# @example
|
24
|
-
# coerce('0-9') # => (0..9)
|
25
|
-
#
|
26
|
-
# @api public
|
27
|
-
def convert(value)
|
28
|
-
case value.to_s
|
29
|
-
when /\A(\-?\d+)\Z/
|
30
|
-
::Range.new($1.to_i, $1.to_i)
|
31
|
-
when /\A(-?\d+?)(\.{2}\.?|-|,)(-?\d+)\Z/
|
32
|
-
::Range.new($1.to_i, $3.to_i, $2 == '...')
|
33
|
-
when /\A(\w)(\.{2}\.?|-|,)(\w)\Z/
|
34
|
-
::Range.new($1.to_s, $3.to_s, $2 == '...')
|
35
|
-
else
|
36
|
-
fail InvalidArgument, "#{value} could not be coerced into Range type"
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end # RangeConverter
|
40
|
-
end # Conversion
|
41
|
-
end # TTY
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe TTY::Conversion::ArrayConverter do
|
6
|
-
let(:object) { described_class.new }
|
7
|
-
let(:enumerable) { [] }
|
8
|
-
|
9
|
-
subject { object.convert(enumerable) }
|
10
|
-
|
11
|
-
context 'Array type' do
|
12
|
-
it { is_expected.to eq(enumerable) }
|
13
|
-
end
|
14
|
-
|
15
|
-
context 'Hash type' do
|
16
|
-
let(:enumerable) { {a: 1, b: 2} }
|
17
|
-
|
18
|
-
it { is_expected.to include([:a, 1]) }
|
19
|
-
|
20
|
-
it { is_expected.to include([:b, 2]) }
|
21
|
-
end
|
22
|
-
|
23
|
-
context 'responds to #to_ary' do
|
24
|
-
let(:converted) { [] }
|
25
|
-
let(:enumerable) { double('Enumerable', to_ary: converted) }
|
26
|
-
|
27
|
-
it { is_expected.to eq(converted) }
|
28
|
-
end
|
29
|
-
|
30
|
-
context 'does not respond to #to_ary' do
|
31
|
-
let(:enumerable) { double('Enumerable') }
|
32
|
-
|
33
|
-
it 'raises error' do
|
34
|
-
expect { subject }.to raise_error(TTY::TypeError)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,117 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe TTY::Conversion::BooleanConverter, '#convert' do
|
6
|
-
let(:object) { described_class.new }
|
7
|
-
|
8
|
-
subject(:converter) { object.convert(value) }
|
9
|
-
|
10
|
-
context "with empty" do
|
11
|
-
let(:value) { '' }
|
12
|
-
|
13
|
-
it { expect { subject }.to raise_error(TTY::Conversion::TypeError) }
|
14
|
-
end
|
15
|
-
|
16
|
-
context "with true" do
|
17
|
-
let(:value) { true }
|
18
|
-
|
19
|
-
it { is_expected.to eq(true) }
|
20
|
-
end
|
21
|
-
|
22
|
-
context "with 'true'" do
|
23
|
-
let(:value) { 'true' }
|
24
|
-
|
25
|
-
it { is_expected.to eq(true) }
|
26
|
-
end
|
27
|
-
|
28
|
-
context "with TRUE" do
|
29
|
-
let(:value) { TRUE }
|
30
|
-
|
31
|
-
it { is_expected.to eq(true) }
|
32
|
-
end
|
33
|
-
|
34
|
-
context "with 'TRUE'" do
|
35
|
-
let(:value) { 'TRUE' }
|
36
|
-
|
37
|
-
it { is_expected.to eq(true) }
|
38
|
-
end
|
39
|
-
|
40
|
-
context "with 't'" do
|
41
|
-
let(:value) { 't' }
|
42
|
-
|
43
|
-
it { is_expected.to eq(true) }
|
44
|
-
end
|
45
|
-
|
46
|
-
context "with 'T'" do
|
47
|
-
let(:value) { 'T' }
|
48
|
-
|
49
|
-
it { is_expected.to eq(true) }
|
50
|
-
end
|
51
|
-
|
52
|
-
context "with 1" do
|
53
|
-
let(:value) { 1 }
|
54
|
-
|
55
|
-
it { is_expected.to eq(true) }
|
56
|
-
end
|
57
|
-
|
58
|
-
context "with '1'" do
|
59
|
-
let(:value) { '1' }
|
60
|
-
|
61
|
-
it { is_expected.to eq(true) }
|
62
|
-
end
|
63
|
-
|
64
|
-
context "with false" do
|
65
|
-
let(:value) { false }
|
66
|
-
|
67
|
-
it { is_expected.to eq(false) }
|
68
|
-
end
|
69
|
-
|
70
|
-
context "with 'false'" do
|
71
|
-
let(:value) { 'false' }
|
72
|
-
|
73
|
-
it { is_expected.to eq(false) }
|
74
|
-
end
|
75
|
-
|
76
|
-
context "with FALSE" do
|
77
|
-
let(:value) { FALSE }
|
78
|
-
|
79
|
-
it { is_expected.to eq(false) }
|
80
|
-
end
|
81
|
-
|
82
|
-
context "with 'FALSE'" do
|
83
|
-
let(:value) { 'FALSE' }
|
84
|
-
|
85
|
-
it { is_expected.to eq(false) }
|
86
|
-
end
|
87
|
-
|
88
|
-
context "with 'f'" do
|
89
|
-
let(:value) { 'f' }
|
90
|
-
|
91
|
-
it { is_expected.to eq(false) }
|
92
|
-
end
|
93
|
-
|
94
|
-
context "with 'F'" do
|
95
|
-
let(:value) { 'F' }
|
96
|
-
|
97
|
-
it { is_expected.to eq(false) }
|
98
|
-
end
|
99
|
-
|
100
|
-
context "with 0" do
|
101
|
-
let(:value) { 0 }
|
102
|
-
|
103
|
-
it { is_expected.to eq(false) }
|
104
|
-
end
|
105
|
-
|
106
|
-
context "with '0'" do
|
107
|
-
let(:value) { '0' }
|
108
|
-
|
109
|
-
it { is_expected.to eq(false) }
|
110
|
-
end
|
111
|
-
|
112
|
-
context "with FOO" do
|
113
|
-
let(:value) { 'FOO' }
|
114
|
-
|
115
|
-
it { expect { subject }.to raise_error(TTY::Conversion::TypeError) }
|
116
|
-
end
|
117
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe TTY::Conversion::FloatConverter, '#convert' do
|
6
|
-
let(:object) { described_class.new }
|
7
|
-
let(:strict) { true }
|
8
|
-
|
9
|
-
subject(:converter) { object.convert(value, strict) }
|
10
|
-
|
11
|
-
context 'with empty' do
|
12
|
-
let(:value) { '' }
|
13
|
-
|
14
|
-
it { expect { subject }.to raise_error(TTY::InvalidArgument) }
|
15
|
-
end
|
16
|
-
|
17
|
-
context 'with 1 as string' do
|
18
|
-
let(:value) { '1' }
|
19
|
-
|
20
|
-
it { is_expected.to eql 1.0 }
|
21
|
-
end
|
22
|
-
|
23
|
-
context 'with float' do
|
24
|
-
let(:value) { '1.2a' }
|
25
|
-
|
26
|
-
it { expect { subject }.to raise_error(TTY::InvalidArgument) }
|
27
|
-
end
|
28
|
-
|
29
|
-
context 'with float not strict' do
|
30
|
-
let(:value) { '1.2abc'}
|
31
|
-
let(:strict) { false }
|
32
|
-
|
33
|
-
it { is_expected.to eql 1.2 }
|
34
|
-
end
|
35
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe TTY::Conversion::IntegerConverter, '#convert' do
|
6
|
-
let(:object) { described_class.new }
|
7
|
-
let(:strict) { true }
|
8
|
-
|
9
|
-
subject(:converter) { object.convert(value, strict) }
|
10
|
-
|
11
|
-
context 'with empty' do
|
12
|
-
let(:value) { '' }
|
13
|
-
|
14
|
-
it { expect { subject }.to raise_error(TTY::InvalidArgument) }
|
15
|
-
end
|
16
|
-
|
17
|
-
context 'with 1 as string' do
|
18
|
-
let(:value) { '1' }
|
19
|
-
|
20
|
-
it { is_expected.to eql 1 }
|
21
|
-
end
|
22
|
-
|
23
|
-
context 'with float' do
|
24
|
-
let(:value) { 1.2 }
|
25
|
-
|
26
|
-
it { expect { subject }.to raise_error(TTY::InvalidArgument) }
|
27
|
-
end
|
28
|
-
|
29
|
-
context 'with float not strict' do
|
30
|
-
let(:value) { 1.2 }
|
31
|
-
let(:strict) { false }
|
32
|
-
|
33
|
-
it { is_expected.to eql 1 }
|
34
|
-
end
|
35
|
-
|
36
|
-
context 'with letters not strict' do
|
37
|
-
let(:value) { '1abc' }
|
38
|
-
let(:strict) { false }
|
39
|
-
|
40
|
-
it { is_expected.to eql 1 }
|
41
|
-
end
|
42
|
-
end
|
@@ -1,75 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe TTY::Conversion::RangeConverter, '#convert' do
|
6
|
-
let(:object) { described_class.new }
|
7
|
-
|
8
|
-
subject(:converter) { object.convert(value) }
|
9
|
-
|
10
|
-
context 'with empty' do
|
11
|
-
let(:value) { '' }
|
12
|
-
|
13
|
-
it { expect { subject }.to raise_error(TTY::InvalidArgument) }
|
14
|
-
end
|
15
|
-
|
16
|
-
context 'with 1' do
|
17
|
-
let(:value) { '1' }
|
18
|
-
|
19
|
-
it { is_expected.to eq(1..1) }
|
20
|
-
end
|
21
|
-
|
22
|
-
context 'with 1..10' do
|
23
|
-
let(:value) { '1..10' }
|
24
|
-
|
25
|
-
it { is_expected.to eq(1..10) }
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'with 1-10' do
|
29
|
-
let(:value) { '1-10' }
|
30
|
-
|
31
|
-
it { is_expected.to eq(1..10) }
|
32
|
-
end
|
33
|
-
|
34
|
-
context 'with 1,10' do
|
35
|
-
let(:value) { '1,10' }
|
36
|
-
|
37
|
-
it { is_expected.to eq(1..10) }
|
38
|
-
end
|
39
|
-
|
40
|
-
context 'with 1...10' do
|
41
|
-
let(:value) { '1...10'}
|
42
|
-
|
43
|
-
it { is_expected.to eq(1...10) }
|
44
|
-
end
|
45
|
-
|
46
|
-
context 'with -1..10' do
|
47
|
-
let(:value) { '-1..10' }
|
48
|
-
|
49
|
-
it { is_expected.to eq(-1..10) }
|
50
|
-
end
|
51
|
-
|
52
|
-
context 'with 1..-10' do
|
53
|
-
let(:value) { '1..-10' }
|
54
|
-
|
55
|
-
it { is_expected.to eq(1..-10) }
|
56
|
-
end
|
57
|
-
|
58
|
-
context 'with a..z' do
|
59
|
-
let(:value) { 'a..z' }
|
60
|
-
|
61
|
-
it { is_expected.to eq('a'..'z')}
|
62
|
-
end
|
63
|
-
|
64
|
-
context 'with a-z' do
|
65
|
-
let(:value) { 'a-z' }
|
66
|
-
|
67
|
-
it { is_expected.to eq('a'..'z')}
|
68
|
-
end
|
69
|
-
|
70
|
-
context 'with A..Z' do
|
71
|
-
let(:value) { 'A..Z' }
|
72
|
-
|
73
|
-
it { is_expected.to eq('A'..'Z')}
|
74
|
-
end
|
75
|
-
end # coerce
|