XXX: defaults
[perl/html-form-simple.git] / t / html.t
1 #!/usr/bin/env perl
2
3 use strict;
4 use warnings;
5
6 use Test::More;
7
8 plan tests => 65;
9
10 use_ok('HTML::Form::Simple');
11
12 my $form = HTML::Form::Simple->new;
13 ok($form, 'new form');
14
15 # form
16
17 is(
18         $form->start,
19         '<form>',
20         'empty start'
21 );
22
23 is(
24         $form->start({method => 'get', action => '', ignore => undef}),
25         '<form action="" method="get">',
26         'start with attributes'
27 );
28
29 is(
30         eval { $form->start('should be a hashref') },
31         undef,
32         'invalid attributes'
33 );
34
35 is(
36         $form->stop,
37         '</form>',
38         'stop'
39 );
40
41 # hidden
42
43 is(
44         $form->hidden,
45         '<input type="hidden">',
46         'empty hidden'
47 );
48
49 is(
50         $form->hidden(foo => 'bar'),
51         '<input name="foo" type="hidden" value="bar">',
52         'hidden'
53 );
54
55 is(
56         $form->hidden(undef, undef, {value => 'bar', name => 'foo', id => 'foo'}),
57         '<input id="foo" name="foo" type="hidden" value="bar">',
58         'hidden options'
59 );
60
61 is_deeply(
62         [ $form->hidden(foo => [1, 0], {class => 'test'}) ],
63         [
64                 '<input class="test" name="foo" type="hidden" value="1">',
65                 '<input class="test" name="foo" type="hidden" value="0">',
66         ],
67         'hidden array'
68 );
69
70 is_deeply(
71         [ $form->hidden({2 => 0, 10 => 1}, {class => 'test'}) ],
72         [
73                 '<input class="test" name="10" type="hidden" value="1">',
74                 '<input class="test" name="2" type="hidden" value="0">',
75         ],
76         'hidden hash'
77 );
78
79 {
80         local $, = "\n";
81         is(
82                 scalar $form->hidden({2 => [1, 0], 10 => 2}, {class => 'test'}),
83                 join("\n",
84                         '<input class="test" name="10" type="hidden" value="2">',
85                         '<input class="test" name="2" type="hidden" value="1">',
86                         '<input class="test" name="2" type="hidden" value="0">',
87                 ),
88                 'scalar hiddens'
89         );
90 }
91
92 # submit
93
94 is(
95         $form->submit,
96         '<input type="submit">',
97         'empty submit'
98 );
99
100 is(
101         $form->submit('<OK>'),
102         '<input type="submit" value="&lt;OK>">',
103         'submit value'
104 );
105
106 is(
107         $form->submit({disabled => 1, id => 'test', type => 'button'}),
108         '<input disabled id="test" type="button">',
109         'submit attributes'
110 );
111
112 is(
113         $form->submit('<OK>', {type => '', value => 'override', id => ''}),
114         '<input value="&lt;OK>">',
115         'submit overrides'
116 );
117
118 # input
119
120 is(
121         $form->text,
122         '<input type="text">',
123         'empty input'
124 );
125
126 is(
127         $form->text(undef, undef, undef),
128         '<input type="text">',
129         'explicit empty input'
130 );
131
132 is(
133         $form->text('test'),
134         '<input id="test" name="test" type="text">',
135         'input with name'
136 );
137
138 is(
139         $form->text(undef, 'test'),
140         '<input type="text" value="test">',
141         'input with value'
142 );
143
144 is(
145         $form->text(undef, {value => 'test'}),
146         '<input type="text" value="test">',
147         'input with attribute value'
148 );
149
150 is(
151         $form->text({name => 'test', value => ''}),
152         '<input id="test" name="test" type="text" value="">',
153         'input with only attributes'
154 );
155
156 is(
157         $form->text('', '', {
158                 disabled => 0,
159                 something => undef,
160                 class => undef,
161                 style => '',
162                 name => 'ignore',
163                 value => 'overrides',
164         }),
165         '<input name="" type="text" value="">',
166         'input with empty attributes'
167 );
168
169 is(
170         $form->text(undef, undef, {name => '0', value => '0'}),
171         '<input id="0" name="0" type="text" value="0">',
172         'input overrides'
173 );
174
175 is(
176         $form->text('name', {id => ''}),
177         '<input name="name" type="text">',
178         'input with id override'
179 );
180
181 is(
182         $form->text('<">', '<">', {id => '>"<'}),
183         '<input id=">&quot;&lt;" name="&lt;&quot;>" type="text" value="&lt;&quot;>">',
184         'input quoting'
185 );
186
187 is(
188         $form->text(undef, {disabled => 'something'}),
189         '<input disabled type="text">',
190         'disabled input'
191 );
192
193 is(
194         $form->text({type => 'password'}),
195         '<input type="password">',
196         'password'
197 );
198
199 # textarea
200
201 is(
202         $form->text({rows => 0}),
203         '<textarea rows="0"></textarea>',
204         'minimal textarea'
205 );
206
207 is(
208         $form->text(foo => 'bar', {cols => 42, rows => 1, disabled => 1}),
209         '<textarea disabled cols="42" id="foo" name="foo" rows="1">bar</textarea>',
210         'textarea'
211 );
212
213 is(
214         $form->text(undef, qq{<foo>&bl'a"\n    .}, {cols => undef, rows => '<">'}),
215         qq{<textarea rows="&lt;&quot;>">&lt;foo>&amp;bl'a&quot;\n    .</textarea>},
216         'textarea quoting'
217 );
218
219 # select
220
221 is_deeply(
222         [ $form->select ],
223         [ qw(<select> </select>) ], # malformed html: at least 1 option required
224         'empty select'
225 );
226
227 is_deeply(
228         [ $form->select(undef, [], '', {name => '', class => ''}) ],
229         [ qw(<select> </select>) ],
230         'explicit empty select'
231 );
232
233 is_deeply(
234         [ $form->select(undef, [undef]) ],
235         [ qw(<select> <option> </select>) ],
236         'minimal select'
237 );
238
239 is_deeply(
240         [ $form->select(foo => [1, 2]) ],
241         [
242                 '<select id="foo" name="foo">',
243                 '<option value="1">', '<option value="2">',
244                 '</select>'
245         ],
246         'select contents'
247 );
248
249 is_deeply(
250         [ $form->select(foo => [1, 2], 3) ],
251         [
252                 '<select id="foo" name="foo">',
253                 '<option value="1">', '<option value="2">',
254                 '</select>'
255         ],
256         'select invalid default'
257 );
258
259 is_deeply(
260         [ $form->select(undef, [1, 2], 2) ],
261         [
262                 '<select>',
263                 '<option value="1">', '<option selected value="2">',
264                 '</select>'
265         ],
266         'select default'
267 );
268
269 is_deeply(
270         [
271                 $form->select(foo => [
272                         '<">', {value => 2, disabled => 1, selected => 0, class => 1}, {selected => 1}
273                 ], '2', {id => '', class => 'a <b', value => 1})
274         ],
275         [
276                 '<select class="a &lt;b" name="foo">',
277                 '<option value="&lt;&quot;>">',
278                 '<option selected disabled class="1" value="2">',
279                 '<option selected>',
280                 '</select>'
281         ],
282         'complex select'
283 );
284
285 is(
286         scalar $form->select(foo => [1, 2]),
287         '<select id="foo" name="foo"><option value="1"><option value="2"></select>',
288         'select scalar'
289 );
290
291 # radio
292
293 is_deeply(
294         [ $form->select(foo => [1], {type => 'radio'}) ],
295         [ '<input id="foo_1" name="foo" type="radio" value="1">' ],
296         'input select'
297 );
298
299 is_deeply(
300         [
301                 $form->select(foo => [
302                         1, {value => 2, name => '', label => ''}, {value => 3, id => '', type => ''}
303                 ], {type => 'checkbox', label => {3 => 'test', 2 => 'ignore'}, value => '1'})
304         ],
305         [
306                 '<input checked id="foo_1" name="foo" type="checkbox" value="1">',
307                 '<input id="foo_2" name="" type="checkbox" value="2">',
308                 '<label><input name="foo" value="3"> test</label>',
309         ],
310         'input selects'
311 );
312
313 is(
314         $form->radio(foo => 'test'),
315         '<label><input id="foo_1" name="foo" type="radio" value="1"> test</label>',
316         'radio method'
317 );
318
319 is(
320         $form->radio(foo => undef, 2),
321         '<input id="foo_2" name="foo" type="radio" value="2">',
322         'labelless radio'
323 );
324
325 is(
326         $form->radio(undef, {checked => 1}),
327         '<input checked type="radio">',
328         'simple radio button'
329 );
330
331 is_deeply(
332         [ $form->radio(undef, ['', '<">']) ],
333         [
334                 '<input type="radio" value="1">',
335                 '<label><input type="radio" value="2"> <"></label>',
336         ],
337         'multiple radios'
338 );
339
340 is_deeply(
341         [ $form->radio(foo => 'test', ['foo', ''], {value => '', id => ''}) ],
342         [
343                 '<label><input name="foo" type="radio" value="foo"> test</label>',
344                 '<label><input checked name="foo" type="radio" value=""> test</label>',
345         ],
346         'multiple radios with custom value'
347 );
348
349 is_deeply(
350         [ $form->radio(foo => ['', 0], [0, 1, '']) ],
351         [
352                 '<input id="foo_0" name="foo" type="radio" value="0">',
353                 '<label><input id="foo_1" name="foo" type="radio" value="1"> 0</label>',
354                 '<input id="foo_" name="foo" type="radio" value="">',
355         ],
356         'multiple radios with custom values'
357 );
358
359 {
360         # make sure arguments aren't modified
361         my @args = (foo => [0, 1], [0, {value => 1}], {name => 0, value => 1});
362         my @orgs = (foo => [0, 1], [0, {value => 1}], {name => 0, value => 1});
363         my @output = (
364                 '<label><input id="foo_0" name="foo" type="radio" value="0"> 0</label>',
365                 '<label><input checked id="foo_1" name="foo" type="radio" value="1"> 1</label>',
366         );
367
368         is_deeply(
369                 [ $form->radio(@args) ],
370                 \@output,
371                 'options var to radio'
372         );
373
374         is_deeply(
375                 [ $form->check(@args) ],
376                 [
377                         '<label><input checked id="foo_1" name="foo" type="checkbox" value="1"> 0</label>',
378                         '<label><input checked id="foo_2" name="foo" type="checkbox" value="2"> 1</label>',
379                 ],
380                 'options var to check'
381         );
382
383         is(
384                 scalar $form->radio(@args),
385                 join('', @output),
386                 'options var again to radio'
387         );
388
389         is_deeply(\@args, \@orgs, 'options var unmodified');
390 }
391
392 # check
393
394 is(
395         $form->check('foo'),
396         '<input id="foo_1" name="foo" type="checkbox" value="1">',
397         'check method'
398 );
399
400 is(
401         $form->check(foo => '<">'),
402         '<label><input id="foo_1" name="foo" type="checkbox" value="1"> <"></label>',
403         'labeled checkbox'
404 );
405
406 is(
407         $form->check(foo => {label => 'test', value => undef}, {disabled => 1}),
408         '<label><input disabled id="foo" name="foo" type="checkbox"> test</label>',
409         'check parameters'
410 );
411
412 is_deeply(
413         [ $form->check(undef, '', 1) ],
414         [ '<input checked type="checkbox" value="1">' ],
415         'anonymous checkbox'
416 );
417
418 is_deeply(
419         [ $form->check(undef, ['', '<">']) ],
420         [
421                 '<input type="checkbox" value="1">',
422                 '<label><input type="checkbox" value="2"> <"></label>',
423         ],
424         'multiple checkboxes'
425 );
426
427 is_deeply(
428         [ $form->check(undef, [{}, undef], 1) ],
429         [
430                 '<input checked type="checkbox" value="1">',
431                 '<input checked type="checkbox" value="2">',
432         ],
433         'multiple checked checkboxes'
434 );
435
436 {
437         local $, = ' | ';
438         is(
439                 scalar $form->check(foo => [1, 0], {value => 0}),
440                 join(' | ',
441                         '<label><input id="foo_1" name="foo" type="checkbox" value="1"> 1</label>',
442                         '<label><input id="foo_2" name="foo" type="checkbox" value="2"> 0</label>',
443                 ),
444                 'merged checkboxes'
445         );
446 }
447
448 is_deeply(
449         [ $form->check(undef, [{value => 4, type => 'radio'}], [1, 0, 0], {value => 3}) ],
450         [
451                 '<input checked type="radio" value="4">',
452                 '<input type="checkbox" value="2">',
453                 '<input checked type="checkbox" value="3">',
454         ],
455         'various checkboxes'
456 );
457
458 # defaults
459
460 my $defform = HTML::Form::Simple->new({foo => '<">', '' => 'empty', 0 => 0});
461 ok($defform, 'form with defaults');
462
463 is(
464         $defform->hidden(''),
465         '<input name="" type="hidden" value="empty">',
466         'hidden with default'
467 );
468
469 is(
470         $defform->hidden(undef),
471         '<input type="hidden">',
472         'nameless hidden'
473 );
474
475 is(
476         $defform->text('foo'),
477         '<input id="foo" name="foo" type="text" value="&lt;&quot;>">',
478         'input with default'
479 );
480
481 is(
482         $defform->text('foo', {value => 'custom'}),
483         '<input id="foo" name="foo" type="text" value="custom">',
484         'input with value and default'
485 );
486
487 is_deeply(
488         [ $defform->radio(0 => undef, [1, 0]) ],
489         [
490                 '<input id="0_1" name="0" type="radio" value="1">',
491                 '<input checked id="0_0" name="0" type="radio" value="0">',
492         ],
493         'select with default'
494 );
495
496 #TODO
497