XXX: reverse radio options
[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 => 66;
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         '<input id="foo_test" name="foo" type="radio" value="test">',
316         'radio method'
317 );
318
319 is(
320         $form->radio(foo => undef, 'test'),
321         '<label><input id="foo_1" name="foo" type="radio" value="1"> test</label>',
322         'labeled 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="">',
335                 '<input type="radio" value="&lt;&quot;>">',
336         ],
337         'multiple radios'
338 );
339
340 is_deeply(
341         [ $form->radio(undef, undef, ['', '<">']) ],
342         [
343                 '<input type="radio" value="1">',
344                 '<label><input type="radio" value="2"> <"></label>',
345         ],
346         'multiple radio labels'
347 );
348
349 is_deeply(
350         [ $form->radio(foo => ['foo', ''], 'test', {value => '', id => ''}) ],
351         [
352                 '<label><input name="foo" type="radio" value="foo"> test</label>',
353                 '<label><input checked name="foo" type="radio" value=""> test</label>',
354         ],
355         'multiple radios with custom value'
356 );
357
358 is_deeply(
359         [ $form->radio(foo => [0, 1, ''], ['', 0]) ],
360         [
361                 '<input id="foo_0" name="foo" type="radio" value="0">',
362                 '<label><input id="foo_1" name="foo" type="radio" value="1"> 0</label>',
363                 '<input id="foo_" name="foo" type="radio" value="">',
364         ],
365         'multiple radios with custom values'
366 );
367
368 {
369         # make sure arguments aren't modified
370         my @args = (foo => [0, {value => 1}], [0, 1], {name => 0, value => 1});
371         my @orgs = (foo => [0, {value => 1}], [0, 1], {name => 0, value => 1});
372         my @output = (
373                 '<label><input id="foo_0" name="foo" type="radio" value="0"> 0</label>',
374                 '<label><input checked id="foo_1" name="foo" type="radio" value="1"> 1</label>',
375         );
376
377         is_deeply(
378                 [ $form->radio(@args) ],
379                 \@output,
380                 'options var to radio'
381         );
382
383         is_deeply(
384                 [ $form->check(@args) ],
385                 [
386                         '<label><input checked id="foo_1" name="foo" type="checkbox" value="1"> 0</label>',
387                         '<input checked id="foo_1" name="foo" type="checkbox" value="1">',
388                 ],
389                 'options var to check'
390         );
391
392         is(
393                 scalar $form->radio(@args),
394                 join('', @output),
395                 'options var again to radio'
396         );
397
398         is_deeply(\@args, \@orgs, 'options var unmodified');
399 }
400
401 # check
402
403 is(
404         $form->check('foo'),
405         '<input id="foo_1" name="foo" type="checkbox" value="1">',
406         'check method'
407 );
408
409 is(
410         $form->check(foo => '<">'),
411         '<label><input id="foo_1" name="foo" type="checkbox" value="1"> <"></label>',
412         'labeled checkbox'
413 );
414
415 is(
416         $form->check(foo => {label => 'test', value => undef}, {disabled => 1}),
417         '<label><input disabled id="foo" name="foo" type="checkbox"> test</label>',
418         'check parameters'
419 );
420
421 is_deeply(
422         [ $form->check(undef, '', 1) ],
423         [ '<input checked type="checkbox" value="1">' ],
424         'anonymous checkbox'
425 );
426
427 is_deeply(
428         [ $form->check(undef, ['', '<">']) ],
429         [
430                 '<input type="checkbox" value="1">',
431                 '<label><input type="checkbox" value="2"> <"></label>',
432         ],
433         'multiple checkboxes'
434 );
435
436 is_deeply(
437         [ $form->check(undef, [{}, undef], 1) ],
438         [
439                 '<input checked type="checkbox" value="1">',
440                 '<input checked type="checkbox" value="2">',
441         ],
442         'multiple checked checkboxes'
443 );
444
445 {
446         local $, = ' | ';
447         is(
448                 scalar $form->check(foo => [1, 0], {value => 0}),
449                 join(' | ',
450                         '<label><input id="foo_1" name="foo" type="checkbox" value="1"> 1</label>',
451                         '<label><input id="foo_2" name="foo" type="checkbox" value="2"> 0</label>',
452                 ),
453                 'merged checkboxes'
454         );
455 }
456
457 is_deeply(
458         [ $form->check(undef, [{value => 4, type => 'radio'}], [1, 0, 0], {value => 3}) ],
459         [
460                 '<input checked type="radio" value="4">',
461                 '<input type="checkbox" value="2">',
462                 '<input checked type="checkbox" value="3">',
463         ],
464         'various checkboxes'
465 );
466
467 # defaults
468
469 my $defform = HTML::Form::Simple->new({foo => '<">', '' => 'empty', 0 => 0});
470 ok($defform, 'form with defaults');
471
472 is(
473         $defform->hidden(''),
474         '<input name="" type="hidden" value="empty">',
475         'hidden with default'
476 );
477
478 is(
479         $defform->hidden(undef),
480         '<input type="hidden">',
481         'nameless hidden'
482 );
483
484 is(
485         $defform->text('foo'),
486         '<input id="foo" name="foo" type="text" value="&lt;&quot;>">',
487         'input with default'
488 );
489
490 is(
491         $defform->text('foo', {value => 'custom'}),
492         '<input id="foo" name="foo" type="text" value="custom">',
493         'input with value and default'
494 );
495
496 is_deeply(
497         [ $defform->radio(0 => [1, 0]) ],
498         [
499                 '<input id="0_1" name="0" type="radio" value="1">',
500                 '<input checked id="0_0" name="0" type="radio" value="0">',
501         ],
502         'select with default'
503 );
504
505 #TODO
506