forme 1.11.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +54 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +235 -209
- data/Rakefile +1 -7
- data/lib/forme/bs3.rb +18 -4
- data/lib/forme/erb.rb +13 -25
- data/lib/forme/form.rb +144 -149
- data/lib/forme/input.rb +1 -1
- data/lib/forme/rails.rb +39 -83
- data/lib/forme/raw.rb +2 -2
- data/lib/forme/tag.rb +3 -12
- data/lib/forme/template.rb +110 -0
- data/lib/forme/transformers/formatter.rb +4 -1
- data/lib/forme/transformers/helper.rb +0 -1
- data/lib/forme/transformers/inputs_wrapper.rb +4 -4
- 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 +57 -0
- data/lib/roda/plugins/forme_route_csrf.rb +16 -34
- data/lib/roda/plugins/forme_set.rb +39 -76
- data/lib/sequel/plugins/forme.rb +40 -50
- data/lib/sequel/plugins/forme_i18n.rb +3 -1
- data/lib/sequel/plugins/forme_set.rb +3 -1
- data/spec/all.rb +1 -1
- data/spec/bs3_reference_spec.rb +18 -18
- data/spec/bs3_sequel_plugin_spec.rb +17 -17
- data/spec/bs3_spec.rb +23 -11
- data/spec/erb_helper.rb +69 -58
- data/spec/erubi_capture_helper.rb +198 -0
- data/spec/forme_spec.rb +21 -32
- data/spec/rails_integration_spec.rb +39 -25
- data/spec/roda_integration_spec.rb +118 -70
- 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 +29 -12
- data/spec/sequel_set_plugin_spec.rb +9 -2
- data/spec/shared_erb_specs.rb +71 -0
- data/spec/sinatra_integration_spec.rb +5 -6
- data/spec/spec_helper.rb +21 -8
- metadata +9 -7
- data/lib/forme/erb_form.rb +0 -74
- data/lib/forme/sinatra.rb +0 -17
data/spec/bs3_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require_relative '../lib/forme/bs3'
|
3
3
|
|
4
4
|
describe "Forme Bootstrap3 (BS3) forms" do
|
5
5
|
def sel(opts, s)
|
@@ -99,6 +99,18 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
|
+
it "should consider form's :errors hash based on the :key option" do
|
103
|
+
@f.opts[:errors] = { 'foo' => 'must be present' }
|
104
|
+
@f.input(:text, :key=>"foo").to_s.must_equal "<div class=\"form-group has-error\"><input aria-describedby=\"foo_error_message\" aria-invalid=\"true\" class=\"form-control\" id=\"foo\" name=\"foo\" type=\"text\"/><span class=\"help-block with-errors\">must be present</span></div>"
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should consider form's :errors hash based on the :key option when using namespaces" do
|
108
|
+
@f.opts[:errors] = { 'bar' => { 'foo' => 'must be present' } }
|
109
|
+
@f.with_opts(:namespace=>['bar']) do
|
110
|
+
@f.input(:text, :key=>"foo").to_s.must_equal "<div class=\"form-group has-error\"><input aria-describedby=\"bar_foo_error_message\" aria-invalid=\"true\" class=\"form-control\" id=\"bar_foo\" name=\"bar[foo]\" type=\"text\"/><span class=\"help-block with-errors\">must be present</span></div>"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
102
114
|
it "should support a with_obj method that changes the object and namespace for the given block" do
|
103
115
|
@f.with_obj([:a, :c], 'bar') do
|
104
116
|
@f.input(:first).to_s.must_equal '<div class="form-group"><input class="form-control" id="bar_first" name="bar[first]" type="text" value="a"/></div>'
|
@@ -481,19 +493,19 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
481
493
|
end
|
482
494
|
|
483
495
|
it "should automatically note the input has errors if :error option is used" do
|
484
|
-
@f.input(:text, :error=>'Bad Stuff!', :value=>'foo').to_s.must_equal '<div class="form-group has-error"><input class="form-control" type="text" value="foo"/><span class="help-block with-errors">Bad Stuff!</span></div>'
|
496
|
+
@f.input(:text, :error=>'Bad Stuff!', :value=>'foo').to_s.must_equal '<div class="form-group has-error"><input aria-invalid="true" class="form-control" type="text" value="foo"/><span class="help-block with-errors">Bad Stuff!</span></div>'
|
485
497
|
end
|
486
498
|
|
487
499
|
it "should add an error message after the label" do
|
488
|
-
@f.input(:text, :error=>'Bad Stuff!', :value=>'foo', :label=>"Foo").to_s.must_equal '<div class="form-group has-error"><label>Foo</label> <input class="form-control" type="text" value="foo"/><span class="help-block with-errors">Bad Stuff!</span></div>'
|
500
|
+
@f.input(:text, :error=>'Bad Stuff!', :value=>'foo', :label=>"Foo").to_s.must_equal '<div class="form-group has-error"><label>Foo</label> <input aria-invalid="true" class="form-control" type="text" value="foo"/><span class="help-block with-errors">Bad Stuff!</span></div>'
|
489
501
|
end
|
490
502
|
|
491
503
|
it "should add to existing :class option if :error option is used" do
|
492
|
-
@f.input(:text, :error=>'Bad Stuff!', :class=>'bar', :value=>'foo').to_s.must_equal '<div class="form-group has-error"><input class="form-control bar" type="text" value="foo"/><span class="help-block with-errors">Bad Stuff!</span></div>'
|
504
|
+
@f.input(:text, :error=>'Bad Stuff!', :class=>'bar', :value=>'foo').to_s.must_equal '<div class="form-group has-error"><input aria-invalid="true" class="form-control bar" type="text" value="foo"/><span class="help-block with-errors">Bad Stuff!</span></div>'
|
493
505
|
end
|
494
506
|
|
495
507
|
it "should respect :error_attr option for setting the attributes for the error message span" do
|
496
|
-
@f.input(:text, :error=>'Bad Stuff!', :value=>'foo', :error_attr=>{:class=>'foo'}).to_s.must_equal '<div class="form-group has-error"><input class="form-control" type="text" value="foo"/><span class="foo help-block with-errors">Bad Stuff!</span></div>'
|
508
|
+
@f.input(:text, :error=>'Bad Stuff!', :value=>'foo', :error_attr=>{:class=>'foo'}).to_s.must_equal '<div class="form-group has-error"><input aria-invalid="true" class="form-control" type="text" value="foo"/><span class="foo help-block with-errors">Bad Stuff!</span></div>'
|
497
509
|
end
|
498
510
|
|
499
511
|
it "#open should return an opening tag" do
|
@@ -527,12 +539,12 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
527
539
|
end
|
528
540
|
|
529
541
|
it "#tag should accept children as procs" do
|
530
|
-
@f.tag(:div, {:class=>"foo"}, lambda{|t| t.
|
542
|
+
@f.tag(:div, {:class=>"foo"}, lambda{|t| t.tag(:input, :class=>t.attr[:class])}).to_s.must_equal '<div class="foo"><input class="form-control foo" type="text"/></div>'
|
531
543
|
end
|
532
544
|
|
533
545
|
it "#tag should accept children as methods" do
|
534
546
|
o = Object.new
|
535
|
-
def o.foo(t) t.
|
547
|
+
def o.foo(t) t.tag(:input, :class=>t.attr[:class]) end
|
536
548
|
@f.tag(:div, {:class=>"foo"}, o.method(:foo)).to_s.must_equal '<div class="foo"><input class="form-control foo" type="text"/></div>'
|
537
549
|
end
|
538
550
|
|
@@ -624,7 +636,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
624
636
|
end
|
625
637
|
|
626
638
|
it "inputs should have helper displayed inside wrapper, after error" do
|
627
|
-
@f.input(:text, :help=>"List type of foo", :error=>'bad', :wrapper=>:li).to_s.must_equal '<li class="has-error"><input class="form-control" type="text"/><span class="help-block with-errors">bad</span><span class="helper">List type of foo</span></li>'
|
639
|
+
@f.input(:text, :help=>"List type of foo", :error=>'bad', :wrapper=>:li).to_s.must_equal '<li class="has-error"><input aria-invalid="true" class="form-control" type="text"/><span class="help-block with-errors">bad</span><span class="helper">List type of foo</span></li>'
|
628
640
|
end
|
629
641
|
|
630
642
|
it "inputs should accept a :formatter option to use a custom formatter" do
|
@@ -661,7 +673,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
661
673
|
end
|
662
674
|
|
663
675
|
it "inputs should accept a :error_handler option to use a custom error_handler" do
|
664
|
-
@f.input(:textarea, :error_handler=>proc{|t, i| [t, "!!! #{i.opts[:error]}"]}, :error=>'bar', :id=>:foo).to_s.must_equal '<div class="form-group"><textarea class="form-control" id="foo"></textarea>!!! bar</div>'
|
676
|
+
@f.input(:textarea, :error_handler=>proc{|t, i| [t, "!!! #{i.opts[:error]}"]}, :error=>'bar', :id=>:foo).to_s.must_equal '<div class="form-group"><textarea aria-describedby="foo_error_message" aria-invalid="true" class="form-control" id="foo"></textarea>!!! bar</div>'
|
665
677
|
end
|
666
678
|
|
667
679
|
it "#inputs should accept a :inputs_wrapper option to use a custom inputs_wrapper" do
|
@@ -679,7 +691,7 @@ describe "Forme Bootstrap3 (BS3) forms" do
|
|
679
691
|
end
|
680
692
|
|
681
693
|
it "inputs should accept a :error_handler=>nil option to not use an error_handler" do
|
682
|
-
@f.input(:textarea, :error_handler=>nil, :error=>'bar', :id=>:foo).to_s.must_equal '<div class="form-group"><textarea class="form-control" id="foo"></textarea></div>'
|
694
|
+
@f.input(:textarea, :error_handler=>nil, :error=>'bar', :id=>:foo).to_s.must_equal '<div class="form-group"><textarea aria-invalid="true" class="form-control" id="foo"></textarea></div>'
|
683
695
|
end
|
684
696
|
|
685
697
|
it "#inputs should accept a :inputs_wrapper=>nil option to not use an inputs_wrapper" do
|
data/spec/erb_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative 'shared_erb_specs'
|
2
|
+
|
1
3
|
ERB_BLOCK = lambda do |r|
|
2
4
|
r.get '' do
|
3
5
|
erb <<END
|
@@ -65,6 +67,29 @@ END
|
|
65
67
|
END
|
66
68
|
end
|
67
69
|
|
70
|
+
r.get 'nest_seq_simple' do
|
71
|
+
@album = Album.load(:name=>'N', :copies_sold=>2, :id=>1)
|
72
|
+
@album.associations[:artist] = Artist.load(:name=>'A', :id=>2)
|
73
|
+
@nest = <<END
|
74
|
+
n1
|
75
|
+
<% f.subform(:artist) do %>
|
76
|
+
n2
|
77
|
+
<%= f.input(:name2) %>
|
78
|
+
n3
|
79
|
+
<% end %>
|
80
|
+
n4
|
81
|
+
END
|
82
|
+
erb <<END
|
83
|
+
0
|
84
|
+
<% form(@album, :action=>'/baz') do |f| %>
|
85
|
+
1
|
86
|
+
<%= erb(@nest, :locals=>{:f=>f}) %>
|
87
|
+
3
|
88
|
+
<% end %>
|
89
|
+
4
|
90
|
+
END
|
91
|
+
end
|
92
|
+
|
68
93
|
r.get 'nest_seq' do
|
69
94
|
@album = Album.load(:name=>'N', :copies_sold=>2, :id=>1)
|
70
95
|
@album.associations[:artist] = Artist.load(:name=>'A', :id=>2)
|
@@ -92,6 +117,50 @@ END
|
|
92
117
|
END
|
93
118
|
end
|
94
119
|
|
120
|
+
r.get 'grid-block' do
|
121
|
+
@album = Album.load(:name=>'N', :copies_sold=>2, :id=>1)
|
122
|
+
@album.associations[:artist] = Artist.load(:name=>'A', :id=>2)
|
123
|
+
erb <<END
|
124
|
+
0
|
125
|
+
<% form(@album, {:action=>'/baz'}, :button=>'Sub') do |f| %>
|
126
|
+
1
|
127
|
+
<% f.subform(:artist, :inputs=>[:name], :legend=>'Foo', :grid=>true, :labels=>%w'Name') do %>
|
128
|
+
2
|
129
|
+
<% end %>
|
130
|
+
3
|
131
|
+
<% end %>
|
132
|
+
4
|
133
|
+
END
|
134
|
+
end
|
135
|
+
|
136
|
+
r.get 'grid-noblock' do
|
137
|
+
@album = Album.load(:name=>'N', :copies_sold=>2, :id=>1)
|
138
|
+
@album.associations[:artist] = Artist.load(:name=>'A', :id=>2)
|
139
|
+
erb <<END
|
140
|
+
0
|
141
|
+
<% form(@album, {:action=>'/baz'}, :button=>'Sub') do |f| %>
|
142
|
+
1
|
143
|
+
<%= f.subform(:artist, :inputs=>[:name], :legend=>'Foo', :grid=>true, :labels=>%w'Name') %>
|
144
|
+
2
|
145
|
+
<% end %>
|
146
|
+
3
|
147
|
+
END
|
148
|
+
end
|
149
|
+
|
150
|
+
r.get 'grid-noblock-multiple' do
|
151
|
+
@artist = Artist.load(:name=>'A', :id=>2)
|
152
|
+
@artist.associations[:albums] = [Album.load(:name=>'N', :copies_sold=>2, :id=>1)]
|
153
|
+
erb <<END
|
154
|
+
0
|
155
|
+
<% form(@artist, {:action=>'/baz'}, :button=>'Sub') do |f| %>
|
156
|
+
1
|
157
|
+
<%= f.subform(:albums, :inputs=>[:name, :copies_sold], :legend=>'Foo', :grid=>true, :labels=>%w'Name Copies') %>
|
158
|
+
2
|
159
|
+
<% end %>
|
160
|
+
3
|
161
|
+
END
|
162
|
+
end
|
163
|
+
|
95
164
|
r.get 'hash' do
|
96
165
|
erb "<% form({:action=>'/baz'}, :obj=>[:foo]) do |f| %> <%= f.input(:first) %> <% end %>"
|
97
166
|
end
|
@@ -127,61 +196,3 @@ END
|
|
127
196
|
erb "<%= form(:action=>'/baz') %>"
|
128
197
|
end
|
129
198
|
end
|
130
|
-
|
131
|
-
module FormeErbSpecs
|
132
|
-
extend Minitest::Spec::DSL
|
133
|
-
|
134
|
-
before do
|
135
|
-
o = Object.new
|
136
|
-
def o.puts(*) end
|
137
|
-
@rack = {'rack.input'=>'', 'REQUEST_METHOD'=>'GET', 'rack.errors'=>o, 'SCRIPT_NAME'=>''}
|
138
|
-
end
|
139
|
-
|
140
|
-
it "#form should add start and end tags and yield Forme::Form instance" do
|
141
|
-
sin_get('/').must_equal '<form action="/baz"> <p>FBB</p> <input id="first" name="first" type="text" value="foo"/> <input id="last" name="last" type="text" value="bar"/> <input type="submit" value="Save"/> </form>'
|
142
|
-
end
|
143
|
-
|
144
|
-
it "#form should have inputs work with a block" do
|
145
|
-
sin_get('/inputs_block').must_equal '<form action="/baz"><fieldset class="inputs"><legend>FBB</legend> <input id="last" name="last" type="text" value="bar"/> </fieldset></form>'
|
146
|
-
end
|
147
|
-
|
148
|
-
it "#form should have inputs with fieldset_ol wrapper work with block" do
|
149
|
-
sin_get('/inputs_block_wrapper').must_equal '<form action="/baz"><fieldset class="inputs"><legend>FBB</legend><ol> <input id="last" name="last" type="text" value="bar"/> </ol></fieldset></form>'
|
150
|
-
end
|
151
|
-
|
152
|
-
it "#form should add start and end tags and yield Forme::Form instance" do
|
153
|
-
sin_get('/nest').must_equal '<form action="/baz"> <p>FBB</p> <div> <input id="first" name="first" type="text" value="foo"/> <input id="last" name="last" type="text" value="bar"/> </div> </form>'
|
154
|
-
end
|
155
|
-
|
156
|
-
it "#form should correctly handle situation where multiple templates are used with same form object" do
|
157
|
-
sin_get('/nest_sep').must_equal '0 <form action="/baz"> 1 <p>FBB</p> 2 n1 <div> n2 <input id="first" name="first" type="text" value="foo"/> <input id="last" name="last" type="text" value="bar"/> n3 </div> n4 <fieldset class="inputs"><legend>Foo</legend><input id="first" name="first" type="text" value="foo"/><input id="last" name="last" type="text" value="bar"/></fieldset> n5 3 </form>4'
|
158
|
-
end
|
159
|
-
|
160
|
-
it "#form should correctly handle situation Sequel integration with subforms where multiple templates are used with same form object" do
|
161
|
-
sin_get('/nest_seq').sub(%r{<input name="_csrf" type="hidden" value="([^"]+)"/>}, '<input name="_csrf" type="hidden" value="csrf"/>').must_equal '0 <form action="/baz" class="forme album" method="post"><input name="_csrf" type="hidden" value="csrf"/> 1 <input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="2"/><fieldset class="inputs"><legend>Foo</legend><label>Name: <input id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="A"/></label></fieldset> 2 n1 <input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="2"/><fieldset class="inputs"><legend>Artist</legend> n2 <label>Name2: <input id="album_artist_attributes_name2" name="album[artist_attributes][name2]" type="text" value="A2"/></label> n3 </fieldset> n4 <input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="2"/><fieldset class="inputs"><legend>Bar</legend><label>Name3: <input id="album_artist_attributes_name3" name="album[artist_attributes][name3]" type="text" value="A3"/></label></fieldset> n5 3 </form>4'
|
162
|
-
end
|
163
|
-
|
164
|
-
it "#form should accept two hashes instead of requiring obj as first argument" do
|
165
|
-
sin_get('/hash').must_equal '<form action="/baz"> <input id="first" name="first" type="text" value="foo"/> </form>'
|
166
|
-
end
|
167
|
-
|
168
|
-
it "#form should deal with emitted code" do
|
169
|
-
sin_get('/legend').must_equal '<form action="/baz"> <p>FBB</p> <fieldset class="inputs"><legend>Foo</legend><input id="first" name="first" type="text" value="foo"/><input id="last" name="last" type="text" value="bar"/></fieldset> <p>FBB2</p> </form>'
|
170
|
-
end
|
171
|
-
|
172
|
-
it "#form should work with :inputs, :button, and :legend options" do
|
173
|
-
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>'
|
174
|
-
end
|
175
|
-
|
176
|
-
it "#form should work without a block" do
|
177
|
-
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>'
|
178
|
-
end
|
179
|
-
|
180
|
-
it "#form should work without a block and still have hidden tags emitted" do
|
181
|
-
sin_get('/noblock_post').sub(%r{<input name=\"_csrf\" type=\"hidden\" value=\"([^\"]+)\"/>}, "<input name=\"_csrf\" type=\"hidden\" value=\"csrf\"/>").must_equal '<form method="post"><input name="_csrf" type="hidden" value="csrf"/><input type="submit" value="xyz"/></form>'
|
182
|
-
end
|
183
|
-
|
184
|
-
it "#form with an empty form should work" do
|
185
|
-
sin_get('/noblock_empty').must_equal '<form action="/baz"></form>'
|
186
|
-
end
|
187
|
-
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
require_relative 'shared_erb_specs'
|
2
|
+
|
3
|
+
ERUBI_CAPTURE_BLOCK = lambda do |r|
|
4
|
+
r.get '' do
|
5
|
+
erb <<END
|
6
|
+
<%|= form([:foo, :bar], :action=>'/baz') do |f| %>
|
7
|
+
<p>FBB</p>
|
8
|
+
<%= f.input(:first) %>
|
9
|
+
<%= f.input(:last) %>
|
10
|
+
<%= f.button('Save') %>
|
11
|
+
<%| end %>
|
12
|
+
END
|
13
|
+
end
|
14
|
+
|
15
|
+
r.get 'inputs_block' do
|
16
|
+
erb <<END
|
17
|
+
<%|= form([:foo, :bar], :action=>'/baz') do |f| %><%|= f.inputs(:legend=>'FBB') do %>
|
18
|
+
<%= f.input(:last) %>
|
19
|
+
<%| end %><%| end %>
|
20
|
+
END
|
21
|
+
end
|
22
|
+
|
23
|
+
r.get 'inputs_block_wrapper' do
|
24
|
+
erb <<END
|
25
|
+
<%|= form([:foo, :bar], {:action=>'/baz'}, :inputs_wrapper=>:fieldset_ol) do |f| %><%|= f.inputs(:legend=>'FBB') do %>
|
26
|
+
<%= f.input(:last) %>
|
27
|
+
<%| end %><%| end %>
|
28
|
+
END
|
29
|
+
end
|
30
|
+
|
31
|
+
r.get 'nest' do
|
32
|
+
erb <<END
|
33
|
+
<%|= form([:foo, :bar], :action=>'/baz') do |f| %>
|
34
|
+
<%= f.tag(:p, {}, 'FBB') %>
|
35
|
+
<%|= f.tag(:div) do %>
|
36
|
+
<%= f.input(:first) %>
|
37
|
+
<%= f.input(:last) %>
|
38
|
+
<%| end %>
|
39
|
+
|
40
|
+
<%| end %>
|
41
|
+
END
|
42
|
+
end
|
43
|
+
|
44
|
+
r.get 'nest_sep' do
|
45
|
+
@nest = <<END
|
46
|
+
n1
|
47
|
+
<%|= f.tag(:div) do %>
|
48
|
+
n2
|
49
|
+
<%= f.input(:first) %>
|
50
|
+
<%= f.input(:last) %>
|
51
|
+
n3
|
52
|
+
<%| end %>
|
53
|
+
n4
|
54
|
+
<%= f.inputs([:first, :last], :legend=>'Foo') %>
|
55
|
+
n5
|
56
|
+
END
|
57
|
+
erb <<END
|
58
|
+
0
|
59
|
+
<%|= form([:foo, :bar], :action=>'/baz') do |f| %>
|
60
|
+
1
|
61
|
+
<%= f.tag(:p, {}, 'FBB') %>
|
62
|
+
2
|
63
|
+
<%= erb(@nest, :locals=>{:f=>f}) %>
|
64
|
+
3
|
65
|
+
<%| end %>
|
66
|
+
4
|
67
|
+
END
|
68
|
+
end
|
69
|
+
|
70
|
+
r.get 'nest_seq_simple' do
|
71
|
+
@album = Album.load(:name=>'N', :copies_sold=>2, :id=>1)
|
72
|
+
@album.associations[:artist] = Artist.load(:name=>'A', :id=>2)
|
73
|
+
@nest = <<END
|
74
|
+
n1
|
75
|
+
<%|= f.subform(:artist) do %>
|
76
|
+
n2
|
77
|
+
<%= f.input(:name2) %>
|
78
|
+
n3
|
79
|
+
<%| end %>
|
80
|
+
n4
|
81
|
+
END
|
82
|
+
erb <<END
|
83
|
+
0
|
84
|
+
<%|= form(@album, :action=>'/baz') do |f| %>
|
85
|
+
1
|
86
|
+
<%= erb(@nest, :locals=>{:f=>f}) %>
|
87
|
+
3
|
88
|
+
<%| end %>
|
89
|
+
4
|
90
|
+
END
|
91
|
+
end
|
92
|
+
|
93
|
+
r.get 'nest_seq' do
|
94
|
+
@album = Album.load(:name=>'N', :copies_sold=>2, :id=>1)
|
95
|
+
@album.associations[:artist] = Artist.load(:name=>'A', :id=>2)
|
96
|
+
@nest = <<END
|
97
|
+
n1
|
98
|
+
<%|= f.subform(:artist) do %>
|
99
|
+
n2
|
100
|
+
<%= f.input(:name2) %>
|
101
|
+
n3
|
102
|
+
<%| end %>
|
103
|
+
n4
|
104
|
+
<%= f.subform(:artist, :inputs=>[:name3], :legend=>'Bar') %>
|
105
|
+
n5
|
106
|
+
END
|
107
|
+
erb <<END
|
108
|
+
0
|
109
|
+
<%|= form(@album, :action=>'/baz') do |f| %>
|
110
|
+
1
|
111
|
+
<%= f.subform(:artist, :inputs=>[:name], :legend=>'Foo') %>
|
112
|
+
2
|
113
|
+
<%= erb(@nest, :locals=>{:f=>f}) %>
|
114
|
+
3
|
115
|
+
<%| end %>
|
116
|
+
4
|
117
|
+
END
|
118
|
+
end
|
119
|
+
|
120
|
+
r.get 'grid-block' do
|
121
|
+
@album = Album.load(:name=>'N', :copies_sold=>2, :id=>1)
|
122
|
+
@album.associations[:artist] = Artist.load(:name=>'A', :id=>2)
|
123
|
+
erb <<END
|
124
|
+
0
|
125
|
+
<%|= form(@album, {:action=>'/baz'}, :button=>'Sub') do |f| %>
|
126
|
+
1
|
127
|
+
<%|= f.subform(:artist, :inputs=>[:name], :legend=>'Foo', :grid=>true, :labels=>%w'Name') do %>
|
128
|
+
2
|
129
|
+
<%| end %>
|
130
|
+
3
|
131
|
+
<%| end %>
|
132
|
+
4
|
133
|
+
END
|
134
|
+
end
|
135
|
+
|
136
|
+
r.get 'grid-noblock' do
|
137
|
+
@album = Album.load(:name=>'N', :copies_sold=>2, :id=>1)
|
138
|
+
@album.associations[:artist] = Artist.load(:name=>'A', :id=>2)
|
139
|
+
erb <<END
|
140
|
+
0
|
141
|
+
<%|= form(@album, {:action=>'/baz'}, :button=>'Sub') do |f| %>
|
142
|
+
1
|
143
|
+
<%= f.subform(:artist, :inputs=>[:name], :legend=>'Foo', :grid=>true, :labels=>%w'Name') %>
|
144
|
+
2
|
145
|
+
<%| end %>
|
146
|
+
3
|
147
|
+
END
|
148
|
+
end
|
149
|
+
|
150
|
+
r.get 'grid-noblock-multiple' do
|
151
|
+
@artist = Artist.load(:name=>'A', :id=>2)
|
152
|
+
@artist.associations[:albums] = [Album.load(:name=>'N', :copies_sold=>2, :id=>1)]
|
153
|
+
erb <<END
|
154
|
+
0
|
155
|
+
<%|= form(@artist, {:action=>'/baz'}, :button=>'Sub') do |f| %>
|
156
|
+
1
|
157
|
+
<%= f.subform(:albums, :inputs=>[:name, :copies_sold], :legend=>'Foo', :grid=>true, :labels=>%w'Name Copies') %>
|
158
|
+
2
|
159
|
+
<%| end %>
|
160
|
+
3
|
161
|
+
END
|
162
|
+
end
|
163
|
+
|
164
|
+
r.get 'hash' do
|
165
|
+
erb "<%|= form({:action=>'/baz'}, :obj=>[:foo]) do |f| %> <%= f.input(:first) %> <%| end %>"
|
166
|
+
end
|
167
|
+
|
168
|
+
r.get 'legend' do
|
169
|
+
erb <<END
|
170
|
+
<%|= form([:foo, :bar], :action=>'/baz') do |f| %>
|
171
|
+
<p>FBB</p>
|
172
|
+
<%= f.inputs([:first, :last], :legend=>'Foo') %>
|
173
|
+
<p>FBB2</p>
|
174
|
+
<%| end %>
|
175
|
+
END
|
176
|
+
end
|
177
|
+
|
178
|
+
r.get 'combined' do
|
179
|
+
erb <<END
|
180
|
+
<%|= form([:foo, :bar], {:action=>'/baz'}, :inputs=>[:first], :button=>'xyz', :legend=>'123') do |f| %>
|
181
|
+
<p>FBB</p>
|
182
|
+
<%= f.input(:last) %>
|
183
|
+
<%| end %>
|
184
|
+
END
|
185
|
+
end
|
186
|
+
|
187
|
+
r.get 'noblock' do
|
188
|
+
erb "<%= form([:foo, :bar], {:action=>'/baz'}, :inputs=>[:first], :button=>'xyz', :legend=>'123') %>"
|
189
|
+
end
|
190
|
+
|
191
|
+
r.get 'noblock_post' do
|
192
|
+
erb "<%= form({:method=>:post}, :button=>'xyz') %>"
|
193
|
+
end
|
194
|
+
|
195
|
+
r.get 'noblock_empty' do
|
196
|
+
erb "<%= form(:action=>'/baz') %>"
|
197
|
+
end
|
198
|
+
end
|
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)
|
@@ -317,6 +317,10 @@ describe "Forme plain forms" do
|
|
317
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>}
|
318
318
|
end
|
319
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
|
+
|
320
324
|
it "should have explicit labeler and trtd wrapper work with multiple select boxes for dates" do
|
321
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>}
|
322
326
|
end
|
@@ -627,13 +631,19 @@ describe "Forme plain forms" do
|
|
627
631
|
@f.tag(:textarea, {:name=>:foo}, :bar).to_s.must_equal '<textarea name="foo">bar</textarea>'
|
628
632
|
end
|
629
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
|
+
|
630
640
|
it "#tag should accept children as procs" do
|
631
|
-
@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>'
|
632
642
|
end
|
633
643
|
|
634
644
|
it "#tag should accept children as methods" do
|
635
645
|
o = Object.new
|
636
|
-
def o.foo(t) t.
|
646
|
+
def o.foo(t) t.tag(:input, :class=>t.attr[:class]) end
|
637
647
|
@f.tag(:div, {:class=>"foo"}, o.method(:foo)).to_s.must_equal '<div class="foo"><input class="foo"/></div>'
|
638
648
|
end
|
639
649
|
|
@@ -641,6 +651,10 @@ describe "Forme plain forms" do
|
|
641
651
|
@f.inputs([:textarea, :text]).to_s.must_equal '<fieldset class="inputs"><textarea></textarea><input type="text"/></fieldset>'
|
642
652
|
end
|
643
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
|
+
|
644
658
|
it "should have default #inputs method accept an :attr option" do
|
645
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>'
|
646
660
|
end
|
@@ -801,41 +815,15 @@ describe "Forme plain forms" do
|
|
801
815
|
proc{@f.input(:textarea, :wrapper=>Object.new).to_s}.must_raise(Forme::Error)
|
802
816
|
proc{@f.input(:textarea, :formatter=>nil).to_s}.must_raise(Forme::Error)
|
803
817
|
end
|
804
|
-
end
|
805
|
-
|
806
|
-
describe "Forme::Form :hidden_tags option " do
|
807
|
-
before do
|
808
|
-
@f = Forme::Form.new
|
809
|
-
end
|
810
|
-
|
811
|
-
it "should handle hash" do
|
812
|
-
Forme.form({}, :hidden_tags=>[{:a=>'b'}]).to_s.must_equal '<form><input name="a" type="hidden" value="b"/></form>'
|
813
|
-
end
|
814
|
-
|
815
|
-
it "should handle array" do
|
816
|
-
Forme.form({}, :hidden_tags=>[["a ", "b"]]).to_s.must_equal '<form>a b</form>'
|
817
|
-
end
|
818
|
-
|
819
|
-
it "should handle string" do
|
820
|
-
Forme.form({}, :hidden_tags=>["a "]).to_s.must_equal '<form>a </form>'
|
821
|
-
end
|
822
|
-
|
823
|
-
it "should handle proc return hash" do
|
824
|
-
Forme.form({}, :hidden_tags=>[lambda{|tag| {:a=>'b'}}]).to_s.must_equal '<form><input name="a" type="hidden" value="b"/></form>'
|
825
|
-
end
|
826
|
-
|
827
|
-
it "should handle proc return tag" do
|
828
|
-
Forme.form({:method=>'post'}, :hidden_tags=>[lambda{|tag| tag.form._tag(tag.attr[:method])}]).to_s.must_equal '<form method="post"><post></post></form>'
|
829
|
-
end
|
830
818
|
|
831
|
-
it "should
|
832
|
-
|
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>'
|
833
821
|
end
|
834
822
|
end
|
835
823
|
|
836
824
|
describe "Forme custom" do
|
837
825
|
it "formatters can be specified as a proc" do
|
838
|
-
Forme::Form.new(:formatter=>proc{|i| i.
|
826
|
+
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>'
|
839
827
|
end
|
840
828
|
|
841
829
|
it "serializers can be specified as a proc" do
|
@@ -1052,6 +1040,7 @@ describe "Forme built-in custom" do
|
|
1052
1040
|
Forme::Form.new(:serializer=>:text).button().to_s.must_equal ""
|
1053
1041
|
Forme::Form.new(:serializer=>:text).inputs([[:textarea, {:label=>"Foo", :value=>"Bar"}]], :legend=>'Baz').to_s.must_equal "Baz\n---\nFoo: Bar\n\n"
|
1054
1042
|
Forme::Form.new(:serializer=>:text).tag(:p){|f| f.input(:textarea, :label=>"Foo", :value=>"Bar")}.to_s.must_equal "Foo: Bar\n\n"
|
1043
|
+
Forme::Form.new(:serializer=>:text).tag(:p, {}, ['a']).to_s.must_equal "a"
|
1055
1044
|
end
|
1056
1045
|
end
|
1057
1046
|
|
@@ -1,34 +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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
14
|
-
require 'forme/rails'
|
5
|
+
require 'action_controller/railtie'
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'active_pack/gem_version'
|
9
|
+
rescue LoadError
|
10
|
+
end
|
11
|
+
require_relative '../lib/forme/rails'
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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::HostAuthorization) if defined?(ActionDispatch::HostAuthorization)
|
24
|
-
config.middleware.delete(ActionDispatch::ShowExceptions)
|
25
|
-
config.middleware.delete(Rack::Lock)
|
26
|
-
config.secret_key_base = 'foo'*15
|
27
|
-
config.secret_token = 'secret token'*15 if Rails.respond_to?(:version) && Rails.version < '5.2'
|
28
|
-
config.eager_load = true
|
29
|
-
initialize!
|
30
|
-
end
|
31
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 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
|
32
46
|
class FormeController < ActionController::Base
|
33
47
|
helper Forme::Rails::ERB
|
34
48
|
|