forme 1.9.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +70 -0
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +396 -202
  5. data/lib/forme/bs3.rb +19 -5
  6. data/lib/forme/erb.rb +18 -16
  7. data/lib/forme/form.rb +151 -118
  8. data/lib/forme/input.rb +1 -1
  9. data/lib/forme/rails.rb +41 -72
  10. data/lib/forme/raw.rb +2 -2
  11. data/lib/forme/sinatra.rb +6 -2
  12. data/lib/forme/tag.rb +3 -12
  13. data/lib/forme/template.rb +118 -0
  14. data/lib/forme/transformers/error_handler.rb +46 -1
  15. data/lib/forme/transformers/formatter.rb +36 -35
  16. data/lib/forme/transformers/helper.rb +0 -1
  17. data/lib/forme/transformers/inputs_wrapper.rb +6 -6
  18. data/lib/forme/transformers/labeler.rb +19 -0
  19. data/lib/forme/transformers/wrapper.rb +1 -1
  20. data/lib/forme/version.rb +2 -2
  21. data/lib/forme.rb +15 -2
  22. data/lib/roda/plugins/forme.rb +1 -1
  23. data/lib/roda/plugins/forme_erubi_capture.rb +62 -0
  24. data/lib/roda/plugins/forme_route_csrf.rb +16 -20
  25. data/lib/roda/plugins/forme_set.rb +177 -0
  26. data/lib/sequel/plugins/forme.rb +42 -55
  27. data/lib/sequel/plugins/forme_i18n.rb +3 -1
  28. data/lib/sequel/plugins/forme_set.rb +50 -28
  29. data/spec/all.rb +1 -1
  30. data/spec/bs3_reference_spec.rb +18 -18
  31. data/spec/bs3_sequel_plugin_spec.rb +7 -7
  32. data/spec/bs3_spec.rb +23 -11
  33. data/spec/erb_helper.rb +73 -58
  34. data/spec/erubi_capture_helper.rb +202 -0
  35. data/spec/forme_spec.rb +80 -29
  36. data/spec/rails_integration_spec.rb +47 -24
  37. data/spec/roda_integration_spec.rb +459 -48
  38. data/spec/sequel_helper.rb +0 -1
  39. data/spec/sequel_i18n_helper.rb +1 -1
  40. data/spec/sequel_i18n_plugin_spec.rb +3 -2
  41. data/spec/sequel_plugin_spec.rb +25 -8
  42. data/spec/sequel_set_plugin_spec.rb +10 -3
  43. data/spec/shared_erb_specs.rb +75 -0
  44. data/spec/sinatra_integration_spec.rb +5 -6
  45. data/spec/spec_helper.rb +23 -5
  46. metadata +30 -8
  47. data/lib/forme/erb_form.rb +0 -74
data/spec/forme_spec.rb CHANGED
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
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.form.tag(:input, :class=>t.attr[:class])}).to_s.must_equal '<div class="foo"><input class="foo"/></div>'
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.form.tag(:input, :class=>t.attr[:class]) end
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
- describe "Forme::Form :hidden_tags option " do
779
- before do
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
- it "should handle hash" do
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
- it "should handle array" do
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
- it "should handle string" do
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
- it "should handle proc return hash" do
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
- it "should handle proc return tag" do
800
- Forme.form({:method=>'post'}, :hidden_tags=>[lambda{|tag| tag.form._tag(tag.attr[:method])}]).to_s.must_equal '<form method="post"><post></post></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
- it "should raise error for unhandled object" do
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.form._tag(:textarea, i.opts[:name]=>:name)}).input(:text, :name=>'foo').to_s.must_equal '<textarea foo="name"></textarea>'
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
- require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
- require File.join(File.dirname(File.expand_path(__FILE__)), 'sequel_helper.rb')
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
- class FormeRails < Rails::Application
17
- routes.append do
18
- %w'index inputs_block inputs_block_wrapper nest nest_sep nest_inputs nest_seq hash legend combined noblock noblock_post safe_buffer'.each do |action|
19
- get action, :controller=>'forme', :action=>action
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