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