user_input 1.0.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.
- data/.document +5 -0
- data/.gitignore +22 -0
- data/LICENSE +20 -0
- data/README.rdoc +61 -0
- data/Rakefile +45 -0
- data/VERSION +1 -0
- data/lib/user_input/option_parser.rb +213 -0
- data/lib/user_input/type_safe_hash.rb +134 -0
- data/lib/user_input.rb +246 -0
- data/spec/option_parser_spec.rb +158 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/type_safe_hash_spec.rb +123 -0
- data/spec/user_input_spec.rb +284 -0
- metadata +81 -0
@@ -0,0 +1,284 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require 'lib/user_input'
|
3
|
+
require 'ipaddr'
|
4
|
+
require 'date'
|
5
|
+
require 'set'
|
6
|
+
|
7
|
+
describe "UserInput" do
|
8
|
+
describe String do
|
9
|
+
it "Should accept anything that can have to_s called on the class method" do
|
10
|
+
String.from_user_input("OMGWTFBBQ").should == "OMGWTFBBQ"
|
11
|
+
String.from_user_input(1).should == "1"
|
12
|
+
end
|
13
|
+
it "Should accept only equal strings (or things that can be to_s'd to an equal string) on the instance method" do
|
14
|
+
"OMGWTFBBQ".from_user_input("OMGWTFBBQ").should == "OMGWTFBBQ"
|
15
|
+
"OMGWTFBBQ".from_user_input("wat").should be_nil
|
16
|
+
"1".from_user_input(1).should == "1"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe Boolean do
|
21
|
+
it "Should accept true/false as boolean" do
|
22
|
+
Boolean.from_user_input(true).should == true
|
23
|
+
Boolean.from_user_input(false).should == false
|
24
|
+
end
|
25
|
+
it "Should accept various strings (true, false, on, off, y, n, enabled, disabled) as boolean values" do
|
26
|
+
Boolean.from_user_input("true").should == true
|
27
|
+
Boolean.from_user_input("on").should == true
|
28
|
+
Boolean.from_user_input("y").should == true
|
29
|
+
Boolean.from_user_input("enabled").should == true
|
30
|
+
|
31
|
+
Boolean.from_user_input("false").should == false
|
32
|
+
Boolean.from_user_input("off").should == false
|
33
|
+
Boolean.from_user_input("n").should == false
|
34
|
+
Boolean.from_user_input("disabled").should == false
|
35
|
+
end
|
36
|
+
it "Should generally not accept anything else as a boolean value" do
|
37
|
+
Boolean.from_user_input(12321).should be_nil
|
38
|
+
Boolean.from_user_input("fkjdjaslfs").should be_nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe TrueClass do
|
43
|
+
it "Should accept true as itself" do
|
44
|
+
true.from_user_input(true).should == true
|
45
|
+
end
|
46
|
+
it "Should accept various strings (true, on, y, enabled) as true" do
|
47
|
+
true.from_user_input("true").should == true
|
48
|
+
true.from_user_input("on").should == true
|
49
|
+
true.from_user_input("y").should == true
|
50
|
+
true.from_user_input("enabled").should == true
|
51
|
+
end
|
52
|
+
it "Should generally not accept anything else as true" do
|
53
|
+
true.from_user_input(3423).should be_nil
|
54
|
+
true.from_user_input("fkjdjaslfs").should be_nil
|
55
|
+
true.from_user_input(false).should be_nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe FalseClass do
|
60
|
+
it "Should accept false as itself" do
|
61
|
+
false.from_user_input(false).should == false
|
62
|
+
end
|
63
|
+
it "Should accept various strings (false, off, n, disabled) as false" do
|
64
|
+
false.from_user_input("false").should == false
|
65
|
+
false.from_user_input("off").should == false
|
66
|
+
false.from_user_input("n").should == false
|
67
|
+
false.from_user_input("disabled").should == false
|
68
|
+
end
|
69
|
+
it "Should generally not accept anything else as false" do
|
70
|
+
false.from_user_input(3423).should be_nil
|
71
|
+
false.from_user_input("fkjdjaslfs").should be_nil
|
72
|
+
false.from_user_input(true).should be_nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe Date do
|
77
|
+
it "Should accept a Date object as a date object" do
|
78
|
+
Date.parse("January 20th, 2004").should_not be_nil
|
79
|
+
Date.from_user_input(Date.parse("January 20th, 2004")).should == Date.parse("January 20th, 2004")
|
80
|
+
end
|
81
|
+
it "Should accept a string that Date.parse would accept as a date object" do
|
82
|
+
Date.from_user_input("January 20th, 2004").should == Date.parse("January 20th, 2004")
|
83
|
+
end
|
84
|
+
it "Should not accept other strings as date objects." do
|
85
|
+
Date.from_user_input("dfjskjfdsf").should be_nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe Integer do
|
90
|
+
it "Should take an integer object as an integer" do
|
91
|
+
Integer.from_user_input(1).should == 1
|
92
|
+
end
|
93
|
+
it "Should take a string with an acceptable format (including leading and trailing whitespace) as an integer object" do
|
94
|
+
Integer.from_user_input("1").should == 1
|
95
|
+
Integer.from_user_input(" 124342").should == 124342
|
96
|
+
Integer.from_user_input(" 4234 ").should == 4234
|
97
|
+
end
|
98
|
+
it "Should not accept other strings or objects as integers" do
|
99
|
+
Integer.from_user_input("boom!").should be_nil
|
100
|
+
Integer.from_user_input("1.223").should be_nil
|
101
|
+
Integer.from_user_input(1.234).should be_nil
|
102
|
+
end
|
103
|
+
it "Should accept an equal integer object or string on the instance method" do
|
104
|
+
1.from_user_input(1).should == 1
|
105
|
+
1.from_user_input("1").should == 1
|
106
|
+
end
|
107
|
+
it "Should not accept other numbers, strings, or values on the instance method" do
|
108
|
+
1.from_user_input(324).should be_nil
|
109
|
+
1.from_user_input("boom!").should be_nil
|
110
|
+
1.from_user_input("123").should be_nil
|
111
|
+
1.from_user_input(1.23).should be_nil
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe Float do
|
116
|
+
it "Should take a Float or Integer object as an float" do
|
117
|
+
Float.from_user_input(1.23).should == 1.23
|
118
|
+
Float.from_user_input(1).should == 1.0
|
119
|
+
end
|
120
|
+
it "Should take a string with an acceptable format (including leading and trailing whitespace) as an float object" do
|
121
|
+
Float.from_user_input("1.32").should == 1.32
|
122
|
+
Float.from_user_input(" 1243.42").should == 1243.42
|
123
|
+
Float.from_user_input(" 42.34 ").should == 42.34
|
124
|
+
Float.from_user_input("1").should == 1.0
|
125
|
+
end
|
126
|
+
it "Should not accept other strings or objects as floats" do
|
127
|
+
Float.from_user_input("boom!").should be_nil
|
128
|
+
end
|
129
|
+
it "Should accept an equal float object or string on the instance method" do
|
130
|
+
(1.23).from_user_input(1.23).should == 1.23
|
131
|
+
(1.23).from_user_input("1.23").should == 1.23
|
132
|
+
end
|
133
|
+
it "Should not accept other numbers, strings, or values on the instance method" do
|
134
|
+
(1.23).from_user_input(324.34).should be_nil
|
135
|
+
(1.23).from_user_input("boom!").should be_nil
|
136
|
+
(1.23).from_user_input("123").should be_nil
|
137
|
+
(1.23).from_user_input(1).should be_nil
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe Regexp do
|
142
|
+
it "Should accept a matching regex and return the match object" do
|
143
|
+
/abba/.from_user_input("yabbadabbadoo").should be_kind_of(MatchData)
|
144
|
+
end
|
145
|
+
it "Should not accept a non-matching regex and return nil" do
|
146
|
+
/abba/.from_user_input("boom").should be_nil
|
147
|
+
end
|
148
|
+
it "Should not accept non-strings" do
|
149
|
+
/abba/.from_user_input(1).should be_nil
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe Range do
|
154
|
+
it "Should accept any value within the given range, but none outside" do
|
155
|
+
(1..5).from_user_input(1).should == 1
|
156
|
+
(1..5).from_user_input(50).should be_nil
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe Array do
|
161
|
+
it "Should always turn the input into an array if it isn't already" do
|
162
|
+
Array.from_user_input(1).should == [1]
|
163
|
+
Array.from_user_input([1]).should == [1]
|
164
|
+
[Integer].from_user_input(1).should == [1]
|
165
|
+
end
|
166
|
+
it "Should raise an ArgumentError if you try to use it on an incorrect array instance" do
|
167
|
+
proc {
|
168
|
+
[].from_user_input([1])
|
169
|
+
}.should raise_error(ArgumentError)
|
170
|
+
proc {
|
171
|
+
[1,2,3].from_user_input([1])
|
172
|
+
}.should raise_error(ArgumentError)
|
173
|
+
end
|
174
|
+
it "Should flatten an inner array to a value if the type specified isn't an array" do
|
175
|
+
[Integer].from_user_input([[1,2,3]]).should == [1]
|
176
|
+
end
|
177
|
+
it "Should do a recursive check on the input based on the type of the first element in the instance method" do
|
178
|
+
[Integer].from_user_input([1, 2, 3]).should == [1, 2, 3]
|
179
|
+
[Integer].from_user_input([1, 2, 3, "blah"]).should == [1, 2, 3]
|
180
|
+
[[Integer]].from_user_input([[1,2,3],[4,5,6]]).should == [[1,2,3],[4,5,6]]
|
181
|
+
[[Integer]].from_user_input([[1,2,3],4]).should == [[1,2,3],[4]] # this behaviour is questionable, but follows from useful behaviour in the first Array spec.
|
182
|
+
[[Integer]].from_user_input([[1,2,3],"boom"]).should == [[1,2,3]]
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe Hash do
|
187
|
+
it "Should raise an ArgumentError if you try to use it on an incorrect hash instance" do
|
188
|
+
proc {
|
189
|
+
{}.from_user_input({})
|
190
|
+
}.should raise_error(ArgumentError)
|
191
|
+
proc {
|
192
|
+
{:x=>:y, :z=>:a}.from_user_input({})
|
193
|
+
}.should raise_error(ArgumentError)
|
194
|
+
end
|
195
|
+
it "Should return nil for a non-hash" do
|
196
|
+
{1 => 2}.from_user_input(1).should be_nil
|
197
|
+
end
|
198
|
+
it "Should return nil for an empty hash, or a hash with no compatible values" do
|
199
|
+
{1 => 2}.from_user_input({}).should be_nil
|
200
|
+
{1 => 2}.from_user_input({2=>1}).should be_nil
|
201
|
+
end
|
202
|
+
it "Should do a recursive check on the key/value pair passed in." do
|
203
|
+
{String=>1}.from_user_input({"blah"=>1, "blorp"=>2}).should == {"blah"=>1}
|
204
|
+
{String=>{Integer=>String}}.from_user_input({"boom"=>{1=>"stuff"}, "floom"=>"wat"}).should == {"boom"=>{1=>"stuff"}}
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
describe Set do
|
209
|
+
before :each do
|
210
|
+
@set = Set["a", "b", 1, "23.4", 34.2]
|
211
|
+
end
|
212
|
+
it "Should return an item if it can be validated as being in the Set" do
|
213
|
+
@set.from_user_input("a").should == "a"
|
214
|
+
@set.from_user_input(1).should == 1
|
215
|
+
@set.from_user_input(23.4).should == "23.4"
|
216
|
+
@set.from_user_input("34.2").should == 34.2
|
217
|
+
end
|
218
|
+
it "Should return nil if it isn't compatible with any member of the Set" do
|
219
|
+
@set.from_user_input("c").should be_nil
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
describe Symbol do
|
224
|
+
it "Should raise an error if you try to take user input as a symbol, because that's dumb" do
|
225
|
+
proc {
|
226
|
+
Symbol.from_user_input(:BOOM)
|
227
|
+
}.should raise_error(ArgumentError)
|
228
|
+
end
|
229
|
+
|
230
|
+
it "Should return the symbol if both can be converted to the same string, nil otherwise" do
|
231
|
+
:blah.from_user_input("blah").should == :blah
|
232
|
+
:blah.from_user_input(:blah).should == :blah
|
233
|
+
:blah.from_user_input("boom").should be_nil
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
describe IPAddr do
|
238
|
+
it "Should return the object if it's already an IPAddr" do
|
239
|
+
IPAddr.from_user_input(IPAddr.new("127.0.0.1")).should == IPAddr.new("127.0.0.1")
|
240
|
+
end
|
241
|
+
it "Should return an IPAddr object if the string given it is a valid ip address." do
|
242
|
+
IPAddr.from_user_input("127.0.0.1").should == IPAddr.new("127.0.0.1")
|
243
|
+
IPAddr.from_user_input("::d234").should == IPAddr.new("::d234")
|
244
|
+
end
|
245
|
+
it "Should return nil for a string that can't convert into an IPAddr" do
|
246
|
+
IPAddr.from_user_input("boom").should be_nil
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
class TestClass
|
251
|
+
attr :v
|
252
|
+
def initialize(v = 0)
|
253
|
+
@v = v
|
254
|
+
end
|
255
|
+
def ==(o)
|
256
|
+
v == o.v
|
257
|
+
end
|
258
|
+
end
|
259
|
+
class DerivedTestClass < TestClass
|
260
|
+
end
|
261
|
+
|
262
|
+
describe Class do
|
263
|
+
it "Should treat itself or a derived class as acceptable" do
|
264
|
+
TestClass.from_user_input(TestClass).should == TestClass
|
265
|
+
TestClass.from_user_input(DerivedTestClass).should == DerivedTestClass
|
266
|
+
TestClass.from_user_input(String).should be_nil
|
267
|
+
end
|
268
|
+
|
269
|
+
it "Should pass through an instance of an arbitrary class given if the instance is of the same class" do
|
270
|
+
tci = TestClass.new
|
271
|
+
dtci = DerivedTestClass.new
|
272
|
+
TestClass.from_user_input(tci).should == tci
|
273
|
+
TestClass.from_user_input(dtci).should == dtci
|
274
|
+
TestClass.from_user_input("").should be_nil
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
describe Object do
|
279
|
+
it "Should treat an arbitrary object (that doesn't have a more detailed implementation above) as the same if they test equal" do
|
280
|
+
TestClass.new(1).from_user_input(TestClass.new(1)).should == TestClass.new(1)
|
281
|
+
TestClass.new(1).from_user_input(TestClass.new(2)).should be_nil
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: user_input
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Graham Batty
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-02-04 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.2.9
|
24
|
+
version:
|
25
|
+
description: Provides simple, convention-based, user input validation and coercion. Also provides a 'type safe hash' and command line option parser that use it.
|
26
|
+
email: graham@stormbrew.ca
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- LICENSE
|
33
|
+
- README.rdoc
|
34
|
+
files:
|
35
|
+
- .document
|
36
|
+
- .gitignore
|
37
|
+
- LICENSE
|
38
|
+
- README.rdoc
|
39
|
+
- Rakefile
|
40
|
+
- VERSION
|
41
|
+
- lib/user_input.rb
|
42
|
+
- lib/user_input/option_parser.rb
|
43
|
+
- lib/user_input/type_safe_hash.rb
|
44
|
+
- spec/option_parser_spec.rb
|
45
|
+
- spec/spec.opts
|
46
|
+
- spec/spec_helper.rb
|
47
|
+
- spec/type_safe_hash_spec.rb
|
48
|
+
- spec/user_input_spec.rb
|
49
|
+
has_rdoc: true
|
50
|
+
homepage: http://github.com/stormbrew/user_input
|
51
|
+
licenses: []
|
52
|
+
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options:
|
55
|
+
- --charset=UTF-8
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
requirements: []
|
71
|
+
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 1.3.5
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: Provides simple, convention-based, user input validation and coercion. Also provides a 'type safe hash' and command line option parser that use it.
|
77
|
+
test_files:
|
78
|
+
- spec/option_parser_spec.rb
|
79
|
+
- spec/spec_helper.rb
|
80
|
+
- spec/type_safe_hash_spec.rb
|
81
|
+
- spec/user_input_spec.rb
|