forme 0.10.0 → 1.0.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 +8 -0
- data/lib/forme.rb +29 -2
- data/lib/forme/erb.rb +104 -0
- data/lib/forme/rails.rb +13 -23
- data/lib/forme/sinatra.rb +9 -118
- data/lib/forme/version.rb +1 -1
- data/lib/roda/plugins/forme.rb +17 -0
- data/lib/sequel/plugins/forme.rb +22 -4
- data/spec/erb_helper.rb +177 -0
- data/spec/rails_integration_spec.rb +5 -0
- data/spec/roda_integration_spec.rb +36 -0
- data/spec/sinatra_integration_spec.rb +11 -171
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9fb6883778ebb616402a910c3f46f7bd6ba3734b
|
|
4
|
+
data.tar.gz: aed74dd741f94bb368e97390d14a4000f4b73f39
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 297661c5e245fcbb2f7c671d59c79f77b4d07d3bcded836ace5c7a6049f237b3d7711923178dcfcfdc3ac704a654b491c217112d114f033bd9d241f2c3f9b2f4
|
|
7
|
+
data.tar.gz: 68d7a1d1adbae977f2c26649a72633ae2c954f8701bca70883153eac44fe86113aedd1a47015ad261f2e91ad119945aab56355d54480dda0782bc11896557b26
|
data/CHANGELOG
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
=== 1.0.0 (2014-07-30)
|
|
2
|
+
|
|
3
|
+
* Add roda plugin for forme (jeremyevans)
|
|
4
|
+
|
|
5
|
+
* Move forme/sinatra to forme/erb, since it is ERB and not Sinatra specific (jeremyevans)
|
|
6
|
+
|
|
7
|
+
* Do not extend objects at runtime when using the Sequel support (jeremyevans)
|
|
8
|
+
|
|
1
9
|
=== 0.10.0 (2014-07-01)
|
|
2
10
|
|
|
3
11
|
* Use #[] instead of #send to get input value for object forms if object is a hash (jeremyevans)
|
data/lib/forme.rb
CHANGED
|
@@ -148,6 +148,16 @@ module Forme
|
|
|
148
148
|
# Must respond to +call+ or be a registered symbol.
|
|
149
149
|
attr_reader :serializer
|
|
150
150
|
|
|
151
|
+
# Use appropriate Form subclass for object based on the current class, if the
|
|
152
|
+
# object responds to +forme_form_class+.
|
|
153
|
+
def self.new(obj=nil, opts={})
|
|
154
|
+
if obj && obj.respond_to?(:forme_form_class) && !opts[:_forme_form_class_set]
|
|
155
|
+
obj.forme_form_class(self).new(obj, opts.merge(:_forme_form_class_set=>true))
|
|
156
|
+
else
|
|
157
|
+
super
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
151
161
|
# Create a +Form+ instance and yield it to the block,
|
|
152
162
|
# injecting the opening form tag before yielding and
|
|
153
163
|
# the closing form tag after yielding.
|
|
@@ -403,6 +413,13 @@ module Forme
|
|
|
403
413
|
end
|
|
404
414
|
end
|
|
405
415
|
|
|
416
|
+
# Marks the string as containing already escaped output. Returns string given
|
|
417
|
+
# by default, but subclasses for specific web frameworks can handle automatic
|
|
418
|
+
# html escaping by overriding this.
|
|
419
|
+
def raw_output(s)
|
|
420
|
+
s
|
|
421
|
+
end
|
|
422
|
+
|
|
406
423
|
# Temporarily override the given object and namespace for the form. Any given
|
|
407
424
|
# namespaces are appended to the form's current namespace.
|
|
408
425
|
def with_obj(obj, namespace=nil)
|
|
@@ -471,6 +488,16 @@ module Forme
|
|
|
471
488
|
ensure
|
|
472
489
|
@nesting.pop
|
|
473
490
|
end
|
|
491
|
+
|
|
492
|
+
# Return a serialized opening tag for the given tag.
|
|
493
|
+
def serialize_open(tag)
|
|
494
|
+
raw_output(serializer.serialize_open(tag)) if serializer.respond_to?(:serialize_open)
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
# Return a serialized closing tag for the given tag.
|
|
498
|
+
def serialize_close(tag)
|
|
499
|
+
raw_output(serializer.serialize_close(tag)) if serializer.respond_to?(:serialize_close)
|
|
500
|
+
end
|
|
474
501
|
end
|
|
475
502
|
|
|
476
503
|
# High level abstract tag form, transformed by formatters into the lower
|
|
@@ -510,7 +537,7 @@ module Forme
|
|
|
510
537
|
|
|
511
538
|
# Return a string containing the serialized content of the receiver.
|
|
512
539
|
def to_s
|
|
513
|
-
Forme.transform(:serializer, @opts, @form_opts, self)
|
|
540
|
+
form.raw_output(Forme.transform(:serializer, @opts, @form_opts, self))
|
|
514
541
|
end
|
|
515
542
|
|
|
516
543
|
# Transform the receiver into a lower level +Tag+ form (or an array
|
|
@@ -559,7 +586,7 @@ module Forme
|
|
|
559
586
|
|
|
560
587
|
# Return a string containing the serialized content of the receiver.
|
|
561
588
|
def to_s
|
|
562
|
-
Forme.transform(:serializer, @opts, @form.opts, self)
|
|
589
|
+
form.raw_output(Forme.transform(:serializer, @opts, @form.opts, self))
|
|
563
590
|
end
|
|
564
591
|
|
|
565
592
|
private
|
data/lib/forme/erb.rb
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
require 'forme'
|
|
2
|
+
|
|
3
|
+
module Forme
|
|
4
|
+
module ERB
|
|
5
|
+
HIDDEN_TAGS = []
|
|
6
|
+
|
|
7
|
+
# Add a hidden tag proc that will be used for all forms created via Forme::ERB::Helper#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
|
+
|
|
22
|
+
# Subclass used when using Forme ERB integration.
|
|
23
|
+
# Handles integrating into the view template so that
|
|
24
|
+
# methods with blocks can inject strings into the output.
|
|
25
|
+
class Form < ::Forme::Form
|
|
26
|
+
# Template output object, where serialized output gets
|
|
27
|
+
# injected.
|
|
28
|
+
attr_reader :output
|
|
29
|
+
|
|
30
|
+
# Set the template output object when initializing.
|
|
31
|
+
def initialize(*)
|
|
32
|
+
super
|
|
33
|
+
@output = @opts[:output] ? @opts[:output] : ''
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Serialize the tag and inject it into the output.
|
|
37
|
+
def emit(tag)
|
|
38
|
+
output << tag.to_s
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Capture the inside of the inputs, injecting it into the template
|
|
42
|
+
# if a block is given, or returning it as a string if not.
|
|
43
|
+
def inputs(*a, &block)
|
|
44
|
+
if block
|
|
45
|
+
capture(block){super}
|
|
46
|
+
else
|
|
47
|
+
capture{super}
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Capture the inside of the form, injecting it into the template if
|
|
52
|
+
# a block is given, or returning it as a string if not.
|
|
53
|
+
def form(*a, &block)
|
|
54
|
+
if block
|
|
55
|
+
capture(block){super}
|
|
56
|
+
else
|
|
57
|
+
super
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# If a block is given, inject an opening tag into the
|
|
62
|
+
# output, inject any given children into the output, yield to the
|
|
63
|
+
# block, inject a closing tag into the output.
|
|
64
|
+
# If a block is not given, just return the tag created.
|
|
65
|
+
def tag(type, attr={}, children=[], &block)
|
|
66
|
+
tag = _tag(type, attr, children)
|
|
67
|
+
if block
|
|
68
|
+
capture(block) do
|
|
69
|
+
emit(serialize_open(tag))
|
|
70
|
+
Array(tag.children).each{|c| emit(c)}
|
|
71
|
+
yield self
|
|
72
|
+
emit(serialize_close(tag))
|
|
73
|
+
end
|
|
74
|
+
else
|
|
75
|
+
tag
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def capture(block='') # :nodoc:
|
|
80
|
+
buf_was, @output = @output, block.is_a?(Proc) ? (eval("@_out_buf", block.binding) || @output) : block
|
|
81
|
+
yield
|
|
82
|
+
ret = @output
|
|
83
|
+
@output = buf_was
|
|
84
|
+
ret
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# This is the module used to add the Forme integration
|
|
89
|
+
# to ERB.
|
|
90
|
+
module Helper
|
|
91
|
+
# Create a +Form+ object tied to the current output buffer,
|
|
92
|
+
# using the standard ERB hidden tags.
|
|
93
|
+
def form(obj=nil, attr={}, opts={}, &block)
|
|
94
|
+
if block
|
|
95
|
+
h = {:output=>@_out_buf, :hidden_tags=>Forme::ERB::HIDDEN_TAGS, :env=>env}
|
|
96
|
+
(obj.is_a?(Hash) ? attr = attr.merge(h) : opts = opts.merge(h))
|
|
97
|
+
Form.form(obj, attr, opts, &block)
|
|
98
|
+
else
|
|
99
|
+
Form.form(obj, attr, opts)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
data/lib/forme/rails.rb
CHANGED
|
@@ -38,7 +38,7 @@ module Forme
|
|
|
38
38
|
# Serialize and mark as already escaped the string version of
|
|
39
39
|
# the input.
|
|
40
40
|
def emit(tag)
|
|
41
|
-
template.output_buffer <<
|
|
41
|
+
template.output_buffer << tag.to_s
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
# Capture the inputs into a new output buffer, and return
|
|
@@ -63,12 +63,17 @@ module Forme
|
|
|
63
63
|
|
|
64
64
|
# Return a string version of the input that is already marked as safe.
|
|
65
65
|
def input(*)
|
|
66
|
-
|
|
66
|
+
super.to_s
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
# Return a string version of the button that is already marked as safe.
|
|
70
70
|
def button(*)
|
|
71
|
-
|
|
71
|
+
super.to_s
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Use the template's raw method to mark the given string as html safe.
|
|
75
|
+
def raw_output(s)
|
|
76
|
+
template.raw(s)
|
|
72
77
|
end
|
|
73
78
|
|
|
74
79
|
# If a block is given, create a new output buffer and make sure all the
|
|
@@ -79,37 +84,22 @@ module Forme
|
|
|
79
84
|
if block_given?
|
|
80
85
|
template.send(:with_output_buffer){tag_(type, attr, children, &block)}
|
|
81
86
|
else
|
|
82
|
-
|
|
83
|
-
template.raw(tag.to_s)
|
|
87
|
+
_tag(type, attr, children).to_s
|
|
84
88
|
end
|
|
85
89
|
end
|
|
86
90
|
|
|
87
91
|
def tag_(type, attr={}, children=[]) # :nodoc:
|
|
88
92
|
tag = _tag(type, attr, children)
|
|
89
|
-
emit(
|
|
93
|
+
emit(serialize_open(tag))
|
|
90
94
|
Array(tag.children).each{|c| emit(c)}
|
|
91
95
|
yield self if block_given?
|
|
92
|
-
emit(
|
|
96
|
+
emit(serialize_close(tag))
|
|
93
97
|
end
|
|
94
98
|
end
|
|
95
99
|
|
|
96
100
|
module ERB
|
|
97
|
-
# Create a +Form+ object
|
|
98
|
-
#
|
|
99
|
-
# the closing form tag after yielding.
|
|
100
|
-
#
|
|
101
|
-
# Argument Handling:
|
|
102
|
-
# No args :: Creates a +Form+ object with no options and not associated
|
|
103
|
-
# to an +obj+, and with no attributes in the opening tag.
|
|
104
|
-
# 1 hash arg :: Treated as opening form tag attributes, creating a
|
|
105
|
-
# +Form+ object with no options.
|
|
106
|
-
# 1 non-hash arg :: Treated as the +Form+'s +obj+, with empty options
|
|
107
|
-
# and no attributes in the opening tag.
|
|
108
|
-
# 2 hash args :: First hash is opening attributes, second hash is +Form+
|
|
109
|
-
# options.
|
|
110
|
-
# 1 non-hash arg, 1-2 hash args :: First argument is +Form+'s obj, second is
|
|
111
|
-
# opening attributes, third if provided is
|
|
112
|
-
# +Form+'s options.
|
|
101
|
+
# Create a +Form+ object tied to the current template, and using the standard
|
|
102
|
+
# Rails hidden tags.
|
|
113
103
|
def forme(obj=nil, attr={}, opts={}, &block)
|
|
114
104
|
h = {:template=>self, :hidden_tags=>Forme::Rails::HIDDEN_TAGS}
|
|
115
105
|
(obj.is_a?(Hash) ? attr = attr.merge(h) : opts = opts.merge(h))
|
data/lib/forme/sinatra.rb
CHANGED
|
@@ -1,124 +1,15 @@
|
|
|
1
|
-
require 'forme'
|
|
1
|
+
require 'forme/erb'
|
|
2
2
|
|
|
3
3
|
module Forme
|
|
4
|
+
# For backwards compatibility only. New code should
|
|
5
|
+
# require 'forme/erb' and include the Forme::ERB::Helper
|
|
6
|
+
# class:
|
|
7
|
+
#
|
|
8
|
+
# helpers Forme::ERB::Helper
|
|
4
9
|
module Sinatra
|
|
5
|
-
|
|
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
|
-
|
|
22
|
-
# Subclass used when using Forme/Sinatra ERB integration.
|
|
23
|
-
# Handles integrating into the view template so that
|
|
24
|
-
# methods with blocks can inject strings into the output.
|
|
25
|
-
class Form < ::Forme::Form
|
|
26
|
-
# Template output object, where serialized output gets
|
|
27
|
-
# injected.
|
|
28
|
-
attr_reader :output
|
|
29
|
-
|
|
30
|
-
# Set the template output object when initializing.
|
|
31
|
-
def initialize(*)
|
|
32
|
-
super
|
|
33
|
-
@output = @opts[:output] ? @opts[:output] : ''
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# Serialize the tag and inject it into the output.
|
|
37
|
-
def emit(tag)
|
|
38
|
-
output << tag.to_s
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# Capture the inside of the inputs, injecting it into the template
|
|
42
|
-
# if a block is given, or returning it as a string if not.
|
|
43
|
-
def inputs(*a, &block)
|
|
44
|
-
if block
|
|
45
|
-
capture(block){super}
|
|
46
|
-
else
|
|
47
|
-
capture{super}
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# Capture the inside of the form, injecting it into the template if
|
|
52
|
-
# a block is given, or returning it as a string if not.
|
|
53
|
-
def form(*a, &block)
|
|
54
|
-
if block
|
|
55
|
-
capture(block){super}
|
|
56
|
-
else
|
|
57
|
-
super
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# If a block is given, inject an opening tag into the
|
|
62
|
-
# output, inject any given children into the output, yield to the
|
|
63
|
-
# block, inject a closing tag into the output.
|
|
64
|
-
# If a block is not given, just return the tag created.
|
|
65
|
-
def tag(type, attr={}, children=[], &block)
|
|
66
|
-
tag = _tag(type, attr, children)
|
|
67
|
-
if block
|
|
68
|
-
capture(block) do
|
|
69
|
-
emit(serializer.serialize_open(tag)) if serializer.respond_to?(:serialize_open)
|
|
70
|
-
Array(tag.children).each{|c| emit(c)}
|
|
71
|
-
yield self
|
|
72
|
-
emit(serializer.serialize_close(tag)) if serializer.respond_to?(:serialize_close)
|
|
73
|
-
end
|
|
74
|
-
else
|
|
75
|
-
tag
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def capture(block='')
|
|
80
|
-
buf_was, @output = @output, block.is_a?(Proc) ? (eval("@_out_buf", block.binding) || @output) : block
|
|
81
|
-
yield
|
|
82
|
-
ret = @output
|
|
83
|
-
@output = buf_was
|
|
84
|
-
ret
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
# This is the module used to add the Forme integration
|
|
89
|
-
# to Sinatra. It should be enabled in Sinatra with the
|
|
90
|
-
# following code in your <tt>Sinatra::Base</tt> subclass:
|
|
91
|
-
#
|
|
92
|
-
# helpers Forme::Sinatra::ERB
|
|
93
|
-
module ERB
|
|
94
|
-
# Create a +Form+ object and yield it to the block,
|
|
95
|
-
# injecting the opening form tag before yielding and
|
|
96
|
-
# the closing form tag after yielding.
|
|
97
|
-
#
|
|
98
|
-
# Argument Handling:
|
|
99
|
-
# No args :: Creates a +Form+ object with no options and not associated
|
|
100
|
-
# to an +obj+, and with no attributes in the opening tag.
|
|
101
|
-
# 1 hash arg :: Treated as opening form tag attributes, creating a
|
|
102
|
-
# +Form+ object with no options.
|
|
103
|
-
# 1 non-hash arg :: Treated as the +Form+'s +obj+, with empty options
|
|
104
|
-
# and no attributes in the opening tag.
|
|
105
|
-
# 2 hash args :: First hash is opening attributes, second hash is +Form+
|
|
106
|
-
# options.
|
|
107
|
-
# 1 non-hash arg, 1-2 hash args :: First argument is +Form+'s obj, second is
|
|
108
|
-
# opening attributes, third if provided is
|
|
109
|
-
# +Form+'s options.
|
|
110
|
-
def form(obj=nil, attr={}, opts={}, &block)
|
|
111
|
-
if block
|
|
112
|
-
h = {:output=>@_out_buf, :hidden_tags=>Forme::Sinatra::HIDDEN_TAGS, :env=>env}
|
|
113
|
-
(obj.is_a?(Hash) ? attr = attr.merge(h) : opts = opts.merge(h))
|
|
114
|
-
Form.form(obj, attr, opts, &block)
|
|
115
|
-
else
|
|
116
|
-
Form.form(obj, attr, opts)
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
# Alias of <tt>Forme::Sinatra::ERB</tt>
|
|
10
|
+
ERB = Forme::ERB::Helper
|
|
122
11
|
Erubis = ERB
|
|
12
|
+
Form = Forme::ERB::Form
|
|
13
|
+
HIDDEN_TAGS = Forme::ERB::HIDDEN_TAGS
|
|
123
14
|
end
|
|
124
15
|
end
|
data/lib/forme/version.rb
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'forme/erb'
|
|
2
|
+
|
|
3
|
+
class Roda
|
|
4
|
+
module RodaPlugins
|
|
5
|
+
module Forme
|
|
6
|
+
# Require the render plugin, since forme template integration
|
|
7
|
+
# only makes sense with it.
|
|
8
|
+
def self.load_dependencies(app)
|
|
9
|
+
app.plugin :render
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
InstanceMethods = ::Forme::ERB::Helper
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
register_plugin(:forme, Forme)
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/sequel/plugins/forme.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'forme'
|
|
2
|
+
require 'thread'
|
|
2
3
|
|
|
3
4
|
module Sequel # :nodoc:
|
|
4
5
|
module Plugins # :nodoc:
|
|
@@ -418,9 +419,9 @@ module Sequel # :nodoc:
|
|
|
418
419
|
end
|
|
419
420
|
end
|
|
420
421
|
|
|
421
|
-
# Helper module used for Sequel
|
|
422
|
+
# Helper module used for Sequel forms using ERB template integration. Necessary for
|
|
422
423
|
# proper subform handling when using such forms with partials.
|
|
423
|
-
module
|
|
424
|
+
module ERBSequelForm
|
|
424
425
|
# Capture the inside of the inputs, injecting it into the template
|
|
425
426
|
# if a block is given, or returning it as a string if not.
|
|
426
427
|
def subform(*, &block)
|
|
@@ -431,14 +432,31 @@ module Sequel # :nodoc:
|
|
|
431
432
|
end
|
|
432
433
|
end
|
|
433
434
|
end
|
|
435
|
+
SinatraSequelForm = ERBSequelForm
|
|
436
|
+
|
|
437
|
+
class Form < ::Forme::Form
|
|
438
|
+
include SequelForm
|
|
439
|
+
end
|
|
434
440
|
|
|
435
441
|
module InstanceMethods
|
|
442
|
+
MUTEX = Mutex.new
|
|
443
|
+
FORM_CLASSES = {::Forme::Form=>Form}
|
|
444
|
+
|
|
436
445
|
# Configure the +form+ with support for <tt>Sequel::Model</tt>
|
|
437
446
|
# specific code, such as support for nested attributes.
|
|
438
447
|
def forme_config(form)
|
|
439
|
-
form.extend(SequelForm)
|
|
440
448
|
form.namespaces << model.send(:underscore, model.name)
|
|
441
|
-
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
# Return subclass of base form that includes the necessary Sequel form methods.
|
|
452
|
+
def forme_form_class(base)
|
|
453
|
+
unless klass = MUTEX.synchronize{FORM_CLASSES[base]}
|
|
454
|
+
klass = Class.new(base)
|
|
455
|
+
klass.send(:include, SequelForm)
|
|
456
|
+
klass.send(:include, ERBSequelForm) if defined?(::Forme::ERB::Form) && base == ::Forme::ERB::Form
|
|
457
|
+
MUTEX.synchronize{FORM_CLASSES[base] = klass}
|
|
458
|
+
end
|
|
459
|
+
klass
|
|
442
460
|
end
|
|
443
461
|
|
|
444
462
|
# Return <tt>Forme::Input</tt> instance based on the given arguments.
|
data/spec/erb_helper.rb
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
ERB_BLOCK = lambda do |r|
|
|
2
|
+
r.get '' do
|
|
3
|
+
erb <<END
|
|
4
|
+
<% form([:foo, :bar], :action=>'/baz') do |f| %>
|
|
5
|
+
<p>FBB</p>
|
|
6
|
+
<%= f.input(:first) %>
|
|
7
|
+
<%= f.input(:last) %>
|
|
8
|
+
<%= f.button('Save') %>
|
|
9
|
+
<% end %>
|
|
10
|
+
END
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
r.get 'inputs_block' do
|
|
14
|
+
erb <<END
|
|
15
|
+
<% form([:foo, :bar], :action=>'/baz') do |f| %><% f.inputs(:legend=>'FBB') do %>
|
|
16
|
+
<%= f.input(:last) %>
|
|
17
|
+
<% end %><% end %>
|
|
18
|
+
END
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
r.get 'inputs_block_wrapper' do
|
|
22
|
+
erb <<END
|
|
23
|
+
<% form([:foo, :bar], {:action=>'/baz'}, :inputs_wrapper=>:fieldset_ol) do |f| %><% f.inputs(:legend=>'FBB') do %>
|
|
24
|
+
<%= f.input(:last) %>
|
|
25
|
+
<% end %><% end %>
|
|
26
|
+
END
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
r.get 'nest' do
|
|
30
|
+
erb <<END
|
|
31
|
+
<% form([:foo, :bar], :action=>'/baz') do |f| %>
|
|
32
|
+
<%= f.tag(:p, {}, 'FBB') %>
|
|
33
|
+
<% f.tag(:div) do %>
|
|
34
|
+
<%= f.input(:first) %>
|
|
35
|
+
<%= f.input(:last) %>
|
|
36
|
+
<% end %>
|
|
37
|
+
|
|
38
|
+
<% end %>
|
|
39
|
+
END
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
r.get 'nest_sep' do
|
|
43
|
+
@nest = <<END
|
|
44
|
+
n1
|
|
45
|
+
<% f.tag(:div) do %>
|
|
46
|
+
n2
|
|
47
|
+
<%= f.input(:first) %>
|
|
48
|
+
<%= f.input(:last) %>
|
|
49
|
+
n3
|
|
50
|
+
<% end %>
|
|
51
|
+
n4
|
|
52
|
+
<%= f.inputs([:first, :last], :legend=>'Foo') %>
|
|
53
|
+
n5
|
|
54
|
+
END
|
|
55
|
+
erb <<END
|
|
56
|
+
0
|
|
57
|
+
<% form([:foo, :bar], :action=>'/baz') do |f| %>
|
|
58
|
+
1
|
|
59
|
+
<%= f.tag(:p, {}, 'FBB') %>
|
|
60
|
+
2
|
|
61
|
+
<%= erb(@nest, :locals=>{:f=>f}) %>
|
|
62
|
+
3
|
|
63
|
+
<% end %>
|
|
64
|
+
4
|
|
65
|
+
END
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
r.get 'nest_seq' do
|
|
69
|
+
@album = Album.load(:name=>'N', :copies_sold=>2, :id=>1)
|
|
70
|
+
@album.associations[:artist] = Artist.load(:name=>'A', :id=>2)
|
|
71
|
+
@nest = <<END
|
|
72
|
+
n1
|
|
73
|
+
<% f.subform(:artist) do %>
|
|
74
|
+
n2
|
|
75
|
+
<%= f.input(:name2) %>
|
|
76
|
+
n3
|
|
77
|
+
<% end %>
|
|
78
|
+
n4
|
|
79
|
+
<%= f.subform(:artist, :inputs=>[:name3], :legend=>'Bar') %>
|
|
80
|
+
n5
|
|
81
|
+
END
|
|
82
|
+
erb <<END
|
|
83
|
+
0
|
|
84
|
+
<% form(@album, :action=>'/baz') do |f| %>
|
|
85
|
+
1
|
|
86
|
+
<%= f.subform(:artist, :inputs=>[:name], :legend=>'Foo') %>
|
|
87
|
+
2
|
|
88
|
+
<%= erb(@nest, :locals=>{:f=>f}) %>
|
|
89
|
+
3
|
|
90
|
+
<% end %>
|
|
91
|
+
4
|
|
92
|
+
END
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
r.get 'hash' do
|
|
96
|
+
erb "<% form({:action=>'/baz'}, :obj=>[:foo]) do |f| %> <%= f.input(:first) %> <% end %>"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
r.get 'legend' do
|
|
100
|
+
erb <<END
|
|
101
|
+
<% form([:foo, :bar], :action=>'/baz') do |f| %>
|
|
102
|
+
<p>FBB</p>
|
|
103
|
+
<%= f.inputs([:first, :last], :legend=>'Foo') %>
|
|
104
|
+
<p>FBB2</p>
|
|
105
|
+
<% end %>
|
|
106
|
+
END
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
r.get 'combined' do
|
|
110
|
+
erb <<END
|
|
111
|
+
<% form([:foo, :bar], {:action=>'/baz'}, :inputs=>[:first], :button=>'xyz', :legend=>'123') do |f| %>
|
|
112
|
+
<p>FBB</p>
|
|
113
|
+
<%= f.input(:last) %>
|
|
114
|
+
<% end %>
|
|
115
|
+
END
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
r.get 'noblock' do
|
|
119
|
+
erb "<%= form([:foo, :bar], {:action=>'/baz'}, :inputs=>[:first], :button=>'xyz', :legend=>'123') %>"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
r.get 'noblock_empty' do
|
|
123
|
+
erb "<%= form(:action=>'/baz') %>"
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
shared_examples_for "erb integration" do
|
|
128
|
+
before do
|
|
129
|
+
o = Object.new
|
|
130
|
+
def o.puts(*) end
|
|
131
|
+
@rack = {'rack.input'=>'', 'REQUEST_METHOD'=>'GET', 'rack.errors'=>o, 'SCRIPT_NAME'=>''}
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
specify "#form should add start and end tags and yield Forme::Form instance" do
|
|
135
|
+
sin_get('/').should == '<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>'
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
specify "#form should have inputs work with a block" do
|
|
139
|
+
sin_get('/inputs_block').should == '<form action="/baz"><fieldset class="inputs"><legend>FBB</legend> <input id="last" name="last" type="text" value="bar"/> </fieldset></form>'
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
specify "#form should have inputs with fieldset_ol wrapper work with block" do
|
|
143
|
+
sin_get('/inputs_block_wrapper').should == '<form action="/baz"><fieldset class="inputs"><legend>FBB</legend><ol> <input id="last" name="last" type="text" value="bar"/> </ol></fieldset></form>'
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
specify "#form should add start and end tags and yield Forme::Form instance" do
|
|
147
|
+
sin_get('/nest').should == '<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>'
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
specify "#form should correctly handle situation where multiple templates are used with same form object" do
|
|
151
|
+
sin_get('/nest_sep').should == "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"
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
specify "#form should correctly handle situation Sequel integration with subforms where multiple templates are used with same form object" do
|
|
155
|
+
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\"/><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"
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
specify "#form should accept two hashes instead of requiring obj as first argument" do
|
|
159
|
+
sin_get('/hash').should == '<form action="/baz"> <input id="first" name="first" type="text" value="foo"/> </form>'
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
specify "#form should deal with emitted code" do
|
|
163
|
+
sin_get('/legend').should == '<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>'
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
specify "#form should work with :inputs, :button, and :legend options" do
|
|
167
|
+
sin_get('/combined').should == '<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>'
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
specify "#form should work without a block" do
|
|
171
|
+
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>'
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
specify "#form with an empty form should work" do
|
|
175
|
+
sin_get('/noblock_empty').should == '<form action="/baz"></form>'
|
|
176
|
+
end
|
|
177
|
+
end
|
|
@@ -2,7 +2,11 @@ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
|
|
2
2
|
require File.join(File.dirname(File.expand_path(__FILE__)), 'sequel_helper.rb')
|
|
3
3
|
|
|
4
4
|
require 'rubygems'
|
|
5
|
+
begin
|
|
5
6
|
require 'action_controller/railtie'
|
|
7
|
+
rescue LoadError
|
|
8
|
+
warn "unable to load rails, skipping rails spec"
|
|
9
|
+
else
|
|
6
10
|
require 'forme/rails'
|
|
7
11
|
|
|
8
12
|
class FormeRails < Rails::Application
|
|
@@ -233,3 +237,4 @@ describe "Forme Rails integration" do
|
|
|
233
237
|
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>'
|
|
234
238
|
end
|
|
235
239
|
end
|
|
240
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
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')
|
|
3
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), 'erb_helper.rb')
|
|
4
|
+
|
|
5
|
+
require 'rubygems'
|
|
6
|
+
begin
|
|
7
|
+
require 'roda'
|
|
8
|
+
require(ENV['ERUBIS'] ? 'erubis' : 'erb')
|
|
9
|
+
require 'rack/csrf'
|
|
10
|
+
rescue LoadError
|
|
11
|
+
warn "unable to load roda or rack/csrf, skipping roda spec"
|
|
12
|
+
else
|
|
13
|
+
class FormeRodaTest < Roda
|
|
14
|
+
plugin :forme
|
|
15
|
+
use Rack::Session::Cookie, :secret => "__a_very_long_string__"
|
|
16
|
+
use Rack::Csrf
|
|
17
|
+
|
|
18
|
+
def erb(s, opts={})
|
|
19
|
+
render(opts.merge(:inline=>s))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
route do |r|
|
|
23
|
+
instance_exec(r, &ERB_BLOCK)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe "Forme Roda ERB integration" do
|
|
28
|
+
def sin_get(path)
|
|
29
|
+
s = ''
|
|
30
|
+
FormeRodaTest.app.call(@rack.merge('PATH_INFO'=>path))[2].each{|str| s << str}
|
|
31
|
+
s.gsub(/\s+/, ' ').strip
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it_should_behave_like "erb integration"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
|
2
2
|
require File.join(File.dirname(File.expand_path(__FILE__)), 'sequel_helper.rb')
|
|
3
|
+
require File.join(File.dirname(File.expand_path(__FILE__)), 'erb_helper.rb')
|
|
3
4
|
|
|
4
5
|
require 'rubygems'
|
|
6
|
+
begin
|
|
5
7
|
require 'sinatra/base'
|
|
6
|
-
require 'forme/sinatra'
|
|
7
8
|
require(ENV['ERUBIS'] ? 'erubis' : 'erb')
|
|
8
9
|
require 'rack/csrf'
|
|
9
|
-
|
|
10
|
+
rescue LoadError
|
|
11
|
+
warn "unable to load sinatra or rack/csrf, skipping sinatra spec"
|
|
12
|
+
else
|
|
13
|
+
require 'forme/sinatra'
|
|
10
14
|
class FormeSinatraTest < Sinatra::Base
|
|
11
15
|
helpers(Forme::Sinatra::ERB)
|
|
12
16
|
disable :show_exceptions
|
|
@@ -14,129 +18,11 @@ class FormeSinatraTest < Sinatra::Base
|
|
|
14
18
|
enable :sessions
|
|
15
19
|
use Rack::Csrf
|
|
16
20
|
|
|
17
|
-
get
|
|
18
|
-
|
|
19
|
-
<% form([:foo, :bar], :action=>'/baz') do |f| %>
|
|
20
|
-
<p>FBB</p>
|
|
21
|
-
<%= f.input(:first) %>
|
|
22
|
-
<%= f.input(:last) %>
|
|
23
|
-
<%= f.button('Save') %>
|
|
24
|
-
<% end %>
|
|
25
|
-
END
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
get '/inputs_block' do
|
|
29
|
-
erb <<END
|
|
30
|
-
<% form([:foo, :bar], :action=>'/baz') do |f| %><% f.inputs(:legend=>'FBB') do %>
|
|
31
|
-
<%= f.input(:last) %>
|
|
32
|
-
<% end %><% end %>
|
|
33
|
-
END
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
get '/inputs_block_wrapper' do
|
|
37
|
-
erb <<END
|
|
38
|
-
<% form([:foo, :bar], {:action=>'/baz'}, :inputs_wrapper=>:fieldset_ol) do |f| %><% f.inputs(:legend=>'FBB') do %>
|
|
39
|
-
<%= f.input(:last) %>
|
|
40
|
-
<% end %><% end %>
|
|
41
|
-
END
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
get '/nest' do
|
|
45
|
-
erb <<END
|
|
46
|
-
<% form([:foo, :bar], :action=>'/baz') do |f| %>
|
|
47
|
-
<%= f.tag(:p, {}, 'FBB') %>
|
|
48
|
-
<% f.tag(:div) do %>
|
|
49
|
-
<%= f.input(:first) %>
|
|
50
|
-
<%= f.input(:last) %>
|
|
51
|
-
<% end %>
|
|
52
|
-
|
|
53
|
-
<% end %>
|
|
54
|
-
END
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
get '/nest_sep' do
|
|
58
|
-
@nest = <<END
|
|
59
|
-
n1
|
|
60
|
-
<% f.tag(:div) do %>
|
|
61
|
-
n2
|
|
62
|
-
<%= f.input(:first) %>
|
|
63
|
-
<%= f.input(:last) %>
|
|
64
|
-
n3
|
|
65
|
-
<% end %>
|
|
66
|
-
n4
|
|
67
|
-
<%= f.inputs([:first, :last], :legend=>'Foo') %>
|
|
68
|
-
n5
|
|
69
|
-
END
|
|
70
|
-
erb <<END
|
|
71
|
-
0
|
|
72
|
-
<% form([:foo, :bar], :action=>'/baz') do |f| %>
|
|
73
|
-
1
|
|
74
|
-
<%= f.tag(:p, {}, 'FBB') %>
|
|
75
|
-
2
|
|
76
|
-
<%= erb(@nest, :locals=>{:f=>f}) %>
|
|
77
|
-
3
|
|
78
|
-
<% end %>
|
|
79
|
-
4
|
|
80
|
-
END
|
|
21
|
+
def self.get(path, &block)
|
|
22
|
+
super("/#{path}", &block)
|
|
81
23
|
end
|
|
82
24
|
|
|
83
|
-
|
|
84
|
-
@album = Album.load(:name=>'N', :copies_sold=>2, :id=>1)
|
|
85
|
-
@album.associations[:artist] = Artist.load(:name=>'A', :id=>2)
|
|
86
|
-
@nest = <<END
|
|
87
|
-
n1
|
|
88
|
-
<% f.subform(:artist) do %>
|
|
89
|
-
n2
|
|
90
|
-
<%= f.input(:name2) %>
|
|
91
|
-
n3
|
|
92
|
-
<% end %>
|
|
93
|
-
n4
|
|
94
|
-
<%= f.subform(:artist, :inputs=>[:name3], :legend=>'Bar') %>
|
|
95
|
-
n5
|
|
96
|
-
END
|
|
97
|
-
erb <<END
|
|
98
|
-
0
|
|
99
|
-
<% form(@album, :action=>'/baz') do |f| %>
|
|
100
|
-
1
|
|
101
|
-
<%= f.subform(:artist, :inputs=>[:name], :legend=>'Foo') %>
|
|
102
|
-
2
|
|
103
|
-
<%= erb(@nest, :locals=>{:f=>f}) %>
|
|
104
|
-
3
|
|
105
|
-
<% end %>
|
|
106
|
-
4
|
|
107
|
-
END
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
get '/hash' do
|
|
111
|
-
erb "<% form({:action=>'/baz'}, :obj=>[:foo]) do |f| %> <%= f.input(:first) %> <% end %>"
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
get '/legend' do
|
|
115
|
-
erb <<END
|
|
116
|
-
<% form([:foo, :bar], :action=>'/baz') do |f| %>
|
|
117
|
-
<p>FBB</p>
|
|
118
|
-
<%= f.inputs([:first, :last], :legend=>'Foo') %>
|
|
119
|
-
<p>FBB2</p>
|
|
120
|
-
<% end %>
|
|
121
|
-
END
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
get '/combined' do
|
|
125
|
-
erb <<END
|
|
126
|
-
<% form([:foo, :bar], {:action=>'/baz'}, :inputs=>[:first], :button=>'xyz', :legend=>'123') do |f| %>
|
|
127
|
-
<p>FBB</p>
|
|
128
|
-
<%= f.input(:last) %>
|
|
129
|
-
<% end %>
|
|
130
|
-
END
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
get '/noblock' do
|
|
134
|
-
erb "<%= form([:foo, :bar], {:action=>'/baz'}, :inputs=>[:first], :button=>'xyz', :legend=>'123') %>"
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
get '/noblock_empty' do
|
|
138
|
-
erb "<%= form(:action=>'/baz') %>"
|
|
139
|
-
end
|
|
25
|
+
instance_exec(self, &ERB_BLOCK)
|
|
140
26
|
end
|
|
141
27
|
|
|
142
28
|
describe "Forme Sinatra ERB integration" do
|
|
@@ -145,53 +31,7 @@ describe "Forme Sinatra ERB integration" do
|
|
|
145
31
|
FormeSinatraTest.new.call(@rack.merge('PATH_INFO'=>path))[2].each{|str| s << str}
|
|
146
32
|
s.gsub(/\s+/, ' ').strip
|
|
147
33
|
end
|
|
148
|
-
before do
|
|
149
|
-
o = Object.new
|
|
150
|
-
def o.puts(*) end
|
|
151
|
-
@rack = {'rack.input'=>'', 'REQUEST_METHOD'=>'GET', 'rack.errors'=>o}
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
specify "#form should add start and end tags and yield Forme::Form instance" do
|
|
155
|
-
sin_get('/').should == '<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>'
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
specify "#form should have inputs work with a block" do
|
|
159
|
-
sin_get('/inputs_block').should == '<form action="/baz"><fieldset class="inputs"><legend>FBB</legend> <input id="last" name="last" type="text" value="bar"/> </fieldset></form>'
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
specify "#form should have inputs with fieldset_ol wrapper work with block" do
|
|
163
|
-
sin_get('/inputs_block_wrapper').should == '<form action="/baz"><fieldset class="inputs"><legend>FBB</legend><ol> <input id="last" name="last" type="text" value="bar"/> </ol></fieldset></form>'
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
specify "#form should add start and end tags and yield Forme::Form instance" do
|
|
167
|
-
sin_get('/nest').should == '<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>'
|
|
168
|
-
end
|
|
169
34
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
specify "#form should correctly handle situation Sequel integration with subforms where multiple templates are used with same form object" do
|
|
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\"/><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"
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
specify "#form should accept two hashes instead of requiring obj as first argument" do
|
|
179
|
-
sin_get('/hash').should == '<form action="/baz"> <input id="first" name="first" type="text" value="foo"/> </form>'
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
specify "#form should deal with emitted code" do
|
|
183
|
-
sin_get('/legend').should == '<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>'
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
specify "#form should work with :inputs, :button, and :legend options" do
|
|
187
|
-
sin_get('/combined').should == '<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>'
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
specify "#form should work without a block" do
|
|
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>'
|
|
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
|
|
35
|
+
it_should_behave_like "erb integration"
|
|
36
|
+
end
|
|
197
37
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: forme
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jeremy Evans
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-07-
|
|
11
|
+
date: 2014-07-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: |
|
|
14
14
|
Forme is a forms library with the following goals:
|
|
@@ -30,13 +30,17 @@ files:
|
|
|
30
30
|
- README.rdoc
|
|
31
31
|
- Rakefile
|
|
32
32
|
- lib/forme.rb
|
|
33
|
+
- lib/forme/erb.rb
|
|
33
34
|
- lib/forme/rails.rb
|
|
34
35
|
- lib/forme/sinatra.rb
|
|
35
36
|
- lib/forme/version.rb
|
|
37
|
+
- lib/roda/plugins/forme.rb
|
|
36
38
|
- lib/sequel/plugins/forme.rb
|
|
39
|
+
- spec/erb_helper.rb
|
|
37
40
|
- spec/forme_coverage.rb
|
|
38
41
|
- spec/forme_spec.rb
|
|
39
42
|
- spec/rails_integration_spec.rb
|
|
43
|
+
- spec/roda_integration_spec.rb
|
|
40
44
|
- spec/sequel_helper.rb
|
|
41
45
|
- spec/sequel_plugin_spec.rb
|
|
42
46
|
- spec/sinatra_integration_spec.rb
|