interactive 0.0.0 → 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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/CHANGELOG.markdown +6 -0
- data/README.md +33 -18
- data/Rakefile +4 -0
- data/interactive.gemspec +3 -1
- data/lib/interactive.rb +2 -0
- data/lib/interactive/option.rb +45 -0
- data/lib/interactive/options.rb +40 -0
- data/lib/interactive/question.rb +9 -27
- data/lib/interactive/response.rb +33 -10
- data/lib/interactive/version.rb +1 -1
- metadata +39 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2c6959fba0126e77b3a9147f7f23435a19064cf
|
4
|
+
data.tar.gz: 7418c32a98aacddb6df983502f09abdf738f2d5c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4fe3a14aa9871323c85e1045d9eb0341422ec9489f49484d30756555e053eb1b7ec1c93a431c407b7294f87c9bd302936b7ddac18ef0a6cde98c816def50a0b1
|
7
|
+
data.tar.gz: a3144758369854cbf2790e558147f2a6bcd2f7f3269920e98c37cc08c67519b496fc3a3ff813cdb0534ee09709684eece520276616662b24cf4a9478f9b74d64
|
data/.travis.yml
CHANGED
data/CHANGELOG.markdown
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
v0.1.0 -- Mon Mar 16 07:17:53 EDT 2015
|
2
|
+
--------------------------------------
|
3
|
+
- Added support for handling ranges.
|
4
|
+
- Useful for processing responses of questions like "Which item do you want to
|
5
|
+
use?", where whole number responses such as "1", "2", etc. makes sense.
|
6
|
+
- Refactored, DRY'er.
|
data/README.md
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
# Interactive
|
2
|
+
[](http://badge.fury.io/rb/interactive)
|
3
|
+
[](https://travis-ci.org/Edderic/interactive)
|
4
|
+
[](https://codeclimate.com/github/Edderic/interactive)
|
5
|
+
|
2
6
|
This is a helper module to assist in interactive question-answering events in the command line.
|
3
7
|
|
4
8
|
## Installation
|
@@ -6,7 +10,7 @@ This is a helper module to assist in interactive question-answering events in th
|
|
6
10
|
Add this line to your application's Gemfile:
|
7
11
|
|
8
12
|
```ruby
|
9
|
-
gem '
|
13
|
+
gem 'interactive'
|
10
14
|
```
|
11
15
|
|
12
16
|
And then execute:
|
@@ -15,7 +19,7 @@ And then execute:
|
|
15
19
|
|
16
20
|
Or install it yourself as:
|
17
21
|
|
18
|
-
$ gem install
|
22
|
+
$ gem install interactive
|
19
23
|
|
20
24
|
## Usage
|
21
25
|
|
@@ -23,21 +27,24 @@ If you want to ask a user a question expecting certain answers:
|
|
23
27
|
|
24
28
|
```ruby
|
25
29
|
question = Interactive::Question.new do |ques|
|
26
|
-
ques.question = "
|
27
|
-
ques.options = [
|
30
|
+
ques.question = "Which item do you want to use?"
|
31
|
+
ques.options = [1..3, :cancel, :quit]
|
28
32
|
end
|
29
33
|
```
|
30
34
|
|
31
|
-
You can run the loop and wait for a valid response
|
35
|
+
You can run the loop and wait for a valid response and do query methods on the
|
36
|
+
response:
|
32
37
|
|
33
38
|
```ruby
|
34
39
|
question.ask_and_wait_for_valid_response do |response|
|
35
|
-
if response.
|
36
|
-
#
|
37
|
-
elsif response.
|
38
|
-
#
|
39
|
-
elsif response.
|
40
|
-
# etc
|
40
|
+
if response.whole_num_1?
|
41
|
+
# do stuff if user responded with "1"
|
42
|
+
elsif response.whole_num?
|
43
|
+
# do stuff if user responded with "1", "2", or "3"
|
44
|
+
elsif response.cancel?
|
45
|
+
# do stuff if user responded with "c", etc.
|
46
|
+
elsif response.quit?
|
47
|
+
# do stuff if user responded with "q", etc.
|
41
48
|
end
|
42
49
|
end
|
43
50
|
```
|
@@ -45,7 +52,14 @@ end
|
|
45
52
|
That will ask the question appended by the shortcuts:
|
46
53
|
|
47
54
|
```ruby
|
48
|
-
# =>
|
55
|
+
# => "Which item do you want to use? [1/2/3/c/q]"
|
56
|
+
```
|
57
|
+
|
58
|
+
If the response is valid:
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
$ a
|
62
|
+
# => response.add? will return true
|
49
63
|
```
|
50
64
|
|
51
65
|
If the response is invalid, it prints out the question and goes into detail as
|
@@ -53,11 +67,12 @@ to what the shortcuts stand for:
|
|
53
67
|
|
54
68
|
```ruby
|
55
69
|
$ bad-response
|
56
|
-
# =>
|
57
|
-
# =>
|
58
|
-
# =>
|
59
|
-
# =>
|
60
|
-
# =>
|
70
|
+
# => Which item do you want to use? [1/2/3/c/q]
|
71
|
+
# => 1 -- 1
|
72
|
+
# => 2 -- 2
|
73
|
+
# => 3 -- 3
|
74
|
+
# => c -- cancel
|
75
|
+
# => q -- quit
|
61
76
|
```
|
62
77
|
|
63
78
|
## Development
|
@@ -68,7 +83,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
68
83
|
|
69
84
|
## Contributing
|
70
85
|
|
71
|
-
1. Fork it ( https://github.com/
|
86
|
+
1. Fork it ( https://github.com/edderic/interactive/fork )
|
72
87
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
73
88
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
74
89
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/Rakefile
CHANGED
data/interactive.gemspec
CHANGED
@@ -17,6 +17,8 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.add_development_dependency "bundler", "~> 1.8"
|
21
20
|
spec.add_development_dependency "rake", "~> 10.0"
|
21
|
+
spec.add_development_dependency 'rspec', '~> 3.1'
|
22
|
+
spec.add_development_dependency 'byebug', '~> 3.5'
|
23
|
+
spec.add_development_dependency 'bundler'
|
22
24
|
end
|
data/lib/interactive.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
module Interactive
|
4
|
+
module_function
|
5
|
+
|
6
|
+
def Option(option)
|
7
|
+
if option.to_s.match(/^\d+$/)
|
8
|
+
@option = WholeNumberOption.new(option)
|
9
|
+
else
|
10
|
+
@option = WordOption.new(option)
|
11
|
+
end
|
12
|
+
|
13
|
+
@option
|
14
|
+
end
|
15
|
+
|
16
|
+
class WholeNumberOption < SimpleDelegator
|
17
|
+
def initialize(option)
|
18
|
+
@option = option
|
19
|
+
super(@option)
|
20
|
+
end
|
21
|
+
|
22
|
+
def shortcut_value
|
23
|
+
@option
|
24
|
+
end
|
25
|
+
|
26
|
+
def query_method_name
|
27
|
+
"whole_number_#{shortcut_value}?"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class WordOption < SimpleDelegator
|
32
|
+
def initialize(option)
|
33
|
+
@option = option
|
34
|
+
super(@option)
|
35
|
+
end
|
36
|
+
|
37
|
+
def shortcut_value
|
38
|
+
@option.to_s[0]
|
39
|
+
end
|
40
|
+
|
41
|
+
def query_method_name
|
42
|
+
"#{@option}?"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
module Interactive
|
4
|
+
class Options < SimpleDelegator
|
5
|
+
include Interactive
|
6
|
+
attr_accessor :options
|
7
|
+
|
8
|
+
def initialize(options)
|
9
|
+
flatten_ranges(options)
|
10
|
+
wrap_each_option
|
11
|
+
super(@options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def shortcuts_string
|
15
|
+
"[#{first_chars_without_last_slash(first_chars)}]"
|
16
|
+
end
|
17
|
+
|
18
|
+
def shortcuts_meanings
|
19
|
+
options.inject("") { |accum, opt| "#{accum} #{opt.shortcut_value} -- #{opt}\n"}
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def flatten_ranges(options)
|
25
|
+
@options = options.inject([]) {|accum, opt| opt.respond_to?(:to_a) ? accum | opt.to_a : accum << opt}
|
26
|
+
end
|
27
|
+
|
28
|
+
def wrap_each_option
|
29
|
+
@options.map! {|option| Option(option) }
|
30
|
+
end
|
31
|
+
|
32
|
+
def first_chars
|
33
|
+
options.inject("") { |accum, opt| "#{accum}#{ opt.shortcut_value}/" }
|
34
|
+
end
|
35
|
+
|
36
|
+
def first_chars_without_last_slash(first_chars)
|
37
|
+
first_chars[0..first_chars.length-2]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/interactive/question.rb
CHANGED
@@ -4,23 +4,21 @@ module Interactive
|
|
4
4
|
|
5
5
|
def initialize(&block)
|
6
6
|
yield self
|
7
|
+
|
8
|
+
@options = Interactive::Options.new(Array(@options))
|
9
|
+
|
10
|
+
raise ArgumentError, "question cannot be nil nor empty." if question.nil? || question.empty?
|
11
|
+
raise ArgumentError, "options cannot be empty." if options.empty?
|
7
12
|
end
|
8
13
|
|
9
14
|
def ask_and_wait_for_valid_response(&block)
|
10
|
-
|
11
|
-
|
12
|
-
while resp.invalid? do
|
13
|
-
puts "#{question} #{shortcuts_string}"
|
15
|
+
loop do
|
16
|
+
puts "#{question} #{options.shortcuts_string}"
|
14
17
|
resp = Interactive::Response.new(options)
|
15
|
-
puts shortcuts_meanings if resp.invalid?
|
18
|
+
puts options.shortcuts_meanings if resp.invalid?
|
16
19
|
|
17
20
|
yield resp
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
class NullResponse
|
22
|
-
def invalid?
|
23
|
-
true
|
21
|
+
break unless resp.invalid?
|
24
22
|
end
|
25
23
|
end
|
26
24
|
|
@@ -29,21 +27,5 @@ module Interactive
|
|
29
27
|
def response
|
30
28
|
STDIN.gets.chomp
|
31
29
|
end
|
32
|
-
|
33
|
-
def shortcuts_meanings
|
34
|
-
options.inject("") { |accum, opt| "#{accum} #{opt[0]} -- #{opt}\n"}
|
35
|
-
end
|
36
|
-
|
37
|
-
def options_first_chars
|
38
|
-
options.inject("") { |accum, opt| "#{accum}#{opt[0]}/" }
|
39
|
-
end
|
40
|
-
|
41
|
-
def shortcuts_string
|
42
|
-
"[#{options_first_chars_without_last_slash(options_first_chars)}]"
|
43
|
-
end
|
44
|
-
|
45
|
-
def options_first_chars_without_last_slash(options_first_chars)
|
46
|
-
options_first_chars[0..options_first_chars.length-2]
|
47
|
-
end
|
48
30
|
end
|
49
31
|
end
|
data/lib/interactive/response.rb
CHANGED
@@ -1,26 +1,49 @@
|
|
1
|
+
require 'interactive'
|
2
|
+
|
1
3
|
module Interactive
|
2
4
|
class Response
|
3
5
|
def initialize(*args)
|
4
|
-
|
5
|
-
|
6
|
-
else
|
7
|
-
@args = args
|
8
|
-
end
|
9
|
-
|
10
|
-
raise ArgumentError, "wrong number of arguments (need at least two arguments)" if @args.length == 1
|
11
|
-
raise ArgumentError, "may not use :invalid or 'invalid' as an argument. May not overwrite Interactive::Response#invalid" if @args.map(&:to_s).include?('invalid')
|
6
|
+
@args = Array(args).flatten
|
7
|
+
check_validity
|
12
8
|
|
13
9
|
@_response = STDIN.gets.chomp
|
14
10
|
|
11
|
+
define_methods
|
12
|
+
define_invalid
|
13
|
+
define_whole_number
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def check_validity
|
19
|
+
raise ArgumentError, "may not use :invalid or 'invalid' as an argument. Private method." if @args.map(&:to_s).include?('invalid')
|
20
|
+
raise ArgumentError, "may not use :whole_number or 'whole_number' as an argument. Private method." if @args.map(&:to_s).include?('whole_number')
|
21
|
+
raise ArgumentError, "may not have keyword options that have the same first letter." if first_chars_not_unique
|
22
|
+
raise ArgumentError, "wrong number of arguments (need at least two arguments)." if @args.length < 2
|
23
|
+
end
|
24
|
+
|
25
|
+
def define_methods
|
15
26
|
@args.each do |arg|
|
16
|
-
define_singleton_method
|
17
|
-
@_response.match(/^#{arg
|
27
|
+
define_singleton_method arg.query_method_name do
|
28
|
+
@_response.strip.match(/^#{arg.shortcut_value}$/i) ? true : false
|
18
29
|
end
|
19
30
|
end
|
31
|
+
end
|
20
32
|
|
33
|
+
def define_invalid
|
21
34
|
define_singleton_method "invalid?" do
|
22
35
|
methods(false).reject {|m| m == :invalid? }.none? {|m| send(m) }
|
23
36
|
end
|
24
37
|
end
|
38
|
+
|
39
|
+
def define_whole_number
|
40
|
+
define_singleton_method "whole_number?" do
|
41
|
+
methods(false).select {|m| m.to_s.match(/whole_number_\d+/)}.any? {|m| send(m) }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def first_chars_not_unique
|
46
|
+
@args.map{|arg| arg.shortcut_value }.uniq.length != @args.length
|
47
|
+
end
|
25
48
|
end
|
26
49
|
end
|
data/lib/interactive/version.rb
CHANGED
metadata
CHANGED
@@ -1,43 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: interactive
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Edderic Ugaddan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: rake
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '10.0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '10.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '3.1'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '3.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: byebug
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.5'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
41
69
|
description:
|
42
70
|
email:
|
43
71
|
- edderic@gmail.com
|
@@ -48,6 +76,7 @@ files:
|
|
48
76
|
- ".gitignore"
|
49
77
|
- ".rspec"
|
50
78
|
- ".travis.yml"
|
79
|
+
- CHANGELOG.markdown
|
51
80
|
- CODE_OF_CONDUCT.md
|
52
81
|
- Gemfile
|
53
82
|
- LICENSE.txt
|
@@ -57,6 +86,8 @@ files:
|
|
57
86
|
- bin/setup
|
58
87
|
- interactive.gemspec
|
59
88
|
- lib/interactive.rb
|
89
|
+
- lib/interactive/option.rb
|
90
|
+
- lib/interactive/options.rb
|
60
91
|
- lib/interactive/question.rb
|
61
92
|
- lib/interactive/response.rb
|
62
93
|
- lib/interactive/version.rb
|