forme 1.9.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +70 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +396 -202
- data/lib/forme/bs3.rb +19 -5
- data/lib/forme/erb.rb +18 -16
- data/lib/forme/form.rb +151 -118
- data/lib/forme/input.rb +1 -1
- data/lib/forme/rails.rb +41 -72
- data/lib/forme/raw.rb +2 -2
- data/lib/forme/sinatra.rb +6 -2
- data/lib/forme/tag.rb +3 -12
- data/lib/forme/template.rb +118 -0
- data/lib/forme/transformers/error_handler.rb +46 -1
- data/lib/forme/transformers/formatter.rb +36 -35
- data/lib/forme/transformers/helper.rb +0 -1
- data/lib/forme/transformers/inputs_wrapper.rb +6 -6
- data/lib/forme/transformers/labeler.rb +19 -0
- data/lib/forme/transformers/wrapper.rb +1 -1
- data/lib/forme/version.rb +2 -2
- data/lib/forme.rb +15 -2
- data/lib/roda/plugins/forme.rb +1 -1
- data/lib/roda/plugins/forme_erubi_capture.rb +62 -0
- data/lib/roda/plugins/forme_route_csrf.rb +16 -20
- data/lib/roda/plugins/forme_set.rb +177 -0
- data/lib/sequel/plugins/forme.rb +42 -55
- data/lib/sequel/plugins/forme_i18n.rb +3 -1
- data/lib/sequel/plugins/forme_set.rb +50 -28
- data/spec/all.rb +1 -1
- data/spec/bs3_reference_spec.rb +18 -18
- data/spec/bs3_sequel_plugin_spec.rb +7 -7
- data/spec/bs3_spec.rb +23 -11
- data/spec/erb_helper.rb +73 -58
- data/spec/erubi_capture_helper.rb +202 -0
- data/spec/forme_spec.rb +80 -29
- data/spec/rails_integration_spec.rb +47 -24
- data/spec/roda_integration_spec.rb +459 -48
- data/spec/sequel_helper.rb +0 -1
- data/spec/sequel_i18n_helper.rb +1 -1
- data/spec/sequel_i18n_plugin_spec.rb +3 -2
- data/spec/sequel_plugin_spec.rb +25 -8
- data/spec/sequel_set_plugin_spec.rb +10 -3
- data/spec/shared_erb_specs.rb +75 -0
- data/spec/sinatra_integration_spec.rb +5 -6
- data/spec/spec_helper.rb +23 -5
- metadata +30 -8
- data/lib/forme/erb_form.rb +0 -74
data/spec/forme_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
2
|
|
3
3
|
describe "Forme plain forms" do
|
4
4
|
def sel(opts, s)
|
@@ -116,13 +116,13 @@ describe "Forme plain forms" do
|
|
116
116
|
|
117
117
|
it "should consider form's :errors hash based on the :key option" do
|
118
118
|
@f.opts[:errors] = { 'foo' => 'must be present' }
|
119
|
-
@f.input(:text, :key=>"foo").to_s.must_equal "<input class=\"error\" id=\"foo\" name=\"foo\" type=\"text\"/><span class=\"error_message\">must be present</span>"
|
119
|
+
@f.input(:text, :key=>"foo").to_s.must_equal "<input aria-describedby=\"foo_error_message\" aria-invalid=\"true\" class=\"error\" id=\"foo\" name=\"foo\" type=\"text\"/><span class=\"error_message\" id=\"foo_error_message\">must be present</span>"
|
120
120
|
end
|
121
121
|
|
122
122
|
it "should consider form's :errors hash based on the :key option when using namespaces" do
|
123
123
|
@f.opts[:errors] = { 'bar' => { 'foo' => 'must be present' } }
|
124
124
|
@f.with_opts(:namespace=>['bar']) do
|
125
|
-
@f.input(:text, :key=>"foo").to_s.must_equal "<input class=\"error\" id=\"bar_foo\" name=\"bar[foo]\" type=\"text\"/><span class=\"error_message\">must be present</span>"
|
125
|
+
@f.input(:text, :key=>"foo").to_s.must_equal "<input aria-describedby=\"bar_foo_error_message\" aria-invalid=\"true\" class=\"error\" id=\"bar_foo\" name=\"bar[foo]\" type=\"text\"/><span class=\"error_message\" id=\"bar_foo_error_message\">must be present</span>"
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
@@ -301,6 +301,10 @@ describe "Forme plain forms" do
|
|
301
301
|
@f.input(:date, :name=>"foo", :id=>"bar", :as=>:select, :value=>Date.new(2011, 6, 5)).to_s.must_equal %{<select id="bar" name="foo[year]">#{sel(1900..2050, 2011)}</select>-<select id="bar_month" name="foo[month]">#{sel(1..12, 6)}</select>-<select id="bar_day" name="foo[day]">#{sel(1..31, 5)}</select>}
|
302
302
|
end
|
303
303
|
|
304
|
+
it "should use labels for select boxes for dates if the :as=>:select and :select_labels options are given" do
|
305
|
+
@f.input(:date, :name=>"foo", :id=>"bar", :as=>:select, :value=>Date.new(2011, 6, 5), :select_labels=>{:year=>'Y', :month=>'M', :day=>'D'}, :labeler=>:explicit).to_s.must_equal %{<label class="label-before" for="bar">Y</label><select id="bar" name="foo[year]">#{sel(1900..2050, 2011)}</select>-<label class="label-before" for="bar_month">M</label><select id="bar_month" name="foo[month]">#{sel(1..12, 6)}</select>-<label class="label-before" for="bar_day">D</label><select id="bar_day" name="foo[day]">#{sel(1..31, 5)}</select>}
|
306
|
+
end
|
307
|
+
|
304
308
|
it "should allow ordering date select boxes via :order" do
|
305
309
|
@f.input(:date, :name=>"foo", :id=>"bar", :as=>:select, :value=>Date.new(2011, 6, 5), :order=>[:month, '/', :day, '/', :year]).to_s.must_equal %{<select id="bar" name="foo[month]">#{sel(1..12, 6)}</select>/<select id="bar_day" name="foo[day]">#{sel(1..31, 5)}</select>/<select id="bar_year" name="foo[year]">#{sel(1900..2050, 2011)}</select>}
|
306
310
|
end
|
@@ -313,6 +317,10 @@ describe "Forme plain forms" do
|
|
313
317
|
@f.input(:date, :name=>"foo", :id=>"bar", :as=>:select, :value=>Date.new(2011, 6, 5), :select_options=>{:year=>1970..2020}).to_s.must_equal %{<select id="bar" name="foo[year]">#{sel(1970..2020, 2011)}</select>-<select id="bar_month" name="foo[month]">#{sel(1..12, 6)}</select>-<select id="bar_day" name="foo[day]">#{sel(1..31, 5)}</select>}
|
314
318
|
end
|
315
319
|
|
320
|
+
it "should support :select_options with both values and text for dates when :as=>:select is given" do
|
321
|
+
@f.input(:date, :name=>"foo", :id=>"bar", :as=>:select, :value=>Date.new(2011, 6, 5), :select_options=>{:year=>[[2011, 'A'], [2012, 'B']]}).to_s.must_equal %{<select id="bar" name="foo[year]"><option selected="selected" value="2011">A</option><option value="2012">B</option></select>-<select id="bar_month" name="foo[month]">#{sel(1..12, 6)}</select>-<select id="bar_day" name="foo[day]">#{sel(1..31, 5)}</select>}
|
322
|
+
end
|
323
|
+
|
316
324
|
it "should have explicit labeler and trtd wrapper work with multiple select boxes for dates" do
|
317
325
|
@f.input(:date, :name=>"foo", :id=>"bar", :as=>:select, :value=>Date.new(2011, 6, 5), :wrapper=>:trtd, :labeler=>:explicit, :label=>'Baz').to_s.must_equal %{<tr><td><label class="label-before" for="bar">Baz</label></td><td><select id="bar" name="foo[year]">#{sel(1900..2050, 2011)}</select>-<select id="bar_month" name="foo[month]">#{sel(1..12, 6)}</select>-<select id="bar_day" name="foo[day]">#{sel(1..31, 5)}</select></td></tr>}
|
318
326
|
end
|
@@ -433,7 +441,11 @@ describe "Forme plain forms" do
|
|
433
441
|
end
|
434
442
|
|
435
443
|
it "should create set of radio buttons with :error and :error_attr options" do
|
436
|
-
@f.input(:radioset, :options=>[1, 2, 3], :selected=>2, :error=>'foo', :error_attr=>{'bar'=>'baz'}).to_s.must_equal '<label class="option"><input type="radio" value="1"/> 1</label><label class="option"><input checked="checked" type="radio" value="2"/> 2</label><label class="option"><input class="error" type="radio" value="3"/> 3</label><span bar="baz" class="error_message">foo</span>'
|
444
|
+
@f.input(:radioset, :options=>[1, 2, 3], :selected=>2, :error=>'foo', :error_attr=>{'bar'=>'baz'}).to_s.must_equal '<label class="option"><input type="radio" value="1"/> 1</label><label class="option"><input checked="checked" type="radio" value="2"/> 2</label><label class="option"><input aria-invalid="true" class="error" type="radio" value="3"/> 3</label><span bar="baz" class="error_message">foo</span>'
|
445
|
+
end
|
446
|
+
|
447
|
+
it "should support custom error_handler for set of radio buttons" do
|
448
|
+
@f.input(:radioset, :options=>[1, 2, 3], :selected=>2, :error=>'foo', :error_attr=>{'bar'=>'baz'}, :error_handler=>lambda{|tag, input| input.tag(:div, {}, tag)}).to_s.must_equal '<div><label class="option"><input type="radio" value="1"/> 1</label><label class="option"><input checked="checked" type="radio" value="2"/> 2</label><label class="option"><input type="radio" value="3"/> 3</label></div>'
|
437
449
|
end
|
438
450
|
|
439
451
|
it "should create set of checkbox buttons" do
|
@@ -457,10 +469,26 @@ describe "Forme plain forms" do
|
|
457
469
|
@f.input(:checkboxset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :label=>'foo').to_s.must_equal '<span class="label">foo</span><label class="option"><input type="checkbox" value="1"/> a</label><label class="option"><input type="checkbox" value="2"/> b</label><label class="option"><input type="checkbox" value="3"/> c</label>'
|
458
470
|
end
|
459
471
|
|
472
|
+
it "should support fieldset/legend for checkboxsets" do
|
473
|
+
@f.input(:checkboxset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :label=>'foo', :labeler=>:legend, :wrapper=>:fieldset).to_s.must_equal '<fieldset><legend>foo</legend><label class="option"><input type="checkbox" value="1"/> a</label><label class="option"><input type="checkbox" value="2"/> b</label><label class="option"><input type="checkbox" value="3"/> c</label></fieldset>'
|
474
|
+
end
|
475
|
+
|
476
|
+
it "should support legend with attributes for checkboxsets" do
|
477
|
+
@f.input(:checkboxset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :label=>'foo', :label_attr=>{:class=>"baz"}, :tag_label_attr=>{:class=>"bar"}, :labeler=>:legend, :wrapper=>:fieldset).to_s.must_equal '<fieldset><legend class="baz">foo</legend><label class="bar"><input type="checkbox" value="1"/> a</label><label class="bar"><input type="checkbox" value="2"/> b</label><label class="bar"><input type="checkbox" value="3"/> c</label></fieldset>'
|
478
|
+
end
|
479
|
+
|
480
|
+
it "should support legend with attributes for checkboxsets, handling errors with :error_handler=>:after_legend" do
|
481
|
+
@f.input(:checkboxset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :id=>:quux, :label=>'foo', :label_attr=>{:class=>"baz"}, :tag_label_attr=>{:class=>"bar"}, :labeler=>:legend, :wrapper=>:fieldset, :error=>'bar2', :error_handler=>:after_legend).to_s.must_equal '<fieldset><legend class="baz">foo</legend><span class="error_message" id="quux_1_error_message">bar2</span><label class="bar"><input aria-describedby="quux_1_error_message" aria-invalid="true" class="error" id="quux_1" type="checkbox" value="1"/> a</label><label class="bar"><input id="quux_2" type="checkbox" value="2"/> b</label><label class="bar"><input id="quux_3" type="checkbox" value="3"/> c</label></fieldset>'
|
482
|
+
end
|
483
|
+
|
460
484
|
it "should support :tag_labeler for checkboxsets" do
|
461
485
|
@f.input(:checkboxset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :tag_labeler=>:explicit).to_s.must_equal '<input type="checkbox" value="1"/><label class="option label-after">a</label><input type="checkbox" value="2"/><label class="option label-after">b</label><input type="checkbox" value="3"/><label class="option label-after">c</label>'
|
462
486
|
end
|
463
487
|
|
488
|
+
it "should support custom :labeler for checkboxsets" do
|
489
|
+
@f.input(:checkboxset, :options=>[[:a, 1], [:b, 2], [:c, 3]], :label=>'foo', :labeler=>lambda{|tag, input| input.tag(:div, {}, tag)}).to_s.must_equal '<div><label class="option"><input type="checkbox" value="1"/> a</label><label class="option"><input type="checkbox" value="2"/> b</label><label class="option"><input type="checkbox" value="3"/> c</label></div>'
|
490
|
+
end
|
491
|
+
|
464
492
|
it "should create set of checkbox buttons with options and values with hashes" do
|
465
493
|
@f.input(:checkboxset, :options=>[[:a, {:attr=>{:foo=>1}}], [:b, {:class=>'foo', :value=>2}], [:c, {:id=>:baz}]], :selected=>2).to_s.must_equal '<label class="option"><input foo="1" type="checkbox" value="a"/> a</label><label class="option"><input checked="checked" class="foo" type="checkbox" value="2"/> b</label><label class="option"><input id="baz" type="checkbox" value="c"/> c</label>'
|
466
494
|
end
|
@@ -491,7 +519,7 @@ describe "Forme plain forms" do
|
|
491
519
|
end
|
492
520
|
|
493
521
|
it "should respect the :error option for checkbox sets" do
|
494
|
-
@f.input(:checkboxset, :options=>[1, 2, 3], :error=>'foo', :value=>2).to_s.must_equal '<label class="option"><input type="checkbox" value="1"/> 1</label><label class="option"><input checked="checked" type="checkbox" value="2"/> 2</label><label class="option"><input class="error" type="checkbox" value="3"/> 3</label><span class="error_message">foo</span>'
|
522
|
+
@f.input(:checkboxset, :options=>[1, 2, 3], :error=>'foo', :value=>2).to_s.must_equal '<label class="option"><input type="checkbox" value="1"/> 1</label><label class="option"><input checked="checked" type="checkbox" value="2"/> 2</label><label class="option"><input aria-invalid="true" class="error" type="checkbox" value="3"/> 3</label><span class="error_message">foo</span>'
|
495
523
|
end
|
496
524
|
|
497
525
|
it "should create set of checkbox buttons with fieldsets and legends for optgroups" do
|
@@ -558,19 +586,23 @@ describe "Forme plain forms" do
|
|
558
586
|
end
|
559
587
|
|
560
588
|
it "should automatically note the input has errors if :error option is used" do
|
561
|
-
@f.input(:text, :error=>'Bad Stuff!', :value=>'foo').to_s.must_equal '<input class="error" type="text" value="foo"/><span class="error_message">Bad Stuff!</span>'
|
589
|
+
@f.input(:text, :error=>'Bad Stuff!', :value=>'foo').to_s.must_equal '<input aria-invalid="true" class="error" type="text" value="foo"/><span class="error_message">Bad Stuff!</span>'
|
562
590
|
end
|
563
591
|
|
564
592
|
it "should add an error message after the label" do
|
565
|
-
@f.input(:text, :error=>'Bad Stuff!', :value=>'foo', :label=>"Foo").to_s.must_equal '<label>Foo: <input class="error" type="text" value="foo"/></label><span class="error_message">Bad Stuff!</span>'
|
593
|
+
@f.input(:text, :error=>'Bad Stuff!', :value=>'foo', :label=>"Foo").to_s.must_equal '<label>Foo: <input aria-invalid="true" class="error" type="text" value="foo"/></label><span class="error_message">Bad Stuff!</span>'
|
566
594
|
end
|
567
595
|
|
568
596
|
it "should add to existing :class option if :error option is used" do
|
569
|
-
@f.input(:text, :error=>'Bad Stuff!', :class=>'bar', :value=>'foo').to_s.must_equal '<input class="bar error" type="text" value="foo"/><span class="error_message">Bad Stuff!</span>'
|
597
|
+
@f.input(:text, :error=>'Bad Stuff!', :class=>'bar', :value=>'foo').to_s.must_equal '<input aria-invalid="true" class="bar error" type="text" value="foo"/><span class="error_message">Bad Stuff!</span>'
|
570
598
|
end
|
571
599
|
|
572
600
|
it "should respect :error_attr option for setting the attributes for the error message span" do
|
573
|
-
@f.input(:text, :error=>'Bad Stuff!', :value=>'foo', :error_attr=>{:class=>'foo'}).to_s.must_equal '<input class="error" type="text" value="foo"/><span class="foo error_message">Bad Stuff!</span>'
|
601
|
+
@f.input(:text, :error=>'Bad Stuff!', :value=>'foo', :error_attr=>{:class=>'foo'}).to_s.must_equal '<input aria-invalid="true" class="error" type="text" value="foo"/><span class="foo error_message">Bad Stuff!</span>'
|
602
|
+
end
|
603
|
+
|
604
|
+
it "should use aria-describedby and aria-invalid tags for errors with where the id attribute can be determined" do
|
605
|
+
@f.input(:text, :error=>'Bad Stuff!', :id=>:bar, :value=>'foo', :error_attr=>{:class=>'foo'}).to_s.must_equal '<input aria-describedby="bar_error_message" aria-invalid="true" class="error" id="bar" type="text" value="foo"/><span class="foo error_message" id="bar_error_message">Bad Stuff!</span>'
|
574
606
|
end
|
575
607
|
|
576
608
|
it "#open should return an opening tag" do
|
@@ -599,13 +631,19 @@ describe "Forme plain forms" do
|
|
599
631
|
@f.tag(:textarea, {:name=>:foo}, :bar).to_s.must_equal '<textarea name="foo">bar</textarea>'
|
600
632
|
end
|
601
633
|
|
634
|
+
it "#tag should accept a block" do
|
635
|
+
@f.tag(:div){@f.tag(:textarea)}.to_s.must_equal '<div><textarea></textarea></div>'
|
636
|
+
@f.tag(:div, :name=>'a'){@f.tag(:textarea)}.to_s.must_equal '<div name="a"><textarea></textarea></div>'
|
637
|
+
@f.tag(:div, {:name=>'a'}, ["text"]){@f.tag(:textarea)}.to_s.must_equal '<div name="a">text<textarea></textarea></div>'
|
638
|
+
end
|
639
|
+
|
602
640
|
it "#tag should accept children as procs" do
|
603
|
-
@f.tag(:div, {:class=>"foo"}, lambda{|t| t.
|
641
|
+
@f.tag(:div, {:class=>"foo"}, lambda{|t| t.tag(:input, :class=>t.attr[:class])}).to_s.must_equal '<div class="foo"><input class="foo"/></div>'
|
604
642
|
end
|
605
643
|
|
606
644
|
it "#tag should accept children as methods" do
|
607
645
|
o = Object.new
|
608
|
-
def o.foo(t) t.
|
646
|
+
def o.foo(t) t.tag(:input, :class=>t.attr[:class]) end
|
609
647
|
@f.tag(:div, {:class=>"foo"}, o.method(:foo)).to_s.must_equal '<div class="foo"><input class="foo"/></div>'
|
610
648
|
end
|
611
649
|
|
@@ -613,6 +651,10 @@ describe "Forme plain forms" do
|
|
613
651
|
@f.inputs([:textarea, :text]).to_s.must_equal '<fieldset class="inputs"><textarea></textarea><input type="text"/></fieldset>'
|
614
652
|
end
|
615
653
|
|
654
|
+
it "should have an #inputs method for multiple inputs wrapped in a fieldset when using an empty block" do
|
655
|
+
@f.inputs([:textarea, :text]){}.to_s.must_equal '<fieldset class="inputs"><textarea></textarea><input type="text"/></fieldset>'
|
656
|
+
end
|
657
|
+
|
616
658
|
it "should have default #inputs method accept an :attr option" do
|
617
659
|
@f.inputs([:textarea, :text], :legend=>'Inputs', :attr=>{:class=>'foo', :bar=>'baz'}).to_s.must_equal '<fieldset bar="baz" class="foo inputs"><legend>Inputs</legend><textarea></textarea><input type="text"/></fieldset>'
|
618
660
|
end
|
@@ -696,7 +738,7 @@ describe "Forme plain forms" do
|
|
696
738
|
end
|
697
739
|
|
698
740
|
it "inputs should have helper displayed inside wrapper, after error" do
|
699
|
-
@f.input(:text, :help=>"List type of foo", :error=>'bad', :wrapper=>:li).to_s.must_equal '<li><input class="error" type="text"/><span class="error_message">bad</span><span class="helper">List type of foo</span></li>'
|
741
|
+
@f.input(:text, :help=>"List type of foo", :error=>'bad', :wrapper=>:li).to_s.must_equal '<li><input aria-invalid="true" class="error" type="text"/><span class="error_message">bad</span><span class="helper">List type of foo</span></li>'
|
700
742
|
end
|
701
743
|
|
702
744
|
it "inputs should accept a :formatter option to use a custom formatter" do
|
@@ -729,7 +771,7 @@ describe "Forme plain forms" do
|
|
729
771
|
end
|
730
772
|
|
731
773
|
it "inputs should accept a :error_handler option to use a custom error_handler" do
|
732
|
-
@f.input(:textarea, :error_handler=>proc{|t, i| [t, "!!! #{i.opts[:error]}"]}, :error=>'bar', :id=>:foo).to_s.must_equal '<textarea class="error" id="foo"></textarea>!!! bar'
|
774
|
+
@f.input(:textarea, :error_handler=>proc{|t, i| [t, "!!! #{i.opts[:error]}"]}, :error=>'bar', :id=>:foo).to_s.must_equal '<textarea aria-describedby="foo_error_message" aria-invalid="true" class="error" id="foo"></textarea>!!! bar'
|
733
775
|
end
|
734
776
|
|
735
777
|
it "#inputs should accept a :inputs_wrapper option to use a custom inputs_wrapper" do
|
@@ -745,7 +787,7 @@ describe "Forme plain forms" do
|
|
745
787
|
end
|
746
788
|
|
747
789
|
it "inputs should accept a :error_handler=>nil option to not use an error_handler" do
|
748
|
-
@f.input(:textarea, :error_handler=>nil, :error=>'bar', :id=>:foo).to_s.must_equal '<textarea class="error" id="foo"></textarea>'
|
790
|
+
@f.input(:textarea, :error_handler=>nil, :error=>'bar', :id=>:foo).to_s.must_equal '<textarea aria-invalid="true" class="error" id="foo"></textarea>'
|
749
791
|
end
|
750
792
|
|
751
793
|
it "#inputs should accept a :inputs_wrapper=>nil option to not use an inputs_wrapper" do
|
@@ -773,41 +815,45 @@ describe "Forme plain forms" do
|
|
773
815
|
proc{@f.input(:textarea, :wrapper=>Object.new).to_s}.must_raise(Forme::Error)
|
774
816
|
proc{@f.input(:textarea, :formatter=>nil).to_s}.must_raise(Forme::Error)
|
775
817
|
end
|
776
|
-
end
|
777
818
|
|
778
|
-
|
779
|
-
|
780
|
-
@f = Forme::Form.new
|
819
|
+
it "should handle :before and :after hook options" do
|
820
|
+
Forme.form({}, :before=>lambda{|f| f.tag(:input, :type=>:hidden, :name=>:a, :value=>'b')}, :after=>lambda{|f| f.tag(:input, :type=>:hidden, :name=>:c, :value=>'d')}){|f| f.tag(:input)}.to_s.must_equal '<form><input name="a" type="hidden" value="b"/><input/><input name="c" type="hidden" value="d"/></form>'
|
781
821
|
end
|
822
|
+
end
|
782
823
|
|
783
|
-
|
824
|
+
describe "Forme::Form :hidden_tags option " do
|
825
|
+
silence_warnings "should handle hash" do
|
784
826
|
Forme.form({}, :hidden_tags=>[{:a=>'b'}]).to_s.must_equal '<form><input name="a" type="hidden" value="b"/></form>'
|
785
827
|
end
|
786
828
|
|
787
|
-
|
829
|
+
silence_warnings "should handle array" do
|
788
830
|
Forme.form({}, :hidden_tags=>[["a ", "b"]]).to_s.must_equal '<form>a b</form>'
|
789
831
|
end
|
790
832
|
|
791
|
-
|
833
|
+
silence_warnings "should handle string" do
|
792
834
|
Forme.form({}, :hidden_tags=>["a "]).to_s.must_equal '<form>a </form>'
|
793
835
|
end
|
794
836
|
|
795
|
-
|
837
|
+
silence_warnings "should handle proc return hash" do
|
796
838
|
Forme.form({}, :hidden_tags=>[lambda{|tag| {:a=>'b'}}]).to_s.must_equal '<form><input name="a" type="hidden" value="b"/></form>'
|
797
839
|
end
|
798
840
|
|
799
|
-
|
800
|
-
Forme.form({
|
841
|
+
silence_warnings "should handle proc return hash when from takes a block" do
|
842
|
+
Forme.form({}, :hidden_tags=>[lambda{|tag| {:a=>'b'}}]){}.to_s.must_equal '<form><input name="a" type="hidden" value="b"/></form>'
|
801
843
|
end
|
802
844
|
|
803
|
-
|
845
|
+
silence_warnings "should handle proc return tag" do
|
846
|
+
Forme.form({:method=>'post'}, :hidden_tags=>[lambda{|tag| tag.tag(tag.attr[:method])}]).to_s.must_equal '<form method="post"><post></post></form>'
|
847
|
+
end
|
848
|
+
|
849
|
+
silence_warnings "should raise error for unhandled object" do
|
804
850
|
proc{Forme.form({}, :hidden_tags=>[Object.new])}.must_raise Forme::Error
|
805
851
|
end
|
806
852
|
end
|
807
853
|
|
808
854
|
describe "Forme custom" do
|
809
855
|
it "formatters can be specified as a proc" do
|
810
|
-
Forme::Form.new(:formatter=>proc{|i| i.
|
856
|
+
Forme::Form.new(:formatter=>proc{|i| i.tag(:textarea, i.opts[:name]=>:name)}).input(:text, :name=>'foo').to_s.must_equal '<textarea foo="name"></textarea>'
|
811
857
|
end
|
812
858
|
|
813
859
|
it "serializers can be specified as a proc" do
|
@@ -819,7 +865,7 @@ describe "Forme custom" do
|
|
819
865
|
end
|
820
866
|
|
821
867
|
it "error_handlers can be specified as a proc" do
|
822
|
-
Forme::Form.new(:error_handler=>proc{|t, i| [t, "!!! #{i.opts[:error]}"]}).input(:textarea, :name=>'foo', :error=>'bar').to_s.must_equal '<textarea class="error" name="foo"></textarea>!!! bar'
|
868
|
+
Forme::Form.new(:error_handler=>proc{|t, i| [t, "!!! #{i.opts[:error]}"]}).input(:textarea, :name=>'foo', :error=>'bar').to_s.must_equal '<textarea aria-invalid="true" class="error" name="foo"></textarea>!!! bar'
|
823
869
|
end
|
824
870
|
|
825
871
|
it "wrappers can be specified as a proc" do
|
@@ -854,6 +900,10 @@ describe "Forme built-in custom" do
|
|
854
900
|
Forme::Form.new(:formatter=>:readonly).input(:select, :label=>"Foo", :options=>[1, 2, 3], :value=>2).to_s.must_equal "<label>Foo: <span>2</span></label>"
|
855
901
|
end
|
856
902
|
|
903
|
+
it "formatter: readonly removes hidden inputs" do
|
904
|
+
Forme::Form.new(:formatter=>:readonly).input(:hidden, :value=>"Bar").to_s.must_equal ""
|
905
|
+
end
|
906
|
+
|
857
907
|
it "formatter: readonly formats text into paragraphs for textarea inputs" do
|
858
908
|
Forme::Form.new(:formatter=>:readonly).input(:textarea, :label=>"Foo", :value=>"\n Bar\nBaz\n\nQuuz\n\n1\n2 \n").to_s.must_equal "<label>Foo: <div class=\"readonly-textarea\"><p> Bar<br />Baz</p><p>Quuz</p><p>1<br />2 </p></div></label>"
|
859
909
|
end
|
@@ -877,7 +927,7 @@ describe "Forme built-in custom" do
|
|
877
927
|
end
|
878
928
|
|
879
929
|
it "labeler: explicit should handle tags with errors" do
|
880
|
-
Forme::Form.new(:labeler=>:explicit).input(:text, :error=>'Bad Stuff!', :value=>'f', :id=>'foo', :label=>'bar').to_s.must_equal '<label class="label-before" for="foo">bar</label><input class="error" id="foo" type="text" value="f"/><span class="error_message">Bad Stuff!</span>'
|
930
|
+
Forme::Form.new(:labeler=>:explicit).input(:text, :error=>'Bad Stuff!', :value=>'f', :id=>'foo', :label=>'bar').to_s.must_equal '<label class="label-before" for="foo">bar</label><input aria-describedby="foo_error_message" aria-invalid="true" class="error" id="foo" type="text" value="f"/><span class="error_message" id="foo_error_message">Bad Stuff!</span>'
|
881
931
|
end
|
882
932
|
|
883
933
|
it "wrapper: li wraps tag in an li" do
|
@@ -915,7 +965,7 @@ describe "Forme built-in custom" do
|
|
915
965
|
end
|
916
966
|
|
917
967
|
it "wrapper: trtd should use at most 2 td tags" do
|
918
|
-
Forme::Form.new(:wrapper=>:trtd, :labeler=>:explicit).input(:textarea, :id=>'foo', :label=>'Foo', :error=>'Bar').to_s.must_equal '<tr><td><label class="label-before" for="foo">Foo</label></td><td><textarea class="error" id="foo"></textarea><span class="error_message">Bar</span></td></tr>'
|
968
|
+
Forme::Form.new(:wrapper=>:trtd, :labeler=>:explicit).input(:textarea, :id=>'foo', :label=>'Foo', :error=>'Bar').to_s.must_equal '<tr><td><label class="label-before" for="foo">Foo</label></td><td><textarea aria-describedby="foo_error_message" aria-invalid="true" class="error" id="foo"></textarea><span class="error_message" id="foo_error_message">Bar</span></td></tr>'
|
919
969
|
end
|
920
970
|
|
921
971
|
it "wrapper: trtd should handle inputs with label after" do
|
@@ -1020,6 +1070,7 @@ describe "Forme built-in custom" do
|
|
1020
1070
|
Forme::Form.new(:serializer=>:text).button().to_s.must_equal ""
|
1021
1071
|
Forme::Form.new(:serializer=>:text).inputs([[:textarea, {:label=>"Foo", :value=>"Bar"}]], :legend=>'Baz').to_s.must_equal "Baz\n---\nFoo: Bar\n\n"
|
1022
1072
|
Forme::Form.new(:serializer=>:text).tag(:p){|f| f.input(:textarea, :label=>"Foo", :value=>"Bar")}.to_s.must_equal "Foo: Bar\n\n"
|
1073
|
+
Forme::Form.new(:serializer=>:text).tag(:p, {}, ['a']).to_s.must_equal "a"
|
1023
1074
|
end
|
1024
1075
|
end
|
1025
1076
|
|
@@ -1,33 +1,48 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require_relative 'sequel_helper'
|
3
3
|
|
4
|
-
require 'rubygems'
|
5
4
|
begin
|
6
|
-
require 'action_controller/railtie'
|
7
|
-
rescue LoadError
|
8
|
-
warn "unable to load rails, skipping rails spec"
|
9
|
-
else
|
10
|
-
begin
|
11
|
-
require 'active_pack/gem_version'
|
12
|
-
rescue LoadError
|
13
|
-
end
|
14
|
-
require 'forme/rails'
|
5
|
+
require 'action_controller/railtie'
|
15
6
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
7
|
+
begin
|
8
|
+
require 'active_pack/gem_version'
|
9
|
+
rescue LoadError
|
10
|
+
end
|
11
|
+
require_relative '../lib/forme/rails'
|
12
|
+
|
13
|
+
if Rails.respond_to?(:version) && Rails.version.start_with?('4')
|
14
|
+
# Work around issue in backported openssl environments where
|
15
|
+
# secret is 64 bytes intead of 32 bytes
|
16
|
+
require 'active_support/message_encryptor'
|
17
|
+
def (ActiveSupport::MessageEncryptor).new(secret, *signature_key_or_options)
|
18
|
+
obj = allocate
|
19
|
+
obj.send(:initialize, secret[0, 32], *signature_key_or_options)
|
20
|
+
obj
|
20
21
|
end
|
21
22
|
end
|
22
|
-
config.active_support.deprecation = :stderr
|
23
|
-
config.middleware.delete(ActionDispatch::ShowExceptions)
|
24
|
-
config.middleware.delete(Rack::Lock)
|
25
|
-
config.secret_key_base = 'foo'*15
|
26
|
-
config.secret_token = 'secret token'*15 if Rails.respond_to?(:version) && Rails.version < '5.2'
|
27
|
-
config.eager_load = true
|
28
|
-
initialize!
|
29
|
-
end
|
30
23
|
|
24
|
+
class FormeRails < Rails::Application
|
25
|
+
routes.append do
|
26
|
+
%w'index inputs_block inputs_block_wrapper nest nest_sep nest_inputs nest_seq hash legend combined hidden_tags noblock noblock_post safe_buffer'.each do |action|
|
27
|
+
get action, :controller=>'forme', :action=>action
|
28
|
+
end
|
29
|
+
end
|
30
|
+
config.active_support.deprecation = :stderr
|
31
|
+
config.middleware.delete(ActionDispatch::HostAuthorization) if defined?(ActionDispatch::HostAuthorization)
|
32
|
+
config.middleware.delete(ActionDispatch::ShowExceptions)
|
33
|
+
config.middleware.delete(Rack::Lock)
|
34
|
+
config.secret_key_base = 'foo'*15
|
35
|
+
config.secret_token = 'secret token'*15 if Rails.respond_to?(:version) && Rails.version < '5.2'
|
36
|
+
config.eager_load = true
|
37
|
+
begin
|
38
|
+
initialize!
|
39
|
+
rescue NoMethodError
|
40
|
+
raise LoadError
|
41
|
+
end
|
42
|
+
end
|
43
|
+
rescue LoadError
|
44
|
+
warn "unable to load or setup rails, skipping rails spec"
|
45
|
+
else
|
31
46
|
class FormeController < ActionController::Base
|
32
47
|
helper Forme::Rails::ERB
|
33
48
|
|
@@ -177,6 +192,10 @@ END
|
|
177
192
|
END
|
178
193
|
end
|
179
194
|
|
195
|
+
def hidden_tags
|
196
|
+
render :inline => "<%= forme([:foo, :bar], {:action=>'/baz'}, :hidden_tags=>[{'a'=>'b'}]) %>"
|
197
|
+
end
|
198
|
+
|
180
199
|
def noblock
|
181
200
|
render :inline => "<%= forme([:foo, :bar], {:action=>'/baz'}, :inputs=>[:first], :button=>'xyz', :legend=>'123') %>"
|
182
201
|
end
|
@@ -248,6 +267,10 @@ describe "Forme Rails integration" do
|
|
248
267
|
sin_get('/combined').must_equal '<form action="/baz"><fieldset class="inputs"><legend>123</legend><input id="first" name="first" type="text" value="foo"/></fieldset> <p>FBB</p> <input id="last" name="last" type="text" value="bar"/> <input type="submit" value="xyz"/></form>'
|
249
268
|
end
|
250
269
|
|
270
|
+
silence_warnings "#form should support :hidden_tags option" do
|
271
|
+
sin_get('/hidden_tags').must_equal '<form action="/baz"><input name="a" type="hidden" value="b"/></form>'
|
272
|
+
end
|
273
|
+
|
251
274
|
it "#form should work without a block" do
|
252
275
|
sin_get('/noblock').must_equal '<form action="/baz"><fieldset class="inputs"><legend>123</legend><input id="first" name="first" type="text" value="foo"/></fieldset><input type="submit" value="xyz"/></form>'
|
253
276
|
end
|