forme 1.12.0 → 2.2.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 +228 -206
- data/Rakefile +1 -7
- data/lib/forme/bs3.rb +23 -9
- data/lib/forme/erb.rb +13 -25
- data/lib/forme/form.rb +146 -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/error_handler.rb +10 -10
- data/lib/forme/transformers/formatter.rb +32 -34
- 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 +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 +45 -54
- data/lib/sequel/plugins/forme_i18n.rb +3 -1
- data/lib/sequel/plugins/forme_set.rb +2 -4
- data/spec/all.rb +1 -1
- data/spec/bs3_reference_spec.rb +291 -314
- data/spec/bs3_sequel_plugin_spec.rb +155 -155
- data/spec/bs3_spec.rb +247 -206
- data/spec/erb_helper.rb +69 -58
- data/spec/erubi_capture_helper.rb +198 -0
- data/spec/forme_coverage.rb +1 -0
- data/spec/forme_spec.rb +438 -377
- data/spec/rails_integration_spec.rb +21 -11
- data/spec/roda_integration_spec.rb +136 -70
- data/spec/sequel_helper.rb +3 -2
- data/spec/sequel_i18n_helper.rb +1 -1
- data/spec/sequel_i18n_plugin_spec.rb +6 -6
- data/spec/sequel_plugin_spec.rb +262 -150
- data/spec/sequel_set_plugin_spec.rb +9 -3
- data/spec/shared_erb_specs.rb +71 -0
- data/spec/sinatra_integration_spec.rb +31 -6
- data/spec/spec_helper.rb +21 -8
- metadata +8 -6
- data/lib/forme/erb_form.rb +0 -74
- data/lib/forme/sinatra.rb +0 -17
@@ -1,7 +1,6 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require_relative 'sequel_helper'
|
3
3
|
|
4
|
-
require 'rubygems'
|
5
4
|
begin
|
6
5
|
require 'action_controller/railtie'
|
7
6
|
|
@@ -9,23 +8,22 @@ begin
|
|
9
8
|
require 'active_pack/gem_version'
|
10
9
|
rescue LoadError
|
11
10
|
end
|
12
|
-
|
11
|
+
require_relative '../lib/forme/rails'
|
13
12
|
|
14
13
|
if Rails.respond_to?(:version) && Rails.version.start_with?('4')
|
15
14
|
# Work around issue in backported openssl environments where
|
16
15
|
# secret is 64 bytes intead of 32 bytes
|
17
16
|
require 'active_support/message_encryptor'
|
18
|
-
ActiveSupport::MessageEncryptor.
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
}
|
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
|
21
|
+
end
|
24
22
|
end
|
25
23
|
|
26
24
|
class FormeRails < Rails::Application
|
27
25
|
routes.append do
|
28
|
-
%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|
|
26
|
+
%w'index inputs_block inputs_block_wrapper nest nest_sep nest_inputs nest_seq hash legend combined noblock noblock_post safe_buffer no_forgery_protection'.each do |action|
|
29
27
|
get action, :controller=>'forme', :action=>action
|
30
28
|
end
|
31
29
|
end
|
@@ -59,6 +57,14 @@ class FormeController < ActionController::Base
|
|
59
57
|
END
|
60
58
|
end
|
61
59
|
|
60
|
+
def no_forgery_protection
|
61
|
+
def self.protect_against_forgery?; false end
|
62
|
+
render :inline => <<END
|
63
|
+
<%= forme(:method=>'POST') do |f| %>
|
64
|
+
<% end %>
|
65
|
+
END
|
66
|
+
end
|
67
|
+
|
62
68
|
def inputs_block
|
63
69
|
render :inline => <<END
|
64
70
|
<%= forme([:foo, :bar], :action=>'/baz') do |f| %>
|
@@ -272,5 +278,9 @@ describe "Forme Rails integration" do
|
|
272
278
|
it "#form should handle Rails SafeBuffers" do
|
273
279
|
sin_get('/safe_buffer').must_equal '<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>'
|
274
280
|
end
|
281
|
+
|
282
|
+
it "#form should handle case where forgery protection is disabled" do
|
283
|
+
sin_get('/no_forgery_protection').must_equal '<form method="POST"> </form>'
|
284
|
+
end
|
275
285
|
end
|
276
286
|
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 'roda'
|
8
7
|
require 'tilt'
|
@@ -17,34 +16,39 @@ rescue LoadError
|
|
17
16
|
rescue LoadError
|
18
17
|
require 'tilt/erb'
|
19
18
|
end
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
if defined?(Roda::RodaVersionNumber) && Roda::RodaVersionNumber >= 30100
|
26
|
-
require 'roda/session_middleware'
|
27
|
-
opts[:sessions_convert_symbols] = true
|
28
|
-
use RodaSessionMiddleware, :secret=>SecureRandom.random_bytes(64), :key=>'rack.session'
|
29
|
-
else
|
30
|
-
use Rack::Session::Cookie, :secret => "__a_very_long_string__"
|
31
|
-
end
|
32
|
-
|
33
|
-
def erb(s, opts={})
|
34
|
-
render(opts.merge(:inline=>s))
|
19
|
+
else
|
20
|
+
begin
|
21
|
+
require 'erubi/capture_end'
|
22
|
+
require_relative 'erubi_capture_helper'
|
23
|
+
rescue LoadError
|
35
24
|
end
|
25
|
+
end
|
36
26
|
|
37
|
-
|
38
|
-
|
39
|
-
|
27
|
+
def FormeRodaTest(block=ERB_BLOCK)
|
28
|
+
Class.new(Roda) do
|
29
|
+
opts[:check_dynamic_arity] = opts[:check_arity] = :warn
|
30
|
+
|
31
|
+
if defined?(Roda::RodaVersionNumber) && Roda::RodaVersionNumber >= 30100
|
32
|
+
require 'roda/session_middleware'
|
33
|
+
opts[:sessions_convert_symbols] = true
|
34
|
+
use RodaSessionMiddleware, :secret=>SecureRandom.random_bytes(64), :key=>'rack.session'
|
35
|
+
else
|
36
|
+
use Rack::Session::Cookie, :secret => "__a_very_long_string__"
|
40
37
|
end
|
41
|
-
|
42
|
-
|
38
|
+
|
39
|
+
def erb(s, opts={})
|
40
|
+
render(opts.merge(:inline=>s))
|
43
41
|
end
|
44
|
-
|
45
|
-
|
42
|
+
|
43
|
+
route do |r|
|
44
|
+
r.get 'use_request_specific_token', :use do |use|
|
45
|
+
render :inline=>"[#{Base64.strict_encode64(send(:csrf_secret))}]<%= form({:method=>:post}, {:use_request_specific_token=>#{use == '1'}}) %>"
|
46
|
+
end
|
47
|
+
r.get 'csrf', :use do |use|
|
48
|
+
render :inline=>"<%= form({:method=>:post}, {:csrf=>#{use == '1'}}) %>"
|
49
|
+
end
|
50
|
+
instance_exec(r, &block)
|
46
51
|
end
|
47
|
-
instance_exec(r, &ERB_BLOCK)
|
48
52
|
end
|
49
53
|
end
|
50
54
|
|
@@ -54,7 +58,7 @@ rescue LoadError
|
|
54
58
|
warn "unable to load rack/csrf, skipping roda csrf plugin spec"
|
55
59
|
else
|
56
60
|
describe "Forme Roda ERB integration with roda forme and csrf plugins" do
|
57
|
-
app = FormeRodaCSRFTest =
|
61
|
+
app = FormeRodaCSRFTest = FormeRodaTest()
|
58
62
|
app.plugin :csrf
|
59
63
|
app.plugin :forme
|
60
64
|
|
@@ -68,64 +72,85 @@ describe "Forme Roda ERB integration with roda forme and csrf plugins" do
|
|
68
72
|
end
|
69
73
|
end
|
70
74
|
|
75
|
+
module FormeRouteCsrfSpecs
|
76
|
+
extend Minitest::Spec::DSL
|
77
|
+
include FormeErbSpecs
|
78
|
+
|
79
|
+
it "should have a valid CSRF tag" do
|
80
|
+
output = sin_get('/use_request_specific_token/1')
|
81
|
+
output =~ /\[([^\]]+)\].*?value=\"([^\"]+)\"/
|
82
|
+
secret = $1
|
83
|
+
token = $2
|
84
|
+
app.new({'SCRIPT_NAME'=>'', 'PATH_INFO'=>'/use_request_specific_token/1', 'REQUEST_METHOD'=>'POST', 'rack.session'=>{'_roda_csrf_secret'=>secret}, 'rack.input'=>StringIO.new}).valid_csrf?(:token=>token).must_equal true
|
85
|
+
app.new({'SCRIPT_NAME'=>'', 'PATH_INFO'=>'/use_request_specific_token/2', 'REQUEST_METHOD'=>'POST', 'rack.session'=>{'_roda_csrf_secret'=>secret}, 'rack.input'=>StringIO.new}).valid_csrf?(:token=>token).must_equal false
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should handle the :use_request_specific_token => true option" do
|
89
|
+
output = sin_get('/use_request_specific_token/1')
|
90
|
+
output =~ /\[([^\]]+)\].*?value=\"([^\"]+)\"/
|
91
|
+
secret = $1
|
92
|
+
token = $2
|
93
|
+
app.new({'SCRIPT_NAME'=>'', 'PATH_INFO'=>'/use_request_specific_token/1', 'REQUEST_METHOD'=>'POST', 'rack.session'=>{'_roda_csrf_secret'=>secret}, 'rack.input'=>StringIO.new}).valid_csrf?(:token=>token).must_equal true
|
94
|
+
app.new({'SCRIPT_NAME'=>'', 'PATH_INFO'=>'/use_request_specific_token/2', 'REQUEST_METHOD'=>'POST', 'rack.session'=>{'_roda_csrf_secret'=>secret}, 'rack.input'=>StringIO.new}).valid_csrf?(:token=>token).must_equal false
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should handle the :use_request_specific_token => false option" do
|
98
|
+
output = sin_get('/use_request_specific_token/0')
|
99
|
+
output =~ /\[([^\]]+)\].*?value=\"([^\"]+)\"/
|
100
|
+
secret = $1
|
101
|
+
token = $2
|
102
|
+
app.new({'SCRIPT_NAME'=>'', 'PATH_INFO'=>'/use_request_specific_token/0', 'REQUEST_METHOD'=>'POST', 'rack.session'=>{'_roda_csrf_secret'=>secret}, 'rack.input'=>StringIO.new}).valid_csrf?(:token=>token).must_equal(plugin_opts.empty? ? false : true)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should handle the :csrf option" do
|
106
|
+
sin_get('/csrf/1').must_include '<input name="_csrf" type="hidden" value="'
|
107
|
+
sin_get('/csrf/0').wont_include '<input name="_csrf" type="hidden" value="'
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
71
111
|
begin
|
72
112
|
require 'roda/plugins/route_csrf'
|
113
|
+
require 'roda/plugins/capture_erb'
|
114
|
+
require 'roda/plugins/inject_erb'
|
73
115
|
rescue LoadError
|
74
|
-
warn "unable to load
|
116
|
+
warn "unable to load necessary Roda plugins, skipping forme_erubi_capture plugin spec"
|
75
117
|
else
|
118
|
+
describe "Forme Roda Erubi::CaptureEnd integration with roda forme_route_csrf" do
|
119
|
+
app = FormeRodaTest(ERUBI_CAPTURE_BLOCK)
|
120
|
+
app.plugin :forme_erubi_capture
|
121
|
+
app.plugin :render, :engine_opts=>{'erb'=>{:engine_class=>Erubi::CaptureEndEngine}}
|
122
|
+
|
123
|
+
define_method(:app){app}
|
124
|
+
define_method(:plugin_opts){{}}
|
125
|
+
define_method(:sin_get) do |path|
|
126
|
+
s = String.new
|
127
|
+
app.call(@rack.merge('PATH_INFO'=>path))[2].each{|str| s << str}
|
128
|
+
s.gsub(/\s+/, ' ').strip
|
129
|
+
end
|
130
|
+
|
131
|
+
include FormeRouteCsrfSpecs
|
132
|
+
end if defined?(ERUBI_CAPTURE_BLOCK)
|
133
|
+
|
76
134
|
[{}, {:require_request_specific_tokens=>false}].each do |plugin_opts|
|
77
135
|
describe "Forme Roda ERB integration with roda forme_route_csrf and route_csrf plugin with #{plugin_opts}" do
|
78
|
-
app =
|
136
|
+
app = FormeRodaTest()
|
79
137
|
app.plugin :forme_route_csrf
|
80
138
|
app.plugin :route_csrf, plugin_opts
|
81
139
|
|
140
|
+
define_method(:app){app}
|
141
|
+
define_method(:plugin_opts){plugin_opts}
|
82
142
|
define_method(:sin_get) do |path|
|
83
143
|
s = String.new
|
84
144
|
app.call(@rack.merge('PATH_INFO'=>path))[2].each{|str| s << str}
|
85
145
|
s.gsub(/\s+/, ' ').strip
|
86
146
|
end
|
87
147
|
|
88
|
-
include
|
89
|
-
|
90
|
-
it "should handle the :hidden_tags option" do
|
91
|
-
output = sin_get('/use_request_specific_token/1')
|
92
|
-
output =~ /\[([^\]]+)\].*?value=\"([^\"]+)\"/
|
93
|
-
secret = $1
|
94
|
-
token = $2
|
95
|
-
app.new({'SCRIPT_NAME'=>'', 'PATH_INFO'=>'/use_request_specific_token/1', 'REQUEST_METHOD'=>'POST', 'rack.session'=>{'_roda_csrf_secret'=>secret}, 'rack.input'=>StringIO.new}).valid_csrf?(:token=>token).must_equal true
|
96
|
-
app.new({'SCRIPT_NAME'=>'', 'PATH_INFO'=>'/use_request_specific_token/2', 'REQUEST_METHOD'=>'POST', 'rack.session'=>{'_roda_csrf_secret'=>secret}, 'rack.input'=>StringIO.new}).valid_csrf?(:token=>token).must_equal false
|
97
|
-
end
|
98
|
-
|
99
|
-
it "should handle the :use_request_specific_token => true option" do
|
100
|
-
output = sin_get('/use_request_specific_token/1')
|
101
|
-
output =~ /\[([^\]]+)\].*?value=\"([^\"]+)\"/
|
102
|
-
secret = $1
|
103
|
-
token = $2
|
104
|
-
app.new({'SCRIPT_NAME'=>'', 'PATH_INFO'=>'/use_request_specific_token/1', 'REQUEST_METHOD'=>'POST', 'rack.session'=>{'_roda_csrf_secret'=>secret}, 'rack.input'=>StringIO.new}).valid_csrf?(:token=>token).must_equal true
|
105
|
-
app.new({'SCRIPT_NAME'=>'', 'PATH_INFO'=>'/use_request_specific_token/2', 'REQUEST_METHOD'=>'POST', 'rack.session'=>{'_roda_csrf_secret'=>secret}, 'rack.input'=>StringIO.new}).valid_csrf?(:token=>token).must_equal false
|
106
|
-
end
|
107
|
-
|
108
|
-
it "should handle the :use_request_specific_token => false option" do
|
109
|
-
output = sin_get('/use_request_specific_token/0')
|
110
|
-
output =~ /\[([^\]]+)\].*?value=\"([^\"]+)\"/
|
111
|
-
secret = $1
|
112
|
-
token = $2
|
113
|
-
app.new({'SCRIPT_NAME'=>'', 'PATH_INFO'=>'/use_request_specific_token/0', 'REQUEST_METHOD'=>'POST', 'rack.session'=>{'_roda_csrf_secret'=>secret}, 'rack.input'=>StringIO.new}).valid_csrf?(:token=>token).must_equal(plugin_opts.empty? ? false : true)
|
114
|
-
end
|
115
|
-
|
116
|
-
it "should handle the :hidden_tags option" do
|
117
|
-
sin_get('/hidden_tags').must_include 'name="foo" type="hidden" value="bar"'
|
118
|
-
end
|
119
|
-
|
120
|
-
it "should handle the :csrf option" do
|
121
|
-
sin_get('/csrf/1').must_include '<input name="_csrf" type="hidden" value="'
|
122
|
-
sin_get('/csrf/0').wont_include '<input name="_csrf" type="hidden" value="'
|
123
|
-
end
|
148
|
+
include FormeRouteCsrfSpecs
|
124
149
|
end
|
125
150
|
|
126
151
|
describe "Forme Roda ERB Sequel integration with roda forme_set plugin and route_csrf plugin with #{plugin_opts}" do
|
127
152
|
before do
|
128
|
-
@app =
|
153
|
+
@app = FormeRodaTest()
|
129
154
|
@app.plugin :route_csrf, plugin_opts
|
130
155
|
@app.plugin(:forme_set, :secret=>'1'*64)
|
131
156
|
|
@@ -147,13 +172,18 @@ else
|
|
147
172
|
def _forme_set(meth, obj, orig_hash, *form_args, &block)
|
148
173
|
hash = {}
|
149
174
|
forme_set_block = orig_hash.delete(:forme_set_block)
|
175
|
+
handle_params = hash.delete(:handle_params)
|
150
176
|
orig_hash.each{|k,v| hash[k.to_s] = v}
|
151
|
-
album =
|
177
|
+
album = obj
|
152
178
|
ret, _, data, hmac = nil
|
153
179
|
|
154
180
|
@app.route do |r|
|
155
181
|
r.get do
|
156
|
-
|
182
|
+
if @block = env[:block]
|
183
|
+
render(:inline=>'<% form(*env[:args]) do |f| %><%= @block.call(f) %><% end %>')
|
184
|
+
else
|
185
|
+
form(*env[:args])
|
186
|
+
end
|
157
187
|
end
|
158
188
|
r.post do
|
159
189
|
r.params.replace(env[:params])
|
@@ -167,12 +197,32 @@ else
|
|
167
197
|
data = $2
|
168
198
|
hmac = $3
|
169
199
|
data.gsub!(""", '"') if data
|
170
|
-
h = {"album"=>hash, "_forme_set_data"=>data, "_forme_set_data_hmac"=>hmac, "_csrf"=>csrf}
|
200
|
+
h = {"album"=>hash, "_forme_set_data"=>data, "_forme_set_data_hmac"=>hmac, "_csrf"=>csrf, "body"=>body}
|
171
201
|
if data && hmac
|
202
|
+
h = handle_params.call(h) if handle_params
|
172
203
|
forme_call(h)
|
173
204
|
end
|
174
205
|
meth == :forme_parse ? ret : h
|
175
206
|
end
|
207
|
+
|
208
|
+
it "should have subform work correctly" do
|
209
|
+
@app.route do |r|
|
210
|
+
@album = Album.load(:name=>'N', :copies_sold=>2, :id=>1)
|
211
|
+
@album.associations[:artist] = Artist.load(:name=>'A', :id=>2)
|
212
|
+
erb <<END
|
213
|
+
0
|
214
|
+
<% form(@album, {:action=>'/baz'}, :button=>'Sub') do |f| %>
|
215
|
+
1
|
216
|
+
<%= f.subform(:artist, :inputs=>[:name], :legend=>'Foo', :grid=>true, :labels=>%w'Name') %>
|
217
|
+
2
|
218
|
+
<% end %>
|
219
|
+
3
|
220
|
+
END
|
221
|
+
end
|
222
|
+
|
223
|
+
body = @app.call('REQUEST_METHOD'=>'GET')[2].join.gsub("\n", ' ').gsub(/ +/, ' ').chomp(' ')
|
224
|
+
body.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"/><table><caption>Foo</caption><thead><tr><th>Name</th></tr></thead><tbody><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'
|
225
|
+
end
|
176
226
|
|
177
227
|
it "#forme_set should include HMAC values if form includes inputs for obj" do
|
178
228
|
h = forme_set(@ab, :name=>'Foo')
|
@@ -196,6 +246,18 @@ else
|
|
196
246
|
@ab.copies_sold.must_be_nil
|
197
247
|
end
|
198
248
|
|
249
|
+
it "#forme_set handle missing csrf" do
|
250
|
+
h = forme_set(@ab, :name=>'Foo'){|f| f.input(:name)}
|
251
|
+
@ab.name = nil
|
252
|
+
data = JSON.parse(h["_forme_set_data"])
|
253
|
+
data.delete('csrf')
|
254
|
+
data = data.to_json
|
255
|
+
hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA512.new, '1'*64, data)
|
256
|
+
forme_call(h.merge("_forme_set_data_hmac"=>hmac, "_forme_set_data"=>data))
|
257
|
+
@ab.name.must_equal 'Foo'
|
258
|
+
@ab.copies_sold.must_be_nil
|
259
|
+
end
|
260
|
+
|
199
261
|
it "#forme_set should handle custom form namespaces" do
|
200
262
|
forme_set(@ab, {"album"=>{"name"=>'Foo', 'copies_sold'=>'100'}}, {}, :namespace=>'album'){|f| f.input(:name); f.input(:copies_sold)}
|
201
263
|
@ab.name.must_equal 'Foo'
|
@@ -469,6 +531,10 @@ else
|
|
469
531
|
@ab.forme_validations.merge!(hash[:validations])
|
470
532
|
@ab.valid?.must_equal true
|
471
533
|
end
|
534
|
+
|
535
|
+
it "should handle forms with objects that don't support forme_inputs" do
|
536
|
+
forme_set(String, {:name=>'Foo'}, {}, :inputs=>[:name])['body'].must_equal '<form><fieldset class="inputs"><input id="name" name="name" type="text" value="String"/></fieldset></form>'
|
537
|
+
end
|
472
538
|
end
|
473
539
|
end
|
474
540
|
end
|
data/spec/sequel_helper.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
require 'rubygems'
|
2
1
|
require 'sequel'
|
3
2
|
|
4
|
-
db_url =
|
3
|
+
db_url = RUBY_ENGINE == 'jruby' ? 'jdbc:sqlite::memory:' : 'sqlite:/'
|
5
4
|
DB = Sequel.connect(db_url, :identifier_mangling=>false)
|
6
5
|
DB.extension(:freeze_datasets)
|
7
6
|
Sequel.default_timezone = :utc
|
@@ -18,6 +17,8 @@ DB.create_table(:albums) do
|
|
18
17
|
Date :release_date
|
19
18
|
DateTime :created_at
|
20
19
|
Integer :copies_sold
|
20
|
+
Float :fl
|
21
|
+
BigDecimal :bd
|
21
22
|
end
|
22
23
|
DB.create_table(:album_infos) do
|
23
24
|
primary_key :id
|
data/spec/sequel_i18n_helper.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
|
1
|
+
require_relative 'spec_helper'
|
2
2
|
|
3
3
|
begin
|
4
4
|
raise LoadError if defined?(JRUBY_VERSION) && /\A9\.2\./.match(JRUBY_VERSION)
|
5
|
-
|
5
|
+
require_relative 'sequel_i18n_helper'
|
6
6
|
rescue LoadError
|
7
7
|
warn "unable to load i18n, skipping i18n Sequel plugin spec"
|
8
8
|
else
|
@@ -13,19 +13,19 @@ describe "Forme Sequel::Model forms" do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should not change the usual label input if translation is not present" do
|
16
|
-
@b.input(:name).
|
16
|
+
@b.input(:name).must_equal '<label>Name: <input id="invoice_name" maxlength="255" name="invoice[name]" type="text" value="b"/></label>'
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should use the translation for the label if present" do
|
20
|
-
@b.input(:summary).
|
20
|
+
@b.input(:summary).must_equal '<label>Brief Description: <input id="invoice_summary" maxlength="255" name="invoice[summary]" type="text" value="a brief summary"/></label>'
|
21
21
|
end
|
22
22
|
|
23
23
|
it "should not change the usual legend for the subform if the translation is not present" do
|
24
|
-
Forme.form(Firm[1]){|f| f.subform(:invoices){ f.input(:name) }}.
|
24
|
+
Forme.form(Firm[1]){|f| f.subform(:invoices){ f.input(:name) }}.must_equal '<form class="forme firm" method="post"><input id="firm_invoices_attributes_0_id" name="firm[invoices_attributes][0][id]" type="hidden" value="1"/><fieldset class="inputs"><legend>Invoice #1</legend><label>Name: <input id="firm_invoices_attributes_0_name" maxlength="255" name="firm[invoices_attributes][0][name]" type="text" value="b"/></label></fieldset></form>'
|
25
25
|
end
|
26
26
|
|
27
27
|
it "should use the translation for the legend on the subform if present" do
|
28
|
-
Forme.form(Firm[1]){|f| f.subform(:clients){ f.input(:name) }}.
|
28
|
+
Forme.form(Firm[1]){|f| f.subform(:clients){ f.input(:name) }}.must_equal '<form class="forme firm" method="post"><input id="firm_clients_attributes_0_id" name="firm[clients_attributes][0][id]" type="hidden" value="1"/><fieldset class="inputs"><legend>Clientes</legend><label>Name: <input id="firm_clients_attributes_0_name" maxlength="255" name="firm[clients_attributes][0][name]" type="text" value="a great client"/></label></fieldset></form>'
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|