questions 1.0.1
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 +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +62 -0
- data/Rakefile +34 -0
- data/VERSION +1 -0
- data/lib/questions/answer.rb +129 -0
- data/lib/questions/answers.rb +196 -0
- data/lib/questions/question.rb +104 -0
- data/lib/questions/version.rb +3 -0
- data/lib/questions.rb +4 -0
- data/questions.gemspec +28 -0
- data/spec/questions/answer_spec.rb +120 -0
- data/spec/questions/answers_spec.rb +255 -0
- data/spec/questions/question_spec.rb +72 -0
- data/spec/spec_helper.rb +12 -0
- metadata +164 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 41e385aa0a2fa87149846bfa99223235a5910887
|
4
|
+
data.tar.gz: 5aa6e4a359aad4dc0bfa7232b79daabc4a746934
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c1056f0f6f023509511d95659796f301be00924d129e2c2a38cdffed01df1899b2adf275367c1e662c5dfc959bd2c874a323fce5ce66a2dae997ee013b145d08
|
7
|
+
data.tar.gz: c74a6eca07e5d9a80327b2df544bae4bd9adfe042479a37eb9e1d109266d1b781a2d10022842d990a69866a7e6674bd2db36a9be8f96b2d11cbc3eea60ddddfa
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 DSIW
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# Question
|
2
|
+
|
3
|
+
Ask human a question. She or he has to select one answer.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'questions'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install questions
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
### Preamble
|
22
|
+
``` ruby
|
23
|
+
require "questions"
|
24
|
+
include Questions
|
25
|
+
```
|
26
|
+
|
27
|
+
### Long way
|
28
|
+
``` ruby
|
29
|
+
q = Question.new("File does exist, what should be done?")
|
30
|
+
q.answers = [:skip, :overwrite, :abort]
|
31
|
+
answer = q.ask
|
32
|
+
# SHELL:
|
33
|
+
# $ File does exist, what should be done? [s]kip, [o]verwrite, [a]bort
|
34
|
+
# s<enter>
|
35
|
+
answer #=> :skip
|
36
|
+
```
|
37
|
+
|
38
|
+
### Short way
|
39
|
+
``` ruby
|
40
|
+
answer = Question.ask "File does exist, what should be done?", [:skip, :overwrite, :abort]
|
41
|
+
# SHELL:
|
42
|
+
# $ File does exist, what should be done? [s]kip, [o]verwrite, [a]bort
|
43
|
+
# s<enter>
|
44
|
+
answer #=> :skip
|
45
|
+
```
|
46
|
+
|
47
|
+
### Hashish way
|
48
|
+
``` ruby
|
49
|
+
answer = Question.ask "File does exist, what should be done?", skip: true, overwrite: false, abort: true
|
50
|
+
# SHELL:
|
51
|
+
# $ File does exist, what should be done? [s]kip, [a]bort
|
52
|
+
# s<enter>
|
53
|
+
answer #=> :skip
|
54
|
+
```
|
55
|
+
|
56
|
+
## Contributing
|
57
|
+
|
58
|
+
1. Fork it
|
59
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
60
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
61
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
62
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/version_task'
|
5
|
+
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
|
8
|
+
RSpec::Core::RakeTask.new do |t|
|
9
|
+
# Put spec opts in a file named .rspec in root
|
10
|
+
end
|
11
|
+
|
12
|
+
Rake::VersionTask.new
|
13
|
+
|
14
|
+
task :doc => [ 'doc:clean', 'doc:api' ]
|
15
|
+
|
16
|
+
CLOBBER << "doc"
|
17
|
+
CLEAN << "doc"
|
18
|
+
namespace :doc do
|
19
|
+
require 'yard'
|
20
|
+
YARD::Rake::YardocTask.new(:api) do |t|
|
21
|
+
t.files = ['lib/**/*.rb']
|
22
|
+
t.options = [
|
23
|
+
'--output-dir', 'doc/api',
|
24
|
+
'--markup', 'markdown'
|
25
|
+
]
|
26
|
+
end
|
27
|
+
|
28
|
+
desc 'Remove YARD Documentation'
|
29
|
+
task :clean do
|
30
|
+
system("rm -rf #{File.dirname(__FILE__)}/doc/api")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
task :default => [:spec]
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.1
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Questions
|
4
|
+
class Answer
|
5
|
+
SPECIAL_ENDINGS = [:all]
|
6
|
+
|
7
|
+
# Instantiates new Answer object.
|
8
|
+
#
|
9
|
+
# Only the first key value pair will be used.
|
10
|
+
#
|
11
|
+
# @param [Hash] answer_hash Key (instruction); value (activeness) is `true` or `false`.
|
12
|
+
#
|
13
|
+
# @example Hash with one item
|
14
|
+
# Answer.new({:overwrite => true}) #=> [o]verwrite
|
15
|
+
# Answer.new(:overwrite => true) #=> [o]verwrite
|
16
|
+
# Answer.new(:overwrite) #=> [o]verwrite
|
17
|
+
# Answer.new({:overwrite => false}) #=> ""
|
18
|
+
# Answer.new(:overwrite => false) #=> ""
|
19
|
+
# Answer.new({:overwrite => nil}) #=> ""
|
20
|
+
#
|
21
|
+
# @example Items of hash with more than one item will be ignored
|
22
|
+
# Answer.new({:overwrite => true, :overwrite_all => false}) #=> [o]verwrite
|
23
|
+
# Answer.new({:overwrite => true, :overwrite_all => true}) #=> [o]verwrite
|
24
|
+
def initialize(*answer_hash)
|
25
|
+
hash = answer_hash.first
|
26
|
+
hash = {hash => true} if hash.is_a? Symbol
|
27
|
+
|
28
|
+
unless [Hash, Symbol].any? { |class_name| hash.is_a? class_name }
|
29
|
+
raise ArgumentError, "Parameter has to be a key-value-pair or a symbol"
|
30
|
+
end
|
31
|
+
|
32
|
+
array = hash.first
|
33
|
+
@instruction = array[0]
|
34
|
+
@active = array[1]
|
35
|
+
end
|
36
|
+
|
37
|
+
# Gets instruction
|
38
|
+
#
|
39
|
+
# @example Hash with one item
|
40
|
+
# Answer.new(overwrite: true).instruction #=> :overwrite
|
41
|
+
# Answer.new(overwrite: false).instruction #=> :overwrite
|
42
|
+
attr_reader :instruction
|
43
|
+
|
44
|
+
# Is answer active?
|
45
|
+
#
|
46
|
+
# @example Hash with one item
|
47
|
+
# Answer.new(overwrite: true).active? #=> true
|
48
|
+
# Answer.new(overwrite: false).active? #=> false
|
49
|
+
#
|
50
|
+
# @see {true?}
|
51
|
+
def active?
|
52
|
+
@active
|
53
|
+
end
|
54
|
+
alias :true? :active?
|
55
|
+
|
56
|
+
# Is answer inactive?
|
57
|
+
#
|
58
|
+
# @example Hash with one item
|
59
|
+
# Answer.new(overwrite: true).inactive? #=> false
|
60
|
+
# Answer.new(overwrite: false).inactive? #=> true
|
61
|
+
#
|
62
|
+
# @see {false?}
|
63
|
+
def inactive?
|
64
|
+
!active?
|
65
|
+
end
|
66
|
+
alias :false? :inactive?
|
67
|
+
|
68
|
+
# Sets indicator
|
69
|
+
#
|
70
|
+
# @example Hash with one item
|
71
|
+
# answer = Answer.new(overwrite: true)
|
72
|
+
# answer.indicator = :ov
|
73
|
+
# answer.indicator #=> :ov
|
74
|
+
attr_writer :indicator
|
75
|
+
|
76
|
+
# Gets indicator
|
77
|
+
#
|
78
|
+
# @example with true answer
|
79
|
+
# a = Answer.new(overwrite: true)
|
80
|
+
# a.indicator #=> :o
|
81
|
+
# a.indicator(2) #=> :ov
|
82
|
+
#
|
83
|
+
# @example with special true answer
|
84
|
+
# Answer.new(overwrite_all: true).indicator(2) #=> :OV
|
85
|
+
#
|
86
|
+
# @example with inactive answer
|
87
|
+
# Answer.new(overwrite: false).indicator #=> nil
|
88
|
+
#
|
89
|
+
# @example set indicator
|
90
|
+
# a = Answer.new(overwrite: true)
|
91
|
+
# a.indicator #=> :o
|
92
|
+
# a.indicator = :ov
|
93
|
+
# a.indicator #=> :ov
|
94
|
+
def indicator(first_chars=1)
|
95
|
+
return nil if inactive?
|
96
|
+
return @indicator if @indicator
|
97
|
+
indicator = instruction.to_s[0...first_chars]
|
98
|
+
indicator.upcase! if special?
|
99
|
+
indicator.to_sym
|
100
|
+
end
|
101
|
+
|
102
|
+
# Returns `true` if answer is special. Special answers are answers which ends with one of the {SPECIAL_ENDINGS}, `false` otherwise.
|
103
|
+
def special?
|
104
|
+
SPECIAL_ENDINGS.any? { |ending| instruction.to_s =~ /#{ending}$/ }
|
105
|
+
end
|
106
|
+
|
107
|
+
# Gets indicator hash
|
108
|
+
#
|
109
|
+
# @example Hash with one item
|
110
|
+
# Answer.new(overwrite: true).indicator_hash #=> {:o => :overwrite}
|
111
|
+
# Answer.new(overwrite: false).indicator_hash #=> nil
|
112
|
+
def indicator_hash
|
113
|
+
return nil if inactive?
|
114
|
+
{indicator => instruction}
|
115
|
+
end
|
116
|
+
|
117
|
+
# Gets string representation
|
118
|
+
#
|
119
|
+
# @example Hash with one item
|
120
|
+
# Answer.new(overwrite: true).to_s #=> "[o]verwrite"
|
121
|
+
# Answer.new(overwrite: false).to_s #=> ""
|
122
|
+
def to_s
|
123
|
+
return nil if inactive?
|
124
|
+
instruction_without_indicator = instruction.to_s[indicator.length..-1]
|
125
|
+
humanized = instruction_without_indicator.gsub("_", " ")
|
126
|
+
"[#{indicator}]#{humanized}"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Questions
|
4
|
+
class Answers < Array
|
5
|
+
# Instantiates a new Answers object.
|
6
|
+
#
|
7
|
+
# @param args [Answer, Symbol, Array, Hash] Initial answers
|
8
|
+
#
|
9
|
+
# Each parameter will be send to {#<<}.
|
10
|
+
#
|
11
|
+
# @example parameter as Answer
|
12
|
+
# answers = Answers.new Answer.new(:abort)
|
13
|
+
# answers.first.instruction #=> :abort
|
14
|
+
# answers.first.active #=> true
|
15
|
+
#
|
16
|
+
# @example parameter as Symbol
|
17
|
+
# answers = Answers.new :abort
|
18
|
+
# answers.first.instruction #=> :abort
|
19
|
+
# answers.first.active #=> true
|
20
|
+
#
|
21
|
+
# @example parameter as Array
|
22
|
+
# answers = Answers.new [:abort, Answer.new(:overwrite)]
|
23
|
+
# answers.first.instruction #=> :abort
|
24
|
+
# answers.first.active #=> true
|
25
|
+
# answers.last.instruction #=> :overwrite
|
26
|
+
# answers.last.active #=> true
|
27
|
+
#
|
28
|
+
# @example parameter as Hash
|
29
|
+
# answers = Answers.new({abort: true, overwrite: false, "non-symbol" => "ignored"})
|
30
|
+
# answers.size #=> 2
|
31
|
+
# answers.first.instruction #=> :abort
|
32
|
+
# answers.first.active #=> true
|
33
|
+
# answers.last.instruction #=> :overwrite
|
34
|
+
# answers.last.active #=> false
|
35
|
+
def initialize(*args)
|
36
|
+
args.each { |arg| self << arg }
|
37
|
+
end
|
38
|
+
|
39
|
+
# Adds answer. Answer can be an instance of {Answer}, {Symbol}, a {Hash} or an {Array}. Chaining is
|
40
|
+
# supported.
|
41
|
+
#
|
42
|
+
# @example parameter as Answer
|
43
|
+
# answers = Answers.new
|
44
|
+
# answers << Answer.new(:abort)
|
45
|
+
# answers.first.instruction #=> :abort
|
46
|
+
# answers.first.active #=> true
|
47
|
+
#
|
48
|
+
# @example parameter as Symbol
|
49
|
+
# answers = Answers.new
|
50
|
+
# answers << :abort << :overwrite
|
51
|
+
# answers.first.instruction #=> :abort
|
52
|
+
# answers.first.active #=> true
|
53
|
+
# answers.last.instruction #=> :overwrite
|
54
|
+
# answers.last.active #=> true
|
55
|
+
#
|
56
|
+
# @example parameter as Array
|
57
|
+
# answers = Answers.new
|
58
|
+
# answers << [:abort, Answer.new(:overwrite)]
|
59
|
+
# answers.first.instruction #=> :abort
|
60
|
+
# answers.first.active #=> true
|
61
|
+
# answers.last.instruction #=> :overwrite
|
62
|
+
# answers.last.active #=> true
|
63
|
+
#
|
64
|
+
# @example parameter as Hash
|
65
|
+
# answers = Answers.new
|
66
|
+
# answers << {abort: true, overwrite: false, "non-symbol" => "ignored"}
|
67
|
+
# answers.size #=> 2
|
68
|
+
# answers.first.instruction #=> :abort
|
69
|
+
# answers.first.active #=> true
|
70
|
+
# answers.last.instruction #=> :overwrite
|
71
|
+
# answers.last.active #=> false
|
72
|
+
#
|
73
|
+
# @return [Answers] self
|
74
|
+
def <<(arg)
|
75
|
+
case arg
|
76
|
+
when Answer then super arg
|
77
|
+
when Symbol then super Answer.new(arg)
|
78
|
+
when Array
|
79
|
+
arg.each { |arg| self << arg } # call as Answer or Symbol
|
80
|
+
when Hash
|
81
|
+
self << convert_hash_to_answers(select_symbols(arg)) # call as Array
|
82
|
+
end
|
83
|
+
self
|
84
|
+
end
|
85
|
+
|
86
|
+
# Gets answer by indicator.
|
87
|
+
#
|
88
|
+
# @example
|
89
|
+
# answers = Answers.new [:abort, :overwrite]
|
90
|
+
# answers[:a].instruction #=> :abort
|
91
|
+
# answers[:o].instruction #=> :overwrite
|
92
|
+
#
|
93
|
+
# @return [Answer]
|
94
|
+
def [](indicator)
|
95
|
+
update_indicators_for_uniqueness!
|
96
|
+
select { |answer| answer.indicator == indicator }.first
|
97
|
+
end
|
98
|
+
|
99
|
+
# Updates indicators to get all unique.
|
100
|
+
#
|
101
|
+
# @example
|
102
|
+
# answers = Answers.new [:abort, :abort_all, :abc]
|
103
|
+
# answers.indicators #=> [:a, :A, :a]
|
104
|
+
# answers.has_unique_indicators? #=> false
|
105
|
+
# answers.update_indicators_for_uniqueness!
|
106
|
+
# answers.indicators #=> [:a, :A, :ab]
|
107
|
+
# answers.has_unique_indicators? #=> true
|
108
|
+
def update_indicators_for_uniqueness!
|
109
|
+
return if has_unique_indicators?
|
110
|
+
|
111
|
+
each_with_index do |answer, i|
|
112
|
+
other_indicators = first(i).map(&:indicator)
|
113
|
+
answer.indicator = free_indicator_of(answer, used_indicators: other_indicators)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Gets all indicators of answers.
|
118
|
+
#
|
119
|
+
# @example
|
120
|
+
# answers = Answers.new [:abort, :abort_all, :abc]
|
121
|
+
# answers.indicators #=> [:a, :A, :a]
|
122
|
+
# answers.update_indicators_for_uniqueness!
|
123
|
+
# answers.indicators #=> [:a, :A, :ab]
|
124
|
+
def indicators
|
125
|
+
map(&:indicator)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Returns true if indicators are unique, false otherwise.
|
129
|
+
#
|
130
|
+
# @example
|
131
|
+
# answers = Answers.new [:abort, :abort_all, :abc]
|
132
|
+
# answers.indicators #=> [:a, :A, :a]
|
133
|
+
# answers.has_unique_indicators? #=> false
|
134
|
+
# answers.update_indicators_for_uniqueness!
|
135
|
+
# answers.indicators #=> [:a, :A, :ab]
|
136
|
+
# answers.has_unique_indicators? #=> true
|
137
|
+
def has_unique_indicators?
|
138
|
+
indicators == indicators.uniq
|
139
|
+
end
|
140
|
+
|
141
|
+
# Returns all answers as choice string.
|
142
|
+
#
|
143
|
+
# @example with only true answers
|
144
|
+
# answers = Answers.new [:abort, :abort_all, :abc]
|
145
|
+
# answers.choice_string #=> "[a]bort, [A]bort all, [ab]c"
|
146
|
+
#
|
147
|
+
# @example with false answer
|
148
|
+
# answers = Answers.new {abort: true, abort_all: false, abc: true}
|
149
|
+
# answers.choice_string #=> "[a]bort, [ab]c"
|
150
|
+
def to_s
|
151
|
+
update_indicators_for_uniqueness!
|
152
|
+
map(&:to_s).compact.join(", ")
|
153
|
+
end
|
154
|
+
|
155
|
+
private
|
156
|
+
|
157
|
+
# {"abc" => true, abort: true, overwrite: false} => {abort: true}
|
158
|
+
def select_symbols(args)
|
159
|
+
args.select { |inst, value| inst.is_a?(Symbol) }
|
160
|
+
end
|
161
|
+
|
162
|
+
# {abort: true} => [Answer.new(:abort => true)]
|
163
|
+
def convert_hash_to_answers(answers)
|
164
|
+
answers.reduce([]) { |array, (inst, value)| array << Answer.new({inst => value}) }
|
165
|
+
end
|
166
|
+
|
167
|
+
# :symbol => Answer.new(:symbol)
|
168
|
+
# Answer.new(:symbol) => Answer.new(:symbol)
|
169
|
+
# "string" => raise ArgumentError
|
170
|
+
def convert_symbol_to_answer_or_send_through(arg)
|
171
|
+
case arg
|
172
|
+
when Answer then arg
|
173
|
+
when Symbol then Answer.new(arg)
|
174
|
+
else
|
175
|
+
raise ArgumentError
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# Gets first free indicator for `answer` which isn't used by `used_indicators`.
|
180
|
+
def free_indicator_of answer, opts={}
|
181
|
+
opts = {:used_indicators => []}.merge(opts)
|
182
|
+
used_indicators = opts[:used_indicators]
|
183
|
+
|
184
|
+
i = 1
|
185
|
+
loop do
|
186
|
+
indicator = answer.indicator(i)
|
187
|
+
if used_indicators.include? indicator
|
188
|
+
i+=1
|
189
|
+
redo # next try
|
190
|
+
else
|
191
|
+
return indicator
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Questions
|
4
|
+
# You can ask a question with answers for selection. User can select one answer.
|
5
|
+
#
|
6
|
+
# @example Long way
|
7
|
+
# q = Question.new("File does exist, what should be done?")
|
8
|
+
# q.answers = [:skip, :overwrite, :abort]
|
9
|
+
# answer = q.ask
|
10
|
+
# # SHELL:
|
11
|
+
# # $ File does exist, what should be done? [s]kip, [o]verwrite, [a]bort
|
12
|
+
# # s<enter>
|
13
|
+
# answer #=> :skip
|
14
|
+
#
|
15
|
+
# @example Short way
|
16
|
+
# answer = Question.ask "File does exist, what should be done?", [:skip, :overwrite, :abort]
|
17
|
+
# # SHELL:
|
18
|
+
# # $ File does exist, what should be done? [s]kip, [o]verwrite, [a]bort
|
19
|
+
# # s<enter>
|
20
|
+
# answer #=> :skip
|
21
|
+
#
|
22
|
+
# It's also possible to specify answers as an Hash:
|
23
|
+
#
|
24
|
+
# @example Hashish way
|
25
|
+
# answer = Question.ask "File does exist, what should be done?", skip: true, overwrite: false, abort: true
|
26
|
+
# # SHELL:
|
27
|
+
# # $ File does exist, what should be done? [s]kip, [a]bort
|
28
|
+
# # s<enter>
|
29
|
+
# answer #=> :skip
|
30
|
+
class Question
|
31
|
+
attr_reader :question
|
32
|
+
attr_reader :answers
|
33
|
+
|
34
|
+
# Instantiates a new Question object.
|
35
|
+
#
|
36
|
+
# @param question [String] This message will be printed
|
37
|
+
def initialize(question)
|
38
|
+
@question = question
|
39
|
+
@answers = Answers.new
|
40
|
+
end
|
41
|
+
|
42
|
+
# Sets answers
|
43
|
+
#
|
44
|
+
# @example
|
45
|
+
# q = Question.new("File does exist, what should be done?")
|
46
|
+
# q.answers = [:yes, :no]
|
47
|
+
# q.answers.size #=> 2
|
48
|
+
# q.answers.map(&:instruction) #=> [:yes, :no]
|
49
|
+
#
|
50
|
+
def answers=(*args)
|
51
|
+
@answers.clear
|
52
|
+
args.each { |arg| @answers << arg }
|
53
|
+
end
|
54
|
+
|
55
|
+
# Asks question to user. If user typed wrong indicator, then it will be asked again.
|
56
|
+
#
|
57
|
+
# @example without answers
|
58
|
+
# q = Question.new("What?")
|
59
|
+
# q.ask #=> raise Error
|
60
|
+
#
|
61
|
+
# @example with answers
|
62
|
+
# q = Question.new("What?")
|
63
|
+
# q.answers = [:yes, :no]
|
64
|
+
# q.ask #=> :yes if user typed 'y'
|
65
|
+
#
|
66
|
+
# @return [Symbol] selected answer
|
67
|
+
def ask
|
68
|
+
raise "You have to set answers" if answers.empty?
|
69
|
+
answer = gets "#{@question} #{answers}"
|
70
|
+
answers[answer.to_sym].instruction || ask
|
71
|
+
end
|
72
|
+
|
73
|
+
# Asks question.
|
74
|
+
#
|
75
|
+
# @param question [String] Message that will be printed
|
76
|
+
# @param answers [Array, Hash] Answers that are displayed for selection
|
77
|
+
#
|
78
|
+
# @example
|
79
|
+
# Question.ask("What are you doing?", [:nothing, :cleaning_up])
|
80
|
+
# # SHELL:
|
81
|
+
# # $ What are you doing? [n]othing, [c]leaning up
|
82
|
+
# # n<enter>
|
83
|
+
# # => :nothing
|
84
|
+
#
|
85
|
+
# @example Question with answers as hash.
|
86
|
+
# ask("Do you have a problem?", :yes => true, :no => true)
|
87
|
+
#
|
88
|
+
# @return [Symbol] selected answer
|
89
|
+
def self.ask(question, answers)
|
90
|
+
question = Question.new(question)
|
91
|
+
question.answers = answers
|
92
|
+
question.ask
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
# Prints `msg` and reads user input
|
98
|
+
def gets msg
|
99
|
+
STDOUT.print("#{msg} ")
|
100
|
+
STDOUT.flush
|
101
|
+
STDIN.gets.chomp
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
data/lib/questions.rb
ADDED
data/questions.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'questions/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "questions"
|
8
|
+
spec.version = Questions::VERSION
|
9
|
+
spec.authors = ["DSIW"]
|
10
|
+
spec.email = ["dsiw@dsiw-it.de"]
|
11
|
+
spec.description = %q{Ask human}
|
12
|
+
spec.summary = %q{Ask human}
|
13
|
+
spec.homepage = "https://github.com/DSIW/questions"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "version"
|
24
|
+
spec.add_development_dependency "rspec"
|
25
|
+
spec.add_development_dependency "simplecov"
|
26
|
+
spec.add_development_dependency "yard"
|
27
|
+
spec.add_development_dependency "pry"
|
28
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe :Answer do
|
6
|
+
shared_examples_for 'a true answer' do
|
7
|
+
its(:active?) { should be_true }
|
8
|
+
its(:inactive?) { should be_false }
|
9
|
+
its(:true?) { should be_true }
|
10
|
+
its(:false?) { should be_false }
|
11
|
+
its(:indicator) { should_not be_nil }
|
12
|
+
its(:instruction) { should_not == "" }
|
13
|
+
end
|
14
|
+
|
15
|
+
shared_examples_for 'a true normal answer' do
|
16
|
+
it_should_behave_like 'a true answer'
|
17
|
+
its(:instruction) { should == :overwrite }
|
18
|
+
its(:indicator_hash) { should == {:o => :overwrite} }
|
19
|
+
its(:to_s) { should == "[o]verwrite" }
|
20
|
+
its(:special?) { should be_false }
|
21
|
+
|
22
|
+
its(:indicator) { should == :o }
|
23
|
+
describe "indicator" do
|
24
|
+
it "#indicator(2) == :ov" do
|
25
|
+
subject.indicator(2) == :ov
|
26
|
+
end
|
27
|
+
it "#indicator(3) == :ove" do
|
28
|
+
subject.indicator(3) == :ove
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
shared_examples_for 'a true special answer' do
|
34
|
+
it_should_behave_like 'a true answer'
|
35
|
+
its(:instruction) { should == :overwrite_all }
|
36
|
+
its(:indicator_hash) { should == {:O => :overwrite_all} }
|
37
|
+
its(:to_s) { should == "[O]verwrite all" }
|
38
|
+
its(:special?) { should be_true }
|
39
|
+
|
40
|
+
its(:indicator) { should == :O }
|
41
|
+
describe "indicator" do
|
42
|
+
it "#indicator(2) == :OV" do
|
43
|
+
subject.indicator(2) == :OV
|
44
|
+
end
|
45
|
+
it "#indicator(3) == :OVE" do
|
46
|
+
subject.indicator(3) == :OVE
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
shared_examples_for 'a false answer' do
|
52
|
+
its(:active?) { should be_false }
|
53
|
+
its(:inactive?) { should be_true }
|
54
|
+
its(:true?) { should be_false }
|
55
|
+
its(:false?) { should be_true }
|
56
|
+
its(:indicator) { should be_nil }
|
57
|
+
its(:instruction) { should == :overwrite }
|
58
|
+
its(:indicator_hash) { should be_nil }
|
59
|
+
its(:to_s) { should == nil }
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#initialize" do
|
63
|
+
# true normal
|
64
|
+
context "with true as value" do
|
65
|
+
context "with braces" do
|
66
|
+
subject { Answer.new({:overwrite => true}) }
|
67
|
+
it_should_behave_like 'a true normal answer'
|
68
|
+
end
|
69
|
+
context "without braces" do
|
70
|
+
subject { Answer.new(:overwrite => true) }
|
71
|
+
it_should_behave_like 'a true normal answer'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
context "as symbol" do
|
75
|
+
subject { Answer.new(:overwrite) }
|
76
|
+
it_should_behave_like 'a true normal answer'
|
77
|
+
end
|
78
|
+
|
79
|
+
# true special
|
80
|
+
context "with true as value" do
|
81
|
+
context "with braces" do
|
82
|
+
subject { Answer.new({:overwrite_all => true}) }
|
83
|
+
it_should_behave_like 'a true special answer'
|
84
|
+
end
|
85
|
+
context "without braces" do
|
86
|
+
subject { Answer.new(:overwrite_all => true) }
|
87
|
+
it_should_behave_like 'a true special answer'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
context "as symbol" do
|
91
|
+
subject { Answer.new(:overwrite_all) }
|
92
|
+
it_should_behave_like 'a true special answer'
|
93
|
+
end
|
94
|
+
|
95
|
+
# false
|
96
|
+
context "with false as value" do
|
97
|
+
context "with braces" do
|
98
|
+
subject { Answer.new({:overwrite => false}) }
|
99
|
+
it_should_behave_like 'a false answer'
|
100
|
+
end
|
101
|
+
context "without braces" do
|
102
|
+
subject { Answer.new(:overwrite => false) }
|
103
|
+
it_should_behave_like 'a false answer'
|
104
|
+
end
|
105
|
+
end
|
106
|
+
context "with nil as value" do
|
107
|
+
subject { Answer.new(:overwrite => nil) }
|
108
|
+
it_should_behave_like 'a false answer'
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "#indicator=" do
|
113
|
+
subject { Answer.new(:overwrite) }
|
114
|
+
its(:indicator) { should == :o }
|
115
|
+
it "should set indicator" do
|
116
|
+
subject.indicator = :ov
|
117
|
+
subject.indicator.should == :ov
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,255 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Answers do
|
6
|
+
let(:overwrite) { Answer.new(:overwrite) }
|
7
|
+
let(:no_overwrite) { Answer.new(:overwrite => false) }
|
8
|
+
|
9
|
+
let(:abort) { Answer.new(:abort) }
|
10
|
+
let(:no_abort) { Answer.new(:abort => false) }
|
11
|
+
|
12
|
+
let(:answers_array) { [overwrite, abort] }
|
13
|
+
let(:answers_array_with_false) { [overwrite, no_abort] }
|
14
|
+
|
15
|
+
let(:answers_hash) { {overwrite: true, abort: true} }
|
16
|
+
let(:answers_hash_with_false) { {overwrite: true, abort: false} }
|
17
|
+
|
18
|
+
shared_examples_for "one answer" do
|
19
|
+
its(:size) { should == 1 }
|
20
|
+
its(:first) { should == abort }
|
21
|
+
end
|
22
|
+
|
23
|
+
shared_examples_for "one symbol" do
|
24
|
+
its(:size) { should == 1 }
|
25
|
+
its(:first) { should be_kind_of Answer }
|
26
|
+
its("first.instruction") { should == :abort }
|
27
|
+
end
|
28
|
+
|
29
|
+
shared_examples_for "two answers" do
|
30
|
+
its(:size) { should == 2 }
|
31
|
+
it "each answer should be kind of Answer" do
|
32
|
+
subject.all? { |answer| answer.kind_of? Answer }
|
33
|
+
end
|
34
|
+
its("first.instruction") { should == :overwrite }
|
35
|
+
its("last.instruction") { should == :abort }
|
36
|
+
end
|
37
|
+
|
38
|
+
shared_examples_for "hash with two true items" do
|
39
|
+
its(:size) { should == 2 }
|
40
|
+
it "each answer should be kind of Answer" do
|
41
|
+
subject.all? { |answer| answer.kind_of? Answer }
|
42
|
+
end
|
43
|
+
it "should be :overwrite and :abort" do
|
44
|
+
subject.map(&:instruction).should == [:overwrite, :abort]
|
45
|
+
end
|
46
|
+
it "each answer should be true" do
|
47
|
+
subject.map(&:true?).should == [true, true]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
shared_examples_for "hash with one true and one false item" do
|
52
|
+
its(:size) { should == 2 }
|
53
|
+
it "each answer should be kind of Answer" do
|
54
|
+
subject.all? { |answer| answer.kind_of? Answer }
|
55
|
+
end
|
56
|
+
it "should be :overwrite and :abort" do
|
57
|
+
subject.map(&:instruction).should == [:overwrite, :abort]
|
58
|
+
end
|
59
|
+
it "should be true and false" do
|
60
|
+
subject.map(&:true?).should == [true, false]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#init" do
|
65
|
+
context "when parameter is Answer" do
|
66
|
+
subject { Answers.new(abort) }
|
67
|
+
include_examples "one answer"
|
68
|
+
end
|
69
|
+
context "when parameter is Symbol" do
|
70
|
+
subject { Answers.new(:abort) }
|
71
|
+
include_examples "one symbol"
|
72
|
+
end
|
73
|
+
|
74
|
+
context "when parameter is array" do
|
75
|
+
subject { Answers.new(answers_array) }
|
76
|
+
include_examples "two answers"
|
77
|
+
end
|
78
|
+
context "when parameter is array filled with symbols" do
|
79
|
+
subject { Answers.new([:overwrite, :abort]) }
|
80
|
+
include_examples "two answers"
|
81
|
+
end
|
82
|
+
context "mixed array filled with symbols and answers" do
|
83
|
+
subject { Answers.new([:overwrite, abort]) }
|
84
|
+
include_examples "two answers"
|
85
|
+
end
|
86
|
+
|
87
|
+
context "when parameter is Hash with true values" do
|
88
|
+
subject { Answers.new(answers_hash) }
|
89
|
+
include_examples "hash with two true items"
|
90
|
+
end
|
91
|
+
context "when parameter is Hash with value false" do
|
92
|
+
subject { Answers.new(answers_hash_with_false) }
|
93
|
+
include_examples "hash with one true and one false item"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "#<<" do
|
98
|
+
subject { Answers.new }
|
99
|
+
|
100
|
+
context "when parameter is Answer" do
|
101
|
+
before { subject << abort }
|
102
|
+
include_examples "one answer"
|
103
|
+
end
|
104
|
+
context "when parameters are Answers with chaining" do
|
105
|
+
before { subject << overwrite << abort }
|
106
|
+
include_examples "two answers"
|
107
|
+
end
|
108
|
+
context "when parameter is Symbol" do
|
109
|
+
before { subject << :abort }
|
110
|
+
include_examples "one symbol"
|
111
|
+
end
|
112
|
+
|
113
|
+
context "when parameter is array" do
|
114
|
+
before { subject << answers_array }
|
115
|
+
include_examples "two answers"
|
116
|
+
end
|
117
|
+
context "when parameter is array filled with symbols" do
|
118
|
+
before { subject << [:overwrite, :abort] }
|
119
|
+
include_examples "two answers"
|
120
|
+
end
|
121
|
+
context "mixed array filled with symbols and answers" do
|
122
|
+
before { subject << [:overwrite, abort] }
|
123
|
+
include_examples "two answers"
|
124
|
+
end
|
125
|
+
|
126
|
+
context "when parameter is Hash with true values" do
|
127
|
+
before { subject << answers_hash }
|
128
|
+
include_examples "hash with two true items"
|
129
|
+
end
|
130
|
+
context "when parameter is Hash with value false" do
|
131
|
+
before { subject << answers_hash_with_false }
|
132
|
+
include_examples "hash with one true and one false item"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "#update_indicators_for_uniqueness!" do
|
137
|
+
before { subject << [:abort, :abort_all, :abc] }
|
138
|
+
before { subject.send(:update_indicators_for_uniqueness!) }
|
139
|
+
let(:indicators) { subject.map(&:indicator) }
|
140
|
+
it "indicators should == [:a, :A, :ab]" do
|
141
|
+
indicators.should == [:a, :A, :ab]
|
142
|
+
end
|
143
|
+
it "indicators should only exist unique answers" do
|
144
|
+
indicators.should == indicators.uniq
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "#[]" do
|
149
|
+
before { subject << [:abort, :abort_all, :abc] }
|
150
|
+
it "should select answer by indicator" do
|
151
|
+
subject[:a].indicator.should == :a
|
152
|
+
subject[:a].instruction.should == :abort
|
153
|
+
|
154
|
+
subject[:A].indicator.should == :A
|
155
|
+
subject[:A].instruction.should == :abort_all
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe "#have_unique_indicators?" do
|
160
|
+
before { subject << [:abort, :abort_all, :abc] }
|
161
|
+
it { should_not have_unique_indicators }
|
162
|
+
context "after updating indicators for uniqueness" do
|
163
|
+
before { subject.update_indicators_for_uniqueness! }
|
164
|
+
it { should have_unique_indicators }
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe "#indicators" do
|
169
|
+
before { subject << [:abort, :abort_all, :abc] }
|
170
|
+
its(:indicators) { should == [:a, :A, :a] }
|
171
|
+
context "after updating indicators for uniqueness" do
|
172
|
+
before { subject.update_indicators_for_uniqueness! }
|
173
|
+
its(:indicators) { should == [:a, :A, :ab] }
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "#to_s" do
|
178
|
+
context "all true" do
|
179
|
+
before { subject << [:abort, :abort_all, :abc] }
|
180
|
+
its(:to_s) { should == "[a]bort, [A]bort all, [ab]c" }
|
181
|
+
end
|
182
|
+
context "with false value" do
|
183
|
+
before { subject << {abort: true, abort_all: false, abc: true} }
|
184
|
+
its(:to_s) { should == "[a]bort, [ab]c" }
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe "Private:" do
|
189
|
+
describe "#select_symbols" do
|
190
|
+
let(:hash) { {"abc" => true, abort: true, overwrite: false} }
|
191
|
+
it "should return {abort: true, overwrite: false}" do
|
192
|
+
subject.send(:select_symbols, hash).should == { abort: true, overwrite: false }
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe "#convert_hash_to_answers" do
|
197
|
+
let(:hash) { {abort: true, overwrite: false} }
|
198
|
+
subject do
|
199
|
+
Answers.new.send(:convert_hash_to_answers, hash)
|
200
|
+
end
|
201
|
+
it "each entry should be kind of Answer" do
|
202
|
+
subject.all? { |answer| answer.kind_of? Answer }
|
203
|
+
end
|
204
|
+
its("first.instruction") { should == :abort }
|
205
|
+
its("first.true?") { should be_true }
|
206
|
+
its("last.instruction") { should == :overwrite }
|
207
|
+
its("last.true?") { should be_false }
|
208
|
+
end
|
209
|
+
|
210
|
+
describe "#convert_symbol_to_answer_or_send_through" do
|
211
|
+
subject do
|
212
|
+
Answers.new.send(:convert_symbol_to_answer_or_send_through, parameter)
|
213
|
+
end
|
214
|
+
context "when parameter is a Symbol" do
|
215
|
+
let(:parameter) { :abort }
|
216
|
+
it { should be_kind_of Answer }
|
217
|
+
its(:instruction) { should == :abort }
|
218
|
+
end
|
219
|
+
context "when parameter is an answer" do
|
220
|
+
let(:parameter) { abort }
|
221
|
+
it { should == abort }
|
222
|
+
end
|
223
|
+
context "when parameter is an other object" do
|
224
|
+
let(:parameter) { "string" }
|
225
|
+
it "should raise an ArgumentError" do
|
226
|
+
expect { subject }.to raise_error ArgumentError
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe "#free_indicator_of" do
|
232
|
+
context ":abc" do
|
233
|
+
it "should return :a if it isn't already used" do
|
234
|
+
subject.send(:free_indicator_of, abort, :used_indicators => [:b]).should == :a
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should return :a if :used_indicators is empty" do
|
238
|
+
subject.send(:free_indicator_of, abort, :used_indicators => []).should == :a
|
239
|
+
end
|
240
|
+
|
241
|
+
it "should return :a if no :used_indicators is set" do
|
242
|
+
subject.send(:free_indicator_of, abort).should == :a
|
243
|
+
end
|
244
|
+
|
245
|
+
it "should reuturn :ab if :a is used" do
|
246
|
+
subject.send(:free_indicator_of, abort, :used_indicators => [:a]).should == :ab
|
247
|
+
end
|
248
|
+
|
249
|
+
it "should return :ab if :a and :A is used" do
|
250
|
+
subject.send(:free_indicator_of, abort, :used_indicators => [:a, :A]).should == :ab
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Question do
|
6
|
+
let(:answers_array) { [Answer.new(:overwrite), Answer.new(:abort)] }
|
7
|
+
|
8
|
+
let(:question_msg) { "What to do?" }
|
9
|
+
let(:question) { Question.new(question_msg) }
|
10
|
+
subject { question }
|
11
|
+
|
12
|
+
describe "#init" do
|
13
|
+
its(:answers) { should be_kind_of Answers }
|
14
|
+
its("answers.size") { should == 0 }
|
15
|
+
its(:question) { should == question_msg }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#answers=" do
|
19
|
+
before { subject.answers = [:abort, :overwrite] }
|
20
|
+
its(:answers) { should be_kind_of Answers }
|
21
|
+
its("answers.size") { should == 2 }
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#ask" do
|
25
|
+
it "should raise an error without answers" do
|
26
|
+
expect { subject.ask }.to raise_error /have to set answers/
|
27
|
+
end
|
28
|
+
|
29
|
+
context "with answers" do
|
30
|
+
before { subject.answers = answers_array }
|
31
|
+
before do
|
32
|
+
subject.should_receive(:gets).with("#{question_msg} [o]verwrite, [a]bort").and_return("o")
|
33
|
+
end
|
34
|
+
its(:ask) { should == :overwrite }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "::ask" do
|
39
|
+
context "with answers as array" do
|
40
|
+
subject { Question.ask(question_msg, [:all, :nothing]) }
|
41
|
+
before do
|
42
|
+
Question.any_instance.should_receive(:gets).with("#{question_msg} [A]ll, [n]othing").and_return("A")
|
43
|
+
end
|
44
|
+
it { should == :all }
|
45
|
+
end
|
46
|
+
context "with answers as hash" do
|
47
|
+
subject { Question.ask(question_msg, all: true, nothing: true) }
|
48
|
+
before do
|
49
|
+
Question.any_instance.should_receive(:gets).with("#{question_msg} [A]ll, [n]othing").and_return("A")
|
50
|
+
end
|
51
|
+
it { should == :all }
|
52
|
+
end
|
53
|
+
context "with answers as hash with false value" do
|
54
|
+
subject { Question.ask(question_msg, all: true, not: false, nothing: true) }
|
55
|
+
before do
|
56
|
+
Question.any_instance.should_receive(:gets).with("#{question_msg} [A]ll, [n]othing").and_return("A")
|
57
|
+
end
|
58
|
+
it { should == :all }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "Privates:" do
|
63
|
+
describe "#gets" do
|
64
|
+
before do
|
65
|
+
STDOUT.should_receive(:print).with(question_msg + " ")
|
66
|
+
STDOUT.should_receive(:flush)
|
67
|
+
STDIN.should_receive(:gets).and_return("y\n")
|
68
|
+
end
|
69
|
+
it { subject.send(:gets, question_msg).should == "y" }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'questions'
|
3
|
+
|
4
|
+
RSpec.configure do |config|
|
5
|
+
include Questions
|
6
|
+
|
7
|
+
config.mock_with :rspec
|
8
|
+
|
9
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
10
|
+
config.filter_run :focus => true
|
11
|
+
config.run_all_when_everything_filtered = true
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: questions
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- DSIW
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-03-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: version
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
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'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: Ask human
|
112
|
+
email:
|
113
|
+
- dsiw@dsiw-it.de
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- .gitignore
|
119
|
+
- .rspec
|
120
|
+
- Gemfile
|
121
|
+
- LICENSE.txt
|
122
|
+
- README.md
|
123
|
+
- Rakefile
|
124
|
+
- VERSION
|
125
|
+
- lib/questions.rb
|
126
|
+
- lib/questions/answer.rb
|
127
|
+
- lib/questions/answers.rb
|
128
|
+
- lib/questions/question.rb
|
129
|
+
- lib/questions/version.rb
|
130
|
+
- questions.gemspec
|
131
|
+
- spec/questions/answer_spec.rb
|
132
|
+
- spec/questions/answers_spec.rb
|
133
|
+
- spec/questions/question_spec.rb
|
134
|
+
- spec/spec_helper.rb
|
135
|
+
homepage: https://github.com/DSIW/questions
|
136
|
+
licenses:
|
137
|
+
- MIT
|
138
|
+
metadata: {}
|
139
|
+
post_install_message:
|
140
|
+
rdoc_options: []
|
141
|
+
require_paths:
|
142
|
+
- lib
|
143
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
144
|
+
requirements:
|
145
|
+
- - '>='
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '0'
|
148
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
requirements: []
|
154
|
+
rubyforge_project:
|
155
|
+
rubygems_version: 2.0.0
|
156
|
+
signing_key:
|
157
|
+
specification_version: 4
|
158
|
+
summary: Ask human
|
159
|
+
test_files:
|
160
|
+
- spec/questions/answer_spec.rb
|
161
|
+
- spec/questions/answers_spec.rb
|
162
|
+
- spec/questions/question_spec.rb
|
163
|
+
- spec/spec_helper.rb
|
164
|
+
has_rdoc:
|