forme 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +12 -0
- data/README.rdoc +1 -1
- data/lib/forme.rb +59 -10
- data/lib/forme/rails.rb +24 -3
- data/lib/forme/sinatra.rb +21 -4
- data/lib/forme/version.rb +1 -1
- data/lib/sequel/plugins/forme.rb +1 -1
- data/spec/forme_spec.rb +44 -0
- data/spec/rails_integration_spec.rb +13 -3
- data/spec/sequel_plugin_spec.rb +12 -1
- data/spec/sinatra_integration_spec.rb +19 -10
- metadata +10 -17
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 06d7e50cfae657572071affb86ef307636c65345
|
4
|
+
data.tar.gz: 5eef25b91f833f3a57caef3903d25886cb48f00d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a19e5579fc8f0bfe11c5136f2ecc69db057a23f76d08bc01aad4680c1ebeb9fbd27476a04d60265efe5de1d1e5ab0b16dd615f8bc0081c7b733ef9f188e31581
|
7
|
+
data.tar.gz: ba0fe6ba4e18fe182c0a93eb9b33f28e0d0f30729ec537f2a3b468d8b9db56a75d657aadb17b4c164a3128d901017d7460a7ce8ecd9bd8a923d5017bc1e4d051
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
=== 0.8.0 (2013-10-30)
|
2
|
+
|
3
|
+
* form calls without block or :inputs or :button options are now handled correctly in the Sinatra integration (jeremyevans)
|
4
|
+
|
5
|
+
* CSRF token tags are now automatically added to forms in Rails and Sinatra if using rack_csrf (jeremyevans) (#5)
|
6
|
+
|
7
|
+
* Form objects now support a :hidden_tags option for automatically adding hidden tags (jeremyevans)
|
8
|
+
|
9
|
+
* Sequel many_to_one associations with existing and required values no longer have a blank option added by default (jeremyevans)
|
10
|
+
|
11
|
+
* ActiveSupport::SafeBuffer objects are now automatically treated as raw in the Rails integration (jeremyevans)
|
12
|
+
|
1
13
|
=== 0.7.0 (2012-05-02)
|
2
14
|
|
3
15
|
* Support :label_position option in both of the labelers, can be set to :before or :after to override the default (jeremyevans)
|
data/README.rdoc
CHANGED
@@ -76,7 +76,7 @@ You can even do everything in a single method call:
|
|
76
76
|
|
77
77
|
= Basic Design
|
78
78
|
|
79
|
-
|
79
|
+
Internally, Forme builds an abstract syntax tree of objects that
|
80
80
|
represent the form. The abstract syntax tree goes through a
|
81
81
|
series of transformations that convert it from high level
|
82
82
|
abstract forms to low level abstract forms and finally to
|
data/lib/forme.rb
CHANGED
@@ -99,7 +99,7 @@ module Forme
|
|
99
99
|
# +obj+ or +block+, but not both. If +obj+ is given, should be
|
100
100
|
# either a +Class+ instance or it should respond to +call+. If a
|
101
101
|
# +Class+ instance is given, instances of that class should respond
|
102
|
-
# to +call+, and
|
102
|
+
# to +call+, and a new instance of that class should be used
|
103
103
|
# for each transformation.
|
104
104
|
def self.register_transformer(type, sym, obj=nil, &block)
|
105
105
|
raise Error, "Not a valid transformer type" unless TRANSFORMERS.has_key?(type)
|
@@ -145,6 +145,7 @@ module Forme
|
|
145
145
|
# :obj :: Sets the +obj+ attribute
|
146
146
|
# :error_handler :: Sets the +error_handler+ for the form
|
147
147
|
# :formatter :: Sets the +formatter+ for the form
|
148
|
+
# :hidden_tags :: Sets the hidden tags to automatically add to this form.
|
148
149
|
# :inputs_wrapper :: Sets the +inputs_wrapper+ for the form
|
149
150
|
# :labeler :: Sets the +labeler+ for the form
|
150
151
|
# :wrapper :: Sets the +wrapper+ for the form
|
@@ -175,6 +176,15 @@ module Forme
|
|
175
176
|
# Must respond to +call+ or be a registered symbol.
|
176
177
|
attr_reader :serializer
|
177
178
|
|
179
|
+
# The hidden tags to automatically add to the form. If set, this should be an
|
180
|
+
# array, where elements are one of the following types:
|
181
|
+
# String, Array, Forme::Tag :: Added directly as a child of the form tag.
|
182
|
+
# Hash :: Adds a hidden tag for each entry, with keys as the name of the hidden
|
183
|
+
# tag and values as the value of the hidden tag.
|
184
|
+
# Proc :: Will be called with the form tag object, and should return an instance
|
185
|
+
# of one of the handled types (or nil to not add a tag).
|
186
|
+
attr_reader :hidden_tags
|
187
|
+
|
178
188
|
# Create a +Form+ instance and yield it to the block,
|
179
189
|
# injecting the opening form tag before yielding and
|
180
190
|
# the closing form tag after yielding.
|
@@ -232,6 +242,7 @@ module Forme
|
|
232
242
|
end
|
233
243
|
config = CONFIGURATIONS[@opts[:config]||Forme.default_config]
|
234
244
|
TRANSFORMER_TYPES.each{|k| instance_variable_set(:"@#{k}", transformer(k, @opts.fetch(k, config[k])))}
|
245
|
+
@hidden_tags = @opts[:hidden_tags]
|
235
246
|
@nesting = []
|
236
247
|
end
|
237
248
|
|
@@ -285,7 +296,7 @@ module Forme
|
|
285
296
|
|
286
297
|
# Create a form tag with the given attributes.
|
287
298
|
def form(attr={}, &block)
|
288
|
-
tag(:form, attr, &block)
|
299
|
+
tag(:form, attr, method(:hidden_form_tags), &block)
|
289
300
|
end
|
290
301
|
|
291
302
|
# Formats the +input+ using the +formatter+.
|
@@ -429,6 +440,35 @@ module Forme
|
|
429
440
|
|
430
441
|
private
|
431
442
|
|
443
|
+
# Return array of hidden tags to use for this form,
|
444
|
+
# or nil if the form does not have hidden tags added automatically.
|
445
|
+
def hidden_form_tags(form_tag)
|
446
|
+
if hidden_tags
|
447
|
+
tags = []
|
448
|
+
hidden_tags.each do |hidden_tag|
|
449
|
+
hidden_tag = hidden_tag.call(form_tag) if hidden_tag.respond_to?(:call)
|
450
|
+
tags.concat(parse_hidden_tags(hidden_tag))
|
451
|
+
end
|
452
|
+
tags
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
# Handle various types of hidden tags for the form.
|
457
|
+
def parse_hidden_tags(hidden_tag)
|
458
|
+
case hidden_tag
|
459
|
+
when Array
|
460
|
+
hidden_tag
|
461
|
+
when Tag, String
|
462
|
+
[hidden_tag]
|
463
|
+
when Hash
|
464
|
+
hidden_tag.map{|k,v| _tag(:input, :type=>:hidden, :name=>k, :value=>v)}
|
465
|
+
when nil
|
466
|
+
[]
|
467
|
+
else
|
468
|
+
raise Error, "unhandled hidden_tag response: #{hidden_tag.inspect}"
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
432
472
|
# Extend +obj+ with +Serialized+ and associate it with the receiver, such
|
433
473
|
# that calling +to_s+ on the object will use the receiver's serializer
|
434
474
|
# to generate the resulting string.
|
@@ -530,15 +570,8 @@ module Forme
|
|
530
570
|
|
531
571
|
# Set the +form+, +type+, +attr+, and +children+.
|
532
572
|
def initialize(form, type, attr={}, children=nil)
|
533
|
-
case children
|
534
|
-
when Array
|
535
|
-
@children = children
|
536
|
-
when nil
|
537
|
-
@children = nil
|
538
|
-
else
|
539
|
-
@children = [children]
|
540
|
-
end
|
541
573
|
@form, @type, @attr = form, type, (attr||{})
|
574
|
+
@children = parse_children(children)
|
542
575
|
end
|
543
576
|
|
544
577
|
# Adds a child to the array of receiver's children.
|
@@ -560,6 +593,22 @@ module Forme
|
|
560
593
|
def to_s
|
561
594
|
form.serialize(self)
|
562
595
|
end
|
596
|
+
|
597
|
+
private
|
598
|
+
|
599
|
+
# Convert children constructor argument into the children to use for the tag.
|
600
|
+
def parse_children(children)
|
601
|
+
case children
|
602
|
+
when Array
|
603
|
+
children
|
604
|
+
when Proc, Method
|
605
|
+
parse_children(children.call(self))
|
606
|
+
when nil
|
607
|
+
nil
|
608
|
+
else
|
609
|
+
[children]
|
610
|
+
end
|
611
|
+
end
|
563
612
|
end
|
564
613
|
|
565
614
|
# Module that can extend objects associating them with a specific
|
data/lib/forme/rails.rb
CHANGED
@@ -1,7 +1,28 @@
|
|
1
1
|
require 'forme'
|
2
2
|
|
3
|
+
class ActiveSupport::SafeBuffer
|
4
|
+
include Forme::Raw
|
5
|
+
end
|
6
|
+
|
3
7
|
module Forme
|
4
|
-
module Rails
|
8
|
+
module Rails
|
9
|
+
HIDDEN_TAGS = []
|
10
|
+
|
11
|
+
# Add a hidden tag proc that will be used for all forms created via Forme::Rails::ERB#form.
|
12
|
+
# The block is yielded the Forme::Tag object for the form tag.
|
13
|
+
# The block should return either nil if hidden tag should be added, or a Forme::Tag object (or an array of them),
|
14
|
+
# or a hash with keys specifying the name of the tags and the values specifying the values of the tags .
|
15
|
+
def self.add_hidden_tag(&block)
|
16
|
+
HIDDEN_TAGS << block
|
17
|
+
end
|
18
|
+
|
19
|
+
# Add CSRF token tag by default for POST forms
|
20
|
+
add_hidden_tag do |tag|
|
21
|
+
if (form = tag.form) && (template = form.template) && template.protect_against_forgery? && tag.attr[:method].to_s.upcase == 'POST'
|
22
|
+
{template.request_forgery_protection_token=>template.form_authenticity_token}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
5
26
|
# Subclass used when using Forme/Rails ERB integration,
|
6
27
|
# handling integration with the view template.
|
7
28
|
class Form < ::Forme::Form
|
@@ -66,7 +87,7 @@ module Forme
|
|
66
87
|
def tag_(type, attr={}, children=[])
|
67
88
|
tag = _tag(type, attr, children)
|
68
89
|
emit(serializer.serialize_open(tag)) if serializer.respond_to?(:serialize_open)
|
69
|
-
Array(children).each{|c| emit(c)}
|
90
|
+
Array(tag.children).each{|c| emit(c)}
|
70
91
|
yield self if block_given?
|
71
92
|
emit(serializer.serialize_close(tag)) if serializer.respond_to?(:serialize_close)
|
72
93
|
end
|
@@ -90,7 +111,7 @@ module Forme
|
|
90
111
|
# opening attributes, third if provided is
|
91
112
|
# +Form+'s options.
|
92
113
|
def forme(obj=nil, attr={}, opts={}, &block)
|
93
|
-
h = {:template=>self}
|
114
|
+
h = {:template=>self, :hidden_tags=>Forme::Rails::HIDDEN_TAGS}
|
94
115
|
(obj.is_a?(Hash) ? attr = attr.merge(h) : opts = opts.merge(h))
|
95
116
|
Form.form(obj, attr, opts, &block)
|
96
117
|
end
|
data/lib/forme/sinatra.rb
CHANGED
@@ -1,7 +1,24 @@
|
|
1
1
|
require 'forme'
|
2
2
|
|
3
3
|
module Forme
|
4
|
-
module Sinatra
|
4
|
+
module Sinatra
|
5
|
+
HIDDEN_TAGS = []
|
6
|
+
|
7
|
+
# Add a hidden tag proc that will be used for all forms created via Forme::Sinatra::ERB#form.
|
8
|
+
# The block is yielded the Forme::Tag object for the form tag.
|
9
|
+
# The block should return either nil if hidden tag should be added, or a Forme::Tag object (or an array of them),
|
10
|
+
# or a hash with keys specifying the name of the tags and the values specifying the values of the tags .
|
11
|
+
def self.add_hidden_tag(&block)
|
12
|
+
HIDDEN_TAGS << block
|
13
|
+
end
|
14
|
+
|
15
|
+
# Add CSRF token tag by default for POST forms
|
16
|
+
add_hidden_tag do |tag|
|
17
|
+
if defined?(::Rack::Csrf) && (form = tag.form) && (env = form.opts[:env]) && tag.attr[:method].to_s.upcase == 'POST'
|
18
|
+
{::Rack::Csrf.field=>::Rack::Csrf.token(env)}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
5
22
|
# Subclass used when using Forme/Sinatra ERB integration.
|
6
23
|
# Handles integrating into the view template so that
|
7
24
|
# methods with blocks can inject strings into the output.
|
@@ -37,7 +54,7 @@ module Forme
|
|
37
54
|
if block
|
38
55
|
capture(block){super}
|
39
56
|
else
|
40
|
-
|
57
|
+
super
|
41
58
|
end
|
42
59
|
end
|
43
60
|
|
@@ -50,7 +67,7 @@ module Forme
|
|
50
67
|
if block
|
51
68
|
capture(block) do
|
52
69
|
emit(serializer.serialize_open(tag)) if serializer.respond_to?(:serialize_open)
|
53
|
-
children.each{|c| emit(c)}
|
70
|
+
Array(tag.children).each{|c| emit(c)}
|
54
71
|
yield self
|
55
72
|
emit(serializer.serialize_close(tag)) if serializer.respond_to?(:serialize_close)
|
56
73
|
end
|
@@ -92,7 +109,7 @@ module Forme
|
|
92
109
|
# +Form+'s options.
|
93
110
|
def form(obj=nil, attr={}, opts={}, &block)
|
94
111
|
if block
|
95
|
-
h = {:output=>@_out_buf}
|
112
|
+
h = {:output=>@_out_buf, :hidden_tags=>Forme::Sinatra::HIDDEN_TAGS, :env=>env}
|
96
113
|
(obj.is_a?(Hash) ? attr = attr.merge(h) : opts = opts.merge(h))
|
97
114
|
Form.form(obj, attr, opts, &block)
|
98
115
|
else
|
data/lib/forme/version.rb
CHANGED
data/lib/sequel/plugins/forme.rb
CHANGED
@@ -309,8 +309,8 @@ module Sequel # :nodoc:
|
|
309
309
|
wrapper ? wrapper.call(radios, _input(:radio, opts)) : radios
|
310
310
|
else
|
311
311
|
opts[:id] = form.namespaced_id(key) unless opts.has_key?(:id)
|
312
|
-
opts[:add_blank] = true if !opts.has_key?(:add_blank)
|
313
312
|
opts[:required] = true if !opts.has_key?(:required) && (sch = obj.model.db_schema[key]) && !sch[:allow_null]
|
313
|
+
opts[:add_blank] = true if !opts.has_key?(:add_blank) && !(opts[:required] && opts[:value])
|
314
314
|
handle_label(field)
|
315
315
|
::Forme.attr_classes(opts[:wrapper_attr], "required") if opts[:required]
|
316
316
|
_input(:select, opts)
|
data/spec/forme_spec.rb
CHANGED
@@ -246,6 +246,16 @@ describe "Forme plain forms" do
|
|
246
246
|
@f.tag(:textarea, {:name=>:foo}, :bar).to_s.should == '<textarea name="foo">bar</textarea>'
|
247
247
|
end
|
248
248
|
|
249
|
+
specify "#tag should accept children as procs" do
|
250
|
+
@f.tag(:div, {:class=>"foo"}, lambda{|t| t.form.tag(:input, :class=>t.attr[:class])}).to_s.should == '<div class="foo"><input class="foo"/></div>'
|
251
|
+
end
|
252
|
+
|
253
|
+
specify "#tag should accept children as methods" do
|
254
|
+
o = Object.new
|
255
|
+
def o.foo(t) t.form.tag(:input, :class=>t.attr[:class]) end
|
256
|
+
@f.tag(:div, {:class=>"foo"}, o.method(:foo)).to_s.should == '<div class="foo"><input class="foo"/></div>'
|
257
|
+
end
|
258
|
+
|
249
259
|
specify "should have an #inputs method for multiple inputs wrapped in a fieldset" do
|
250
260
|
@f.inputs([:textarea, :text]).to_s.should == '<fieldset class="inputs"><textarea></textarea><input type="text"/></fieldset>'
|
251
261
|
end
|
@@ -325,6 +335,10 @@ describe "Forme plain forms" do
|
|
325
335
|
@f.input(:checkbox, :labeler=>:explicit, :label=>'Foo', :value=>'foo', :name=>'a', :id=>'bar', :label_position=>:before).to_s.should == '<label for="bar">Foo</label><input id="bar_hidden" name="a" type="hidden" value="0"/><input id="bar" name="a" type="checkbox" value="foo"/>'
|
326
336
|
end
|
327
337
|
|
338
|
+
specify "inputs handle implicit labels or checkboxes without hidden fields with :label_position=>:before" do
|
339
|
+
@f.input(:checkbox, :label=>'Foo', :value=>'foo', :name=>'a', :id=>'bar', :label_position=>:before, :no_hidden=>true).to_s.should == '<label>Foo <input id="bar" name="a" type="checkbox" value="foo"/></label>'
|
340
|
+
end
|
341
|
+
|
328
342
|
specify "inputs should accept a :error_handler option to use a custom error_handler" do
|
329
343
|
@f.input(:textarea, :error_handler=>proc{|t, i| [t, "!!! #{i.opts[:error]}"]}, :error=>'bar', :id=>:foo).to_s.should == '<textarea class="error" id="foo"></textarea>!!! bar'
|
330
344
|
end
|
@@ -360,6 +374,36 @@ describe "Forme plain forms" do
|
|
360
374
|
end
|
361
375
|
end
|
362
376
|
|
377
|
+
describe "Forme::Form :hidden_tags option " do
|
378
|
+
before do
|
379
|
+
@f = Forme::Form.new
|
380
|
+
end
|
381
|
+
|
382
|
+
specify "should handle hash" do
|
383
|
+
Forme.form({}, :hidden_tags=>[{:a=>'b'}]).to_s.should == '<form><input name="a" type="hidden" value="b"/></form>'
|
384
|
+
end
|
385
|
+
|
386
|
+
specify "should handle array" do
|
387
|
+
Forme.form({}, :hidden_tags=>[["a ", "b"]]).to_s.should == '<form>a b</form>'
|
388
|
+
end
|
389
|
+
|
390
|
+
specify "should handle string" do
|
391
|
+
Forme.form({}, :hidden_tags=>["a "]).to_s.should == '<form>a </form>'
|
392
|
+
end
|
393
|
+
|
394
|
+
specify "should handle proc return hash" do
|
395
|
+
Forme.form({}, :hidden_tags=>[lambda{|tag| {:a=>'b'}}]).to_s.should == '<form><input name="a" type="hidden" value="b"/></form>'
|
396
|
+
end
|
397
|
+
|
398
|
+
specify "should handle proc return tag" do
|
399
|
+
Forme.form({:method=>'post'}, :hidden_tags=>[lambda{|tag| tag.form._tag(tag.attr[:method])}]).to_s.should == '<form method="post"><post></post></form>'
|
400
|
+
end
|
401
|
+
|
402
|
+
specify "should raise error for unhandled object" do
|
403
|
+
proc{Forme.form({}, :hidden_tags=>[Object.new])}.should raise_error
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
363
407
|
describe "Forme custom" do
|
364
408
|
specify "formatters can be specified as a proc" do
|
365
409
|
Forme::Form.new(:formatter=>proc{|i| i.form._tag(:textarea, i.opts.map{|k,v| [v.upcase, k.to_s.downcase]})}).input(:text, :name=>'foo').to_s.should == '<textarea FOO="name"></textarea>'
|
@@ -6,10 +6,12 @@ require 'action_controller/railtie'
|
|
6
6
|
require 'forme/rails'
|
7
7
|
|
8
8
|
class FormeRails < Rails::Application
|
9
|
-
config.secret_token = routes.append {
|
9
|
+
config.secret_token = routes.append { get ':action' , :controller=>'forme' }.inspect
|
10
10
|
config.active_support.deprecation = :stderr
|
11
11
|
config.middleware.delete(ActionDispatch::ShowExceptions)
|
12
|
-
config.
|
12
|
+
config.middleware.delete("Rack::Lock")
|
13
|
+
config.secret_key_base = 'foo'
|
14
|
+
config.eager_load = true
|
13
15
|
initialize!
|
14
16
|
end
|
15
17
|
|
@@ -139,6 +141,10 @@ END
|
|
139
141
|
def noblock
|
140
142
|
render :inline => "<%= forme([:foo, :bar], {:action=>'/baz'}, :inputs=>[:first], :button=>'xyz', :legend=>'123') %>"
|
141
143
|
end
|
144
|
+
|
145
|
+
def safe_buffer
|
146
|
+
render :inline => "<%= forme([:foo, :bar], {:action=>'/baz'}, :inputs=>[:first], :button=>'xyz', :legend=>'<b>foo</b>'.html_safe) %>"
|
147
|
+
end
|
142
148
|
end
|
143
149
|
|
144
150
|
describe "Forme Rails integration" do
|
@@ -174,7 +180,7 @@ describe "Forme Rails integration" do
|
|
174
180
|
end
|
175
181
|
|
176
182
|
specify "#form should correctly handle situation Sequel integration with subforms where multiple templates are used with same form object" do
|
177
|
-
sin_get('/nest_seq').should == "0 <form action=\"/baz\" class=\"forme album\" method=\"post\"
|
183
|
+
sin_get('/nest_seq').sub(%r{<input name=\"authenticity_token\" type=\"hidden\" value=\"([^\"]+)\"/>}, "<input name=\"authenticity_token\" type=\"hidden\" value=\"csrf\"/>").should == "0 <form action=\"/baz\" class=\"forme album\" method=\"post\"><input name=\"authenticity_token\" 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\" 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\"/> n2 <label>Name2: <input id=\"album_artist_attributes_name2\" name=\"album[artist_attributes][name2]\" type=\"text\" value=\"A2\"/></label> n3 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"
|
178
184
|
end
|
179
185
|
|
180
186
|
specify "#form should accept two hashes instead of requiring obj as first argument" do
|
@@ -192,4 +198,8 @@ describe "Forme Rails integration" do
|
|
192
198
|
specify "#form should work without a block" do
|
193
199
|
sin_get('/noblock').should == '<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>'
|
194
200
|
end
|
201
|
+
|
202
|
+
specify "#form should handle Rails SafeBuffers" do
|
203
|
+
sin_get('/safe_buffer').should == '<form action="/baz"><fieldset class="inputs"><legend><b>foo</b></legend><input id="first" name="first" type="text" value="foo"/></fieldset><input type="submit" value="xyz"/></form>'
|
204
|
+
end
|
195
205
|
end
|
data/spec/sequel_plugin_spec.rb
CHANGED
@@ -17,6 +17,13 @@ describe "Forme Sequel::Model forms" do
|
|
17
17
|
@b.form(:class=>:foo, :method=>:get).to_s.should == '<form class="foo forme album" method="get"></form>'
|
18
18
|
end
|
19
19
|
|
20
|
+
specify "should handle invalid methods" do
|
21
|
+
def @ab.db_schema
|
22
|
+
super.merge(:foo=>{:type=>:bar})
|
23
|
+
end
|
24
|
+
@b.input(:foo, :value=>'baz').to_s.should == '<label>Foo: <input id="album_foo" name="album[foo]" type="text" value="baz"/></label>'
|
25
|
+
end
|
26
|
+
|
20
27
|
specify "should allow an array of classes" do
|
21
28
|
@b.form(:class=>[:foo, :bar]).to_s.should == '<form class="foo bar forme album" method="post"></form>'
|
22
29
|
@b.form(:class=>[:foo, [:bar, :baz]]).to_s.should == '<form class="foo bar baz forme album" method="post"></form>'
|
@@ -122,12 +129,16 @@ describe "Forme Sequel::Model forms" do
|
|
122
129
|
@c.input(:artist).to_s.should == '<label>Artist: <select id="album_artist_id" name="album[artist_id]"><option value=""></option><option value="1">a</option><option selected="selected" value="2">d</option></select></label>'
|
123
130
|
end
|
124
131
|
|
132
|
+
specify "should not add a blank option by default if there is a default value and it is required" do
|
133
|
+
@b.input(:artist, :required=>true).to_s.should == '<label>Artist<abbr title="required">*</abbr>: <select id="album_artist_id" name="album[artist_id]" required="required"><option selected="selected" value="1">a</option><option value="2">d</option></select></label>'
|
134
|
+
end
|
135
|
+
|
125
136
|
specify "should allow overriding default input type using a :type option" do
|
126
137
|
@b.input(:artist, :type=>:string, :value=>nil).to_s.should == '<label>Artist: <input id="album_artist" name="album[artist]" type="text"/></label>'
|
127
138
|
end
|
128
139
|
|
129
140
|
specify "should use a required wrapper tag for many_to_one required associations" do
|
130
|
-
@b.input(:artist, :required=>true, :wrapper=>:li).to_s.should == '<li class="many_to_one required"><label>Artist<abbr title="required">*</abbr>: <select id="album_artist_id" name="album[artist_id]" required="required"><option
|
141
|
+
@b.input(:artist, :required=>true, :wrapper=>:li).to_s.should == '<li class="many_to_one required"><label>Artist<abbr title="required">*</abbr>: <select id="album_artist_id" name="album[artist_id]" required="required"><option selected="selected" value="1">a</option><option value="2">d</option></select></label></li>'
|
131
142
|
end
|
132
143
|
|
133
144
|
specify "should use a set of radio buttons for many_to_one associations with :as=>:radio option" do
|
@@ -5,11 +5,14 @@ require 'rubygems'
|
|
5
5
|
require 'sinatra/base'
|
6
6
|
require 'forme/sinatra'
|
7
7
|
require(ENV['ERUBIS'] ? 'erubis' : 'erb')
|
8
|
+
require 'rack/csrf'
|
8
9
|
|
9
10
|
class FormeSinatraTest < Sinatra::Base
|
10
11
|
helpers(Forme::Sinatra::ERB)
|
11
12
|
disable :show_exceptions
|
12
13
|
enable :raise_errors
|
14
|
+
enable :sessions
|
15
|
+
use Rack::Csrf
|
13
16
|
|
14
17
|
get '/' do
|
15
18
|
erb <<END
|
@@ -24,21 +27,17 @@ END
|
|
24
27
|
|
25
28
|
get '/inputs_block' do
|
26
29
|
erb <<END
|
27
|
-
<% form([:foo, :bar], :action=>'/baz') do |f| %>
|
28
|
-
<% f.inputs(:legend=>'FBB') do %>
|
30
|
+
<% form([:foo, :bar], :action=>'/baz') do |f| %><% f.inputs(:legend=>'FBB') do %>
|
29
31
|
<%= f.input(:last) %>
|
30
|
-
<% end %>
|
31
|
-
<% end %>
|
32
|
+
<% end %><% end %>
|
32
33
|
END
|
33
34
|
end
|
34
35
|
|
35
36
|
get '/inputs_block_wrapper' do
|
36
37
|
erb <<END
|
37
|
-
<% form([:foo, :bar], {:action=>'/baz'}, :inputs_wrapper=>:fieldset_ol) do |f| %>
|
38
|
-
<% f.inputs(:legend=>'FBB') do %>
|
38
|
+
<% form([:foo, :bar], {:action=>'/baz'}, :inputs_wrapper=>:fieldset_ol) do |f| %><% f.inputs(:legend=>'FBB') do %>
|
39
39
|
<%= f.input(:last) %>
|
40
|
-
<% end %>
|
41
|
-
<% end %>
|
40
|
+
<% end %><% end %>
|
42
41
|
END
|
43
42
|
end
|
44
43
|
|
@@ -134,11 +133,17 @@ END
|
|
134
133
|
get '/noblock' do
|
135
134
|
erb "<%= form([:foo, :bar], {:action=>'/baz'}, :inputs=>[:first], :button=>'xyz', :legend=>'123') %>"
|
136
135
|
end
|
136
|
+
|
137
|
+
get '/noblock_empty' do
|
138
|
+
erb "<%= form(:action=>'/baz') %>"
|
139
|
+
end
|
137
140
|
end
|
138
141
|
|
139
142
|
describe "Forme Sinatra ERB integration" do
|
140
143
|
def sin_get(path)
|
141
|
-
|
144
|
+
s = ''
|
145
|
+
FormeSinatraTest.new.call(@rack.merge('PATH_INFO'=>path))[2].each{|str| s << str}
|
146
|
+
s.gsub(/\s+/, ' ').strip
|
142
147
|
end
|
143
148
|
before do
|
144
149
|
o = Object.new
|
@@ -167,7 +172,7 @@ describe "Forme Sinatra ERB integration" do
|
|
167
172
|
end
|
168
173
|
|
169
174
|
specify "#form should correctly handle situation Sequel integration with subforms where multiple templates are used with same form object" do
|
170
|
-
sin_get('/nest_seq').should == "0 <form action=\"/baz\" class=\"forme album\" method=\"post\"
|
175
|
+
sin_get('/nest_seq').sub(%r{<input name=\"_csrf\" type=\"hidden\" value=\"([^\"]+)\"/>}, "<input name=\"_csrf\" type=\"hidden\" value=\"csrf\"/>").should == "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\" 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\"/> n2 <label>Name2: <input id=\"album_artist_attributes_name2\" name=\"album[artist_attributes][name2]\" type=\"text\" value=\"A2\"/></label> n3 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"
|
171
176
|
end
|
172
177
|
|
173
178
|
specify "#form should accept two hashes instead of requiring obj as first argument" do
|
@@ -185,4 +190,8 @@ describe "Forme Sinatra ERB integration" do
|
|
185
190
|
specify "#form should work without a block" do
|
186
191
|
sin_get('/noblock').should == '<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>'
|
187
192
|
end
|
193
|
+
|
194
|
+
specify "#form with an empty form should work" do
|
195
|
+
sin_get('/noblock_empty').should == '<form action="/baz"></form>'
|
196
|
+
end
|
188
197
|
end
|
metadata
CHANGED
@@ -1,28 +1,22 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: forme
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.8.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Jeremy Evans
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2013-10-30 00:00:00.000000000 Z
|
13
12
|
dependencies: []
|
14
|
-
description:
|
15
|
-
|
13
|
+
description: |
|
14
|
+
Forme is a forms library with the following goals:
|
16
15
|
|
17
16
|
1) Have no external dependencies
|
18
|
-
|
19
17
|
2) Have a simple API
|
20
|
-
|
21
18
|
3) Support forms both with and without related objects
|
22
|
-
|
23
19
|
4) Allow compiling down to different types of output
|
24
|
-
|
25
|
-
'
|
26
20
|
email: code@jeremyevans.net
|
27
21
|
executables: []
|
28
22
|
extensions: []
|
@@ -48,33 +42,32 @@ files:
|
|
48
42
|
- lib/sequel/plugins/forme.rb
|
49
43
|
homepage: http://gihub.com/jeremyevans/forme
|
50
44
|
licenses: []
|
45
|
+
metadata: {}
|
51
46
|
post_install_message:
|
52
47
|
rdoc_options:
|
53
48
|
- --quiet
|
54
49
|
- --line-numbers
|
55
50
|
- --inline-source
|
56
51
|
- --title
|
57
|
-
-
|
52
|
+
- 'Forme: HTML forms library'
|
58
53
|
- --main
|
59
54
|
- README.rdoc
|
60
55
|
require_paths:
|
61
56
|
- lib
|
62
57
|
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
-
none: false
|
64
58
|
requirements:
|
65
|
-
- -
|
59
|
+
- - '>='
|
66
60
|
- !ruby/object:Gem::Version
|
67
61
|
version: '0'
|
68
62
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
-
none: false
|
70
63
|
requirements:
|
71
|
-
- -
|
64
|
+
- - '>='
|
72
65
|
- !ruby/object:Gem::Version
|
73
66
|
version: '0'
|
74
67
|
requirements: []
|
75
68
|
rubyforge_project:
|
76
|
-
rubygems_version:
|
69
|
+
rubygems_version: 2.0.3
|
77
70
|
signing_key:
|
78
|
-
specification_version:
|
71
|
+
specification_version: 4
|
79
72
|
summary: HTML forms library
|
80
73
|
test_files: []
|