forme 1.12.0 → 2.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 +34 -0
- data/README.rdoc +226 -204
- data/lib/forme/bs3.rb +18 -4
- data/lib/forme/erb.rb +18 -16
- data/lib/forme/form.rb +150 -117
- data/lib/forme/input.rb +1 -1
- data/lib/forme/rails.rb +41 -72
- data/lib/forme/raw.rb +2 -2
- data/lib/forme/sinatra.rb +6 -2
- data/lib/forme/tag.rb +3 -12
- data/lib/forme/template.rb +118 -0
- data/lib/forme/transformers/helper.rb +0 -1
- data/lib/forme/transformers/inputs_wrapper.rb +4 -4
- data/lib/forme/version.rb +2 -2
- data/lib/forme.rb +13 -2
- data/lib/roda/plugins/forme.rb +1 -1
- data/lib/roda/plugins/forme_erubi_capture.rb +62 -0
- data/lib/roda/plugins/forme_route_csrf.rb +16 -34
- data/lib/roda/plugins/forme_set.rb +39 -76
- data/lib/sequel/plugins/forme.rb +37 -51
- data/lib/sequel/plugins/forme_i18n.rb +3 -1
- data/spec/all.rb +1 -1
- data/spec/bs3_reference_spec.rb +18 -18
- data/spec/bs3_sequel_plugin_spec.rb +7 -7
- data/spec/bs3_spec.rb +23 -11
- data/spec/erb_helper.rb +73 -58
- data/spec/erubi_capture_helper.rb +202 -0
- data/spec/forme_spec.rb +30 -15
- data/spec/rails_integration_spec.rb +17 -11
- data/spec/roda_integration_spec.rb +123 -68
- data/spec/sequel_helper.rb +0 -1
- data/spec/sequel_i18n_helper.rb +1 -1
- data/spec/sequel_i18n_plugin_spec.rb +2 -2
- data/spec/sequel_plugin_spec.rb +11 -2
- data/spec/sequel_set_plugin_spec.rb +3 -3
- data/spec/shared_erb_specs.rb +75 -0
- data/spec/sinatra_integration_spec.rb +5 -6
- data/spec/spec_helper.rb +21 -3
- metadata +8 -5
- data/lib/forme/erb_form.rb +0 -74
data/spec/sequel_plugin_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require_relative 'sequel_helper'
|
3
3
|
|
4
4
|
describe "Forme Sequel::Model forms" do
|
5
5
|
before do
|
@@ -9,6 +9,15 @@ describe "Forme Sequel::Model forms" do
|
|
9
9
|
@c = Forme::Form.new(@ac)
|
10
10
|
end
|
11
11
|
|
12
|
+
it "should handle Forme::Form subclasses" do
|
13
|
+
c = Class.new(Forme::Form) do
|
14
|
+
def form(*)
|
15
|
+
super{|f| f.tag(:input, :type=>:hidden, :name=>'a', :value=>'b')}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
c.new(@ab).form.to_s.must_equal '<form class="forme album" method="post"><input name="a" type="hidden" value="b"/></form>'
|
19
|
+
end
|
20
|
+
|
12
21
|
it "should add appropriate attributes by default" do
|
13
22
|
@b.form.to_s.must_equal '<form class="forme album" method="post"></form>'
|
14
23
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require_relative 'sequel_helper'
|
3
3
|
|
4
4
|
describe "Sequel forme_set plugin" do
|
5
5
|
before do
|
@@ -227,6 +227,6 @@ describe "Sequel forme_set plugin" do
|
|
227
227
|
@ab.freeze
|
228
228
|
@ab.forme_inputs.must_equal({})
|
229
229
|
@ab.forme_validations.must_equal({})
|
230
|
-
@f.input(:name).
|
230
|
+
@f.input(:name).must_equal '<label>Name: <input id="album_name" maxlength="255" name="album[name]" type="text"/></label>'
|
231
231
|
end
|
232
232
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module FormeErbSpecs
|
2
|
+
extend Minitest::Spec::DSL
|
3
|
+
|
4
|
+
before do
|
5
|
+
o = Object.new
|
6
|
+
def o.puts(*) end
|
7
|
+
@rack = {'rack.input'=>'', 'REQUEST_METHOD'=>'GET', 'rack.errors'=>o, 'SCRIPT_NAME'=>''}
|
8
|
+
end
|
9
|
+
|
10
|
+
it "#form should add start and end tags and yield Forme::Form instance" do
|
11
|
+
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>'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "#form should have inputs work with a block" do
|
15
|
+
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>'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "#form should have inputs with fieldset_ol wrapper work with block" do
|
19
|
+
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>'
|
20
|
+
end
|
21
|
+
|
22
|
+
it "#form should add start and end tags and yield Forme::Form instance" do
|
23
|
+
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>'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "#form should correctly handle situation where multiple templates are used with same form object" do
|
27
|
+
sin_get('/nest_sep').sub(/ 4\z/, '4').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'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "#form should correctly handle situation Sequel integration with subforms where multiple templates are used with same form object" do
|
31
|
+
sin_get('/nest_seq_simple').sub(/ 4\z/, '4').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 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 3 </form>4'
|
32
|
+
|
33
|
+
sin_get('/nest_seq').sub(/ 4\z/, '4').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'
|
34
|
+
end
|
35
|
+
|
36
|
+
it "#form should correctly handle subform with :grid option with block" do
|
37
|
+
sin_get('/grid-block').sub(/ 4\z/, '4').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 <table><caption>Foo</caption><thead><tr><th>Name</th></tr></thead><tbody><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="2"/><tr><td class="string"><input id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="A"/></td> 2 </tr></tbody></table> 3 <input type="submit" value="Sub"/></form>4'
|
38
|
+
end
|
39
|
+
|
40
|
+
it "#form should correctly handle subform with :grid option without block" do
|
41
|
+
sin_get('/grid-noblock').sub(/ 3\z/, '3').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 <table><caption>Foo</caption><thead><tr><th>Name</th></tr></thead><tbody><input id="album_artist_attributes_id" name="album[artist_attributes][id]" type="hidden" value="2"/><tr><td class="string"><input id="album_artist_attributes_name" maxlength="255" name="album[artist_attributes][name]" type="text" value="A"/></td></tr></tbody></table> 2 <input type="submit" value="Sub"/></form>3'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "#form should correctly handle subform with :grid option without block" do
|
45
|
+
sin_get('/grid-noblock-multiple').sub(/ 3\z/, '3').sub(%r{<input name="_csrf" type="hidden" value="([^"]+)"/>}, '<input name="_csrf" type="hidden" value="csrf"/>').must_equal '0 <form action="/baz" class="forme artist" method="post"><input name="_csrf" type="hidden" value="csrf"/> 1 <table><caption>Foo</caption><thead><tr><th>Name</th><th>Copies</th></tr></thead><tbody><input id="artist_albums_attributes_0_id" name="artist[albums_attributes][0][id]" type="hidden" value="1"/><tr><td class="string"><input id="artist_albums_attributes_0_name" maxlength="255" name="artist[albums_attributes][0][name]" type="text" value="N"/></td><td class="integer"><input id="artist_albums_attributes_0_copies_sold" name="artist[albums_attributes][0][copies_sold]" type="number" value="2"/></td></tr></tbody></table> 2 <input type="submit" value="Sub"/></form>3'
|
46
|
+
end
|
47
|
+
|
48
|
+
it "#form should accept two hashes instead of requiring obj as first argument" do
|
49
|
+
sin_get('/hash').must_equal '<form action="/baz"> <input id="first" name="first" type="text" value="foo"/> </form>'
|
50
|
+
end
|
51
|
+
|
52
|
+
it "#form should deal with emitted code" do
|
53
|
+
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>'
|
54
|
+
end
|
55
|
+
|
56
|
+
it "#form should work with :inputs, :button, and :legend options" do
|
57
|
+
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>'
|
58
|
+
end
|
59
|
+
|
60
|
+
it "#form should work without a block" do
|
61
|
+
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>'
|
62
|
+
end
|
63
|
+
|
64
|
+
it "#form should work without a block and still have hidden tags emitted" do
|
65
|
+
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>'
|
66
|
+
end
|
67
|
+
|
68
|
+
silence_warnings "#form should support :hidden_tags option" do
|
69
|
+
sin_get('/hidden_tags').sub(%r{<input name="_csrf" type="hidden" value="([^"]+)"/>}, '').must_equal '<form action="/baz"><input name="a" type="hidden" value="b"/></form>'
|
70
|
+
end
|
71
|
+
|
72
|
+
it "#form with an empty form should work" do
|
73
|
+
sin_get('/noblock_empty').must_equal '<form action="/baz"></form>'
|
74
|
+
end
|
75
|
+
end
|
@@ -1,8 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require_relative 'sequel_helper'
|
3
|
+
require_relative 'erb_helper'
|
4
4
|
|
5
|
-
require 'rubygems'
|
6
5
|
begin
|
7
6
|
require 'sinatra/base'
|
8
7
|
require 'rack/csrf'
|
@@ -19,9 +18,9 @@ rescue LoadError
|
|
19
18
|
require 'erb'
|
20
19
|
end
|
21
20
|
end
|
22
|
-
|
21
|
+
require_relative '../lib/forme/erb'
|
23
22
|
class FormeSinatraTest < Sinatra::Base
|
24
|
-
helpers(Forme::
|
23
|
+
helpers(Forme::ERB::Helper)
|
25
24
|
disable :show_exceptions
|
26
25
|
enable :raise_errors
|
27
26
|
enable :sessions
|
data/spec/spec_helper.rb
CHANGED
@@ -6,13 +6,31 @@ if ENV['WARNING']
|
|
6
6
|
end
|
7
7
|
|
8
8
|
if ENV['COVERAGE']
|
9
|
-
|
9
|
+
require_relative 'forme_coverage'
|
10
10
|
SimpleCov.forme_coverage
|
11
11
|
end
|
12
12
|
|
13
|
-
|
13
|
+
require_relative '../lib/forme'
|
14
14
|
|
15
|
-
require 'rubygems'
|
16
15
|
ENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins
|
17
16
|
gem 'minitest'
|
18
17
|
require 'minitest/global_expectations/autorun'
|
18
|
+
|
19
|
+
module Minitest::Spec::DSL
|
20
|
+
def silence_warnings(name, &block)
|
21
|
+
it(name) do
|
22
|
+
silence_warnings do
|
23
|
+
instance_exec(&block)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Minitest::Spec
|
30
|
+
def silence_warnings
|
31
|
+
verbose, $VERBOSE = $VERBOSE, nil
|
32
|
+
yield
|
33
|
+
ensure
|
34
|
+
$VERBOSE = verbose
|
35
|
+
end
|
36
|
+
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:
|
4
|
+
version: 2.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: 2021-
|
11
|
+
date: 2021-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -172,13 +172,13 @@ files:
|
|
172
172
|
- lib/forme.rb
|
173
173
|
- lib/forme/bs3.rb
|
174
174
|
- lib/forme/erb.rb
|
175
|
-
- lib/forme/erb_form.rb
|
176
175
|
- lib/forme/form.rb
|
177
176
|
- lib/forme/input.rb
|
178
177
|
- lib/forme/rails.rb
|
179
178
|
- lib/forme/raw.rb
|
180
179
|
- lib/forme/sinatra.rb
|
181
180
|
- lib/forme/tag.rb
|
181
|
+
- lib/forme/template.rb
|
182
182
|
- lib/forme/transformers/error_handler.rb
|
183
183
|
- lib/forme/transformers/formatter.rb
|
184
184
|
- lib/forme/transformers/helper.rb
|
@@ -188,6 +188,7 @@ files:
|
|
188
188
|
- lib/forme/transformers/wrapper.rb
|
189
189
|
- lib/forme/version.rb
|
190
190
|
- lib/roda/plugins/forme.rb
|
191
|
+
- lib/roda/plugins/forme_erubi_capture.rb
|
191
192
|
- lib/roda/plugins/forme_route_csrf.rb
|
192
193
|
- lib/roda/plugins/forme_set.rb
|
193
194
|
- lib/sequel/plugins/forme.rb
|
@@ -198,6 +199,7 @@ files:
|
|
198
199
|
- spec/bs3_sequel_plugin_spec.rb
|
199
200
|
- spec/bs3_spec.rb
|
200
201
|
- spec/erb_helper.rb
|
202
|
+
- spec/erubi_capture_helper.rb
|
201
203
|
- spec/forme_coverage.rb
|
202
204
|
- spec/forme_spec.rb
|
203
205
|
- spec/rails_integration_spec.rb
|
@@ -207,6 +209,7 @@ files:
|
|
207
209
|
- spec/sequel_i18n_plugin_spec.rb
|
208
210
|
- spec/sequel_plugin_spec.rb
|
209
211
|
- spec/sequel_set_plugin_spec.rb
|
212
|
+
- spec/shared_erb_specs.rb
|
210
213
|
- spec/sinatra_integration_spec.rb
|
211
214
|
- spec/spec_helper.rb
|
212
215
|
homepage: http://github.com/jeremyevans/forme
|
@@ -233,14 +236,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
233
236
|
requirements:
|
234
237
|
- - ">="
|
235
238
|
- !ruby/object:Gem::Version
|
236
|
-
version:
|
239
|
+
version: 1.9.2
|
237
240
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
238
241
|
requirements:
|
239
242
|
- - ">="
|
240
243
|
- !ruby/object:Gem::Version
|
241
244
|
version: '0'
|
242
245
|
requirements: []
|
243
|
-
rubygems_version: 3.2.
|
246
|
+
rubygems_version: 3.2.32
|
244
247
|
signing_key:
|
245
248
|
specification_version: 4
|
246
249
|
summary: HTML forms library
|
data/lib/forme/erb_form.rb
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
# frozen-string-literal: true
|
2
|
-
|
3
|
-
require 'forme'
|
4
|
-
|
5
|
-
module Forme
|
6
|
-
module ERB
|
7
|
-
# Subclass used when using Forme ERB integration.
|
8
|
-
# Handles integrating into the view template so that
|
9
|
-
# methods with blocks can inject strings into the output.
|
10
|
-
class Form < ::Forme::Form
|
11
|
-
# Template output object, where serialized output gets
|
12
|
-
# injected.
|
13
|
-
attr_reader :output
|
14
|
-
|
15
|
-
# Set the template output object when initializing.
|
16
|
-
def initialize(*)
|
17
|
-
super
|
18
|
-
@output = @opts[:output] ? @opts[:output] : String.new
|
19
|
-
end
|
20
|
-
|
21
|
-
# Serialize the tag and inject it into the output.
|
22
|
-
def emit(tag)
|
23
|
-
output << tag.to_s
|
24
|
-
end
|
25
|
-
|
26
|
-
# Capture the inside of the inputs, injecting it into the template
|
27
|
-
# if a block is given, or returning it as a string if not.
|
28
|
-
def inputs(*a, &block)
|
29
|
-
if block
|
30
|
-
capture(block){super}
|
31
|
-
else
|
32
|
-
capture{super}
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# Capture the inside of the form, injecting it into the template if
|
37
|
-
# a block is given, or returning it as a string if not.
|
38
|
-
def form(*a, &block)
|
39
|
-
if block
|
40
|
-
capture(block){super}
|
41
|
-
else
|
42
|
-
super
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# If a block is given, inject an opening tag into the
|
47
|
-
# output, inject any given children into the output, yield to the
|
48
|
-
# block, inject a closing tag into the output.
|
49
|
-
# If a block is not given, just return the tag created.
|
50
|
-
def tag(type, attr={}, children=[], &block)
|
51
|
-
tag = _tag(type, attr, children)
|
52
|
-
if block
|
53
|
-
capture(block) do
|
54
|
-
emit(serialize_open(tag))
|
55
|
-
Array(tag.children).each{|c| emit(c)}
|
56
|
-
yield self
|
57
|
-
emit(serialize_close(tag))
|
58
|
-
end
|
59
|
-
else
|
60
|
-
tag
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def capture(block=String.new) # :nodoc:
|
65
|
-
buf_was, @output = @output, block.is_a?(Proc) ? (eval("@_out_buf", block.binding) || @output) : block
|
66
|
-
yield
|
67
|
-
ret = @output
|
68
|
-
@output = buf_was
|
69
|
-
ret
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|