form_input 0.9.0.pre1

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.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/LICENSE +19 -0
  4. data/README.md +3160 -0
  5. data/Rakefile +19 -0
  6. data/example/controllers/ramaze/press_release.rb +104 -0
  7. data/example/controllers/ramaze/profile.rb +38 -0
  8. data/example/controllers/sinatra/press_release.rb +114 -0
  9. data/example/controllers/sinatra/profile.rb +39 -0
  10. data/example/forms/change_password_form.rb +17 -0
  11. data/example/forms/login_form.rb +14 -0
  12. data/example/forms/lost_password_form.rb +14 -0
  13. data/example/forms/new_password_form.rb +15 -0
  14. data/example/forms/password_form.rb +18 -0
  15. data/example/forms/press_release_form.rb +153 -0
  16. data/example/forms/profile_form.rb +21 -0
  17. data/example/forms/signup_form.rb +25 -0
  18. data/example/views/press_release.slim +65 -0
  19. data/example/views/profile.slim +28 -0
  20. data/example/views/snippets/form_block.slim +27 -0
  21. data/example/views/snippets/form_chunked.slim +25 -0
  22. data/example/views/snippets/form_hidden.slim +21 -0
  23. data/example/views/snippets/form_panel.slim +89 -0
  24. data/form_input.gemspec +32 -0
  25. data/lib/form_input/core.rb +1165 -0
  26. data/lib/form_input/localize.rb +49 -0
  27. data/lib/form_input/r18n/cs.yml +97 -0
  28. data/lib/form_input/r18n/en.yml +70 -0
  29. data/lib/form_input/r18n/pl.yml +122 -0
  30. data/lib/form_input/r18n/sk.yml +120 -0
  31. data/lib/form_input/r18n.rb +163 -0
  32. data/lib/form_input/steps.rb +365 -0
  33. data/lib/form_input/types.rb +176 -0
  34. data/lib/form_input/version.rb +12 -0
  35. data/lib/form_input.rb +5 -0
  36. data/test/helper.rb +21 -0
  37. data/test/localize/en.yml +63 -0
  38. data/test/r18n/cs.yml +60 -0
  39. data/test/r18n/xx.yml +51 -0
  40. data/test/reference/cs.txt +352 -0
  41. data/test/reference/cs.yml +14 -0
  42. data/test/reference/en.txt +76 -0
  43. data/test/reference/en.yml +8 -0
  44. data/test/reference/pl.txt +440 -0
  45. data/test/reference/pl.yml +16 -0
  46. data/test/reference/sk.txt +352 -0
  47. data/test/reference/sk.yml +14 -0
  48. data/test/test_core.rb +1272 -0
  49. data/test/test_localize.rb +27 -0
  50. data/test/test_r18n.rb +373 -0
  51. data/test/test_steps.rb +482 -0
  52. data/test/test_types.rb +307 -0
  53. metadata +145 -0
