forme 2.2.0 → 2.3.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.
@@ -1,703 +0,0 @@
1
- require_relative 'spec_helper'
2
- require_relative 'sequel_helper'
3
-
4
- describe "Forme Sequel::Model forms" do
5
- before do
6
- @ab = Album[1]
7
- @b = Forme::Form.new(@ab)
8
- @ac = Album[2]
9
- @c = Forme::Form.new(@ac)
10
- end
11
-
12
- it "should handle Forme::Form subclasses" do
13
- c = Class.new(Forme::Form) do
14
- def form(*)
15
- super{|f| f.tag(:input, :type=>:hidden, :name=>'a', :value=>'b')}
16
- end
17
- end
18
- c.new(@ab).form.must_equal '<form class="forme album" method="post"><input name="a" type="hidden" value="b"/></form>'
19
- end
20
-
21
- it "should have humanize handle objects that support #humanize" do
22
- s = Object.new
23
- def s.to_s; self end
24
- def s.humanize; 'X' end
25
- @b.humanize(s).must_equal 'X'
26
- end
27
-
28
- it "should have humanize handle objects that support #humanize" do
29
- s = 'x_b_id'
30
- class << s
31
- undef :humanize if method_defined?(:humanize)
32
- end
33
- @b.humanize(s).must_equal 'X b'
34
- end
35
-
36
- it "should add appropriate attributes by default" do
37
- @b.form.must_equal '<form class="forme album" method="post"></form>'
38
- end
39
-
40
- it "should allow overriding of attributes" do
41
- @b.form(:class=>:foo, :method=>:get).must_equal '<form class="foo forme album" method="get"></form>'
42
- end
43
-
44
- it "should handle invalid methods" do
45
- def @ab.db_schema
46
- super.merge(:foo=>{:type=>:bar})
47
- end
48
- @b.input(:foo, :value=>'baz').must_equal '<label>Foo: <input id="album_foo" name="album[foo]" type="text" value="baz"/></label>'
49
- end
50
-
51
- it "should allow an array of classes" do
52
- @b.form(:class=>[:foo, :bar]).must_equal '<form class="foo bar forme album" method="post"></form>'
53
- @b.form(:class=>[:foo, [:bar, :baz]]).must_equal '<form class="foo bar baz forme album" method="post"></form>'
54
- end
55
-
56
- it "should use a text field for strings" do
57
- @b.input(:name).must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" type="text" value="b"/></label>'
58
- @c.input(:name).must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" type="text" value="c"/></label>'
59
- end
60
-
61
- it "should allow :as=>:textarea to use a textarea" do
62
- @b.input(:name, :as=>:textarea).must_equal '<label>Name: <textarea id="album_name" maxlength="255" name="album[name]">b</textarea></label>'
63
- @c.input(:name, :as=>:textarea).must_equal '<label>Name: <textarea id="album_name" maxlength="255" name="album[name]">c</textarea></label>'
64
- end
65
-
66
- it "should allow :type=>:textarea to use a textarea" do
67
- @b.input(:name, :type=>:textarea).must_equal '<label>Name: <textarea id="album_name" maxlength="255" name="album[name]">b</textarea></label>'
68
- @c.input(:name, :type=>:textarea).must_equal '<label>Name: <textarea id="album_name" maxlength="255" name="album[name]">c</textarea></label>'
69
- end
70
-
71
- it "should respect :value and :key options when using :type option" do
72
- @b.input(:name, :type=>:textarea, :value=>'a', :key=>'f').must_equal '<label>Name: <textarea id="album_f" maxlength="255" name="album[f]">a</textarea></label>'
73
- end
74
-
75
- it "should not include labels for hidden inputs" do
76
- @b.input(:name, :type=>:hidden).must_equal '<input id="album_name" name="album[name]" type="hidden" value="b"/>'
77
- end
78
-
79
- it "should use text input with inputmode and pattern for integer fields" do
80
- @b.input(:copies_sold).must_equal '<label>Copies sold: <input id="album_copies_sold" inputmode="numeric" name="album[copies_sold]" pattern="-?[0-9]*" type="text" value="10"/></label>'
81
- end
82
-
83
- it "should use text input for numeric fields" do
84
- @b.input(:bd).must_equal '<label>Bd: <input id="album_bd" name="album[bd]" type="text"/></label>'
85
- end
86
-
87
- it "should use text input float fields" do
88
- @b.input(:fl).must_equal '<label>Fl: <input id="album_fl" name="album[fl]" type="text"/></label>'
89
- end
90
-
91
- it "should use date inputs for Dates" do
92
- @b.input(:release_date).must_equal '<label>Release date: <input id="album_release_date" name="album[release_date]" type="date" value="2011-06-05"/></label>'
93
- end
94
-
95
- it "should use datetime inputs for Time" do
96
- @b.input(:created_at).must_match %r{<label>Created at: <input id="album_created_at" name="album\[created_at\]" type="datetime-local" value="2011-06-05T00:00:00.000"/></label>}
97
- end
98
-
99
- it "should use datetime inputs for DateTimes" do
100
- @ab.values[:created_at] = DateTime.new(2011, 6, 5)
101
- @b.input(:created_at).must_equal '<label>Created at: <input id="album_created_at" name="album[created_at]" type="datetime-local" value="2011-06-05T00:00:00.000"/></label>'
102
- end
103
-
104
- it "should use file inputs without value" do
105
- @b.input(:name, :type=>:file).must_equal '<label>Name: <input id="album_name" name="album[name]" type="file"/></label>'
106
- end
107
-
108
- it "should include type as wrapper class" do
109
- @ab.values[:created_at] = DateTime.new(2011, 6, 5)
110
- f = Forme::Form.new(@ab, :wrapper=>:li)
111
- f.input(:name).must_equal '<li class="string"><label>Name: <input id="album_name" maxlength="255" name="album[name]" type="text" value="b"/></label></li>'
112
- f.input(:release_date).must_equal '<li class="date"><label>Release date: <input id="album_release_date" name="album[release_date]" type="date" value="2011-06-05"/></label></li>'
113
- f.input(:created_at).must_equal '<li class="datetime"><label>Created at: <input id="album_created_at" name="album[created_at]" type="datetime-local" value="2011-06-05T00:00:00.000"/></label></li>'
114
- end
115
-
116
- it "should handle :wrapper_attr to add attribues on the wrapper" do
117
- @b.input(:name, :wrapper_attr=>{:foo=>'bar'}, :wrapper=>:div).must_equal '<div class="string" foo="bar"><label>Name: <input id="album_name" maxlength="255" name="album[name]" type="text" value="b"/></label></div>'
118
- end
119
-
120
- it "should handle :key to override the key" do
121
- @b.input(:name, :key=>:f).must_equal '<label>Name: <input id="album_f" maxlength="255" name="album[f]" type="text" value="b"/></label>'
122
- end
123
-
124
- it "should include required * in label if required" do
125
- @b.input(:name, :required=>true).must_equal '<label>Name<abbr title="required">*</abbr>: <input id="album_name" maxlength="255" name="album[name]" required="required" type="text" value="b"/></label>'
126
- end
127
-
128
- it "should add required to label even if :label option specified" do
129
- @b.input(:name, :required=>true, :label=>'Foo').must_equal '<label>Foo<abbr title="required">*</abbr>: <input id="album_name" maxlength="255" name="album[name]" required="required" type="text" value="b"/></label>'
130
- end
131
-
132
- it "should not add required to label even if :label option is nil" do
133
- @b.input(:name, :required=>true, :label=>nil).must_equal '<input id="album_name" maxlength="255" name="album[name]" required="required" type="text" value="b"/>'
134
- end
135
-
136
- it "should include required wrapper class if required" do
137
- f = Forme::Form.new(@ab, :wrapper=>:li)
138
- f.input(:name, :required=>true).must_equal '<li class="string required"><label>Name<abbr title="required">*</abbr>: <input id="album_name" maxlength="255" name="album[name]" required="required" type="text" value="b"/></label></li>'
139
- end
140
-
141
- it "should use a select box for tri-valued boolean fields" do
142
- @b.input(:gold).must_equal '<label>Gold: <select id="album_gold" name="album[gold]"><option value=""></option><option value="t">True</option><option selected="selected" value="f">False</option></select></label>'
143
- @c.input(:gold).must_equal '<label>Gold: <select id="album_gold" name="album[gold]"><option value=""></option><option selected="selected" value="t">True</option><option value="f">False</option></select></label>'
144
- end
145
-
146
- it "should handle :value option for boolean fields" do
147
- @b.input(:gold, :value=>nil).must_equal '<label>Gold: <select id="album_gold" name="album[gold]"><option value=""></option><option value="t">True</option><option value="f">False</option></select></label>'
148
- @b.input(:gold, :value=>true).must_equal '<label>Gold: <select id="album_gold" name="album[gold]"><option value=""></option><option selected="selected" value="t">True</option><option value="f">False</option></select></label>'
149
- @b.input(:gold, :value=>false).must_equal '<label>Gold: <select id="album_gold" name="album[gold]"><option value=""></option><option value="t">True</option><option selected="selected" value="f">False</option></select></label>'
150
- end
151
-
152
- it "should respect :true_label and :false_label options for tri-valued boolean fields" do
153
- @b.input(:gold, :true_label=>"Foo", :false_label=>"Bar").must_equal '<label>Gold: <select id="album_gold" name="album[gold]"><option value=""></option><option value="t">Foo</option><option selected="selected" value="f">Bar</option></select></label>'
154
- end
155
-
156
- it "should respect :true_value and :false_value options for tri-valued boolean fields" do
157
- @b.input(:gold, :true_value=>"Foo", :false_value=>"Bar").must_equal '<label>Gold: <select id="album_gold" name="album[gold]"><option value=""></option><option value="Foo">True</option><option value="Bar">False</option></select></label>'
158
- end
159
-
160
- it "should respect :add_blank option for tri-valued boolean fields" do
161
- @b.input(:gold, :add_blank=>'NULL').must_equal '<label>Gold: <select id="album_gold" name="album[gold]"><option value="">NULL</option><option value="t">True</option><option selected="selected" value="f">False</option></select></label>'
162
- end
163
-
164
- it "should use a select box for dual-valued boolean fields where :required => false" do
165
- @b.input(:platinum, :required=>false).must_equal '<label>Platinum: <select id="album_platinum" name="album[platinum]"><option value=""></option><option value="t">True</option><option selected="selected" value="f">False</option></select></label>'
166
- @c.input(:platinum, :required=>false).must_equal '<label>Platinum: <select id="album_platinum" name="album[platinum]"><option value=""></option><option selected="selected" value="t">True</option><option value="f">False</option></select></label>'
167
- end
168
-
169
- it "should use a checkbox for dual-valued boolean fields" do
170
- @b.input(:platinum).must_equal '<input id="album_platinum_hidden" name="album[platinum]" type="hidden" value="f"/><label><input id="album_platinum" name="album[platinum]" type="checkbox" value="t"/> Platinum</label>'
171
- @c.input(:platinum).must_equal '<input id="album_platinum_hidden" name="album[platinum]" type="hidden" value="f"/><label><input checked="checked" id="album_platinum" name="album[platinum]" type="checkbox" value="t"/> Platinum</label>'
172
- end
173
-
174
- it "should respect :value option for checkbox for dual-valued boolean fields" do
175
- @b.input(:platinum, :value=>nil).must_equal '<input id="album_platinum_hidden" name="album[platinum]" type="hidden" value="f"/><label><input id="album_platinum" name="album[platinum]" type="checkbox" value="t"/> Platinum</label>'
176
- @b.input(:platinum, :value=>false).must_equal '<input id="album_platinum_hidden" name="album[platinum]" type="hidden" value="f"/><label><input id="album_platinum" name="album[platinum]" type="checkbox" value="t"/> Platinum</label>'
177
- @b.input(:platinum, :value=>true).must_equal '<input id="album_platinum_hidden" name="album[platinum]" type="hidden" value="f"/><label><input checked="checked" id="album_platinum" name="album[platinum]" type="checkbox" value="t"/> Platinum</label>'
178
- end
179
-
180
- it "should use radio buttons for boolean fields if :as=>:radio is used" do
181
- @b.input(:platinum, :as=>:radio).must_equal '<span class="label">Platinum</span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label class="option"><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label>'
182
- @c.input(:platinum, :as=>:radio).must_equal '<span class="label">Platinum</span><label class="option"><input checked="checked" id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label class="option"><input id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label>'
183
- end
184
-
185
- it "should handle :value given if :as=>:radio is used" do
186
- @b.input(:platinum, :as=>:radio, :value=>nil).must_equal '<span class="label">Platinum</span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label class="option"><input id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label>'
187
- @b.input(:platinum, :as=>:radio, :value=>true).must_equal '<span class="label">Platinum</span><label class="option"><input checked="checked" id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label class="option"><input id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label>'
188
- @b.input(:platinum, :as=>:radio, :value=>false).must_equal '<span class="label">Platinum</span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label class="option"><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label>'
189
- end
190
-
191
- it "should wrap both inputs if :as=>:radio is used" do
192
- @b = Forme::Form.new(@ab, :wrapper=>:li)
193
- @b.input(:platinum, :as=>:radio).must_equal '<li class="boolean"><span class="label">Platinum</span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label class="option"><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label></li>'
194
- @b.input(:platinum, :as=>:radio, :wrapper=>:div, :tag_wrapper=>:span).must_equal '<div class="boolean"><span class="label">Platinum</span><span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label></span><span><label class="option"><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label></span></div>'
195
- end
196
-
197
- it "should handle errors on radio buttons for boolean fields if :as=>:radio is used" do
198
- @ab.errors.add(:platinum, 'foo')
199
- @b.input(:platinum, :as=>:radio).must_equal '<span class="label">Platinum</span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label class="option"><input aria-describedby="album_platinum_no_error_message" aria-invalid="true" checked="checked" class="error" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label><span class="error_message" id="album_platinum_no_error_message">foo</span>'
200
- end
201
-
202
- it "should handle Raw :label options if :as=>:radio is used" do
203
- @b.input(:platinum, :as=>:radio, :label=>Forme.raw('Foo:<br />')).must_equal '<span class="label">Foo:<br /></span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label class="option"><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label>'
204
- @b.input(:platinum, :as=>:radio, :label=>'Foo:<br />').must_equal '<span class="label">Foo:&lt;br /&gt;</span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label class="option"><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label>'
205
- end
206
-
207
- it "should respect :true_label and :false_label options for boolean fields if :as=>:radio is used" do
208
- @b.input(:platinum, :as=>:radio, :true_label=>"Foo", :false_label=>"Bar").must_equal '<span class="label">Platinum</span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Foo</label><label class="option"><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> Bar</label>'
209
- end
210
-
211
- it "should respect :true_value and :false_value options for boolean fields if :as=>:radio is used" do
212
- @b.input(:platinum, :as=>:radio, :true_value=>"Foo", :false_value=>"Bar").must_equal '<span class="label">Platinum</span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="Foo"/> Yes</label><label class="option"><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="Bar"/> No</label>'
213
- end
214
-
215
- it "should respect :formatter=>:readonly option for boolean fields if :as=>:radio is used" do
216
- @b.input(:platinum, :as=>:radio, :formatter=>:readonly).must_equal '<span class="label">Platinum</span><label class="option"><input disabled="disabled" id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label class="option"><input checked="checked" disabled="disabled" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label>'
217
- end
218
-
219
- it "should use a select box for many_to_one associations" do
220
- @b.input(:artist).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option selected="selected" value="1">a</option><option value="2">d</option></select></label>'
221
- @c.input(:artist).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option value="1">a</option><option selected="selected" value="2">d</option></select></label>'
222
- end
223
-
224
- it "should respect given :key option for many_to_one associations" do
225
- @b.input(:artist, :key=>'f').must_equal '<label>Artist: <select id="album_f" name="album[f]"><option value=""></option><option selected="selected" value="1">a</option><option value="2">d</option></select></label>'
226
- end
227
-
228
- it "should respect given :value option for many_to_one associations" do
229
- @b.input(:artist, :value=>2).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option value="1">a</option><option selected="selected" value="2">d</option></select></label>'
230
- end
231
-
232
- it "should not add a blank option by default if there is a default value and it is required" do
233
- @b.input(:artist, :required=>true).must_equal '<label>Artist<abbr title="required">*</abbr>: <select id="album_artist_id" name="album[artist_id]" required="required"><option selected="selected" value="1">a</option><option value="2">d</option></select></label>'
234
- end
235
-
236
- it "should allow overriding default input type using a :type option" do
237
- @b.input(:artist, :type=>:string, :value=>nil).must_equal '<label>Artist: <input id="album_artist" name="album[artist]" type="text"/></label>'
238
- end
239
-
240
- it "should automatically set :required for many_to_one assocations based on whether the field is required" do
241
- begin
242
- Album.db_schema[:artist_id][:allow_null] = false
243
- @b.input(:artist).must_equal '<label>Artist<abbr title="required">*</abbr>: <select id="album_artist_id" name="album[artist_id]" required="required"><option selected="selected" value="1">a</option><option value="2">d</option></select></label>'
244
- @b.input(:artist, :required=>false).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option selected="selected" value="1">a</option><option value="2">d</option></select></label>'
245
- ensure
246
- Album.db_schema[:artist_id][:allow_null] = true
247
- end
248
- end
249
-
250
- it "should use a required wrapper tag for many_to_one required associations" do
251
- @b.input(:artist, :required=>true, :wrapper=>:li).must_equal '<li class="many_to_one required"><label>Artist<abbr title="required">*</abbr>: <select id="album_artist_id" name="album[artist_id]" required="required"><option selected="selected" value="1">a</option><option value="2">d</option></select></label></li>'
252
- end
253
-
254
- it "should use a set of radio buttons for many_to_one associations with :as=>:radio option" do
255
- @b.input(:artist, :as=>:radio).must_equal '<span class="label">Artist</span><label class="option"><input checked="checked" id="album_artist_id_1" name="album[artist_id]" type="radio" value="1"/> a</label><label class="option"><input id="album_artist_id_2" name="album[artist_id]" type="radio" value="2"/> d</label>'
256
- @c.input(:artist, :as=>:radio).must_equal '<span class="label">Artist</span><label class="option"><input id="album_artist_id_1" name="album[artist_id]" type="radio" value="1"/> a</label><label class="option"><input checked="checked" id="album_artist_id_2" name="album[artist_id]" type="radio" value="2"/> d</label>'
257
- end
258
-
259
- it "should handle Raw label for many_to_one associations with :as=>:radio option" do
260
- @b.input(:artist, :as=>:radio, :label=>Forme.raw('Foo:<br />')).must_equal '<span class="label">Foo:<br /></span><label class="option"><input checked="checked" id="album_artist_id_1" name="album[artist_id]" type="radio" value="1"/> a</label><label class="option"><input id="album_artist_id_2" name="album[artist_id]" type="radio" value="2"/> d</label>'
261
- @b.input(:artist, :as=>:radio, :label=>'Foo<br />').must_equal '<span class="label">Foo&lt;br /&gt;</span><label class="option"><input checked="checked" id="album_artist_id_1" name="album[artist_id]" type="radio" value="1"/> a</label><label class="option"><input id="album_artist_id_2" name="album[artist_id]" type="radio" value="2"/> d</label>'
262
- end
263
-
264
- it "should correctly use the forms wrapper for wrapping radio buttons for many_to_one associations with :as=>:radio option" do
265
- @b = Forme::Form.new(@ab, :wrapper=>:li)
266
- @b.input(:artist, :as=>:radio).must_equal '<li class="many_to_one"><span class="label">Artist</span><label class="option"><input checked="checked" id="album_artist_id_1" name="album[artist_id]" type="radio" value="1"/> a</label><label class="option"><input id="album_artist_id_2" name="album[artist_id]" type="radio" value="2"/> d</label></li>'
267
- end
268
-
269
- it "should support custom wrappers for many_to_one associations with :as=>:radio via :tag_wrapper option" do
270
- @b = Forme::Form.new(@ab, :wrapper=>:li)
271
- @b.input(:artist, :as=>:radio, :wrapper=>proc{|t, i| i.tag(:div, {}, [t])}, :tag_wrapper=>proc{|t, i| i.tag(:span, {}, [t])}).must_equal '<div><span class="label">Artist</span><span><label class="option"><input checked="checked" id="album_artist_id_1" name="album[artist_id]" type="radio" value="1"/> a</label></span><span><label class="option"><input id="album_artist_id_2" name="album[artist_id]" type="radio" value="2"/> d</label></span></div>'
272
- end
273
-
274
- it "should respect an :options entry" do
275
- @b.input(:artist, :options=>Artist.order(:name).map{|a| [a.name, a.id+1]}).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option value="2">a</option><option value="3">d</option></select></label>'
276
- @c.input(:artist, :options=>Artist.order(:name).map{|a| [a.name, a.id+1]}).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option selected="selected" value="2">a</option><option value="3">d</option></select></label>'
277
- end
278
-
279
- it "should support :name_method option for choosing name method" do
280
- @b.input(:artist, :name_method=>:idname).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option selected="selected" value="1">1a</option><option value="2">2d</option></select></label>'
281
- @c.input(:artist, :name_method=>:idname).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option value="1">1a</option><option selected="selected" value="2">2d</option></select></label>'
282
- end
283
-
284
- it "should support :name_method option being a callable object" do
285
- @b.input(:artist, :name_method=>lambda{|obj| obj.idname * 2}).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option selected="selected" value="1">1a1a</option><option value="2">2d2d</option></select></label>'
286
- @c.input(:artist, :name_method=>lambda{|obj| obj.idname * 2}).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option value="1">1a1a</option><option selected="selected" value="2">2d2d</option></select></label>'
287
- end
288
-
289
- it "should support :dataset option providing dataset to search" do
290
- @b.input(:artist, :dataset=>Artist.reverse_order(:name)).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option value="2">d</option><option selected="selected" value="1">a</option></select></label>'
291
- @c.input(:artist, :dataset=>Artist.reverse_order(:name)).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option selected="selected" value="2">d</option><option value="1">a</option></select></label>'
292
- end
293
-
294
- it "should support :dataset option being a callback proc returning modified dataset to search" do
295
- @b.input(:artist, :dataset=>proc{|ds| ds.reverse_order(:name)}).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option value="2">d</option><option selected="selected" value="1">a</option></select></label>'
296
- @c.input(:artist, :dataset=>proc{|ds| ds.reverse_order(:name)}).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option selected="selected" value="2">d</option><option value="1">a</option></select></label>'
297
- end
298
-
299
- it "should try a list of methods to get a suitable one for select box naming" do
300
- al = Class.new(Album){def self.name() 'Album' end}
301
- ar = Class.new(Artist)
302
- al.many_to_one :artist, :class=>ar
303
- ar.class_eval{undef_method(:name)}
304
- f = Forme::Form.new(al.new)
305
-
306
- ar.class_eval{def number() "#{self[:name]}1" end}
307
- f.input(:artist).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option value="1">a1</option><option value="2">d1</option></select></label>'
308
-
309
- ar.class_eval{def title() "#{self[:name]}2" end}
310
- f.input(:artist).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option value="1">a2</option><option value="2">d2</option></select></label>'
311
-
312
- ar.class_eval{def name() "#{self[:name]}3" end}
313
- f.input(:artist).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option value="1">a3</option><option value="2">d3</option></select></label>'
314
-
315
- ar.class_eval{def forme_name() "#{self[:name]}4" end}
316
- f.input(:artist).must_equal '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option value="1">a4</option><option value="2">d4</option></select></label>'
317
- end
318
-
319
- it "should raise an error when using an association without a usable name method" do
320
- al = Class.new(Album)
321
- ar = Class.new(Artist)
322
- al.many_to_one :artist, :class=>ar
323
- ar.class_eval{undef_method(:name)}
324
- proc{Forme::Form.new(al.new).input(:artist)}.must_raise(Sequel::Plugins::Forme::Error)
325
- end
326
-
327
- it "should use a multiple select box for one_to_many associations" do
328
- @b.input(:tracks).must_equal '<label>Tracks: <select id="album_track_pks" multiple="multiple" name="album[track_pks][]"><option selected="selected" value="1">m</option><option selected="selected" value="2">n</option><option value="3">o</option></select></label>'
329
- @c.input(:tracks).must_equal '<label>Tracks: <select id="album_track_pks" multiple="multiple" name="album[track_pks][]"><option value="1">m</option><option value="2">n</option><option selected="selected" value="3">o</option></select></label>'
330
- end
331
-
332
- it "should :respect given :key option for one_to_many associations" do
333
- @b.input(:tracks, :key=>:f).must_equal '<label>Tracks: <select id="album_f" multiple="multiple" name="album[f][]"><option selected="selected" value="1">m</option><option selected="selected" value="2">n</option><option value="3">o</option></select></label>'
334
- end
335
-
336
- it "should :respect given :array=>false, :multiple=>false options for one_to_many associations" do
337
- @b.input(:tracks, :array=>false, :multiple=>false, :value=>1).must_equal '<label>Tracks: <select id="album_track_pks" name="album[track_pks]"><option selected="selected" value="1">m</option><option value="2">n</option><option value="3">o</option></select></label>'
338
- end
339
-
340
- it "should handle case where object doesn't respond to *_pks for one_to_many associations" do
341
- class << @ab
342
- undef track_pks
343
- end
344
- @b.input(:tracks).must_equal '<label>Tracks: <select id="album_track_pks" multiple="multiple" name="album[track_pks][]"><option selected="selected" value="1">m</option><option selected="selected" value="2">n</option><option value="3">o</option></select></label>'
345
- end
346
-
347
- it "should use a multiple select box for many_to_many associations" do
348
- @b.input(:tags).must_equal '<label>Tags: <select id="album_tag_pks" multiple="multiple" name="album[tag_pks][]"><option selected="selected" value="1">s</option><option selected="selected" value="2">t</option><option value="3">u</option></select></label>'
349
- @c.input(:tags).must_equal '<label>Tags: <select id="album_tag_pks" multiple="multiple" name="album[tag_pks][]"><option value="1">s</option><option selected="selected" value="2">t</option><option value="3">u</option></select></label>'
350
- end
351
-
352
- it "should use a multiple select box for pg_array_to_many associations" do
353
- @b.input(:atags).must_equal '<label>Atags: <select id="album_atag_ids" multiple="multiple" name="album[atag_ids][]"><option selected="selected" value="1">s</option><option selected="selected" value="2">t</option><option value="3">u</option></select></label>'
354
- @c.obj.atag_ids.delete(1)
355
- @c.input(:atags).must_equal '<label>Atags: <select id="album_atag_ids" multiple="multiple" name="album[atag_ids][]"><option value="1">s</option><option selected="selected" value="2">t</option><option value="3">u</option></select></label>'
356
- end
357
-
358
- it "should handle an error message on the underlying column for pg_array_to_many associations" do
359
- @ab.errors.add(:atag_ids, 'tis not valid')
360
- @b.input(:atags).must_equal '<label>Atags: <select aria-describedby="album_atag_ids_error_message" aria-invalid="true" class="error" id="album_atag_ids" multiple="multiple" name="album[atag_ids][]"><option selected="selected" value="1">s</option><option selected="selected" value="2">t</option><option value="3">u</option></select></label><span class="error_message" id="album_atag_ids_error_message">tis not valid</span>'
361
- @b.input(:atags, :as=>:checkbox).must_equal '<span class="label">Atags</span><label class="option"><input checked="checked" id="album_atag_ids_1" name="album[atag_ids][]" type="checkbox" value="1"/> s</label><label class="option"><input checked="checked" id="album_atag_ids_2" name="album[atag_ids][]" type="checkbox" value="2"/> t</label><label class="option"><input aria-describedby="album_atag_ids_3_error_message" aria-invalid="true" class="error" id="album_atag_ids_3" name="album[atag_ids][]" type="checkbox" value="3"/> u</label><span class="error_message" id="album_atag_ids_3_error_message">tis not valid</span>'
362
- end
363
-
364
- it "should use a regular select box for *_to_many associations if multiple if false" do
365
- @b.input(:tracks, :multiple=>false).must_equal '<label>Tracks: <select id="album_track_pks" name="album[track_pks][]"><option value="1">m</option><option value="2">n</option><option value="3">o</option></select></label>'
366
- @c.input(:tags, :multiple=>false).must_equal '<label>Tags: <select id="album_tag_pks" name="album[tag_pks][]"><option value="1">s</option><option value="2">t</option><option value="3">u</option></select></label>'
367
- end
368
-
369
- it "should handle a given :value for one_to_many associations" do
370
- @b.input(:tracks, :value=>[1,3]).must_equal '<label>Tracks: <select id="album_track_pks" multiple="multiple" name="album[track_pks][]"><option selected="selected" value="1">m</option><option value="2">n</option><option selected="selected" value="3">o</option></select></label>'
371
- @c.input(:tracks, :value=>nil).must_equal '<label>Tracks: <select id="album_track_pks" multiple="multiple" name="album[track_pks][]"><option value="1">m</option><option value="2">n</option><option value="3">o</option></select></label>'
372
- end
373
-
374
- it "should use multiple checkboxes for one_to_many associations if :as=>:checkbox" do
375
- @b.input(:tracks, :as=>:checkbox).must_equal '<span class="label">Tracks</span><label class="option"><input checked="checked" id="album_track_pks_1" name="album[track_pks][]" type="checkbox" value="1"/> m</label><label class="option"><input checked="checked" id="album_track_pks_2" name="album[track_pks][]" type="checkbox" value="2"/> n</label><label class="option"><input id="album_track_pks_3" name="album[track_pks][]" type="checkbox" value="3"/> o</label>'
376
- @c.input(:tracks, :as=>:checkbox).must_equal '<span class="label">Tracks</span><label class="option"><input id="album_track_pks_1" name="album[track_pks][]" type="checkbox" value="1"/> m</label><label class="option"><input id="album_track_pks_2" name="album[track_pks][]" type="checkbox" value="2"/> n</label><label class="option"><input checked="checked" id="album_track_pks_3" name="album[track_pks][]" type="checkbox" value="3"/> o</label>'
377
- end
378
-
379
- it "should use multiple checkboxes for many_to_many associations if :as=>:checkbox" do
380
- @b.input(:tags, :as=>:checkbox).must_equal '<span class="label">Tags</span><label class="option"><input checked="checked" id="album_tag_pks_1" name="album[tag_pks][]" type="checkbox" value="1"/> s</label><label class="option"><input checked="checked" id="album_tag_pks_2" name="album[tag_pks][]" type="checkbox" value="2"/> t</label><label class="option"><input id="album_tag_pks_3" name="album[tag_pks][]" type="checkbox" value="3"/> u</label>'
381
- @c.input(:tags, :as=>:checkbox).must_equal '<span class="label">Tags</span><label class="option"><input id="album_tag_pks_1" name="album[tag_pks][]" type="checkbox" value="1"/> s</label><label class="option"><input checked="checked" id="album_tag_pks_2" name="album[tag_pks][]" type="checkbox" value="2"/> t</label><label class="option"><input id="album_tag_pks_3" name="album[tag_pks][]" type="checkbox" value="3"/> u</label>'
382
- end
383
-
384
- it "should handle Raw label for associations with :as=>:checkbox" do
385
- @b.input(:tracks, :as=>:checkbox, :label=>Forme.raw('Foo<br />:')).must_equal '<span class="label">Foo<br />:</span><label class="option"><input checked="checked" id="album_track_pks_1" name="album[track_pks][]" type="checkbox" value="1"/> m</label><label class="option"><input checked="checked" id="album_track_pks_2" name="album[track_pks][]" type="checkbox" value="2"/> n</label><label class="option"><input id="album_track_pks_3" name="album[track_pks][]" type="checkbox" value="3"/> o</label>'
386
- @b.input(:tracks, :as=>:checkbox, :label=>'Foo<br />').must_equal '<span class="label">Foo&lt;br /&gt;</span><label class="option"><input checked="checked" id="album_track_pks_1" name="album[track_pks][]" type="checkbox" value="1"/> m</label><label class="option"><input checked="checked" id="album_track_pks_2" name="album[track_pks][]" type="checkbox" value="2"/> n</label><label class="option"><input id="album_track_pks_3" name="album[track_pks][]" type="checkbox" value="3"/> o</label>'
387
- end
388
-
389
- it "should correctly use the forms wrapper for wrapping radio buttons for one_to_many associations with :as=>:checkbox option" do
390
- @b = Forme::Form.new(@ab, :wrapper=>:li)
391
- @b.input(:tracks, :as=>:checkbox).must_equal '<li class="one_to_many"><span class="label">Tracks</span><label class="option"><input checked="checked" id="album_track_pks_1" name="album[track_pks][]" type="checkbox" value="1"/> m</label><label class="option"><input checked="checked" id="album_track_pks_2" name="album[track_pks][]" type="checkbox" value="2"/> n</label><label class="option"><input id="album_track_pks_3" name="album[track_pks][]" type="checkbox" value="3"/> o</label></li>'
392
- end
393
-
394
- it "should support custom wrappers for one_to_many associations with :as=>:checkbox via :tag_wrapper option" do
395
- @b = Forme::Form.new(@ab, :wrapper=>:li)
396
- @b.input(:tracks, :as=>:checkbox, :wrapper=>proc{|t, i| i.tag(:div, i.opts[:wrapper_attr], [t])}, :tag_wrapper=>proc{|t, i| i.tag(:span, {}, [t])}).must_equal '<div class="one_to_many"><span class="label">Tracks</span><span><label class="option"><input checked="checked" id="album_track_pks_1" name="album[track_pks][]" type="checkbox" value="1"/> m</label></span><span><label class="option"><input checked="checked" id="album_track_pks_2" name="album[track_pks][]" type="checkbox" value="2"/> n</label></span><span><label class="option"><input id="album_track_pks_3" name="album[track_pks][]" type="checkbox" value="3"/> o</label></span></div>'
397
- end
398
-
399
- it "should use a text field methods not backed by columns" do
400
- @b.input(:artist_name).must_equal '<label>Artist name: <input id="album_artist_name" name="album[artist_name]" type="text" value="a"/></label>'
401
- @c.input(:artist_name).must_equal '<label>Artist name: <input id="album_artist_name" name="album[artist_name]" type="text" value="d"/></label>'
402
- end
403
-
404
- it "should handle errors on methods not backed by columns" do
405
- @ab.errors.add(:artist_name, 'foo')
406
- @b.input(:artist_name).must_equal '<label>Artist name: <input aria-describedby="album_artist_name_error_message" aria-invalid="true" class="error" id="album_artist_name" name="album[artist_name]" type="text" value="a"/></label><span class="error_message" id="album_artist_name_error_message">foo</span>'
407
- end
408
-
409
- it "should respect a :type option with a schema type as the input type for methods not backed by columns" do
410
- def @ab.foo; false end
411
- @b.input(:foo, :type=>:boolean, :as=>:select).must_equal '<label>Foo: <select id="album_foo" name="album[foo]"><option value=""></option><option value="t">True</option><option selected="selected" value="f">False</option></select></label>'
412
- end
413
-
414
- it "should respect a :type option with an input type as the input type for methods not backed by columns" do
415
- def @ab.foo; "bar" end
416
- @b.input(:foo, :type=>:phone).must_equal '<label>Foo: <input id="album_foo" name="album[foo]" type="phone" value="bar"/></label>'
417
- end
418
-
419
- it "should not override an explicit :error setting" do
420
- @ab.errors.add(:name, 'tis not valid')
421
- @b.input(:name, :error=>nil).must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" type="text" value="b"/></label>'
422
- end
423
-
424
- it "should correctly show an error message if there is one" do
425
- @ab.errors.add(:name, 'tis not valid')
426
- @b.input(:name).must_equal '<label>Name: <input aria-describedby="album_name_error_message" aria-invalid="true" class="error" id="album_name" maxlength="255" name="album[name]" type="text" value="b"/></label><span class="error_message" id="album_name_error_message">tis not valid</span>'
427
- end
428
-
429
- it "should correctly show an error message for many_to_one associations if there is one" do
430
- @ab.errors.add(:artist_id, 'tis not valid')
431
- @b.input(:artist).must_equal '<label>Artist: <select aria-describedby="album_artist_id_error_message" aria-invalid="true" class="error" id="album_artist_id" name="album[artist_id]"><option value=""></option><option selected="selected" value="1">a</option><option value="2">d</option></select></label><span class="error_message" id="album_artist_id_error_message">tis not valid</span>'
432
- end
433
-
434
- it "should raise an error for unhandled associations" do
435
- al = Class.new(Album)
436
- al.one_to_many :tags
437
- al.association_reflection(:tags)[:type] = :foo
438
- proc{Forme::Form.new(al.new).input(:tags)}.must_raise(Sequel::Plugins::Forme::Error)
439
- end
440
-
441
- it "should raise an error for unhandled fields with no :type option" do
442
- proc{@b.input(:foo)}.must_raise(Sequel::Plugins::Forme::Error)
443
- end
444
-
445
- it "should respect a :type option with a schema type as the input type for unhandled fields" do
446
- @b.input(:foo, :type=>:string).must_equal '<label>Foo: <input id="album_foo" name="album[foo]" type="text"/></label>'
447
- @b.input(:password, :type=>:string).must_equal '<label>Password: <input id="album_password" name="album[password]" type="password"/></label>'
448
- end
449
-
450
- it "should respect a :type option with an input type as the input type for unhandled fields" do
451
- @b.input(:foo, :type=>:phone).must_equal '<label>Foo: <input id="album_foo" name="album[foo]" type="phone"/></label>'
452
- end
453
-
454
- it "should respect a :multiple option for the name attribute for unhandled fields" do
455
- @b.input(:foo, :type=>:phone, :multiple=>true).must_equal '<label>Foo: <input id="album_foo" name="album[foo][]" type="phone"/></label>'
456
- end
457
-
458
- it "should add required attribute if the column doesn't support nil values" do
459
- def @ab.db_schema; h = super.dup; h[:name] = h[:name].merge(:allow_null=>false); h end
460
- @b.input(:name).must_equal '<label>Name<abbr title="required">*</abbr>: <input id="album_name" maxlength="255" name="album[name]" required="required" type="text" value="b"/></label>'
461
- end
462
-
463
- it "should use allow nested forms with many_to_one associations" do
464
- Forme.form(@ab){|f| f.subform(:artist){f.input(:name)}}.must_equal '<form class="forme album" method="post"><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><fieldset class="inputs"><legend>Artist</legend><label>Name: <input id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="a"/></label></fieldset></form>'
465
- end
466
-
467
- it "should have #subform respect an :inputs option" do
468
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name])}.must_equal '<form class="forme album" method="post"><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><fieldset class="inputs"><legend>Artist</legend><label>Name: <input id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="a"/></label></fieldset></form>'
469
- end
470
-
471
- it "should have #subform respect an :obj option overriding the object to use" do
472
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :obj=>Artist.new(:name=>'b'))}.must_equal '<form class="forme album" method="post"><fieldset class="inputs"><legend>Artist</legend><label>Name: <input id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="b"/></label></fieldset></form>'
473
- end
474
-
475
- it "should have #subform respect a :legend option if :inputs is used" do
476
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :legend=>'Foo')}.must_equal '<form class="forme album" method="post"><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><fieldset class="inputs"><legend>Foo</legend><label>Name: <input id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="a"/></label></fieldset></form>'
477
- end
478
-
479
- it "should have #subform respect a callable :legend option if :inputs is used" do
480
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :legend=>proc{|o| "Foo - #{o.name}"})}.must_equal '<form class="forme album" method="post"><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><fieldset class="inputs"><legend>Foo - a</legend><label>Name: <input id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="a"/></label></fieldset></form>'
481
- end
482
-
483
- it "should not add hidden primary key field for new many_to_one associated objects" do
484
- @ab.associations[:artist] = Artist.new(:name=>'a')
485
- Forme.form(@ab){|f| f.subform(:artist){f.input(:name)}}.must_equal '<form class="forme album" method="post"><fieldset class="inputs"><legend>Artist</legend><label>Name: <input id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="a"/></label></fieldset></form>'
486
- end
487
-
488
- it "should use allow nested forms with one_to_one associations" do
489
- Forme.form(@ab){|f| f.subform(:album_info, :obj=>AlbumInfo.new(:info=>'a')){f.input(:info)}}.must_equal '<form class="forme album" method="post"><fieldset class="inputs"><legend>Album info</legend><label>Info: <input id="album_album_info_attributes_info" maxlength="255" name="album[album_info_attributes][info]" type="text" value="a"/></label></fieldset></form>'
490
- end
491
-
492
- it "should use allow nested forms with one_to_many associations" do
493
- Forme.form(@ab){|f| f.subform(:tracks){f.input(:name)}}.must_equal '<form class="forme album" method="post"><input id="album_tracks_attributes_0_id" name="album[tracks_attributes][0][id]" type="hidden" value="1"/><input id="album_tracks_attributes_1_id" name="album[tracks_attributes][1][id]" type="hidden" value="2"/><fieldset class="inputs"><legend>Track #1</legend><label>Name: <input id="album_tracks_attributes_0_name" maxlength="255" name="album[tracks_attributes][0][name]" type="text" value="m"/></label></fieldset><fieldset class="inputs"><legend>Track #2</legend><label>Name: <input id="album_tracks_attributes_1_name" maxlength="255" name="album[tracks_attributes][1][name]" type="text" value="n"/></label></fieldset></form>'
494
- end
495
-
496
- it "should support :obj option for *_to_many associations" do
497
- Forme.form(@ab){|f| f.subform(:tracks, :obj=>[Track.new(:name=>'x'), Track.load(:id=>5, :name=>'y')]){f.input(:name)}}.must_equal '<form class="forme album" method="post"><input id="album_tracks_attributes_1_id" name="album[tracks_attributes][1][id]" type="hidden" value="5"/><fieldset class="inputs"><legend>Track #1</legend><label>Name: <input id="album_tracks_attributes_0_name" maxlength="255" name="album[tracks_attributes][0][name]" type="text" value="x"/></label></fieldset><fieldset class="inputs"><legend>Track #2</legend><label>Name: <input id="album_tracks_attributes_1_name" maxlength="255" name="album[tracks_attributes][1][name]" type="text" value="y"/></label></fieldset></form>'
498
- end
499
-
500
- it "should auto number legends when using subform with inputs for *_to_many associations" do
501
- Forme.form(@ab){|f| f.subform(:tracks, :inputs=>[:name])}.must_equal '<form class="forme album" method="post"><input id="album_tracks_attributes_0_id" name="album[tracks_attributes][0][id]" type="hidden" value="1"/><input id="album_tracks_attributes_1_id" name="album[tracks_attributes][1][id]" type="hidden" value="2"/><fieldset class="inputs"><legend>Track #1</legend><label>Name: <input id="album_tracks_attributes_0_name" maxlength="255" name="album[tracks_attributes][0][name]" type="text" value="m"/></label></fieldset><fieldset class="inputs"><legend>Track #2</legend><label>Name: <input id="album_tracks_attributes_1_name" maxlength="255" name="album[tracks_attributes][1][name]" type="text" value="n"/></label></fieldset></form>'
502
- end
503
-
504
- it "should support callable :legend option when using subform with inputs for *_to_many associations" do
505
- Forme.form(@ab){|f| f.subform(:tracks, :inputs=>[:name], :legend=>proc{|o, i| "Track #{i} (#{o.name})"})}.must_equal '<form class="forme album" method="post"><input id="album_tracks_attributes_0_id" name="album[tracks_attributes][0][id]" type="hidden" value="1"/><input id="album_tracks_attributes_1_id" name="album[tracks_attributes][1][id]" type="hidden" value="2"/><fieldset class="inputs"><legend>Track 0 (m)</legend><label>Name: <input id="album_tracks_attributes_0_name" maxlength="255" name="album[tracks_attributes][0][name]" type="text" value="m"/></label></fieldset><fieldset class="inputs"><legend>Track 1 (n)</legend><label>Name: <input id="album_tracks_attributes_1_name" maxlength="255" name="album[tracks_attributes][1][name]" type="text" value="n"/></label></fieldset></form>'
506
- end
507
-
508
- it "should not add hidden primary key field for nested forms with one_to_many associations with new objects" do
509
- @ab.associations[:tracks] = [Track.new(:name=>'m'), Track.new(:name=>'n')]
510
- Forme.form(@ab){|f| f.subform(:tracks){f.input(:name)}}.must_equal '<form class="forme album" method="post"><fieldset class="inputs"><legend>Track #1</legend><label>Name: <input id="album_tracks_attributes_0_name" maxlength="255" name="album[tracks_attributes][0][name]" type="text" value="m"/></label></fieldset><fieldset class="inputs"><legend>Track #2</legend><label>Name: <input id="album_tracks_attributes_1_name" maxlength="255" name="album[tracks_attributes][1][name]" type="text" value="n"/></label></fieldset></form>'
511
- end
512
-
513
- it "should use allow nested forms with many_to_many associations" do
514
- Forme.form(@ab){|f| f.subform(:tags){f.input(:name)}}.must_equal '<form class="forme album" method="post"><input id="album_tags_attributes_0_id" name="album[tags_attributes][0][id]" type="hidden" value="1"/><input id="album_tags_attributes_1_id" name="album[tags_attributes][1][id]" type="hidden" value="2"/><fieldset class="inputs"><legend>Tag #1</legend><label>Name: <input id="album_tags_attributes_0_name" maxlength="255" name="album[tags_attributes][0][name]" type="text" value="s"/></label></fieldset><fieldset class="inputs"><legend>Tag #2</legend><label>Name: <input id="album_tags_attributes_1_name" maxlength="255" name="album[tags_attributes][1][name]" type="text" value="t"/></label></fieldset></form>'
515
- end
516
-
517
- it "should not add hidden primary key field for nested forms with many_to_many associations with new objects" do
518
- @ab.associations[:tags] = [Tag.new(:name=>'s'), Tag.new(:name=>'t')]
519
- Forme.form(@ab){|f| f.subform(:tags){f.input(:name)}}.must_equal '<form class="forme album" method="post"><fieldset class="inputs"><legend>Tag #1</legend><label>Name: <input id="album_tags_attributes_0_name" maxlength="255" name="album[tags_attributes][0][name]" type="text" value="s"/></label></fieldset><fieldset class="inputs"><legend>Tag #2</legend><label>Name: <input id="album_tags_attributes_1_name" maxlength="255" name="album[tags_attributes][1][name]" type="text" value="t"/></label></fieldset></form>'
520
- end
521
-
522
- it "should handle multiple nested levels" do
523
- Forme.form(Artist[1]){|f| f.subform(:albums){f.input(:name); f.subform(:tracks){f.input(:name)}}}.to_s.must_equal '<form class="forme artist" method="post"><input id="artist_albums_attributes_0_id" name="artist[albums_attributes][0][id]" type="hidden" value="1"/><fieldset class="inputs"><legend>Album #1</legend><label>Name: <input id="artist_albums_attributes_0_name" maxlength="255" name="artist[albums_attributes][0][name]" type="text" value="b"/></label><input id="artist_albums_attributes_0_tracks_attributes_0_id" name="artist[albums_attributes][0][tracks_attributes][0][id]" type="hidden" value="1"/><input id="artist_albums_attributes_0_tracks_attributes_1_id" name="artist[albums_attributes][0][tracks_attributes][1][id]" type="hidden" value="2"/><fieldset class="inputs"><legend>Track #1</legend><label>Name: <input id="artist_albums_attributes_0_tracks_attributes_0_name" maxlength="255" name="artist[albums_attributes][0][tracks_attributes][0][name]" type="text" value="m"/></label></fieldset><fieldset class="inputs"><legend>Track #2</legend><label>Name: <input id="artist_albums_attributes_0_tracks_attributes_1_name" maxlength="255" name="artist[albums_attributes][0][tracks_attributes][1][name]" type="text" value="n"/></label></fieldset></fieldset></form>'
524
- end
525
-
526
- it "should have #subform :grid option create a grid" do
527
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true)}.must_equal '<form class="forme album" method="post"><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><table><caption>Artist</caption><thead><tr><th>Name</th></tr></thead><tbody><tr><td class="string"><input id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
528
- end
529
-
530
- it "should have #subform :grid option respect :inputs_opts option to pass options to inputs" do
531
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :inputs_opts=>{:attr=>{:class=>'foo'}})}.must_equal '<form class="forme album" method="post"><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><table class="foo"><caption>Artist</caption><thead><tr><th>Name</th></tr></thead><tbody><tr><td class="string"><input id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
532
- end
533
-
534
- it "should have #subform :grid option handle :legend and :labels options" do
535
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :legend=>'Foo', :labels=>%w'Bar')}.must_equal '<form class="forme album" method="post"><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><table><caption>Foo</caption><thead><tr><th>Bar</th></tr></thead><tbody><tr><td class="string"><input id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
536
- end
537
-
538
- it "should have #subform :grid option handle :legend and :labels nil values" do
539
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :legend=>nil, :labels=>nil)}.must_equal '<form class="forme album" method="post"><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><table><tbody><tr><td class="string"><input id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
540
- end
541
-
542
- it "should have #subform :grid option handle :skip_primary_key option" do
543
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :skip_primary_key=>true)}.must_equal '<form class="forme album" method="post"><table><caption>Artist</caption><thead><tr><th>Name</th></tr></thead><tbody><tr><td class="string"><input id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
544
- end
545
-
546
- it "should have #subform :grid option handle no :inputs or :labels" do
547
- Forme.form(@ab){|f| f.subform(:artist, :grid=>true){f.input(:name)}}.must_equal '<form class="forme album" method="post"><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="1"/><table><caption>Artist</caption><tbody><tr><td class="string"><input id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="a"/></td></tr></tbody></table></form>'
548
- end
549
-
550
- it "should handle non-Sequel forms with Sequel inputs" do
551
- Forme.form{|f| f.input(:name, :obj=>@ab).must_equal '<label>Name: <input id="name" maxlength="255" name="name" type="text" value="b"/></label>'}
552
- end
553
- end
554
-
555
- describe "Forme Sequel plugin default input types based on column names" do
556
- def f(name)
557
- DB.create_table!(:test){String name}
558
- Forme::Form.new(Class.new(Sequel::Model).class_eval{def self.name; 'Test' end; set_dataset :test}.new).input(name, :value=>'foo')
559
- end
560
-
561
- it "should use password input with no value for string columns with name password" do
562
- f(:password).must_equal '<label>Password: <input id="test_password" maxlength="255" name="test[password]" type="password"/></label>'
563
- end
564
-
565
- it "should use email input for string columns with name email" do
566
- f(:email).must_equal '<label>Email: <input id="test_email" maxlength="255" name="test[email]" type="email" value="foo"/></label>'
567
- end
568
-
569
- it "should use tel input for string columns with name phone or fax" do
570
- f(:phone).must_equal '<label>Phone: <input id="test_phone" maxlength="255" name="test[phone]" type="tel" value="foo"/></label>'
571
- f(:fax).must_equal '<label>Fax: <input id="test_fax" maxlength="255" name="test[fax]" type="tel" value="foo"/></label>'
572
- end
573
-
574
- it "should use url input for string columns with name url, uri, or website" do
575
- f(:url).must_equal '<label>Url: <input id="test_url" maxlength="255" name="test[url]" type="url" value="foo"/></label>'
576
- f(:uri).must_equal '<label>Uri: <input id="test_uri" maxlength="255" name="test[uri]" type="url" value="foo"/></label>'
577
- f(:website).must_equal '<label>Website: <input id="test_website" maxlength="255" name="test[website]" type="url" value="foo"/></label>'
578
- end
579
- end
580
-
581
- describe "Forme Sequel plugin default input types based on column type" do
582
- def f(type)
583
- DB.create_table!(:test){column :foo, type}
584
- Forme::Form.new(Class.new(Sequel::Model).class_eval{def self.name; 'Test' end; set_dataset :test}.new).input(:foo, :value=>'foo')
585
- end
586
-
587
- it "should use a file input for blob types" do
588
- f(File).must_equal '<label>Foo: <input id="test_foo" name="test[foo]" type="file"/></label>'
589
- end
590
- end
591
-
592
- describe "Forme Sequel::Model validation parsing" do
593
- def f(*a)
594
- c = Class.new(Album){def self.name; "Album"; end}
595
- c.plugin :validation_class_methods
596
- c.send(*a)
597
- Forme::Form.new(c.new)
598
- end
599
-
600
- it "should turn format into a pattern" do
601
- f(:validates_format_of, :name, :with=>/[A-z]+/).input(:name).must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" pattern="[A-z]+" type="text"/></label>'
602
- end
603
-
604
- it "should not override given :pattern for format validation" do
605
- f(:validates_format_of, :name, :with=>/[A-z]+/).input(:name, :attr=>{:pattern=>'[A-Z]+'}).must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" pattern="[A-Z]+" type="text"/></label>'
606
- end
607
-
608
- it "should respect :title option for format" do
609
- f(:validates_format_of, :name, :with=>/[A-z]+/, :title=>'Foo').input(:name).must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" pattern="[A-z]+" title="Foo" type="text"/></label>'
610
- end
611
-
612
- it "should not override given :title for format validation" do
613
- f(:validates_format_of, :name, :with=>/[A-z]+/, :title=>'Foo').input(:name, :attr=>{:title=>'Bar'}).must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" pattern="[A-z]+" title="Bar" type="text"/></label>'
614
- end
615
-
616
- it "should use maxlength for length :maximum, :is, and :within" do
617
- f(:validates_length_of, :name, :maximum=>10).input(:name).must_equal '<label>Name: <input id="album_name" maxlength="10" name="album[name]" type="text"/></label>'
618
- f(:validates_length_of, :name, :is=>10).input(:name).must_equal '<label>Name: <input id="album_name" maxlength="10" name="album[name]" type="text"/></label>'
619
- f(:validates_length_of, :name, :within=>2..10).input(:name).must_equal '<label>Name: <input id="album_name" maxlength="10" name="album[name]" type="text"/></label>'
620
- f(:validates_length_of, :name, :within=>2...11).input(:name).must_equal '<label>Name: <input id="album_name" maxlength="10" name="album[name]" type="text"/></label>'
621
- end
622
-
623
- it "should not override given :maxlength" do
624
- f(:validates_length_of, :name, :maximum=>10).input(:name, :attr=>{:maxlength=>20}).must_equal '<label>Name: <input id="album_name" maxlength="20" name="album[name]" type="text"/></label>'
625
- end
626
-
627
- it "should not use maxlength for :within that is not a range" do
628
- f(:validates_length_of, :name, :within=>(2..10).to_a).input(:name).must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" type="text"/></label>'
629
- end
630
-
631
- it "should turn numericality into a pattern" do
632
- f(:validates_numericality_of, :name).input(:name).must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" pattern="^[+\-]?\d+(\.\d+)?$" title="must be a number" type="text"/></label>'
633
- end
634
-
635
- it "should turn numericality :only_integer into a pattern" do
636
- f(:validates_numericality_of, :name, :only_integer=>true).input(:name).must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" pattern="^[+\-]?\d+$" title="must be a number" type="text"/></label>'
637
- end
638
-
639
- it "should not override given :pattern for numericality validation" do
640
- f(:validates_numericality_of, :name).input(:name, :attr=>{:pattern=>'[0-9]+'}).must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" pattern="[0-9]+" title="must be a number" type="text"/></label>'
641
- end
642
-
643
- it "should respect :title option for numericality" do
644
- f(:validates_numericality_of, :name, :title=>'Foo').input(:name).must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" pattern="^[+\-]?\d+(\.\d+)?$" title="Foo" type="text"/></label>'
645
- end
646
-
647
- it "should not override given :title for numericality validation" do
648
- f(:validates_numericality_of, :name, :title=>'Foo').input(:name, :attr=>{:title=>'Bar'}).must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" pattern="^[+\-]?\d+(\.\d+)?$" title="Bar" type="text"/></label>'
649
- end
650
-
651
- it "should respect :placeholder option for any validation" do
652
- f(:validates_uniqueness_of, :name, :placeholder=>'must be unique').input(:name).must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" placeholder="must be unique" type="text"/></label>'
653
- end
654
- end
655
-
656
- describe "Forme Sequel::Model default namespacing" do
657
- before do
658
- module Foo
659
- class Album < ::Album
660
- end
661
- end
662
-
663
- @ab = Foo::Album[1]
664
- @b = Forme::Form.new(@ab)
665
- end
666
- after do
667
- Object.send(:remove_const, :Foo)
668
- end
669
-
670
- it "namespaces the form class" do
671
- @b.form.must_equal '<form class="forme foo/album" method="post"></form>'
672
- end
673
-
674
- it "namespaces the input id and name" do
675
- @b.input(:name).must_equal '<label>Name: <input id="foo/album_name" maxlength="255" name="foo/album[name]" type="text" value="b"/></label>'
676
- end
677
- end
678
-
679
- describe "Forme Sequel::Model custom namespacing" do
680
- before do
681
- module Bar
682
- class Album < ::Album
683
- def forme_namespace
684
- 'bar_album'
685
- end
686
- end
687
- end
688
-
689
- @ab = Bar::Album[1]
690
- @b = Forme::Form.new(@ab)
691
- end
692
- after do
693
- Object.send(:remove_const, :Bar)
694
- end
695
-
696
- it "namespaces the form class" do
697
- @b.form.must_equal '<form class="forme bar_album" method="post"></form>'
698
- end
699
-
700
- it "namespaces the form input and name" do
701
- @b.input(:name).must_equal '<label>Name: <input id="bar_album_name" maxlength="255" name="bar_album[name]" type="text" value="b"/></label>'
702
- end
703
- end