forme 1.3.0 → 1.4.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/spec/bs3_spec.rb ADDED
@@ -0,0 +1,690 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
+ require 'forme/bs3'
3
+
4
+ describe "Forme Bootstrap3 (BS3) forms" do
5
+ def sel(opts, s)
6
+ opts.map{|o| "<option #{'selected="selected" ' if o == s}value=\"#{o}\">#{sprintf("%02i", o)}</option>"}.join
7
+ end
8
+
9
+ before do
10
+ @f = Forme::Form.new(:config=>:bs3)
11
+ end
12
+
13
+ it "should create a simple input tags" do
14
+ @f.input(:text).to_s.must_equal '<div class="form-group"><input class="form-control" type="text"/></div>'
15
+ @f.input(:radio).to_s.must_equal '<div class="radio"><input type="radio"/></div>'
16
+ @f.input(:password).to_s.must_equal '<div class="form-group"><input class="form-control" type="password"/></div>'
17
+ @f.input(:checkbox).to_s.must_equal '<div class="checkbox"><input type="checkbox"/></div>'
18
+ @f.input(:submit).to_s.must_equal '<input class="btn btn-default" type="submit"/>'
19
+ end
20
+
21
+ it "should use :name option as attribute" do
22
+ @f.input(:text, :name=>"foo").to_s.must_equal '<div class="form-group"><input class="form-control" name="foo" type="text"/></div>'
23
+ end
24
+
25
+ it "should use :id option as attribute" do
26
+ @f.input(:text, :id=>"foo").to_s.must_equal '<div class="form-group"><input class="form-control" id="foo" type="text"/></div>'
27
+ end
28
+
29
+ it "should use :class option as attribute" do
30
+ @f.input(:text, :class=>"foo").to_s.must_equal '<div class="form-group"><input class="form-control foo" type="text"/></div>'
31
+ end
32
+
33
+ it "should use :value option as attribute" do
34
+ @f.input(:text, :value=>"foo").to_s.must_equal '<div class="form-group"><input class="form-control" type="text" value="foo"/></div>'
35
+ end
36
+
37
+ it "should use :placeholder option as attribute" do
38
+ @f.input(:text, :placeholder=>"foo").to_s.must_equal '<div class="form-group"><input class="form-control" placeholder="foo" type="text"/></div>'
39
+ end
40
+
41
+ it "should use :style option as attribute" do
42
+ @f.input(:text, :style=>"foo").to_s.must_equal '<div class="form-group"><input class="form-control" style="foo" type="text"/></div>'
43
+ end
44
+
45
+ it "should use :key option as name and id attributes" do
46
+ @f.input(:text, :key=>"foo").to_s.must_equal '<div class="form-group"><input class="form-control" id="foo" name="foo" type="text"/></div>'
47
+ end
48
+
49
+ it "should use :key_id option as suffix for :key option id attributes" do
50
+ @f.input(:text, :key=>"foo", :key_id=>'bar').to_s.must_equal '<div class="form-group"><input class="form-control" id="foo_bar" name="foo" type="text"/></div>'
51
+ end
52
+
53
+ it "should have :key option respect :multiple option" do
54
+ @f.input(:text, :key=>"foo", :multiple=>true).to_s.must_equal '<div class="form-group"><input class="form-control" id="foo" name="foo[]" type="text"/></div>'
55
+ end
56
+
57
+ it "should use :key option respect form's current namespace" do
58
+ @f.with_opts(:namespace=>['bar']) do
59
+ @f.input(:text, :key=>"foo").to_s.must_equal '<div class="form-group"><input class="form-control" id="bar_foo" name="bar[foo]" type="text"/></div>'
60
+ @f.input(:text, :key=>"foo", :multiple=>true).to_s.must_equal '<div class="form-group"><input class="form-control" id="bar_foo" name="bar[foo][]" type="text"/></div>'
61
+ @f.with_opts(:namespace=>['bar', 'baz']) do
62
+ @f.input(:text, :key=>"foo").to_s.must_equal '<div class="form-group"><input class="form-control" id="bar_baz_foo" name="bar[baz][foo]" type="text"/></div>'
63
+ end
64
+ end
65
+ end
66
+
67
+ it "should consider form's :values hash for default values based on the :key option if :value is not present" do
68
+ @f.opts[:values] = {'foo'=>'baz'}
69
+ @f.input(:text, :key=>"foo").to_s.must_equal '<div class="form-group"><input class="form-control" id="foo" name="foo" type="text" value="baz"/></div>'
70
+ @f.input(:text, :key=>"foo", :value=>'x').to_s.must_equal '<div class="form-group"><input class="form-control" id="foo" name="foo" type="text" value="x"/></div>'
71
+
72
+ @f.input(:text, :key=>:foo).to_s.must_equal '<div class="form-group"><input class="form-control" id="foo" name="foo" type="text" value="baz"/></div>'
73
+ @f.opts[:values] = {:foo=>'baz'}
74
+ @f.input(:text, :key=>:foo).to_s.must_equal '<div class="form-group"><input class="form-control" id="foo" name="foo" type="text" value="baz"/></div>'
75
+ end
76
+
77
+ it "should consider form's :values hash for default values based on the :key option when using namespaces" do
78
+ @f.opts[:values] = {'bar'=>{'foo'=>'baz'}}
79
+ @f.with_opts(:namespace=>['bar']) do
80
+ @f.input(:text, :key=>"foo").to_s.must_equal '<div class="form-group"><input class="form-control" id="bar_foo" name="bar[foo]" type="text" value="baz"/></div>'
81
+ @f.input(:text, :key=>"foo", :value=>'x').to_s.must_equal '<div class="form-group"><input class="form-control" id="bar_foo" name="bar[foo]" type="text" value="x"/></div>'
82
+ @f.input(:text, :key=>:foo).to_s.must_equal '<div class="form-group"><input class="form-control" id="bar_foo" name="bar[foo]" type="text" value="baz"/></div>'
83
+ end
84
+
85
+ @f.with_opts(:namespace=>[:bar]) do
86
+ @f.input(:text, :key=>:foo).to_s.must_equal '<div class="form-group"><input class="form-control" id="bar_foo" name="bar[foo]" type="text" value="baz"/></div>'
87
+
88
+ @f.opts[:values] = {:bar=>{:foo=>'baz'}}
89
+ @f.input(:text, :key=>:foo).to_s.must_equal '<div class="form-group"><input class="form-control" id="bar_foo" name="bar[foo]" type="text" value="baz"/></div>'
90
+ @f.opts[:values] = {:bar=>{}}
91
+ @f.input(:text, :key=>:foo).to_s.must_equal '<div class="form-group"><input class="form-control" id="bar_foo" name="bar[foo]" type="text"/></div>'
92
+ @f.opts[:values] = {}
93
+ @f.input(:text, :key=>:foo).to_s.must_equal '<div class="form-group"><input class="form-control" id="bar_foo" name="bar[foo]" type="text"/></div>'
94
+
95
+ @f.opts[:values] = {'bar'=>{'quux'=>{'foo'=>'baz'}}}
96
+ @f.with_opts(:namespace=>['bar', 'quux']) do
97
+ @f.input(:text, :key=>"foo").to_s.must_equal '<div class="form-group"><input class="form-control" id="bar_quux_foo" name="bar[quux][foo]" type="text" value="baz"/></div>'
98
+ end
99
+ end
100
+ end
101
+
102
+ it "should support a with_obj method that changes the object and namespace for the given block" do
103
+ @f.with_obj([:a, :c], 'bar') do
104
+ @f.input(:first).to_s.must_equal '<div class="form-group"><input class="form-control" id="bar_first" name="bar[first]" type="text" value="a"/></div>'
105
+ @f.with_obj([:b], 'baz') do
106
+ @f.input(:first).to_s.must_equal '<div class="form-group"><input class="form-control" id="bar_baz_first" name="bar[baz][first]" type="text" value="b"/></div>'
107
+ end
108
+ @f.with_obj([:b], %w'baz quux') do
109
+ @f.input(:first).to_s.must_equal '<div class="form-group"><input class="form-control" id="bar_baz_quux_first" name="bar[baz][quux][first]" type="text" value="b"/></div>'
110
+ end
111
+ @f.with_obj([:b]) do
112
+ @f.input(:first).to_s.must_equal '<div class="form-group"><input class="form-control" id="bar_first" name="bar[first]" type="text" value="b"/></div>'
113
+ end
114
+ @f.input(:last).to_s.must_equal '<div class="form-group"><input class="form-control" id="bar_last" name="bar[last]" type="text" value="c"/></div>'
115
+ end
116
+ end
117
+
118
+ it "should support a each_obj method that changes the object and namespace for multiple objects for the given block" do
119
+ @f.tag(:form) do
120
+ @f.each_obj([[:a, :c], [:b, :d]], 'bar') do
121
+ @f.input(:first)
122
+ @f.input(:last)
123
+ end
124
+ end.to_s.must_equal '<form><div class="form-group"><input class="form-control" id="bar_0_first" name="bar[0][first]" type="text" value="a"/></div><div class="form-group"><input class="form-control" id="bar_0_last" name="bar[0][last]" type="text" value="c"/></div><div class="form-group"><input class="form-control" id="bar_1_first" name="bar[1][first]" type="text" value="b"/></div><div class="form-group"><input class="form-control" id="bar_1_last" name="bar[1][last]" type="text" value="d"/></div></form>'
125
+
126
+ @f.tag(:form) do
127
+ @f.each_obj([[:a, :c], [:b, :d]], %w'bar baz') do
128
+ @f.input(:first)
129
+ @f.input(:last)
130
+ end
131
+ end.to_s.must_equal '<form><div class="form-group"><input class="form-control" id="bar_baz_0_first" name="bar[baz][0][first]" type="text" value="a"/></div><div class="form-group"><input class="form-control" id="bar_baz_0_last" name="bar[baz][0][last]" type="text" value="c"/></div><div class="form-group"><input class="form-control" id="bar_baz_1_first" name="bar[baz][1][first]" type="text" value="b"/></div><div class="form-group"><input class="form-control" id="bar_baz_1_last" name="bar[baz][1][last]" type="text" value="d"/></div></form>'
132
+
133
+ @f.tag(:form) do
134
+ @f.each_obj([[:a, :c], [:b, :d]]) do
135
+ @f.input(:first)
136
+ @f.input(:last)
137
+ end
138
+ end.to_s.must_equal '<form><div class="form-group"><input class="form-control" id="0_first" name="0[first]" type="text" value="a"/></div><div class="form-group"><input class="form-control" id="0_last" name="0[last]" type="text" value="c"/></div><div class="form-group"><input class="form-control" id="1_first" name="1[first]" type="text" value="b"/></div><div class="form-group"><input class="form-control" id="1_last" name="1[last]" type="text" value="d"/></div></form>'
139
+ end
140
+
141
+ it "should allow overriding form inputs on a per-block basis" do
142
+ @f.input(:text).to_s.must_equal '<div class="form-group"><input class="form-control" type="text"/></div>'
143
+ @f.with_opts(:wrapper=>:div){@f.input(:text).to_s}.must_equal '<div><input class="form-control" type="text"/></div>'
144
+ @f.with_opts(:wrapper=>:div){@f.input(:text).to_s.must_equal '<div><input class="form-control" type="text"/></div>'}
145
+ @f.with_opts(:wrapper=>:div) do
146
+ @f.input(:text).to_s.must_equal '<div><input class="form-control" type="text"/></div>'
147
+ @f.with_opts(:wrapper=>:li){@f.input(:text).to_s.must_equal '<li><input class="form-control" type="text"/></li>'}
148
+ @f.input(:text).to_s.must_equal '<div><input class="form-control" type="text"/></div>'
149
+ end
150
+ @f.input(:text).to_s.must_equal '<div class="form-group"><input class="form-control" type="text"/></div>'
151
+ end
152
+
153
+ it "should handle delayed formatting when overriding form inputs on a per-block basis" do
154
+ @f.form do
155
+ @f.input(:text)
156
+ @f.with_opts(:wrapper=>:div) do
157
+ @f.input(:text)
158
+ @f.with_opts(:wrapper=>:li){@f.input(:text)}
159
+ @f.input(:text)
160
+ end
161
+ @f.input(:text)
162
+ end.to_s.must_equal '<form><div class="form-group"><input class="form-control" type="text"/></div><div><input class="form-control" type="text"/></div><li><input class="form-control" type="text"/></li><div><input class="form-control" type="text"/></div><div class="form-group"><input class="form-control" type="text"/></div></form>'
163
+ end
164
+
165
+ it "should support :obj method to with_opts for changing the obj inside the block" do
166
+ @f.form do
167
+ @f.with_opts(:obj=>[:a, :c]) do
168
+ @f.input(:first)
169
+ @f.with_opts(:obj=>[:b]){@f.input(:first)}
170
+ @f.input(:last)
171
+ end
172
+ end.to_s.must_equal '<form><div class="form-group"><input class="form-control" id="first" name="first" type="text" value="a"/></div><div class="form-group"><input class="form-control" id="first" name="first" type="text" value="b"/></div><div class="form-group"><input class="form-control" id="last" name="last" type="text" value="c"/></div></form>'
173
+ end
174
+
175
+ it "should allow arbitrary attributes using the :attr option" do
176
+ @f.input(:text, :attr=>{:bar=>"foo"}).to_s.must_equal '<div class="form-group"><input bar="foo" class="form-control" type="text"/></div>'
177
+ end
178
+
179
+ it "should convert the :data option into attributes" do
180
+ @f.input(:text, :data=>{:bar=>"foo"}).to_s.must_equal '<div class="form-group"><input class="form-control" data-bar="foo" type="text"/></div>'
181
+ end
182
+
183
+ it "should not have standard options override the :attr option" do
184
+ @f.input(:text, :name=>:bar, :attr=>{:name=>"foo"}).to_s.must_equal '<div class="form-group"><input class="form-control" name="foo" type="text"/></div>'
185
+ end
186
+
187
+ it "should combine :class standard option with :attr option" do
188
+ @f.input(:text, :class=>:bar, :attr=>{:class=>"foo"}).to_s.must_equal '<div class="form-group"><input class="form-control foo bar" type="text"/></div>'
189
+ end
190
+
191
+ it "should not have :data options override the :attr option" do
192
+ @f.input(:text, :data=>{:bar=>"baz"}, :attr=>{:"data-bar"=>"foo"}).to_s.must_equal '<div class="form-group"><input class="form-control" data-bar="foo" type="text"/></div>'
193
+ end
194
+
195
+ it "should use :size and :maxlength options as attributes for text inputs" do
196
+ @f.input(:text, :size=>5, :maxlength=>10).to_s.must_equal '<div class="form-group"><input class="form-control" maxlength="10" size="5" type="text"/></div>'
197
+ @f.input(:textarea, :size=>5, :maxlength=>10).to_s.must_equal '<div class="form-group"><textarea class="form-control"></textarea></div>'
198
+ end
199
+
200
+ it "should create hidden input with value 0 for each checkbox with a name" do
201
+ @f.input(:checkbox, :name=>"foo").to_s.must_equal '<div class="checkbox"><input name="foo" type="hidden" value="0"/><input name="foo" type="checkbox"/></div>'
202
+ end
203
+
204
+ it "should not create hidden input with value 0 for each checkbox with a name if :no_hidden option is used" do
205
+ @f.input(:checkbox, :name=>"foo", :no_hidden=>true).to_s.must_equal '<div class="checkbox"><input name="foo" type="checkbox"/></div>'
206
+ end
207
+
208
+ it "should create hidden input with _hidden appended to id for each checkbox with a name and id" do
209
+ @f.input(:checkbox, :name=>"foo", :id=>"bar").to_s.must_equal '<div class="checkbox"><input id="bar_hidden" name="foo" type="hidden" value="0"/><input id="bar" name="foo" type="checkbox"/></div>'
210
+ end
211
+
212
+ it "should create hidden input with value f for each checkbox with a name and value t" do
213
+ @f.input(:checkbox, :name=>"foo", :value=>"t").to_s.must_equal '<div class="checkbox"><input name="foo" type="hidden" value="f"/><input name="foo" type="checkbox" value="t"/></div>'
214
+ end
215
+
216
+ it "should use :hidden_value option for value of hidden input for checkbox" do
217
+ @f.input(:checkbox, :name=>"foo", :hidden_value=>"no").to_s.must_equal '<div class="checkbox"><input name="foo" type="hidden" value="no"/><input name="foo" type="checkbox"/></div>'
218
+ end
219
+
220
+ it "should handle :checked option" do
221
+ @f.input(:checkbox, :checked=>true).to_s.must_equal '<div class="checkbox"><input checked="checked" type="checkbox"/></div>'
222
+ @f.input(:checkbox, :checked=>false).to_s.must_equal '<div class="checkbox"><input type="checkbox"/></div>'
223
+ end
224
+
225
+ it "should create textarea tag" do
226
+ @f.input(:textarea).to_s.must_equal '<div class="form-group"><textarea class="form-control"></textarea></div>'
227
+ @f.input(:textarea, :value=>'a').to_s.must_equal '<div class="form-group"><textarea class="form-control">a</textarea></div>'
228
+ end
229
+
230
+ it "should use :cols and :rows options as attributes for textarea inputs" do
231
+ @f.input(:text, :cols=>5, :rows=>10).to_s.must_equal '<div class="form-group"><input class="form-control" type="text"/></div>'
232
+ @f.input(:textarea, :cols=>5, :rows=>10).to_s.must_equal '<div class="form-group"><textarea class="form-control" cols="5" rows="10"></textarea></div>'
233
+ end
234
+
235
+ it "should create select tag" do
236
+ @f.input(:select).to_s.must_equal '<div class="form-group"><select class="form-control"></select></div>'
237
+ end
238
+
239
+ it "should respect multiple and size options in select tag" do
240
+ @f.input(:select, :multiple=>true, :size=>10).to_s.must_equal '<div class="form-group"><select class="form-control" multiple="multiple" size="10"></select></div>'
241
+ end
242
+
243
+ it "should create date tag" do
244
+ @f.input(:date).to_s.must_equal '<div class="form-group"><input class="form-control" type="date"/></div>'
245
+ end
246
+
247
+ it "should create datetime-local tag" do
248
+ @f.input(:datetime).to_s.must_equal '<div class="form-group"><input class="form-control" type="datetime-local"/></div>'
249
+ end
250
+
251
+ it "should not error for input type :input" do
252
+ @f.input(:input).to_s.must_equal '<div class="form-group"><input class="form-control" type="input"/></div>'
253
+ end
254
+
255
+ it "should use multiple select boxes for dates if the :as=>:select option is given" do
256
+ @f.input(:date, :name=>"foo", :id=>"bar", :as=>:select, :value=>Date.new(2011, 6, 5)).to_s.must_equal %{<div class="form-group"><select class="form-control" id="bar" name="foo[year]">#{sel(1900..2050, 2011)}</select>-<select class="form-control" id="bar_month" name="foo[month]">#{sel(1..12, 6)}</select>-<select class="form-control" id="bar_day" name="foo[day]">#{sel(1..31, 5)}</select></div>}
257
+ end
258
+
259
+ it "should allow ordering date select boxes via :order" do
260
+ @f.input(:date, :name=>"foo", :id=>"bar", :as=>:select, :value=>Date.new(2011, 6, 5), :order=>[:month, '/', :day, '/', :year]).to_s.must_equal %{<div class="form-group"><select class="form-control" id="bar" name="foo[month]">#{sel(1..12, 6)}</select>/<select class="form-control" id="bar_day" name="foo[day]">#{sel(1..31, 5)}</select>/<select class="form-control" id="bar_year" name="foo[year]">#{sel(1900..2050, 2011)}</select></div>}
261
+ end
262
+
263
+ it "should allow only using specific date select boxes via :order" do
264
+ @f.input(:date, :name=>"foo", :id=>"bar", :as=>:select, :value=>Date.new(2011, 6, 5), :order=>[:month, :year]).to_s.must_equal %{<div class="form-group"><select class="form-control" id="bar" name="foo[month]">#{sel(1..12, 6)}</select><select class="form-control" id="bar_year" name="foo[year]">#{sel(1900..2050, 2011)}</select></div>}
265
+ end
266
+
267
+ it "should support :select_options for dates when :as=>:select is given" do
268
+ @f.input(:date, :name=>"foo", :id=>"bar", :as=>:select, :value=>Date.new(2011, 6, 5), :select_options=>{:year=>1970..2020}).to_s.must_equal %{<div class=\"form-group\"><select class="form-control" id="bar" name="foo[year]">#{sel(1970..2020, 2011)}</select>-<select class="form-control" id="bar_month" name="foo[month]">#{sel(1..12, 6)}</select>-<select class="form-control" id="bar_day" name="foo[day]">#{sel(1..31, 5)}</select></div>}
269
+ end
270
+
271
+ it "should have explicit labeler and trtd wrapper work with multiple select boxes for dates" do
272
+ @f.input(:date, :name=>"foo", :id=>"bar", :as=>:select, :value=>Date.new(2011, 6, 5), :wrapper=>:trtd, :labeler=>:explicit, :label=>'Baz').to_s.must_equal %{<tr><td><label class="label-before" for="bar">Baz</label></td><td><select class="form-control" id="bar" name="foo[year]">#{sel(1900..2050, 2011)}</select>-<select class="form-control" id="bar_month" name="foo[month]">#{sel(1..12, 6)}</select>-<select class="form-control" id="bar_day" name="foo[day]">#{sel(1..31, 5)}</select></td></tr>}
273
+ end
274
+
275
+ it "should use multiple select boxes for datetimes if the :as=>:select option is given" do
276
+ @f.input(:datetime, :name=>"foo", :id=>"bar", :as=>:select, :value=>DateTime.new(2011, 6, 5, 4, 3, 2)).to_s.must_equal %{<div class=\"form-group\"><select class="form-control" id="bar" name="foo[year]">#{sel(1900..2050, 2011)}</select>-<select class="form-control" id="bar_month" name="foo[month]">#{sel(1..12, 6)}</select>-<select class="form-control" id="bar_day" name="foo[day]">#{sel(1..31, 5)}</select> <select class="form-control" id="bar_hour" name="foo[hour]">#{sel(0..23, 4)}</select>:<select class="form-control" id="bar_minute" name="foo[minute]">#{sel(0..59, 3)}</select>:<select class="form-control" id="bar_second" name="foo[second]">#{sel(0..59, 2)}</select></div>}
277
+ end
278
+
279
+ it "should allow ordering select boxes for datetimes via :order" do
280
+ @f.input(:datetime, :name=>"foo", :id=>"bar", :as=>:select, :value=>DateTime.new(2011, 6, 5, 4, 3, 2), :order=>[:day, '/', :month, 'T', :hour, ':', :minute]).to_s.must_equal %{<div class=\"form-group\"><select class="form-control" id="bar" name="foo[day]">#{sel(1..31, 5)}</select>/<select class="form-control" id="bar_month" name="foo[month]">#{sel(1..12, 6)}</select>T<select class="form-control" id="bar_hour" name="foo[hour]">#{sel(0..23, 4)}</select>:<select class="form-control" id="bar_minute" name="foo[minute]">#{sel(0..59, 3)}</select></div>}
281
+ end
282
+
283
+ it "should support :select_options for datetimes when :as=>:select option is given" do
284
+ @f.input(:datetime, :name=>"foo", :id=>"bar", :as=>:select, :value=>DateTime.new(2011, 6, 5, 10, 3, 2), :select_options=>{:year=>1970..2020, :hour=>9..17}).to_s.must_equal %{<div class="form-group"><select class="form-control" id="bar" name="foo[year]">#{sel(1970..2020, 2011)}</select>-<select class="form-control" id="bar_month" name="foo[month]">#{sel(1..12, 6)}</select>-<select class="form-control" id="bar_day" name="foo[day]">#{sel(1..31, 5)}</select> <select class="form-control" id="bar_hour" name="foo[hour]">#{sel(9..17, 10)}</select>:<select class="form-control" id="bar_minute" name="foo[minute]">#{sel(0..59, 3)}</select>:<select class="form-control" id="bar_second" name="foo[second]">#{sel(0..59, 2)}</select></div>}
285
+ end
286
+
287
+ it "should create select tag with options" do
288
+ @f.input(:select, :options=>[1, 2, 3], :selected=>2).to_s.must_equal '<div class="form-group"><select class="form-control"><option>1</option><option selected="selected">2</option><option>3</option></select></div>'
289
+ @f.input(:select, :options=>[1, 2, 3], :value=>2).to_s.must_equal '<div class="form-group"><select class="form-control"><option>1</option><option selected="selected">2</option><option>3</option></select></div>'
290
+ end
291
+
292
+ it "should create select tag with options and values" do
293
+ @f.input(:select, :options=>[[:a, 1], [:b, 2], [:c, 3]], :selected=>2).to_s.must_equal '<div class="form-group"><select class="form-control"><option value="1">a</option><option selected="selected" value="2">b</option><option value="3">c</option></select></div>'
294
+ end
295
+
296
+ it "should create select tag with option groups" do
297
+ @f.input(:select, :optgroups=>[['d', [[:a, 1], [:b, 2]]], ['e', [[:c, 3]]]], :selected=>2).to_s.must_equal '<div class="form-group"><select class="form-control"><optgroup label="d"><option value="1">a</option><option selected="selected" value="2">b</option></optgroup><optgroup label="e"><option value="3">c</option></optgroup></select></div>'
298
+ end
299
+
300
+ it "should create select tag with option groups with attributes" do
301
+ @f.input(:select, :optgroups=>[[{:label=>'d', :class=>'f'}, [[:a, 1], [:b, 2]]], [{:label=>'e', :class=>'g'}, [[:c, 3]]]], :selected=>2).to_s.must_equal '<div class="form-group"><select class="form-control"><optgroup class="f" label="d"><option value="1">a</option><option selected="selected" value="2">b</option></optgroup><optgroup class="g" label="e"><option value="3">c</option></optgroup></select></div>'
302
+ end
303
+
304
+ it "should create select tag with options and values with hashes" do
305
+ @f.input(:select, :options=>[[:a, {:foo=>1}], [:b, {:bar=>4, :value=>2}], [:c, {:baz=>3}]], :selected=>2).to_s.must_equal '<div class="form-group"><select class="form-control"><option foo="1">a</option><option bar="4" selected="selected" value="2">b</option><option baz="3">c</option></select></div>'
306
+ end
307
+
308
+ it "should create select tag with options and values using given method" do
309
+ @f.input(:select, :options=>[[:a, 1], [:b, 2], [:c, 3]], :text_method=>:last, :selected=>2).to_s.must_equal '<div class="form-group"><select class="form-control"><option>1</option><option selected="selected">2</option><option>3</option></select></div>'
310
+ @f.input(:select, :options=>[[:a, 1], [:b, 2], [:c, 3]], :text_method=>:last, :value_method=>:first, :selected=>:b).to_s.must_equal '<div class="form-group"><select class="form-control"><option value="a">1</option><option selected="selected" value="b">2</option><option value="c">3</option></select></div>'
311
+ end
312
+
313
+ it "should use html attributes specified in options" do
314
+ @f.input(:text, :value=>'foo', :name=>'bar').to_s.must_equal '<div class="form-group"><input class="form-control" name="bar" type="text" value="foo"/></div>'
315
+ @f.input(:textarea, :value=>'foo', :name=>'bar').to_s.must_equal '<div class="form-group"><textarea class="form-control" name="bar">foo</textarea></div>'
316
+ @f.input(:select, :name=>'bar', :options=>[1, 2, 3]).to_s.must_equal '<div class="form-group"><select class="form-control" name="bar"><option>1</option><option>2</option><option>3</option></select></div>'
317
+ end
318
+
319
+ it "should support :add_blank option for select inputs" do
320
+ @f.input(:select, :options=>[[:b, 2], [:c, 3]], :add_blank=>true, :value=>2).to_s.must_equal '<div class="form-group"><select class="form-control"><option value=""></option><option selected="selected" value="2">b</option><option value="3">c</option></select></div>'
321
+ end
322
+
323
+ it "should use Forme.default_add_blank_prompt value if :add_blank option is true" do
324
+ begin
325
+ Forme.default_add_blank_prompt = 'foo'
326
+ @f.input(:select, :options=>[[:b, 2], [:c, 3]], :add_blank=>true, :value=>2).to_s.must_equal '<div class="form-group"><select class="form-control"><option value="">foo</option><option selected="selected" value="2">b</option><option value="3">c</option></select></div>'
327
+ ensure
328
+ Forme.default_add_blank_prompt = nil
329
+ end
330
+ end
331
+
332
+ it "should use :add_blank option value as prompt if it is a String" do
333
+ @f.input(:select, :options=>[[:b, 2], [:c, 3]], :add_blank=>"Prompt Here", :value=>2).to_s.must_equal '<div class="form-group"><select class="form-control"><option value="">Prompt Here</option><option selected="selected" value="2">b</option><option value="3">c</option></select></div>'
334
+ end
335
+
336
+ it "should support :add_blank option with :blank_position :after for select inputs" do
337
+ @f.input(:select, :options=>[[:b, 2], [:c, 3]], :add_blank=>true, :blank_position=>:after, :value=>2).to_s.must_equal '<div class="form-group"><select class="form-control"><option selected="selected" value="2">b</option><option value="3">c</option><option value=""></option></select></div>'
338
+ end
339
+
340
+ it "should support :add_blank option with :blank_attr option for select inputs" do
341
+ @f.input(:select, :options=>[[:b, 2], [:c, 3]], :add_blank=>true, :blank_attr=>{:foo=>:bar}, :value=>2).to_s.must_equal '<div class="form-group"><select class="form-control"><option foo="bar" value=""></option><option selected="selected" value="2">b</option><option value="3">c</option></select></div>'
342
+ end
343
+
344
+ it "should create set of radio buttons" do
345
+ @f.input(:radioset, :options=>[1, 2, 3], :selected=>2).to_s.must_equal '<div class="radioset"><div class="radio"><label class="option"><input type="radio" value="1"/> 1</label></div><div class="radio"><label class="option"><input checked="checked" type="radio" value="2"/> 2</label></div><div class="radio"><label class="option"><input type="radio" value="3"/> 3</label></div></div>'
346
+ @f.input(:radioset, :options=>[1, 2, 3], :value=>2).to_s.must_equal '<div class="radioset"><div class="radio"><label class="option"><input type="radio" value="1"/> 1</label></div><div class="radio"><label class="option"><input checked="checked" type="radio" value="2"/> 2</label></div><div class="radio"><label class="option"><input type="radio" value="3"/> 3</label></div></div>'
347
+ end
348
+
349
+ it "should create set of radio buttons with options and values" do
350
+ @f.input(:radioset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :selected=>2).to_s.must_equal '<div class="radioset"><div class="radio"><label class="option"><input type="radio" value="1"/> a</label></div><div class="radio"><label class="option"><input checked="checked" type="radio" value="2"/> b</label></div><div class="radio"><label class="option"><input type="radio" value="3"/> c</label></div></div>'
351
+ end
352
+
353
+ it "should create set of radio buttons with options and values with hashes" do
354
+ @f.input(:radioset, :options=>[[:a, {:attr=>{:foo=>1}}], [:b, {:class=>'foo', :value=>2}], [:c, {:id=>:baz}]], :selected=>2).to_s.must_equal '<div class="radioset"><div class="radio"><label class="option"><input foo="1" type="radio" value="a"/> a</label></div><div class="radio"><label class="option"><input checked="checked" class="foo" type="radio" value="2"/> b</label></div><div class="radio"><label class="option" for="baz"><input id="baz" type="radio" value="c"/> c</label></div></div>'
355
+ end
356
+
357
+ it "should create set of radio buttons with options and values using given method" do
358
+ @f.input(:radioset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :text_method=>:last, :selected=>2).to_s.must_equal '<div class="radioset"><div class="radio"><label class="option"><input type="radio" value="1"/> 1</label></div><div class="radio"><label class="option"><input checked="checked" type="radio" value="2"/> 2</label></div><div class="radio"><label class="option"><input type="radio" value="3"/> 3</label></div></div>'
359
+ @f.input(:radioset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :text_method=>:last, :value_method=>:first, :selected=>:b).to_s.must_equal '<div class="radioset"><div class="radio"><label class="option"><input type="radio" value="a"/> 1</label></div><div class="radio"><label class="option"><input checked="checked" type="radio" value="b"/> 2</label></div><div class="radio"><label class="option"><input type="radio" value="c"/> 3</label></div></div>'
360
+ end
361
+
362
+ it "should support :add_blank option for radioset inputs" do
363
+ @f.input(:radioset, :options=>[[:b, 2], [:c, 3]], :add_blank=>true, :value=>2).to_s.must_equal '<div class="radioset"><div class="radio"><label class="option"><input type="radio" value=""/> </label></div><div class="radio"><label class="option"><input checked="checked" type="radio" value="2"/> b</label></div><div class="radio"><label class="option"><input type="radio" value="3"/> c</label></div></div>'
364
+ end
365
+
366
+ it "should use :add_blank option value as prompt if it is a String" do
367
+ @f.input(:radioset, :options=>[[:b, 2], [:c, 3]], :add_blank=>"Prompt Here", :value=>2).to_s.must_equal '<div class="radioset"><div class="radio"><label class="option"><input type="radio" value=""/> Prompt Here</label></div><div class="radio"><label class="option"><input checked="checked" type="radio" value="2"/> b</label></div><div class="radio"><label class="option"><input type="radio" value="3"/> c</label></div></div>'
368
+ end
369
+
370
+ it "should respect the :key option for radio sets" do
371
+ @f.input(:radioset, :options=>[1, 2, 3], :key=>:foo, :value=>2).to_s.must_equal '<div class="radioset"><div class="radio"><label class="option" for="foo_1"><input id="foo_1" name="foo" type="radio" value="1"/> 1</label></div><div class="radio"><label class="option" for="foo_2"><input checked="checked" id="foo_2" name="foo" type="radio" value="2"/> 2</label></div><div class="radio"><label class="option" for="foo_3"><input id="foo_3" name="foo" type="radio" value="3"/> 3</label></div></div>'
372
+ end
373
+
374
+ it "should create set of radio buttons with fieldsets and legends for :optgroups" do
375
+ @f.input(:radioset, :optgroups=>[['d', [[:a, 1], [:b, 2]]], ['e', [[:c, 3]]]], :selected=>2).to_s.must_equal '<div class="radioset"><fieldset><legend>d</legend><div class="radio"><label class="option"><input type="radio" value="1"/> a</label></div><div class="radio"><label class="option"><input checked="checked" type="radio" value="2"/> b</label></div></fieldset><fieldset><legend>e</legend><div class="radio"><label class="option"><input type="radio" value="3"/> c</label></div></fieldset></div>'
376
+ end
377
+
378
+ it "should create set of checkbox buttons" do
379
+ @f.input(:checkboxset, :options=>[1, 2, 3], :selected=>2).to_s.must_equal '<div class="checkboxset"><div class="checkbox"><label class="option"><input type="checkbox" value="1"/> 1</label></div><div class="checkbox"><label class="option"><input checked="checked" type="checkbox" value="2"/> 2</label></div><div class="checkbox"><label class="option"><input type="checkbox" value="3"/> 3</label></div></div>'
380
+ @f.input(:checkboxset, :options=>[1, 2, 3], :value=>2).to_s.must_equal '<div class="checkboxset"><div class="checkbox"><label class="option"><input type="checkbox" value="1"/> 1</label></div><div class="checkbox"><label class="option"><input checked="checked" type="checkbox" value="2"/> 2</label></div><div class="checkbox"><label class="option"><input type="checkbox" value="3"/> 3</label></div></div>'
381
+ end
382
+
383
+ it "should create set of checkbox buttons with options and values" do
384
+ @f.input(:checkboxset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :selected=>2).to_s.must_equal '<div class="checkboxset"><div class="checkbox"><label class="option"><input type="checkbox" value="1"/> a</label></div><div class="checkbox"><label class="option"><input checked="checked" type="checkbox" value="2"/> b</label></div><div class="checkbox"><label class="option"><input type="checkbox" value="3"/> c</label></div></div>'
385
+ end
386
+
387
+ it "should create set of checkbox buttons with options and values with hashes" do
388
+ @f.input(:checkboxset, :options=>[[:a, {:attr=>{:foo=>1}}], [:b, {:class=>'foo', :value=>2}], [:c, {:id=>:baz}]], :selected=>2).to_s.must_equal '<div class="checkboxset"><div class="checkbox"><label class="option"><input foo="1" type="checkbox" value="a"/> a</label></div><div class="checkbox"><label class="option"><input checked="checked" class="foo" type="checkbox" value="2"/> b</label></div><div class="checkbox"><label class="option" for="baz"><input id="baz" type="checkbox" value="c"/> c</label></div></div>'
389
+ end
390
+
391
+ it "should create set of checkbox buttons with options and values using given method" do
392
+ @f.input(:checkboxset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :text_method=>:last, :selected=>2).to_s.must_equal '<div class="checkboxset"><div class="checkbox"><label class="option"><input type="checkbox" value="1"/> 1</label></div><div class="checkbox"><label class="option"><input checked="checked" type="checkbox" value="2"/> 2</label></div><div class="checkbox"><label class="option"><input type="checkbox" value="3"/> 3</label></div></div>'
393
+ @f.input(:checkboxset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :text_method=>:last, :value_method=>:first, :selected=>:b).to_s.must_equal '<div class="checkboxset"><div class="checkbox"><label class="option"><input type="checkbox" value="a"/> 1</label></div><div class="checkbox"><label class="option"><input checked="checked" type="checkbox" value="b"/> 2</label></div><div class="checkbox"><label class="option"><input type="checkbox" value="c"/> 3</label></div></div>'
394
+ end
395
+
396
+ it "should support :add_blank option for checkboxset inputs" do
397
+ @f.input(:checkboxset, :options=>[[:b, 2], [:c, 3]], :add_blank=>true, :value=>2).to_s.must_equal '<div class="checkboxset"><div class="checkbox"><label class="option"><input type="checkbox" value=""/> </label></div><div class="checkbox"><label class="option"><input checked="checked" type="checkbox" value="2"/> b</label></div><div class="checkbox"><label class="option"><input type="checkbox" value="3"/> c</label></div></div>'
398
+ end
399
+
400
+ it "should use :add_blank option value as prompt if it is a String" do
401
+ @f.input(:checkboxset, :options=>[[:b, 2], [:c, 3]], :add_blank=>"Prompt Here", :value=>2).to_s.must_equal '<div class="checkboxset"><div class="checkbox"><label class="option"><input type="checkbox" value=""/> Prompt Here</label></div><div class="checkbox"><label class="option"><input checked="checked" type="checkbox" value="2"/> b</label></div><div class="checkbox"><label class="option"><input type="checkbox" value="3"/> c</label></div></div>'
402
+ end
403
+
404
+ it "should respect the :key option for checkbox sets" do
405
+ @f.input(:checkboxset, :options=>[1, 2, 3], :key=>:foo, :value=>2).to_s.must_equal '<div class="checkboxset"><div class="checkbox"><label class="option" for="foo_1"><input id="foo_1" name="foo[]" type="checkbox" value="1"/> 1</label></div><div class="checkbox"><label class="option" for="foo_2"><input checked="checked" id="foo_2" name="foo[]" type="checkbox" value="2"/> 2</label></div><div class="checkbox"><label class="option" for="foo_3"><input id="foo_3" name="foo[]" type="checkbox" value="3"/> 3</label></div></div>'
406
+ end
407
+
408
+ it "should prefer the :name option to :key option for checkbox sets" do
409
+ @f.input(:checkboxset, :options=>[1, 2, 3], :key=>:foo, :name=>'bar[]', :value=>2).to_s.must_equal '<div class="checkboxset"><div class="checkbox"><label class="option" for="foo_1"><input id="foo_1" name="bar[]" type="checkbox" value="1"/> 1</label></div><div class="checkbox"><label class="option" for="foo_2"><input checked="checked" id="foo_2" name="bar[]" type="checkbox" value="2"/> 2</label></div><div class="checkbox"><label class="option" for="foo_3"><input id="foo_3" name="bar[]" type="checkbox" value="3"/> 3</label></div></div>'
410
+ end
411
+
412
+ it "should prefer the :name and :id option to :key option for checkbox sets" do
413
+ @f.input(:checkboxset, :options=>[1, 2, 3], :key=>:foo, :name=>'bar[]', :id=>:baz, :value=>2).to_s.must_equal '<div class="checkboxset"><div class="checkbox"><label class="option" for="baz_1"><input id="baz_1" name="bar[]" type="checkbox" value="1"/> 1</label></div><div class="checkbox"><label class="option" for="baz_2"><input checked="checked" id="baz_2" name="bar[]" type="checkbox" value="2"/> 2</label></div><div class="checkbox"><label class="option" for="baz_3"><input id="baz_3" name="bar[]" type="checkbox" value="3"/> 3</label></div></div>'
414
+ end
415
+
416
+ it "should respect the :error option for checkbox sets" do
417
+ @f.input(:checkboxset, :options=>[1, 2, 3], :error=>'foo-checkboxset', :value=>2).to_s.must_equal '<div class="checkboxset has-error"><div class="checkbox"><label class="option"><input type="checkbox" value="1"/> 1</label></div><div class="checkbox"><label class="option"><input checked="checked" type="checkbox" value="2"/> 2</label></div><div class="checkbox"><label class="option"><input type="checkbox" value="3"/> 3</label></div><span class="help-block with-errors">foo-checkboxset</span></div>'
418
+ end
419
+
420
+ it "should create set of checkbox buttons with fieldsets and legends for optgroups" do
421
+ @f.input(:checkboxset, :optgroups=>[['d', [[:a, 1], [:b, 2]]], ['e', [[:c, 3]]]], :selected=>2).to_s.must_equal '<div class="checkboxset"><fieldset><legend>d</legend><div class="checkbox"><label class="option"><input type="checkbox" value="1"/> a</label></div><div class="checkbox"><label class="option"><input checked="checked" type="checkbox" value="2"/> b</label></div></fieldset><fieldset><legend>e</legend><div class="checkbox"><label class="option"><input type="checkbox" value="3"/> c</label></div></fieldset></div>'
422
+ end
423
+
424
+ it "radio and checkbox inputs should handle :checked option" do
425
+ @f.input(:radio, :checked=>true).to_s.must_equal '<div class="radio"><input checked="checked" type="radio"/></div>'
426
+ @f.input(:radio, :checked=>false).to_s.must_equal '<div class="radio"><input type="radio"/></div>'
427
+ @f.input(:checkbox, :checked=>true).to_s.must_equal '<div class="checkbox"><input checked="checked" type="checkbox"/></div>'
428
+ @f.input(:checkbox, :checked=>false).to_s.must_equal '<div class="checkbox"><input type="checkbox"/></div>'
429
+ end
430
+
431
+ it "inputs should handle :autofocus option" do
432
+ @f.input(:text, :autofocus=>true).to_s.must_equal '<div class="form-group"><input autofocus="autofocus" class="form-control" type="text"/></div>'
433
+ @f.input(:text, :autofocus=>false).to_s.must_equal '<div class="form-group"><input class="form-control" type="text"/></div>'
434
+ end
435
+
436
+ it "inputs should handle :required option" do
437
+ @f.input(:text, :required=>true).to_s.must_equal '<div class="form-group"><input class="form-control" required="required" type="text"/></div>'
438
+ @f.input(:text, :required=>false).to_s.must_equal '<div class="form-group"><input class="form-control" type="text"/></div>'
439
+ end
440
+
441
+ it "inputs should handle :disabled option" do
442
+ @f.input(:text, :disabled=>true).to_s.must_equal '<div class="form-group"><input class="form-control" disabled="disabled" type="text"/></div>'
443
+ @f.input(:text, :disabled=>false).to_s.must_equal '<div class="form-group"><input class="form-control" type="text"/></div>'
444
+ end
445
+
446
+ it "inputs should not include options with nil values" do
447
+ @f.input(:text, :name=>nil).to_s.must_equal '<div class="form-group"><input class="form-control" type="text"/></div>'
448
+ @f.input(:textarea, :name=>nil).to_s.must_equal '<div class="form-group"><textarea class="form-control"></textarea></div>'
449
+ end
450
+
451
+ it "inputs should include options with false values" do
452
+ @f.input(:text, :name=>false).to_s.must_equal '<div class="form-group"><input class="form-control" name="false" type="text"/></div>'
453
+ end
454
+
455
+ it "should automatically create a label if a :label option is used" do
456
+ @f.input(:text, :label=>'Foo', :value=>'foo').to_s.must_equal '<div class="form-group"><label>Foo</label> <input class="form-control" type="text" value="foo"/></div>'
457
+ end
458
+
459
+ it "should set label attributes with :label_attr option" do
460
+ @f.input(:text, :label=>'Foo', :value=>'foo', :label_attr=>{:class=>'bar'}).to_s.must_equal '<div class="form-group"><label class="bar">Foo</label> <input class="form-control" type="text" value="foo"/></div>'
461
+ end
462
+
463
+ it "should handle implicit labels with checkboxes" do
464
+ @f.input(:checkbox, :label=>'Foo', :value=>'foo', :name=>'a').to_s.must_equal '<div class="checkbox"><label><input name="a" type="hidden" value="0"/><input name="a" type="checkbox" value="foo"/> Foo</label></div>'
465
+ end
466
+
467
+ it "should handle implicit labels with :label_position=>:after" do
468
+ @f.input(:text, :label=>'Foo', :value=>'foo', :label_position=>:after).to_s.must_equal '<div class="form-group"><input class="form-control" type="text" value="foo"/> <label>Foo</label></div>'
469
+ end
470
+
471
+ it "should handle implicit labels with checkboxes with :label_position=>:before" do
472
+ @f.input(:checkbox, :label=>'Foo', :value=>'foo', :name=>'a', :label_position=>:before).to_s.must_equal '<div class="checkbox"><label>Foo <input name="a" type="hidden" value="0"/><input name="a" type="checkbox" value="foo"/></label></div>'
473
+ end
474
+
475
+ it "should automatically note the input has errors if :error option is used" do
476
+ @f.input(:text, :error=>'Bad Stuff!', :value=>'foo').to_s.must_equal '<div class="form-group has-error"><input class="form-control" type="text" value="foo"/><span class="help-block with-errors">Bad Stuff!</span></div>'
477
+ end
478
+
479
+ it "should add an error message after the label" do
480
+ @f.input(:text, :error=>'Bad Stuff!', :value=>'foo', :label=>"Foo").to_s.must_equal '<div class="form-group has-error"><label>Foo</label> <input class="form-control" type="text" value="foo"/><span class="help-block with-errors">Bad Stuff!</span></div>'
481
+ end
482
+
483
+ it "should add to existing :class option if :error option is used" do
484
+ @f.input(:text, :error=>'Bad Stuff!', :class=>'bar', :value=>'foo').to_s.must_equal '<div class="form-group has-error"><input class="form-control bar" type="text" value="foo"/><span class="help-block with-errors">Bad Stuff!</span></div>'
485
+ end
486
+
487
+ it "should respect :error_attr option for setting the attributes for the error message span" do
488
+ @f.input(:text, :error=>'Bad Stuff!', :value=>'foo', :error_attr=>{:class=>'foo'}).to_s.must_equal '<div class="form-group has-error"><input class="form-control" type="text" value="foo"/><span class="foo help-block with-errors">Bad Stuff!</span></div>'
489
+ end
490
+
491
+ it "#open should return an opening tag" do
492
+ @f.open(:action=>'foo', :method=>'post').to_s.must_equal '<form action="foo" method="post">'
493
+ end
494
+
495
+ it "#close should return a closing tag" do
496
+ @f.close.to_s.must_equal '</form>'
497
+ end
498
+
499
+ it "#button should return a submit tag" do
500
+ @f.button.to_s.must_equal '<input class="btn btn-default" type="submit"/>'
501
+ end
502
+
503
+ it "#button should accept an options hash" do
504
+ @f.button(:name=>'foo', :value=>'bar').to_s.must_equal '<input class="btn btn-default" name="foo" type="submit" value="bar"/>'
505
+ end
506
+
507
+ it "#button should handle added classes" do
508
+ @f.button(:class=>'btn btn-primary').to_s.must_equal '<input class="btn btn-primary" type="submit"/>'
509
+ @f.button(:class=>'btn-danger').to_s.must_equal '<input class="btn btn-danger" type="submit"/>'
510
+ @f.button(:class=>'btn-success btn-lg').to_s.must_equal '<input class="btn btn-success btn-lg" type="submit"/>'
511
+ end
512
+
513
+ it "#button should accept a string to use as a value" do
514
+ @f.button('foo').to_s.must_equal '<input class="btn btn-default" type="submit" value="foo"/>'
515
+ end
516
+
517
+ it "#tag should accept children as procs" do
518
+ @f.tag(:div, {:class=>"foo"}, lambda{|t| t.form.tag(:input, :class=>t.attr[:class])}).to_s.must_equal '<div class="foo"><input class="form-control foo" type="text"/></div>'
519
+ end
520
+
521
+ it "#tag should accept children as methods" do
522
+ o = Object.new
523
+ def o.foo(t) t.form.tag(:input, :class=>t.attr[:class]) end
524
+ @f.tag(:div, {:class=>"foo"}, o.method(:foo)).to_s.must_equal '<div class="foo"><input class="form-control foo" type="text"/></div>'
525
+ end
526
+
527
+ it "should have an #inputs method for multiple inputs wrapped in a fieldset" do
528
+ @f.inputs([:textarea, :text]).to_s.must_equal '<fieldset class="inputs"><div class="form-group"><textarea class="form-control"></textarea></div><div class="form-group"><input class="form-control" type="text"/></div></fieldset>'
529
+ end
530
+
531
+ it "should have default #inputs method accept an :attr option" do
532
+ @f.inputs([:textarea, :text], :legend=>'Inputs', :attr=>{:class=>'foo', :bar=>'baz'}).to_s.must_equal '<fieldset bar="baz" class="foo inputs"><legend>Inputs</legend><div class="form-group"><textarea class="form-control"></textarea></div><div class="form-group"><input class="form-control" type="text"/></div></fieldset>'
533
+ end
534
+
535
+ it "should have default #inputs method accept a :legend option" do
536
+ @f.inputs([:textarea, :text], :legend=>'Inputs').to_s.must_equal '<fieldset class="inputs"><legend>Inputs</legend><div class="form-group"><textarea class="form-control"></textarea></div><div class="form-group"><input class="form-control" type="text"/></div></fieldset>'
537
+ end
538
+
539
+ it "should have default #inputs method accept a :legend_attr option" do
540
+ @f.inputs([:textarea, :text], :legend=>'Inputs', :legend_attr=>{:class=>'foo'}).to_s.must_equal '<fieldset class="inputs"><legend class="foo">Inputs</legend><div class="form-group"><textarea class="form-control"></textarea></div><div class="form-group"><input class="form-control" type="text"/></div></fieldset>'
541
+ end
542
+
543
+ it "should have an #inputs method take a block and yield to it" do
544
+ @f.inputs{@f.input(:textarea); @f.input(:text)}.to_s.must_equal '<fieldset class="inputs"><div class="form-group"><textarea class="form-control"></textarea></div><div class="form-group"><input class="form-control" type="text"/></div></fieldset>'
545
+ end
546
+
547
+ it "should have an #inputs method work with both args and block" do
548
+ @f.inputs([:textarea]){@f.input(:text)}.to_s.must_equal '<fieldset class="inputs"><div class="form-group"><textarea class="form-control"></textarea></div><div class="form-group"><input class="form-control" type="text"/></div></fieldset>'
549
+ end
550
+
551
+ it "should have an #inputs method support array arguments and creating inputs with the array as argument list" do
552
+ @f.inputs([[:textarea, {:name=>'foo'}], [:text, {:id=>'bar'}]]).to_s.must_equal '<fieldset class="inputs"><div class="form-group"><textarea class="form-control" name="foo"></textarea></div><div class="form-group"><input class="form-control" id="bar" type="text"/></div></fieldset>'
553
+ end
554
+
555
+ it "should have #inputs accept transformer options to modify the options inside the inputs" do
556
+ @f.inputs([:textarea, :text], :wrapper=>:div).to_s.must_equal '<fieldset class="inputs"><div><textarea class="form-control"></textarea></div><div><input class="form-control" type="text"/></div></fieldset>'
557
+ end
558
+
559
+ it "should have #inputs accept :nested_inputs_wrapper options to modify the :input_wrapper option inside the inputs" do
560
+ @f.inputs(:nested_inputs_wrapper=>:div){@f.inputs([:textarea, :text])}.to_s.must_equal '<fieldset class="inputs"><div><div class="form-group"><textarea class="form-control"></textarea></div><div class="form-group"><input class="form-control" type="text"/></div></div></fieldset>'
561
+ end
562
+
563
+
564
+ it "should escape tag content" do
565
+ @f.tag(:div, {}, ['<p></p>']).to_s.must_equal '<div>&lt;p&gt;&lt;/p&gt;</div>'
566
+ end
567
+
568
+ it "should not escape raw tag content using Forme::Raw" do
569
+ @f.tag(:div, {}, ['<p></p>'.dup.extend(Forme::Raw)]).to_s.must_equal '<div><p></p></div>'
570
+ end
571
+
572
+ it "should not escape raw tag content using Forme.raw" do
573
+ @f.tag(:div, {}, [Forme.raw('<p></p>')]).to_s.must_equal '<div><p></p></div>'
574
+ end
575
+
576
+ it "should not escape raw tag content using Form#raw" do
577
+ @f.tag(:div, {}, [@f.raw('<p></p>')]).to_s.must_equal '<div><p></p></div>'
578
+ end
579
+
580
+ it "should escape tag content in attribute values" do
581
+ @f.tag(:div, :foo=>'<p></p>').to_s.must_equal '<div foo="&lt;p&gt;&lt;/p&gt;"></div>'
582
+ end
583
+
584
+ it "should not escape raw tag content in attribute values" do
585
+ @f.tag(:div, :foo=>Forme.raw('<p></p>')).to_s.must_equal '<div foo="<p></p>"></div>'
586
+ end
587
+
588
+ it "should format dates, times, and datetimes in ISO format" do
589
+ @f.tag(:div, :foo=>Date.new(2011, 6, 5)).to_s.must_equal '<div foo="2011-06-05"></div>'
590
+ @f.tag(:div, :foo=>DateTime.new(2011, 6, 5, 4, 3, 2)).to_s.must_equal '<div foo="2011-06-05T04:03:02.000000"></div>'
591
+ @f.tag(:div, :foo=>Time.utc(2011, 6, 5, 4, 3, 2)).to_s.must_match /<div foo="2011-06-05T04:03:02.000000"><\/div>/ #/
592
+ end
593
+
594
+ it "should format bigdecimals in standard notation" do
595
+ @f.tag(:div, :foo=>BigDecimal.new('10000.010')).to_s.must_equal '<div foo="10000.01"></div>'
596
+ end
597
+
598
+ it "inputs should accept a :wrapper option to use a custom wrapper" do
599
+ @f.input(:text, :wrapper=>:li).to_s.must_equal '<li><input class="form-control" type="text"/></li>'
600
+ end
601
+
602
+ it "inputs should accept a :wrapper_attr option to use custom wrapper attributes" do
603
+ @f.input(:text, :wrapper=>:li, :wrapper_attr=>{:class=>"foo"}).to_s.must_equal '<li class="foo"><input class="form-control" type="text"/></li>'
604
+ end
605
+
606
+ it "inputs should accept a :help option to use custom helper text" do
607
+ @f.input(:text, :help=>"List type of foo").to_s.must_equal '<div class="form-group"><input class="form-control" type="text"/><span class="helper">List type of foo</span></div>'
608
+ end
609
+
610
+ it "inputs should accept a :helper_attr option for custom helper attributes" do
611
+ @f.input(:text, :help=>"List type of foo", :helper_attr=>{:class=>'foo'}).to_s.must_equal '<div class="form-group"><input class="form-control" type="text"/><span class="foo helper">List type of foo</span></div>'
612
+ end
613
+
614
+ it "inputs should have helper displayed inside wrapper, after error" do
615
+ @f.input(:text, :help=>"List type of foo", :error=>'bad', :wrapper=>:li).to_s.must_equal '<li class="has-error"><input class="form-control" type="text"/><span class="help-block with-errors">bad</span><span class="helper">List type of foo</span></li>'
616
+ end
617
+
618
+ it "inputs should accept a :formatter option to use a custom formatter" do
619
+ @f.input(:text, :formatter=>:readonly, :value=>'1', :label=>'Foo').to_s.must_equal '<div class="form-group"><label>Foo</label> <span>1</span></div>'
620
+ @f.input(:text, :formatter=>:default, :value=>'1', :label=>'Foo').to_s.must_equal '<div class="form-group"><label>Foo</label> <input class="form-control" type="text" value="1"/></div>'
621
+ @f.input(:text, :formatter=>:bs3_readonly, :value=>'1', :label=>'Foo').to_s.must_equal '<div class="form-group"><label>Foo</label> <input class="form-control" readonly="readonly" type="text" value="1"/></div>'
622
+ end
623
+
624
+ it "inputs should accept a :labeler option to use a custom labeler" do
625
+ @f.input(:textarea, :labeler=>:explicit, :label=>'bar', :id=>:foo).to_s.must_equal '<div class="form-group"><label class="label-before" for="foo">bar</label><textarea class="form-control" id="foo"></textarea></div>'
626
+ end
627
+
628
+ it "inputs handle explicit labels with :label_position=>:after" do
629
+ @f.input(:textarea, :labeler=>:explicit, :label=>'bar', :id=>:foo, :label_position=>:after).to_s.must_equal '<div class="form-group"><textarea class="form-control" id="foo"></textarea><label class="label-after" for="foo">bar</label></div>'
630
+ end
631
+
632
+ it "should handle explicit labels with checkboxes" do
633
+ @f.input(:checkbox, :labeler=>:explicit, :label=>'Foo', :value=>'foo', :name=>'a', :id=>'bar').to_s.must_equal '<div class="checkbox"><input id="bar_hidden" name="a" type="hidden" value="0"/><input id="bar" name="a" type="checkbox" value="foo"/><label class="label-after" for="bar">Foo</label></div>'
634
+ end
635
+
636
+ it "should handle explicit labels with checkboxes with :label_position=>:before" do
637
+ @f.input(:checkbox, :labeler=>:explicit, :label=>'Foo', :value=>'foo', :name=>'a', :id=>'bar', :label_position=>:before).to_s.must_equal '<div class="checkbox"><label class="label-before" for="bar">Foo</label><input id="bar_hidden" name="a" type="hidden" value="0"/><input id="bar" name="a" type="checkbox" value="foo"/></div>'
638
+ end
639
+
640
+ it "inputs handle implicit labels or checkboxes without hidden fields with :label_position=>:before" do
641
+ @f.input(:checkbox, :label=>'Foo', :value=>'foo', :name=>'a', :id=>'bar', :label_position=>:before, :no_hidden=>true).to_s.must_equal '<div class="checkbox"><label for="bar">Foo <input id="bar" name="a" type="checkbox" value="foo"/></label></div>'
642
+ end
643
+
644
+ it "inputs should accept a :error_handler option to use a custom error_handler" do
645
+ @f.input(:textarea, :error_handler=>proc{|t, i| [t, "!!! #{i.opts[:error]}"]}, :error=>'bar', :id=>:foo).to_s.must_equal '<div class="form-group"><textarea class="form-control" id="foo"></textarea>!!! bar</div>'
646
+ end
647
+
648
+ it "#inputs should accept a :inputs_wrapper option to use a custom inputs_wrapper" do
649
+ @f.inputs([:textarea], :inputs_wrapper=>:ol).to_s.must_equal '<ol><div class="form-group"><textarea class="form-control"></textarea></div></ol>'
650
+ @f.inputs([:textarea], :inputs_wrapper=>:bs3_table, :wrapper=>:trtd).to_s.must_equal '<table class="table table-bordered"><tr><td><textarea class="form-control"></textarea></td><td></td></tr></table>'
651
+ end
652
+
653
+ it "inputs should accept a :wrapper=>nil option to not use a wrapper" do
654
+ Forme::Form.new(:config=>:bs3,:wrapper=>:li).input(:text, :wrapper=>nil).to_s.must_equal '<input class="form-control" type="text"/>'
655
+ end
656
+
657
+ it "inputs should accept a :labeler=>nil option to not use a labeler" do
658
+ @f.input(:textarea, :labeler=>nil, :label=>'bar', :id=>:foo).to_s.must_equal '<div class="form-group"><textarea class="form-control" id="foo"></textarea></div>'
659
+ end
660
+
661
+ it "inputs should accept a :error_handler=>nil option to not use an error_handler" do
662
+ @f.input(:textarea, :error_handler=>nil, :error=>'bar', :id=>:foo).to_s.must_equal '<div class="form-group"><textarea class="form-control" id="foo"></textarea></div>'
663
+ end
664
+
665
+ it "#inputs should accept a :inputs_wrapper=>nil option to not use an inputs_wrapper" do
666
+ @f.form{|f| f.inputs([:textarea], :inputs_wrapper=>nil)}.to_s.must_equal '<form><div class="form-group"><textarea class="form-control"></textarea></div></form>'
667
+ end
668
+
669
+ it "#inputs should treat a single hash argument as an options hash with no default inputs" do
670
+ @f.inputs(:inputs_wrapper=>:ol){@f.input(:textarea)}.to_s.must_equal '<ol><div class="form-group"><textarea class="form-control"></textarea></div></ol>'
671
+ end
672
+
673
+ it "should support setting defaults for inputs at the form level" do
674
+ f = Forme::Form.new(:config=>:bs3, :input_defaults=>{'text'=>{:size=>20}, 'textarea'=>{:cols=>80, :rows=>6}})
675
+ f.input(:text, :name=>"foo").to_s.must_equal '<div class="form-group"><input class="form-control" name="foo" size="20" type="text"/></div>'
676
+ f.input(:textarea, :name=>"foo").to_s.must_equal '<div class="form-group"><textarea class="form-control" cols="80" name="foo" rows="6"></textarea></div>'
677
+ end
678
+
679
+ it "should work with input_defaults with symbol keys using using inputs with symbol keys" do
680
+ f = Forme::Form.new(:config=>:bs3, :input_defaults=>{:text=>{:size=>20}, 'text'=>{:size=>30}})
681
+ f.input(:text, :name=>"foo").to_s.must_equal '<div class="form-group"><input class="form-control" name="foo" size="20" type="text"/></div>'
682
+ f.input('text', :name=>"foo").to_s.must_equal '<div class="form-group"><input class="form-control" name="foo" size="30" type="text"/></div>'
683
+ end
684
+
685
+ it "invalid custom transformers should raise an Error" do
686
+ proc{Forme::Form.new(:config=>:bs3, :wrapper=>Object.new).input(:text).to_s}.must_raise(Forme::Error)
687
+ proc{@f.input(:textarea, :wrapper=>Object.new).to_s}.must_raise(Forme::Error)
688
+ proc{@f.input(:textarea, :formatter=>nil).to_s}.must_raise(Forme::Error)
689
+ end
690
+ end