@@ -0,0 +1,307 @@
1
+ # encoding: UTF-8
2
+
3
+ require_relative 'helper'
4
+
5
+ require 'form_input/core'
6
+ require 'form_input/types'
7
+ require 'rack/test'
8
+
9
+ class TestBasicTypesForm < FormInput
10
+
11
+ param :int, INTEGER_ARGS
12
+ param :float, FLOAT_ARGS
13
+ param :bool, BOOL_ARGS
14
+ param :checkbox, CHECKBOX_ARGS
15
+
16
+ end
17
+
18
+ class TestAddressTypesForm < FormInput
19
+
20
+ param :email, EMAIL_ARGS
21
+ param :zip, ZIP_ARGS
22
+ param :phone, PHONE_ARGS
23
+
24
+ end
25
+
26
+ class TestTimeTypesForm < FormInput
27
+
28
+ param :time, TIME_ARGS
29
+ param :us_date, US_DATE_ARGS
30
+ param :uk_date, UK_DATE_ARGS
31
+ param :eu_date, EU_DATE_ARGS
32
+ param :hours, HOURS_ARGS
33
+
34
+ end
35
+
36
+ class TestPrunedTypesForm < FormInput
37
+
38
+ param :str, PRUNED_ARGS
39
+ param :int, INTEGER_ARGS, PRUNED_ARGS
40
+ array :arr, PRUNED_ARGS
41
+ array :int_arr, INTEGER_ARGS, PRUNED_ARGS
42
+ hash :hsh, PRUNED_ARGS
43
+ hash :int_hsh, INTEGER_ARGS, PRUNED_ARGS
44
+
45
+ end
46
+
47
+ class Bacon::Context
48
+
49
+ def each_timezone
50
+ yield nil
51
+ ( -14 .. 12 ).each{ |x| yield "Etc/GMT%+d" % x }
52
+ end
53
+
54
+ def with_timezone( zone )
55
+ saved, ENV[ 'TZ' ] = ENV[ 'TZ' ], zone
56
+ yield
57
+ ensure
58
+ ENV[ 'TZ' ] = saved
59
+ end
60
+
61
+ def with_each_timezone( &block )
62
+ each_timezone{ |zone| with_timezone( zone, &block ) }
63
+ end
64
+
65
+ end
66
+
67
+ describe FormInput do
68
+
69
+ def request( query )
70
+ Rack::Request.new( Rack::MockRequest.env_for( query ) )
71
+ end
72
+
73
+ def names( params )
74
+ params.map{ |x| x && x.name }
75
+ end
76
+
77
+ should 'provide helper regular expressions' do
78
+ for s in %w[ me@dot.com me@1.cz me.foo_bar+com%123=098@x.co.uk Me@BAR.INFO ]
79
+ FormInput::SIMPLE_EMAIL_RE.should.match s
80
+ end
81
+ for s in %w[ m @ @. a@ @b m@d a@.b x@y.z q@y..bot f'x@y.com f?x@foo.bar f!z@x.edu ]
82
+ FormInput::SIMPLE_EMAIL_RE.should.not.match s
83
+ end
84
+
85
+ for s in [ "X", "M.J.", "John Doe", "Šimon Třešňák", "Šimková-Plívová"]
86
+ FormInput::LATIN_NAMES_RE.should.match s
87
+ end
88
+ for s in %w[ ! @ # $ % ^ & * ( ) , : ; ? = | / \\ { } " ' ` ~ \[ \] ] + [ "Алекс", "गांधी", "宮本 茂"]
89
+ FormInput::LATIN_NAMES_RE.should.not.match s
90
+ end
91
+
92
+ for s in [ "0123456789", "+420 602 602 602", "0 (345) 123 123", "905 111-CALL-MAX", "123 123 ext 123"]
93
+ FormInput::PHONE_NUMBER_RE.should.match s
94
+ FormInput::PHONE_NUMBER_RE.should.match s.instance_exec( &FormInput::PHONE_NUMBER_FILTER )
95
+ end
96
+ for s in [ "123/323/569", "123.323.498", "1 - 2" ]
97
+ FormInput::PHONE_NUMBER_RE.should.not.match s
98
+ FormInput::PHONE_NUMBER_RE.should.match s.instance_exec( &FormInput::PHONE_NUMBER_FILTER )
99
+ end
100
+ for s in [ "abc", "01--2323", "12()3", "12(3", "12)3", "-123", "123-" ]
101
+ FormInput::PHONE_NUMBER_RE.should.not.match s
102
+ FormInput::PHONE_NUMBER_RE.should.not.match s.instance_exec( &FormInput::PHONE_NUMBER_FILTER )
103
+ end
104
+
105
+ for s in [ "32 767", "123-1234", "ABC 123", "ABC-ABC", "abc abc" ]
106
+ FormInput::ZIP_CODE_RE.should.match s
107
+ end
108
+ for s in [ "a/b", "1/2", "#23", "1.2", "2+3", "a!", "a--b", "a-", "-a" ]
109
+ FormInput::ZIP_CODE_RE.should.not.match s
110
+ end
111
+ end
112
+
113
+ should 'provide presets for standard parameter types' do
114
+ f = TestBasicTypesForm.new( request( "?int=0123&float=0123.456&bool=true&checkbox=on" ) )
115
+ f.should.be.valid
116
+ f.to_hash.should == { int: 123, float: 123.456, bool: true, checkbox: true }
117
+ f.url_params.should == { int: "123", float: "123.456", bool: "true", checkbox: "true" }
118
+ f.url_query.should == "int=123&float=123.456&bool=true&checkbox=true"
119
+
120
+ f = TestBasicTypesForm.new( request( "?bool=false&checkbox=" ) )
121
+ f.should.be.valid
122
+ f.to_hash.should == { bool: false, checkbox: false }
123
+ f.url_params.should == { bool: "false", checkbox: "" }
124
+ f.url_query.should == "bool=false&checkbox="
125
+
126
+ f = TestBasicTypesForm.new( request( "?int=a&float=b&bool=c&checkbox=d" ) )
127
+ f.should.be.invalid
128
+ names( f.invalid_params ).should == [ :int, :float ]
129
+ f.to_hash.should == { int: "a", float: "b", bool: false, checkbox: true }
130
+ f.url_params.should == { int: "a", float: "b", bool: "false", checkbox: "true" }
131
+ f.url_query.should == "int=a&float=b&bool=false&checkbox=true"
132
+ end
133
+
134
+ should 'provide presets for address parameter types' do
135
+ f = TestAddressTypesForm.new( request( "?email=me@1.com&zip=12345&phone=123%20456%20789" ) )
136
+ f.should.be.valid
137
+ f.to_hash.should == { email: "me@1.com", zip: "12345", phone: "123 456 789" }
138
+ f.url_params.should == { email: "me@1.com", zip: "12345", phone: "123 456 789" }
139
+ f.url_query.should == "email=me%401.com&zip=12345&phone=123+456+789"
140
+
141
+ f = TestAddressTypesForm.new( request( "?email=a&zip=a.b&phone=a" ) )
142
+ f.should.be.invalid
143
+ names( f.invalid_params ).should == [ :email, :zip, :phone ]
144
+ f.to_hash.should == { email: "a", zip: "a.b", phone: "a" }
145
+ f.url_params.should == { email: "a", zip: "a.b", phone: "a" }
146
+ f.url_query.should == "email=a&zip=a.b&phone=a"
147
+ end
148
+
149
+ should 'provide presets for time parameter types' do
150
+ f = TestTimeTypesForm.new
151
+ f.param( :time )[ :placeholder ].should == "YYYY-MM-DD HH:MM:SS"
152
+ f.param( :us_date )[ :placeholder ].should == "MM/DD/YYYY"
153
+ f.param( :uk_date )[ :placeholder ].should == "DD/MM/YYYY"
154
+ f.param( :eu_date )[ :placeholder ].should == "D.M.YYYY"
155
+ f.param( :hours )[ :placeholder ].should == "HH:MM"
156
+
157
+ with_each_timezone do
158
+
159
+ f = TestTimeTypesForm.new( request( "?time=1999-12-31+23:59:48&us_date=1/2/3&uk_date=1/2/3&eu_date=1.2.3&hours=23:59" ) )
160
+ f.should.be.valid
161
+ f.to_hash.should == {
162
+ time: Time.utc( 1999, 12, 31, 23, 59, 48 ),
163
+ us_date: Time.utc( 3, 1, 2 ),
164
+ uk_date: Time.utc( 3, 2, 1 ),
165
+ eu_date: Time.utc( 3, 2, 1 ),
166
+ hours: ( 23 * 60 + 59 ) * 60,
167
+ }
168
+ f.url_params.should == { time: "1999-12-31 23:59:48", us_date: "01/02/0003", uk_date: "01/02/0003", eu_date: "1.2.0003", hours: "23:59" }
169
+ f.url_query.should == "time=1999-12-31+23%3A59%3A48&us_date=01%2F02%2F0003&uk_date=01%2F02%2F0003&eu_date=1.2.0003&hours=23%3A59"
170
+
171
+ f = TestTimeTypesForm.new( request( "?time=3-2-1+0:0:0&us_date=12/31/1999&uk_date=31/12/1999&eu_date=31.12.1999&hours=0:0" ) )
172
+ f.should.be.valid
173
+ f.to_hash.should == {
174
+ time: Time.utc( 3, 2, 1, 0, 0, 0 ),
175
+ us_date: Time.utc( 1999, 12, 31 ),
176
+ uk_date: Time.utc( 1999, 12, 31 ),
177
+ eu_date: Time.utc( 1999, 12, 31 ),
178
+ hours: 0,
179
+ }
180
+ f.url_params.should == { time: "0003-02-01 00:00:00", us_date: "12/31/1999", uk_date: "31/12/1999", eu_date: "31.12.1999", hours: "00:00" }
181
+ f.url_query.should == "time=0003-02-01+00%3A00%3A00&us_date=12%2F31%2F1999&uk_date=31%2F12%2F1999&eu_date=31.12.1999&hours=00%3A00"
182
+
183
+ f = TestTimeTypesForm.new( request( "?time=1+Feb+3+13:15&us_date=1+Feb+3&uk_date=3-2-1&eu_date=Feb+1st+3&hours=1:2" ) )
184
+ f.should.be.valid
185
+ f.to_hash.should == {
186
+ time: Time.utc( 2003, 2, 1, 13, 15, 0 ),
187
+ us_date: Time.utc( 2003, 2, 1 ),
188
+ uk_date: Time.utc( 2003, 2, 1 ),
189
+ eu_date: Time.utc( 2003, 2, 1 ),
190
+ hours: ( 1 * 60 + 2 ) * 60,
191
+ }
192
+ f.url_params.should == { time: "2003-02-01 13:15:00", us_date: "02/01/2003", uk_date: "01/02/2003", eu_date: "1.2.2003", hours: "01:02" }
193
+ f.url_query.should == "time=2003-02-01+13%3A15%3A00&us_date=02%2F01%2F2003&uk_date=01%2F02%2F2003&eu_date=1.2.2003&hours=01%3A02"
194
+
195
+ f = TestTimeTypesForm.new( request( "?time=50+Feb&us_date=foo&uk_date=32+1&eu_date=1+x&hours=25:45" ) )
196
+ f.should.be.invalid
197
+ names( f.invalid_params ).should == [ :time, :us_date, :uk_date, :eu_date, :hours ]
198
+ f.to_hash.should == { time: "50 Feb", us_date: "foo", uk_date: "32 1", eu_date: "1 x", hours: "25:45" }
199
+ f.url_params.should == { time: "50 Feb", us_date: "foo", uk_date: "32 1", eu_date: "1 x", hours: "25:45" }
200
+ f.url_query.should == "time=50+Feb&us_date=foo&uk_date=32+1&eu_date=1+x&hours=25%3A45"
201
+
202
+ f = TestTimeTypesForm.new( request( "?time=&us_date=&uk_date=&eu_date=&hours=" ) )
203
+ f.should.be.valid
204
+ f[ :time, :us_date, :uk_date, :eu_date, :hours ].should == [ nil, nil, nil, nil, nil ]
205
+ f.to_hash.should == {}
206
+ f.url_params.should == {}
207
+ f.url_query.should == ""
208
+
209
+ end
210
+ end
211
+
212
+ describe 'Time parsing helper' do
213
+
214
+ should 'raise when string is not parsed entirely' do
215
+ for c in ( 0..255 ).map( &:chr )
216
+ FormInput.parse_time( "2000", "%Y" ).year.should == 2000
217
+ FormInput.parse_time( "2000" + c, "%Y" + c ).year.should == 2000
218
+
219
+ unless c =~ /\d/
220
+ ->{ FormInput.parse_time( "2000" + c, "%Y" ) }.should.raise ArgumentError
221
+ end
222
+ unless c =~ /\s/
223
+ ->{ FormInput.parse_time( "2000", "%Y" + c ) }.should.raise ArgumentError
224
+ end
225
+
226
+ ->{ FormInput.parse_time( "2000", "%y" ) }.should.raise ArgumentError
227
+ ->{ FormInput.parse_time( "2000" + c, "%y" + c ) }.should.raise ArgumentError
228
+
229
+ ->{ FormInput.parse_time( "2000" + c, "%y" ) }.should.raise ArgumentError
230
+ ->{ FormInput.parse_time( "2000", "%y" + c ) }.should.raise ArgumentError
231
+ end
232
+ end
233
+
234
+ should 'correctly ignore % modifiers in time format' do
235
+ for string, format in [ "2000 %- 2", "%Y %%- %-m", "99 3", "%y %_m", "1/12", "%-d/%m", "FEBRUARY", "%^B" ].each_slice( 2 )
236
+ FormInput.parse_time( string, format ).strftime( format ).should == string
237
+ end
238
+ end
239
+
240
+ should 'work regardless of the timezone' do
241
+ offsets = []
242
+ with_each_timezone do
243
+ offsets << Time.now.utc_offset
244
+ FormInput.parse_time( "2000-12-01 00:00:00", "%Y-%m-%d %H:%M:%S" ).should == Time.utc( 2000, 12, 1, 0, 0, 0 )
245
+ FormInput.parse_time( "2000-12-01 12:13:14", "%Y-%m-%d %H:%M:%S" ).should == Time.utc( 2000, 12, 1, 12, 13, 14 )
246
+ FormInput.parse_time( "2000-12-01 23:59:59", "%Y-%m-%d %H:%M:%S" ).should == Time.utc( 2000, 12, 1, 23, 59, 59 )
247
+
248
+ FormInput.parse_time!( "2000 Dec 1 00:00:00", "%Y-%m-%d %H:%M:%S" ).should == Time.utc( 2000, 12, 1, 0, 0, 0 )
249
+ FormInput.parse_time!( "2000 Dec 1 12:13:14", "%Y-%m-%d %H:%M:%S" ).should == Time.utc( 2000, 12, 1, 12, 13, 14 )
250
+ FormInput.parse_time!( "2000 Dec 1 23:59:59", "%Y-%m-%d %H:%M:%S" ).should == Time.utc( 2000, 12, 1, 23, 59, 59 )
251
+ end
252
+ offsets.uniq.count.should.be >= 24
253
+ end
254
+
255
+ end
256
+
257
+ should 'provide transformation for pruning empty values from input' do
258
+ c = Class.new( FormInput ).copy( TestPrunedTypesForm, transform: nil )
259
+
260
+ f = TestPrunedTypesForm.new( request( "?str=foo&int=1" ) )
261
+ f.to_h.should == { str: "foo", int: 1 }
262
+ f.url_query.should == "str=foo&int=1"
263
+ f = c.new( request( "?str=foo&int=1" ) )
264
+ f.to_h.should == { str: "foo", int: 1 }
265
+ f.url_query.should == "str=foo&int=1"
266
+
267
+ f = TestPrunedTypesForm.new( request( "?str=&int=" ) )
268
+ f.to_h.should == {}
269
+ f.url_query.should == ""
270
+ f[ :str, :int ].should == [ nil, nil ]
271
+ f = c.new( request( "?str=&int=" ) )
272
+ f.to_h.should == {}
273
+ f.url_query.should == ""
274
+ f[ :str, :int ].should == [ "", nil ]
275
+
276
+ f = TestPrunedTypesForm.new( request( "?arr[]=foo&arr[]=&arr[]=bar&arr[]=&int_arr[]=&int_arr[]=5&int_arr[]=" ) )
277
+ f.to_h.should == { arr: [ "foo", "bar" ], int_arr: [ 5 ] }
278
+ f.url_query.should == "arr[]=foo&arr[]=bar&int_arr[]=5"
279
+ f = c.new( request( "?arr[]=foo&arr[]=&arr[]=bar&arr[]=&int_arr[]=&int_arr[]=5&int_arr[]=" ) )
280
+ f.to_h.should == { arr: [ "foo", "", "bar", "" ], int_arr: [ nil, 5, nil ] }
281
+ f.url_query.should == "arr[]=foo&arr[]=&arr[]=bar&arr[]=&int_arr[]=&int_arr[]=5&int_arr[]="
282
+
283
+ f = TestPrunedTypesForm.new( request( "?arr[]=&int_arr[]=" ) )
284
+ f.to_h.should == {}
285
+ f.url_query.should == ""
286
+ f = c.new( request( "?arr[]=&int_arr[]=" ) )
287
+ f.to_h.should == { arr: [ "" ], int_arr: [ nil ] }
288
+ f.url_query.should == "arr[]=&int_arr[]="
289
+
290
+ f = TestPrunedTypesForm.new( request( "?hsh[5]=foo&hsh[8]=&hsh[10]=bar&hsh[13]=&int_hsh[3]=&int_hsh[2]=5&int_hsh[1]=" ) )
291
+ f.to_h.should == { hsh: { 5 => "foo", 10 => "bar" }, int_hsh: { 2 => 5 } }
292
+ f.url_query.should == "hsh[5]=foo&hsh[10]=bar&int_hsh[2]=5"
293
+ f = c.new( request( "?hsh[5]=foo&hsh[8]=&hsh[10]=bar&hsh[13]=&int_hsh[3]=&int_hsh[2]=5&int_hsh[1]=" ) )
294
+ f.to_h.should == { hsh: { 5 => "foo", 8 => "", 10 => "bar", 13 => "" }, int_hsh: { 3 => nil, 2 => 5, 1 => nil } }
295
+ f.url_query.should == "hsh[5]=foo&hsh[8]=&hsh[10]=bar&hsh[13]=&int_hsh[3]=&int_hsh[2]=5&int_hsh[1]="
296
+
297
+ f = TestPrunedTypesForm.new( request( "?hsh[8]=&int_hsh[11]=" ) )
298
+ f.to_h.should == {}
299
+ f.url_query.should == ""
300
+ f = c.new( request( "?hsh[8]=&int_hsh[11]=" ) )
301
+ f.to_h.should == { hsh: { 8 => "" }, int_hsh: { 11 => nil } }
302
+ f.url_query.should == "hsh[8]=&int_hsh[11]="
303
+ end
304
+
305
+ end
306
+
307
+ # EOF #
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: form_input
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0.pre1
5
+ platform: ruby
6
+ authors:
7
+ - Patrik Rak
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-06-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bacon
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.2'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: r18n-core
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
55
+ description: |
56
+ This gem allows you to describe your forms using a simple DSL
57
+ and then takes care of sanitizing, transforming, and validating the input for you,
58
+ providing you with the ready-to-use input in a model-like structure.
59
+ Both simple forms as well as multi-step forms are supported.
60
+ Includes handy accessors for automatically building the forms
61
+ and reporting error messages using a templating engine of your choice.
62
+ Localization support with builtin inflection rules can be enabled, too.
63
+ email: patrik@raxoft.cz
64
+ executables: []
65
+ extensions: []
66
+ extra_rdoc_files: []
67
+ files:
68
+ - ".gitignore"
69
+ - LICENSE
70
+ - README.md
71
+ - Rakefile
72
+ - example/controllers/ramaze/press_release.rb
73
+ - example/controllers/ramaze/profile.rb
74
+ - example/controllers/sinatra/press_release.rb
75
+ - example/controllers/sinatra/profile.rb
76
+ - example/forms/change_password_form.rb
77
+ - example/forms/login_form.rb
78
+ - example/forms/lost_password_form.rb
79
+ - example/forms/new_password_form.rb
80
+ - example/forms/password_form.rb
81
+ - example/forms/press_release_form.rb
82
+ - example/forms/profile_form.rb
83
+ - example/forms/signup_form.rb
84
+ - example/views/press_release.slim
85
+ - example/views/profile.slim
86
+ - example/views/snippets/form_block.slim
87
+ - example/views/snippets/form_chunked.slim
88
+ - example/views/snippets/form_hidden.slim
89
+ - example/views/snippets/form_panel.slim
90
+ - form_input.gemspec
91
+ - lib/form_input.rb
92
+ - lib/form_input/core.rb
93
+ - lib/form_input/localize.rb
94
+ - lib/form_input/r18n.rb
95
+ - lib/form_input/r18n/cs.yml
96
+ - lib/form_input/r18n/en.yml
97
+ - lib/form_input/r18n/pl.yml
98
+ - lib/form_input/r18n/sk.yml
99
+ - lib/form_input/steps.rb
100
+ - lib/form_input/types.rb
101
+ - lib/form_input/version.rb
102
+ - test/helper.rb
103
+ - test/localize/en.yml
104
+ - test/r18n/cs.yml
105
+ - test/r18n/xx.yml
106
+ - test/reference/cs.txt
107
+ - test/reference/cs.yml
108
+ - test/reference/en.txt
109
+ - test/reference/en.yml
110
+ - test/reference/pl.txt
111
+ - test/reference/pl.yml
112
+ - test/reference/sk.txt
113
+ - test/reference/sk.yml
114
+ - test/test_core.rb
115
+ - test/test_localize.rb
116
+ - test/test_r18n.rb
117
+ - test/test_steps.rb
118
+ - test/test_types.rb
119
+ homepage: https://github.com/raxoft/form_input
120
+ licenses:
121
+ - MIT
122
+ metadata: {}
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: 2.0.0
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">"
135
+ - !ruby/object:Gem::Version
136
+ version: 1.3.1
137
+ requirements: []
138
+ rubyforge_project:
139
+ rubygems_version: 2.4.5.1
140
+ signing_key:
141
+ specification_version: 4
142
+ summary: Form helper which sanitizes, transforms, validates and encapsulates web request
143
+ input.
144
+ test_files: []
145
+ has_rdoc: