forme 2.1.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,600 +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.to_s.must_equal '<form class="forme album" method="post"><input name="a" type="hidden" value="b"/></form>'
19
- end
20
-
21
- it "should add appropriate attributes by default" do
22
- @b.form.to_s.must_equal '<form class="forme album" method="post"></form>'
23
- end
24
-
25
- it "should allow overriding of attributes" do
26
- @b.form(:class=>:foo, :method=>:get).to_s.must_equal '<form class="foo forme album" method="get"></form>'
27
- end
28
-
29
- it "should handle invalid methods" do
30
- def @ab.db_schema
31
- super.merge(:foo=>{:type=>:bar})
32
- end
33
- @b.input(:foo, :value=>'baz').to_s.must_equal '<label>Foo: <input id="album_foo" name="album[foo]" type="text" value="baz"/></label>'
34
- end
35
-
36
- it "should allow an array of classes" do
37
- @b.form(:class=>[:foo, :bar]).to_s.must_equal '<form class="foo bar forme album" method="post"></form>'
38
- @b.form(:class=>[:foo, [:bar, :baz]]).to_s.must_equal '<form class="foo bar baz forme album" method="post"></form>'
39
- end
40
-
41
- it "should use a text field for strings" do
42
- @b.input(:name).to_s.must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" type="text" value="b"/></label>'
43
- @c.input(:name).to_s.must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" type="text" value="c"/></label>'
44
- end
45
-
46
- it "should allow :as=>:textarea to use a textarea" do
47
- @b.input(:name, :as=>:textarea).to_s.must_equal '<label>Name: <textarea id="album_name" maxlength="255" name="album[name]">b</textarea></label>'
48
- @c.input(:name, :as=>:textarea).to_s.must_equal '<label>Name: <textarea id="album_name" maxlength="255" name="album[name]">c</textarea></label>'
49
- end
50
-
51
- it "should allow :type=>:textarea to use a textarea" do
52
- @b.input(:name, :type=>:textarea).to_s.must_equal '<label>Name: <textarea id="album_name" maxlength="255" name="album[name]">b</textarea></label>'
53
- @c.input(:name, :type=>:textarea).to_s.must_equal '<label>Name: <textarea id="album_name" maxlength="255" name="album[name]">c</textarea></label>'
54
- end
55
-
56
- it "should not include labels for hidden inputs" do
57
- @b.input(:name, :type=>:hidden).to_s.must_equal '<input id="album_name" name="album[name]" type="hidden" value="b"/>'
58
- end
59
-
60
- it "should use number inputs for integers" do
61
- @b.input(:copies_sold).to_s.must_equal '<label>Copies sold: <input id="album_copies_sold" name="album[copies_sold]" type="number" value="10"/></label>'
62
- end
63
-
64
- it "should use date inputs for Dates" do
65
- @b.input(:release_date).to_s.must_equal '<label>Release date: <input id="album_release_date" name="album[release_date]" type="date" value="2011-06-05"/></label>'
66
- end
67
-
68
- it "should use datetime inputs for Time" do
69
- @b.input(:created_at).to_s.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>}
70
- end
71
-
72
- it "should use datetime inputs for DateTimes" do
73
- @ab.values[:created_at] = DateTime.new(2011, 6, 5)
74
- @b.input(:created_at).to_s.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>'
75
- end
76
-
77
- it "should use file inputs without value" do
78
- @b.input(:name, :type=>:file).to_s.must_equal '<label>Name: <input id="album_name" name="album[name]" type="file"/></label>'
79
- end
80
-
81
- it "should include type as wrapper class" do
82
- @ab.values[:created_at] = DateTime.new(2011, 6, 5)
83
- f = Forme::Form.new(@ab, :wrapper=>:li)
84
- f.input(:name).to_s.must_equal '<li class="string"><label>Name: <input id="album_name" maxlength="255" name="album[name]" type="text" value="b"/></label></li>'
85
- f.input(:release_date).to_s.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>'
86
- f.input(:created_at).to_s.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>'
87
- end
88
-
89
- it "should include required * in label if required" do
90
- @b.input(:name, :required=>true).to_s.must_equal '<label>Name<abbr title="required">*</abbr>: <input id="album_name" maxlength="255" name="album[name]" required="required" type="text" value="b"/></label>'
91
- end
92
-
93
- it "should add required to label even if :label option specified" do
94
- @b.input(:name, :required=>true, :label=>'Foo').to_s.must_equal '<label>Foo<abbr title="required">*</abbr>: <input id="album_name" maxlength="255" name="album[name]" required="required" type="text" value="b"/></label>'
95
- end
96
-
97
- it "should not add required to label even if :label option is nil" do
98
- @b.input(:name, :required=>true, :label=>nil).to_s.must_equal '<input id="album_name" maxlength="255" name="album[name]" required="required" type="text" value="b"/>'
99
- end
100
-
101
- it "should include required wrapper class if required" do
102
- f = Forme::Form.new(@ab, :wrapper=>:li)
103
- f.input(:name, :required=>true).to_s.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>'
104
- end
105
-
106
- it "should use a select box for tri-valued boolean fields" do
107
- @b.input(:gold).to_s.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>'
108
- @c.input(:gold).to_s.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>'
109
- end
110
-
111
- it "should respect :true_label and :false_label options for tri-valued boolean fields" do
112
- @b.input(:gold, :true_label=>"Foo", :false_label=>"Bar").to_s.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>'
113
- end
114
-
115
- it "should respect :true_value and :false_value options for tri-valued boolean fields" do
116
- @b.input(:gold, :true_value=>"Foo", :false_value=>"Bar").to_s.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>'
117
- end
118
-
119
- it "should respect :add_blank option for tri-valued boolean fields" do
120
- @b.input(:gold, :add_blank=>'NULL').to_s.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>'
121
- end
122
-
123
- it "should use a select box for dual-valued boolean fields where :required => false" do
124
- @b.input(:platinum, :required=>false).to_s.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>'
125
- @c.input(:platinum, :required=>false).to_s.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>'
126
- end
127
-
128
- it "should use a checkbox for dual-valued boolean fields" do
129
- @b.input(:platinum).to_s.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>'
130
- @c.input(:platinum).to_s.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>'
131
- end
132
-
133
- it "should use radio buttons for boolean fields if :as=>:radio is used" do
134
- @b.input(:platinum, :as=>:radio).to_s.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>'
135
- @c.input(:platinum, :as=>:radio).to_s.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>'
136
- end
137
-
138
- it "should wrap both inputs if :as=>:radio is used" do
139
- @b = Forme::Form.new(@ab, :wrapper=>:li)
140
- @b.input(:platinum, :as=>:radio).to_s.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>'
141
- @b.input(:platinum, :as=>:radio, :wrapper=>:div, :tag_wrapper=>:span).to_s.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>'
142
- end
143
-
144
- it "should handle errors on radio buttons for boolean fields if :as=>:radio is used" do
145
- @ab.errors.add(:platinum, 'foo')
146
- @b.input(:platinum, :as=>:radio).to_s.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>'
147
- end
148
-
149
- it "should handle Raw :label options if :as=>:radio is used" do
150
- @b.input(:platinum, :as=>:radio, :label=>Forme.raw('Foo:<br />')).to_s.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>'
151
- @b.input(:platinum, :as=>:radio, :label=>'Foo:<br />').to_s.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>'
152
- end
153
-
154
- it "should respect :true_label and :false_label options for boolean fields if :as=>:radio is used" do
155
- @b.input(:platinum, :as=>:radio, :true_label=>"Foo", :false_label=>"Bar").to_s.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>'
156
- end
157
-
158
- it "should respect :true_value and :false_value options for boolean fields if :as=>:radio is used" do
159
- @b.input(:platinum, :as=>:radio, :true_value=>"Foo", :false_value=>"Bar").to_s.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>'
160
- end
161
-
162
- it "should respect :formatter=>:readonly option for boolean fields if :as=>:radio is used" do
163
- @b.input(:platinum, :as=>:radio, :formatter=>:readonly).to_s.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>'
164
- end
165
-
166
- it "should use a select box for many_to_one associations" do
167
- @b.input(:artist).to_s.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>'
168
- @c.input(:artist).to_s.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>'
169
- end
170
-
171
- it "should not add a blank option by default if there is a default value and it is required" do
172
- @b.input(:artist, :required=>true).to_s.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>'
173
- end
174
-
175
- it "should allow overriding default input type using a :type option" do
176
- @b.input(:artist, :type=>:string, :value=>nil).to_s.must_equal '<label>Artist: <input id="album_artist" name="album[artist]" type="text"/></label>'
177
- end
178
-
179
- it "should automatically set :required for many_to_one assocations based on whether the field is required" do
180
- begin
181
- Album.db_schema[:artist_id][:allow_null] = false
182
- @b.input(:artist).to_s.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>'
183
- @b.input(:artist, :required=>false).to_s.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>'
184
- ensure
185
- Album.db_schema[:artist_id][:allow_null] = true
186
- end
187
- end
188
-
189
- it "should use a required wrapper tag for many_to_one required associations" do
190
- @b.input(:artist, :required=>true, :wrapper=>:li).to_s.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>'
191
- end
192
-
193
- it "should use a set of radio buttons for many_to_one associations with :as=>:radio option" do
194
- @b.input(:artist, :as=>:radio).to_s.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>'
195
- @c.input(:artist, :as=>:radio).to_s.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>'
196
- end
197
-
198
- it "should handle Raw label for many_to_one associations with :as=>:radio option" do
199
- @b.input(:artist, :as=>:radio, :label=>Forme.raw('Foo:<br />')).to_s.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>'
200
- @b.input(:artist, :as=>:radio, :label=>'Foo<br />').to_s.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>'
201
- end
202
-
203
- it "should correctly use the forms wrapper for wrapping radio buttons for many_to_one associations with :as=>:radio option" do
204
- @b = Forme::Form.new(@ab, :wrapper=>:li)
205
- @b.input(:artist, :as=>:radio).to_s.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>'
206
- end
207
-
208
- it "should support custom wrappers for many_to_one associations with :as=>:radio via :tag_wrapper option" do
209
- @b = Forme::Form.new(@ab, :wrapper=>:li)
210
- @b.input(:artist, :as=>:radio, :wrapper=>proc{|t, i| i.tag(:div, {}, [t])}, :tag_wrapper=>proc{|t, i| i.tag(:span, {}, [t])}).to_s.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>'
211
- end
212
-
213
- it "should respect an :options entry" do
214
- @b.input(:artist, :options=>Artist.order(:name).map{|a| [a.name, a.id+1]}).to_s.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>'
215
- @c.input(:artist, :options=>Artist.order(:name).map{|a| [a.name, a.id+1]}).to_s.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>'
216
- end
217
-
218
- it "should support :name_method option for choosing name method" do
219
- @b.input(:artist, :name_method=>:idname).to_s.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>'
220
- @c.input(:artist, :name_method=>:idname).to_s.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>'
221
- end
222
-
223
- it "should support :name_method option being a callable object" do
224
- @b.input(:artist, :name_method=>lambda{|obj| obj.idname * 2}).to_s.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>'
225
- @c.input(:artist, :name_method=>lambda{|obj| obj.idname * 2}).to_s.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>'
226
- end
227
-
228
- it "should support :dataset option providing dataset to search" do
229
- @b.input(:artist, :dataset=>Artist.reverse_order(:name)).to_s.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>'
230
- @c.input(:artist, :dataset=>Artist.reverse_order(:name)).to_s.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>'
231
- end
232
-
233
- it "should support :dataset option being a callback proc returning modified dataset to search" do
234
- @b.input(:artist, :dataset=>proc{|ds| ds.reverse_order(:name)}).to_s.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>'
235
- @c.input(:artist, :dataset=>proc{|ds| ds.reverse_order(:name)}).to_s.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>'
236
- end
237
-
238
- it "should try a list of methods to get a suitable one for select box naming" do
239
- al = Class.new(Album){def self.name() 'Album' end}
240
- ar = Class.new(Artist)
241
- al.many_to_one :artist, :class=>ar
242
- ar.class_eval{undef_method(:name)}
243
- f = Forme::Form.new(al.new)
244
-
245
- ar.class_eval{def number() "#{self[:name]}1" end}
246
- f.input(:artist).to_s.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>'
247
-
248
- ar.class_eval{def title() "#{self[:name]}2" end}
249
- f.input(:artist).to_s.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>'
250
-
251
- ar.class_eval{def name() "#{self[:name]}3" end}
252
- f.input(:artist).to_s.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>'
253
-
254
- ar.class_eval{def forme_name() "#{self[:name]}4" end}
255
- f.input(:artist).to_s.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>'
256
- end
257
-
258
- it "should raise an error when using an association without a usable name method" do
259
- al = Class.new(Album)
260
- ar = Class.new(Artist)
261
- al.many_to_one :artist, :class=>ar
262
- ar.class_eval{undef_method(:name)}
263
- proc{Forme::Form.new(al.new).input(:artist)}.must_raise(Sequel::Plugins::Forme::Error)
264
- end
265
-
266
- it "should use a multiple select box for one_to_many associations" do
267
- @b.input(:tracks).to_s.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>'
268
- @c.input(:tracks).to_s.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>'
269
- end
270
-
271
- it "should use a multiple select box for many_to_many associations" do
272
- @b.input(:tags).to_s.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>'
273
- @c.input(:tags).to_s.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>'
274
- end
275
-
276
- it "should use a multiple select box for pg_array_to_many associations" do
277
- @b.input(:atags).to_s.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>'
278
- @c.obj.atag_ids.delete(1)
279
- @c.input(:atags).to_s.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>'
280
- end
281
-
282
- it "should handle an error message on the underlying column for pg_array_to_many associations" do
283
- @ab.errors.add(:atag_ids, 'tis not valid')
284
- @b.input(:atags).to_s.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>'
285
- @b.input(:atags, :as=>:checkbox).to_s.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>'
286
- end
287
-
288
- it "should use a regular select box for *_to_many associations if multiple if false" do
289
- @b.input(:tracks, :multiple=>false).to_s.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>'
290
- @c.input(:tags, :multiple=>false).to_s.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>'
291
- end
292
-
293
- it "should handle a given :value for one_to_many associations" do
294
- @b.input(:tracks, :value=>[1,3]).to_s.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>'
295
- @c.input(:tracks, :value=>nil).to_s.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>'
296
- end
297
-
298
- it "should use multiple checkboxes for one_to_many associations if :as=>:checkbox" do
299
- @b.input(:tracks, :as=>:checkbox).to_s.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>'
300
- @c.input(:tracks, :as=>:checkbox).to_s.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>'
301
- end
302
-
303
- it "should use multiple checkboxes for many_to_many associations if :as=>:checkbox" do
304
- @b.input(:tags, :as=>:checkbox).to_s.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>'
305
- @c.input(:tags, :as=>:checkbox).to_s.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>'
306
- end
307
-
308
- it "should handle Raw label for associations with :as=>:checkbox" do
309
- @b.input(:tracks, :as=>:checkbox, :label=>Forme.raw('Foo<br />:')).to_s.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>'
310
- @b.input(:tracks, :as=>:checkbox, :label=>'Foo<br />').to_s.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>'
311
- end
312
-
313
- it "should correctly use the forms wrapper for wrapping radio buttons for one_to_many associations with :as=>:checkbox option" do
314
- @b = Forme::Form.new(@ab, :wrapper=>:li)
315
- @b.input(:tracks, :as=>:checkbox).to_s.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>'
316
- end
317
-
318
- it "should support custom wrappers for one_to_many associations with :as=>:checkbox via :tag_wrapper option" do
319
- @b = Forme::Form.new(@ab, :wrapper=>:li)
320
- @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])}).to_s.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>'
321
- end
322
-
323
- it "should use a text field methods not backed by columns" do
324
- @b.input(:artist_name).to_s.must_equal '<label>Artist name: <input id="album_artist_name" name="album[artist_name]" type="text" value="a"/></label>'
325
- @c.input(:artist_name).to_s.must_equal '<label>Artist name: <input id="album_artist_name" name="album[artist_name]" type="text" value="d"/></label>'
326
- end
327
-
328
- it "should handle errors on methods not backed by columns" do
329
- @ab.errors.add(:artist_name, 'foo')
330
- @b.input(:artist_name).to_s.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>'
331
- end
332
-
333
- it "should respect a :type option with a schema type as the input type for methods not backed by columns" do
334
- def @ab.foo; false end
335
- @b.input(:foo, :type=>:boolean, :as=>:select).to_s.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>'
336
- end
337
-
338
- it "should respect a :type option with an input type as the input type for methods not backed by columns" do
339
- def @ab.foo; "bar" end
340
- @b.input(:foo, :type=>:phone).to_s.must_equal '<label>Foo: <input id="album_foo" name="album[foo]" type="phone" value="bar"/></label>'
341
- end
342
-
343
- it "should not override an explicit :error setting" do
344
- @ab.errors.add(:name, 'tis not valid')
345
- @b.input(:name, :error=>nil).to_s.must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" type="text" value="b"/></label>'
346
- end
347
-
348
- it "should correctly show an error message if there is one" do
349
- @ab.errors.add(:name, 'tis not valid')
350
- @b.input(:name).to_s.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>'
351
- end
352
-
353
- it "should correctly show an error message for many_to_one associations if there is one" do
354
- @ab.errors.add(:artist_id, 'tis not valid')
355
- @b.input(:artist).to_s.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>'
356
- end
357
-
358
- it "should raise an error for unhandled associations" do
359
- al = Class.new(Album)
360
- al.one_to_many :tags
361
- al.association_reflection(:tags)[:type] = :foo
362
- proc{Forme::Form.new(al.new).input(:tags)}.must_raise(Sequel::Plugins::Forme::Error)
363
- end
364
-
365
- it "should raise an error for unhandled fields with no :type option" do
366
- proc{@b.input(:foo)}.must_raise(Sequel::Plugins::Forme::Error)
367
- end
368
-
369
- it "should respect a :type option with a schema type as the input type for unhandled fields" do
370
- @b.input(:foo, :type=>:string).to_s.must_equal '<label>Foo: <input id="album_foo" name="album[foo]" type="text"/></label>'
371
- @b.input(:password, :type=>:string).to_s.must_equal '<label>Password: <input id="album_password" name="album[password]" type="password"/></label>'
372
- end
373
-
374
- it "should respect a :type option with an input type as the input type for unhandled fields" do
375
- @b.input(:foo, :type=>:phone).to_s.must_equal '<label>Foo: <input id="album_foo" name="album[foo]" type="phone"/></label>'
376
- end
377
-
378
- it "should respect a :multiple option for the name attribute for unhandled fields" do
379
- @b.input(:foo, :type=>:phone, :multiple=>true).to_s.must_equal '<label>Foo: <input id="album_foo" name="album[foo][]" type="phone"/></label>'
380
- end
381
-
382
- it "should add required attribute if the column doesn't support nil values" do
383
- def @ab.db_schema; h = super.dup; h[:name] = h[:name].merge(:allow_null=>false); h end
384
- @b.input(:name).to_s.must_equal '<label>Name<abbr title="required">*</abbr>: <input id="album_name" maxlength="255" name="album[name]" required="required" type="text" value="b"/></label>'
385
- end
386
-
387
- it "should use allow nested forms with many_to_one associations" do
388
- Forme.form(@ab){|f| f.subform(:artist){f.input(:name)}}.to_s.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>'
389
- end
390
-
391
- it "should have #subform respect an :inputs option" do
392
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name])}.to_s.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>'
393
- end
394
-
395
- it "should have #subform respect an :obj option overriding the object to use" do
396
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :obj=>Artist.new(:name=>'b'))}.to_s.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>'
397
- end
398
-
399
- it "should have #subform respect a :legend option if :inputs is used" do
400
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :legend=>'Foo')}.to_s.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>'
401
- end
402
-
403
- it "should have #subform respect a callable :legend option if :inputs is used" do
404
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :legend=>proc{|o| "Foo - #{o.name}"})}.to_s.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>'
405
- end
406
-
407
- it "should not add hidden primary key field for new many_to_one associated objects" do
408
- @ab.associations[:artist] = Artist.new(:name=>'a')
409
- Forme.form(@ab){|f| f.subform(:artist){f.input(:name)}}.to_s.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>'
410
- end
411
-
412
- it "should use allow nested forms with one_to_one associations" do
413
- Forme.form(@ab){|f| f.subform(:album_info, :obj=>AlbumInfo.new(:info=>'a')){f.input(:info)}}.to_s.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>'
414
- end
415
-
416
- it "should use allow nested forms with one_to_many associations" do
417
- Forme.form(@ab){|f| f.subform(:tracks){f.input(:name)}}.to_s.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>'
418
- end
419
-
420
- it "should support :obj option for *_to_many associations" do
421
- Forme.form(@ab){|f| f.subform(:tracks, :obj=>[Track.new(:name=>'x'), Track.load(:id=>5, :name=>'y')]){f.input(:name)}}.to_s.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>'
422
- end
423
-
424
- it "should auto number legends when using subform with inputs for *_to_many associations" do
425
- Forme.form(@ab){|f| f.subform(:tracks, :inputs=>[:name])}.to_s.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>'
426
- end
427
-
428
- it "should support callable :legend option when using subform with inputs for *_to_many associations" do
429
- Forme.form(@ab){|f| f.subform(:tracks, :inputs=>[:name], :legend=>proc{|o, i| "Track #{i} (#{o.name})"})}.to_s.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>'
430
- end
431
-
432
- it "should not add hidden primary key field for nested forms with one_to_many associations with new objects" do
433
- @ab.associations[:tracks] = [Track.new(:name=>'m'), Track.new(:name=>'n')]
434
- Forme.form(@ab){|f| f.subform(:tracks){f.input(:name)}}.to_s.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>'
435
- end
436
-
437
- it "should use allow nested forms with many_to_many associations" do
438
- Forme.form(@ab){|f| f.subform(:tags){f.input(:name)}}.to_s.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>'
439
- end
440
-
441
- it "should not add hidden primary key field for nested forms with many_to_many associations with new objects" do
442
- @ab.associations[:tags] = [Tag.new(:name=>'s'), Tag.new(:name=>'t')]
443
- Forme.form(@ab){|f| f.subform(:tags){f.input(:name)}}.to_s.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>'
444
- end
445
-
446
- it "should handle multiple nested levels" do
447
- Forme.form(Artist[1]){|f| f.subform(:albums){f.input(:name); f.subform(:tracks){f.input(:name)}}}.to_s.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>'
448
- end
449
-
450
- it "should have #subform :grid option create a grid" do
451
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true)}.to_s.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>'
452
- end
453
-
454
- it "should have #subform :grid option respect :inputs_opts option to pass options to inputs" do
455
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :inputs_opts=>{:attr=>{:class=>'foo'}})}.to_s.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>'
456
- end
457
-
458
- it "should have #subform :grid option handle :legend and :labels options" do
459
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :legend=>'Foo', :labels=>%w'Bar')}.to_s.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>'
460
- end
461
-
462
- it "should have #subform :grid option handle :legend and :labels nil values" do
463
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :legend=>nil, :labels=>nil)}.to_s.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>'
464
- end
465
-
466
- it "should have #subform :grid option handle :skip_primary_key option" do
467
- Forme.form(@ab){|f| f.subform(:artist, :inputs=>[:name], :grid=>true, :skip_primary_key=>true)}.to_s.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>'
468
- end
469
-
470
- it "should handle non-Sequel forms with Sequel inputs" do
471
- Forme.form{|f| f.input(:name, :obj=>@ab).to_s.must_equal '<label>Name: <input id="name" maxlength="255" name="name" type="text" value="b"/></label>'}
472
- end
473
- end
474
-
475
- describe "Forme Sequel plugin default input types based on column names" do
476
- def f(name)
477
- DB.create_table!(:test){String name}
478
- Forme::Form.new(Class.new(Sequel::Model).class_eval{def self.name; 'Test' end; set_dataset :test}.new).input(name, :value=>'foo')
479
- end
480
-
481
- it "should use password input with no value for string columns with name password" do
482
- f(:password).to_s.must_equal '<label>Password: <input id="test_password" maxlength="255" name="test[password]" type="password"/></label>'
483
- end
484
-
485
- it "should use email input for string columns with name email" do
486
- f(:email).to_s.must_equal '<label>Email: <input id="test_email" maxlength="255" name="test[email]" type="email" value="foo"/></label>'
487
- end
488
-
489
- it "should use tel input for string columns with name phone or fax" do
490
- f(:phone).to_s.must_equal '<label>Phone: <input id="test_phone" maxlength="255" name="test[phone]" type="tel" value="foo"/></label>'
491
- f(:fax).to_s.must_equal '<label>Fax: <input id="test_fax" maxlength="255" name="test[fax]" type="tel" value="foo"/></label>'
492
- end
493
-
494
- it "should use url input for string columns with name url, uri, or website" do
495
- f(:url).to_s.must_equal '<label>Url: <input id="test_url" maxlength="255" name="test[url]" type="url" value="foo"/></label>'
496
- f(:uri).to_s.must_equal '<label>Uri: <input id="test_uri" maxlength="255" name="test[uri]" type="url" value="foo"/></label>'
497
- f(:website).to_s.must_equal '<label>Website: <input id="test_website" maxlength="255" name="test[website]" type="url" value="foo"/></label>'
498
- end
499
- end
500
-
501
- describe "Forme Sequel plugin default input types based on column type" do
502
- def f(type)
503
- DB.create_table!(:test){column :foo, type}
504
- Forme::Form.new(Class.new(Sequel::Model).class_eval{def self.name; 'Test' end; set_dataset :test}.new).input(:foo, :value=>'foo')
505
- end
506
-
507
- it "should use a file input for blob types" do
508
- f(File).to_s.must_equal '<label>Foo: <input id="test_foo" name="test[foo]" type="file"/></label>'
509
- end
510
- end
511
-
512
- describe "Forme Sequel::Model validation parsing" do
513
- def f(*a)
514
- c = Class.new(Album){def self.name; "Album"; end}
515
- c.plugin :validation_class_methods
516
- c.send(*a)
517
- Forme::Form.new(c.new)
518
- end
519
-
520
- it "should turn format into a pattern" do
521
- f(:validates_format_of, :name, :with=>/[A-z]+/).input(:name).to_s.must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" pattern="[A-z]+" type="text"/></label>'
522
- end
523
-
524
- it "should respect :title option for format" do
525
- f(:validates_format_of, :name, :with=>/[A-z]+/, :title=>'Foo').input(:name).to_s.must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" pattern="[A-z]+" title="Foo" type="text"/></label>'
526
- end
527
-
528
- it "should use maxlength for length :maximum, :is, and :within" do
529
- f(:validates_length_of, :name, :maximum=>10).input(:name).to_s.must_equal '<label>Name: <input id="album_name" maxlength="10" name="album[name]" type="text"/></label>'
530
- f(:validates_length_of, :name, :is=>10).input(:name).to_s.must_equal '<label>Name: <input id="album_name" maxlength="10" name="album[name]" type="text"/></label>'
531
- f(:validates_length_of, :name, :within=>2..10).input(:name).to_s.must_equal '<label>Name: <input id="album_name" maxlength="10" name="album[name]" type="text"/></label>'
532
- f(:validates_length_of, :name, :within=>2...11).input(:name).to_s.must_equal '<label>Name: <input id="album_name" maxlength="10" name="album[name]" type="text"/></label>'
533
- end
534
-
535
- it "should turn numericality into a pattern" do
536
- f(:validates_numericality_of, :name).input(:name).to_s.must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" pattern="^[+\-]?\d+(\.\d+)?$" title="must be a number" type="text"/></label>'
537
- end
538
-
539
- it "should turn numericality :only_integer into a pattern" do
540
- f(:validates_numericality_of, :name, :only_integer=>true).input(:name).to_s.must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" pattern="^[+\-]?\d+$" title="must be a number" type="text"/></label>'
541
- end
542
-
543
- it "should respect :title option for numericality" do
544
- f(:validates_numericality_of, :name, :title=>'Foo').input(:name).to_s.must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" pattern="^[+\-]?\d+(\.\d+)?$" title="Foo" type="text"/></label>'
545
- end
546
-
547
- it "should respect :placeholder option for any validation" do
548
- f(:validates_uniqueness_of, :name, :placeholder=>'must be unique').input(:name).to_s.must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" placeholder="must be unique" type="text"/></label>'
549
- end
550
-
551
- end
552
-
553
- describe "Forme Sequel::Model default namespacing" do
554
- before do
555
- module Foo
556
- class Album < ::Album
557
- end
558
- end
559
-
560
- @ab = Foo::Album[1]
561
- @b = Forme::Form.new(@ab)
562
- end
563
- after do
564
- Object.send(:remove_const, :Foo)
565
- end
566
-
567
- it "namespaces the form class" do
568
- @b.form.to_s.must_equal '<form class="forme foo/album" method="post"></form>'
569
- end
570
-
571
- it "namespaces the input id and name" do
572
- @b.input(:name).to_s.must_equal '<label>Name: <input id="foo/album_name" maxlength="255" name="foo/album[name]" type="text" value="b"/></label>'
573
- end
574
- end
575
-
576
- describe "Forme Sequel::Model custom namespacing" do
577
- before do
578
- module Bar
579
- class Album < ::Album
580
- def forme_namespace
581
- 'bar_album'
582
- end
583
- end
584
- end
585
-
586
- @ab = Bar::Album[1]
587
- @b = Forme::Form.new(@ab)
588
- end
589
- after do
590
- Object.send(:remove_const, :Bar)
591
- end
592
-
593
- it "namespaces the form class" do
594
- @b.form.to_s.must_equal '<form class="forme bar_album" method="post"></form>'
595
- end
596
-
597
- it "namespaces the form input and name" do
598
- @b.input(:name).to_s.must_equal '<label>Name: <input id="bar_album_name" maxlength="255" name="bar_album[name]" type="text" value="b"/></label>'
599
- end
600
- end