forme 1.12.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|