forme 0.6.0 → 0.7.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.
@@ -1,6 +1,6 @@
1
1
  module Forme
2
2
  # Version constant, use <tt>Forme.version</tt> instead.
3
- VERSION = '0.6.0'.freeze
3
+ VERSION = '0.7.0'.freeze
4
4
 
5
5
  # Returns the version as a frozen string (e.g. '0.1.0')
6
6
  def self.version
@@ -84,7 +84,7 @@ module Sequel # :nodoc:
84
84
  options[:legend] = humanize(association)
85
85
  end
86
86
  end
87
- inputs(ins, options, &block)
87
+ _inputs(ins, options, &block)
88
88
  else
89
89
  yield
90
90
  end
@@ -219,10 +219,7 @@ module Sequel # :nodoc:
219
219
 
220
220
  # Add the label to the start of the array, returning the array.
221
221
  def add_label(label, array)
222
- if label
223
- array.unshift(": ") unless label.is_a?(::Forme::Raw)
224
- array.unshift(label)
225
- end
222
+ array.unshift(form._tag(:span, {:class=>:label}, label)) if label
226
223
  array
227
224
  end
228
225
 
@@ -307,7 +304,7 @@ module Sequel # :nodoc:
307
304
  label = opts.delete(:label)
308
305
  val = opts.delete(:value)
309
306
  wrapper, tag_wrapper = get_wrappers
310
- radios = opts.delete(:options).map{|l, pk| _input(:radio, opts.merge(:value=>pk, :wrapper=>tag_wrapper, :label=>l, :checked=>(pk == val)))}
307
+ radios = opts.delete(:options).map{|l, pk| _input(:radio, opts.merge(:value=>pk, :id=>"#{form.namespaced_id(key)}_#{pk}", :wrapper=>tag_wrapper, :label=>l, :label_attr=>{:class=>:option}, :checked=>(pk == val)))}
311
308
  add_label(label, radios)
312
309
  wrapper ? wrapper.call(radios, _input(:radio, opts)) : radios
313
310
  else
@@ -338,7 +335,7 @@ module Sequel # :nodoc:
338
335
  label = opts.delete(:label)
339
336
  val = opts.delete(:value)
340
337
  wrapper, tag_wrapper = get_wrappers
341
- cbs = opts.delete(:options).map{|l, pk| _input(:checkbox, opts.merge(:value=>pk, :wrapper=>tag_wrapper, :label=>l, :checked=>val.include?(pk), :no_hidden=>true))}
338
+ cbs = opts.delete(:options).map{|l, pk| _input(:checkbox, opts.merge(:value=>pk, :id=>"#{form.namespaced_id(field)}_#{pk}", :wrapper=>tag_wrapper, :label=>l, :label_attr=>{:class=>:option}, :checked=>val.include?(pk), :no_hidden=>true))}
342
339
  add_label(label, cbs)
343
340
  wrapper ? wrapper.call(cbs, _input(:checkbox, opts)) : cbs
344
341
  else
@@ -371,8 +368,8 @@ module Sequel # :nodoc:
371
368
  case opts[:as]
372
369
  when :radio
373
370
  wrapper, tag_wrapper = get_wrappers
374
- true_opts = opts.merge(:value=>opts[:true_value]||'t', :label=>opts[:true_label]||'Yes', :error=>nil, :wrapper=>tag_wrapper, :wrapper_attr=>{})
375
- false_opts = opts.merge(:value=>opts[:false_value]||'f', :label=>opts[:false_label]||'No', :wrapper=>tag_wrapper, :wrapper_attr=>{})
371
+ true_opts = opts.merge(:value=>opts[:true_value]||'t', :label=>opts[:true_label]||'Yes', :label_attr=>{:class=>:option}, :error=>nil, :wrapper=>tag_wrapper, :wrapper_attr=>{})
372
+ false_opts = opts.merge(:value=>opts[:false_value]||'f', :label=>opts[:false_label]||'No', :label_attr=>{:class=>:option}, :wrapper=>tag_wrapper, :wrapper_attr=>{})
376
373
  if i = opts[:id]
377
374
  true_opts[:id] = "#{i}_yes"
378
375
  false_opts[:id] = "#{i}_no"
@@ -387,7 +384,7 @@ module Sequel # :nodoc:
387
384
  v = opts[:value] || obj.send(field)
388
385
  opts[:value] = (v ? 't' : 'f') unless v.nil?
389
386
  opts[:add_blank] = true
390
- opts[:options] = [['True', 't'], ['False', 'f']]
387
+ opts[:options] = [[opts[:true_label]||'True', opts[:true_value]||'t'], [opts[:false_label]||'False', opts[:false_value]||'f']]
391
388
  _input(:select, opts)
392
389
  else
393
390
  opts[:checked] = obj.send(field)
@@ -453,6 +450,20 @@ module Sequel # :nodoc:
453
450
  end
454
451
  end
455
452
 
453
+ # Helper module used for Sequel/Sinatra forms. Necessary for
454
+ # proper subform handling when using such forms with partials.
455
+ module SinatraSequelForm
456
+ # Capture the inside of the inputs, injecting it into the template
457
+ # if a block is given, or returning it as a string if not.
458
+ def subform(*, &block)
459
+ if block
460
+ capture(block){super}
461
+ else
462
+ capture{super}
463
+ end
464
+ end
465
+ end
466
+
456
467
  module InstanceMethods
457
468
  # Configure the +form+ with support for <tt>Sequel::Model</tt>
458
469
  # specific code, such as support for nested attributes.
@@ -460,6 +471,7 @@ module Sequel # :nodoc:
460
471
  form.extend(SequelForm)
461
472
  form.nested_associations = []
462
473
  form.namespaces = [model.send(:underscore, model.name)]
474
+ form.extend(SinatraSequelForm) if defined?(::Forme::Sinatra::Form) && form.is_a?(::Forme::Sinatra::Form)
463
475
  end
464
476
 
465
477
  # Return <tt>Forme::Input</tt> instance based on the given arguments.
@@ -42,6 +42,10 @@ describe "Forme plain forms" do
42
42
  @f.input(:text, :placeholder=>"foo").to_s.should == '<input placeholder="foo" type="text"/>'
43
43
  end
44
44
 
45
+ specify "should use :style option as attribute" do
46
+ @f.input(:text, :style=>"foo").to_s.should == '<input style="foo" type="text"/>'
47
+ end
48
+
45
49
  specify "should allow arbitrary attributes using the :attr option" do
46
50
  @f.input(:text, :attr=>{:bar=>"foo"}).to_s.should == '<input bar="foo" type="text"/>'
47
51
  end
@@ -62,6 +66,11 @@ describe "Forme plain forms" do
62
66
  @f.input(:text, :data=>{:bar=>"baz"}, :attr=>{:"data-bar"=>"foo"}).to_s.should == '<input data-bar="foo" type="text"/>'
63
67
  end
64
68
 
69
+ specify "should use :size and :maxlength options as attributes for text inputs" do
70
+ @f.input(:text, :size=>5, :maxlength=>10).to_s.should == '<input maxlength="10" size="5" type="text"/>'
71
+ @f.input(:textarea, :size=>5, :maxlength=>10).to_s.should == '<textarea></textarea>'
72
+ end
73
+
65
74
  specify "should create hidden input with value 0 for each checkbox with a name" do
66
75
  @f.input(:checkbox, :name=>"foo").to_s.should == '<input name="foo" type="hidden" value="0"/><input name="foo" type="checkbox"/>'
67
76
  end
@@ -89,6 +98,12 @@ describe "Forme plain forms" do
89
98
 
90
99
  specify "should create textarea tag" do
91
100
  @f.input(:textarea).to_s.should == '<textarea></textarea>'
101
+ @f.input(:textarea, :value=>'a').to_s.should == '<textarea>a</textarea>'
102
+ end
103
+
104
+ specify "should use :cols and :rows options as attributes for textarea inputs" do
105
+ @f.input(:text, :cols=>5, :rows=>10).to_s.should == '<input type="text"/>'
106
+ @f.input(:textarea, :cols=>5, :rows=>10).to_s.should == '<textarea cols="5" rows="10"></textarea>'
92
107
  end
93
108
 
94
109
  specify "should create select tag" do
@@ -181,6 +196,18 @@ describe "Forme plain forms" do
181
196
  @f.input(:text, :label=>'Foo', :value=>'foo', :label_attr=>{:class=>'bar'}).to_s.should == '<label class="bar">Foo: <input type="text" value="foo"/></label>'
182
197
  end
183
198
 
199
+ specify "should handle implicit labels with checkboxes" do
200
+ @f.input(:checkbox, :label=>'Foo', :value=>'foo', :name=>'a').to_s.should == '<input name="a" type="hidden" value="0"/><label><input name="a" type="checkbox" value="foo"/> Foo</label>'
201
+ end
202
+
203
+ specify "should handle implicit labels with :label_position=>:after" do
204
+ @f.input(:text, :label=>'Foo', :value=>'foo', :label_position=>:after).to_s.should == '<label><input type="text" value="foo"/> Foo</label>'
205
+ end
206
+
207
+ specify "should handle implicit labels with checkboxes with :label_position=>:before" do
208
+ @f.input(:checkbox, :label=>'Foo', :value=>'foo', :name=>'a', :label_position=>:before).to_s.should == '<input name="a" type="hidden" value="0"/><label>Foo <input name="a" type="checkbox" value="foo"/></label>'
209
+ end
210
+
184
211
  specify "should automatically note the input has errors if :error option is used" do
185
212
  @f.input(:text, :error=>'Bad Stuff!', :value=>'foo').to_s.should == '<input class="error" type="text" value="foo"/><span class="error_message">Bad Stuff!</span>'
186
213
  end
@@ -286,6 +313,18 @@ describe "Forme plain forms" do
286
313
  @f.input(:textarea, :labeler=>:explicit, :label=>'bar', :id=>:foo).to_s.should == '<label for="foo">bar</label><textarea id="foo"></textarea>'
287
314
  end
288
315
 
316
+ specify "inputs handle explicit labels with :label_position=>:after" do
317
+ @f.input(:textarea, :labeler=>:explicit, :label=>'bar', :id=>:foo, :label_position=>:after).to_s.should == '<textarea id="foo"></textarea><label for="foo">bar</label>'
318
+ end
319
+
320
+ specify "should handle explicit labels with checkboxes" do
321
+ @f.input(:checkbox, :labeler=>:explicit, :label=>'Foo', :value=>'foo', :name=>'a', :id=>'bar').to_s.should == '<input id="bar_hidden" name="a" type="hidden" value="0"/><input id="bar" name="a" type="checkbox" value="foo"/><label for="bar">Foo</label>'
322
+ end
323
+
324
+ specify "should handle explicit labels with checkboxes with :label_position=>:before" do
325
+ @f.input(:checkbox, :labeler=>:explicit, :label=>'Foo', :value=>'foo', :name=>'a', :id=>'bar', :label_position=>:before).to_s.should == '<label for="bar">Foo</label><input id="bar_hidden" name="a" type="hidden" value="0"/><input id="bar" name="a" type="checkbox" value="foo"/>'
326
+ end
327
+
289
328
  specify "inputs should accept a :error_handler option to use a custom error_handler" do
290
329
  @f.input(:textarea, :error_handler=>proc{|t, i| [t, "!!! #{i.opts[:error]}"]}, :error=>'bar', :id=>:foo).to_s.should == '<textarea class="error" id="foo"></textarea>!!! bar'
291
330
  end
@@ -547,6 +586,11 @@ describe "Forme.form DSL" do
547
586
  Forme.form{|f| f.should be_a_kind_of(Forme::Form)}
548
587
  end
549
588
 
589
+ specify "should respect an array of classes" do
590
+ Forme.form(:class=>[:foo, :bar]).to_s.should == '<form class="foo bar"></form>'
591
+ Forme.form(:class=>[:foo, [:bar, :baz]]).to_s.should == '<form class="foo bar baz"></form>'
592
+ end
593
+
550
594
  specify "should have inputs called instead the block be added to the existing form" do
551
595
  Forme.form{|f| f.input(:text)}.to_s.should == '<form><input type="text"/></form>'
552
596
  end
@@ -0,0 +1,195 @@
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
+
4
+ require 'rubygems'
5
+ require 'action_controller/railtie'
6
+ require 'forme/rails'
7
+
8
+ class FormeRails < Rails::Application
9
+ config.secret_token = routes.append { match ':action' , :controller=>'forme' }.inspect
10
+ config.active_support.deprecation = :stderr
11
+ config.middleware.delete(ActionDispatch::ShowExceptions)
12
+ config.threadsafe!
13
+ initialize!
14
+ end
15
+
16
+ class FormeController < ActionController::Base
17
+ helper Forme::Rails::ERB
18
+
19
+ def index
20
+ render :inline => <<END
21
+ <%= forme([:foo, :bar], :action=>'/baz') do |f| %>
22
+ <p>FBB</p>
23
+ <%= f.input(:first) %>
24
+ <%= f.input(:last) %>
25
+ <%= f.button('Save') %>
26
+ <% end %>
27
+ END
28
+ end
29
+
30
+ def inputs_block
31
+ render :inline => <<END
32
+ <%= forme([:foo, :bar], :action=>'/baz') do |f| %>
33
+ <%= f.inputs(:legend=>'FBB') do %>
34
+ <%= f.input(:last) %>
35
+ <% end %>
36
+ <% end %>
37
+ END
38
+ end
39
+
40
+ def inputs_block_wrapper
41
+ render :inline => <<END
42
+ <%= forme([:foo, :bar], {:action=>'/baz'}, :inputs_wrapper=>:fieldset_ol) do |f| %>
43
+ <%= f.inputs(:legend=>'FBB') do %>
44
+ <%= f.input(:last) %>
45
+ <% end %>
46
+ <% end %>
47
+ END
48
+ end
49
+
50
+ def nest
51
+ render :inline => <<END
52
+ <%= forme([:foo, :bar], :action=>'/baz') do |f| %>
53
+ <%= f.tag(:p, {}, 'FBB') %>
54
+ <%= f.tag(:div) do %>
55
+ <%= f.input(:first) %>
56
+ <%= f.input(:last) %>
57
+ <% end %>
58
+
59
+ <% end %>
60
+ END
61
+ end
62
+
63
+ def nest_sep
64
+ @nest = <<END
65
+ n1
66
+ <%= f.tag(:div) do %>
67
+ n2
68
+ <%= f.input(:first) %>
69
+ <%= f.input(:last) %>
70
+ n3
71
+ <% end %>
72
+ n4
73
+ <%= f.inputs([:first, :last], :legend=>'Foo') %>
74
+ n5
75
+ END
76
+ render :inline => <<END
77
+ 0
78
+ <%= forme([:foo, :bar], :action=>'/baz') do |f| %>
79
+ 1
80
+ <%= f.tag(:p, {}, 'FBB') %>
81
+ 2
82
+ <%= render(:inline =>@nest, :locals=>{:f=>f}) %>
83
+ 3
84
+ <% end %>
85
+ 4
86
+ END
87
+ end
88
+
89
+ def nest_seq
90
+ @album = Album.load(:name=>'N', :copies_sold=>2, :id=>1)
91
+ @album.associations[:artist] = Artist.load(:name=>'A', :id=>2)
92
+ @nest = <<END
93
+ n1
94
+ <%= f.subform(:artist) do %>
95
+ n2
96
+ <%= f.input(:name2) %>
97
+ n3
98
+ <% end %>
99
+ n4
100
+ <%= f.subform(:artist, :inputs=>[:name3], :legend=>'Bar') %>
101
+ n5
102
+ END
103
+ render :inline => <<END
104
+ 0
105
+ <%= forme(@album, :action=>'/baz') do |f| %>
106
+ 1
107
+ <%= f.subform(:artist, :inputs=>[:name], :legend=>'Foo') %>
108
+ 2
109
+ <%= render(:inline=>@nest, :locals=>{:f=>f}) %>
110
+ 3
111
+ <% end %>
112
+ 4
113
+ END
114
+ end
115
+
116
+ def hash
117
+ render :inline => "<%= forme({:action=>'/baz'}, :obj=>[:foo]) do |f| %> <%= f.input(:first) %> <% end %>"
118
+ end
119
+
120
+ def legend
121
+ render :inline => <<END
122
+ <%= forme([:foo, :bar], :action=>'/baz') do |f| %>
123
+ <p>FBB</p>
124
+ <%= f.inputs([:first, :last], :legend=>'Foo') %>
125
+ <p>FBB2</p>
126
+ <% end %>
127
+ END
128
+ end
129
+
130
+ def combined
131
+ render :inline => <<END
132
+ <%= forme([:foo, :bar], {:action=>'/baz'}, :inputs=>[:first], :button=>'xyz', :legend=>'123') do |f| %>
133
+ <p>FBB</p>
134
+ <%= f.input(:last) %>
135
+ <% end %>
136
+ END
137
+ end
138
+
139
+ def noblock
140
+ render :inline => "<%= forme([:foo, :bar], {:action=>'/baz'}, :inputs=>[:first], :button=>'xyz', :legend=>'123') %>"
141
+ end
142
+ end
143
+
144
+ describe "Forme Rails integration" do
145
+ def sin_get(path)
146
+ res = FormeRails.call(@rack.merge('PATH_INFO'=>path))
147
+ p res unless res[0] == 200
148
+ res[2].join.gsub(/\s+/, ' ').strip
149
+ end
150
+ before do
151
+ o = Object.new
152
+ def o.puts(*) end
153
+ @rack = {'rack.input'=>'', 'REQUEST_METHOD'=>'GET', 'rack.errors'=>o}
154
+ end
155
+
156
+ specify "#form should add start and end tags and yield Forme::Form instance" do
157
+ sin_get('/index').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>'
158
+ end
159
+
160
+ specify "#form should have inputs work with a block" do
161
+ 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>'
162
+ end
163
+
164
+ specify "#form should have inputs with fieldset_ol wrapper work with block" do
165
+ 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>'
166
+ end
167
+
168
+ specify "#form should add start and end tags and yield Forme::Form instance" do
169
+ 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>'
170
+ end
171
+
172
+ specify "#form should correctly handle situation where multiple templates are used with same form object" do
173
+ 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"
174
+ end
175
+
176
+ specify "#form should correctly handle situation Sequel integration with subforms where multiple templates are used with same form object" do
177
+ sin_get('/nest_seq').should == "0 <form action=\"/baz\" class=\"forme album\" method=\"post\"> 1 <input id=\"album_artist_attributes_id\" name=\"album[artist_attributes][id]\" type=\"hidden\" value=\"2\"/><fieldset class=\"inputs\"><legend>Foo</legend><label>Name: <input id=\"album_artist_attributes_name\" name=\"album[artist_attributes][name]\" type=\"text\" value=\"A\"/></label></fieldset> 2 n1 <input id=\"album_artist_attributes_id\" name=\"album[artist_attributes][id]\" type=\"hidden\" value=\"2\"/> n2 <label>Name2: <input id=\"album_artist_attributes_name2\" name=\"album[artist_attributes][name2]\" type=\"text\" value=\"A2\"/></label> n3 n4 <input id=\"album_artist_attributes_id\" name=\"album[artist_attributes][id]\" type=\"hidden\" value=\"2\"/><fieldset class=\"inputs\"><legend>Bar</legend><label>Name3: <input id=\"album_artist_attributes_name3\" name=\"album[artist_attributes][name3]\" type=\"text\" value=\"A3\"/></label></fieldset> n5 3 </form>4"
178
+ end
179
+
180
+ specify "#form should accept two hashes instead of requiring obj as first argument" do
181
+ sin_get('/hash').should == '<form action="/baz"> <input id="first" name="first" type="text" value="foo"/> </form>'
182
+ end
183
+
184
+ specify "#form should deal with emitted code" do
185
+ 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>'
186
+ end
187
+
188
+ specify "#form should work with :inputs, :button, and :legend options" do
189
+ 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>'
190
+ end
191
+
192
+ specify "#form should work without a block" do
193
+ sin_get('/noblock').should == '<form action="/baz"><fieldset class="inputs"><legend>123</legend><input id="first" name="first" type="text" value="foo"/></fieldset><input type="submit" value="xyz"/></form>'
194
+ end
195
+ end
@@ -0,0 +1,71 @@
1
+ require 'rubygems'
2
+ require 'sequel/no_core_ext'
3
+
4
+ DB = Sequel.sqlite
5
+ Sequel.default_timezone = :utc
6
+ DB.create_table(:artists) do
7
+ primary_key :id
8
+ String :name
9
+ end
10
+ DB.create_table(:albums) do
11
+ primary_key :id
12
+ foreign_key :artist_id, :artists
13
+ String :name
14
+ TrueClass :gold
15
+ TrueClass :platinum, :null=>false, :default=>false
16
+ Date :release_date
17
+ DateTime :created_at
18
+ Integer :copies_sold
19
+ end
20
+ DB.create_table(:album_infos) do
21
+ primary_key :id
22
+ foreign_key :album_id, :albums
23
+ String :info
24
+ end
25
+ DB.create_table(:tracks) do
26
+ primary_key :id
27
+ foreign_key :album_id, :albums
28
+ String :name
29
+ end
30
+ DB.create_table(:tags) do
31
+ primary_key :id
32
+ String :name
33
+ end
34
+ DB.create_table(:albums_tags) do
35
+ foreign_key :album_id, :albums
36
+ foreign_key :tag_id, :tags
37
+ end
38
+
39
+ a = DB[:artists].insert(:name=>'a')
40
+ d = DB[:artists].insert(:name=>'d')
41
+ b = DB[:albums].insert(:name=>'b', :artist_id=>a, :gold=>false, :release_date=>Date.new(2011, 6, 5), :created_at=>Date.new(2011, 6, 5), :copies_sold=>10)
42
+ DB[:tracks].insert(:name=>'m', :album_id=>b)
43
+ DB[:tracks].insert(:name=>'n', :album_id=>b)
44
+ c = DB[:albums].insert(:name=>'c', :artist_id=>d, :gold=>true, :platinum=>true)
45
+ DB[:tracks].insert(:name=>'o', :album_id=>c)
46
+ s = DB[:tags].insert(:name=>'s')
47
+ t = DB[:tags].insert(:name=>'t')
48
+ u = DB[:tags].insert(:name=>'u')
49
+ [[b, s], [b, t], [c, t]].each{|k, v| DB[:albums_tags].insert(k, v)}
50
+
51
+ Sequel::Model.plugin :forme
52
+ class Album < Sequel::Model
53
+ many_to_one :artist, :order=>:name
54
+ one_to_one :album_info
55
+ one_to_many :tracks
56
+ many_to_many :tags
57
+
58
+ def artist_name
59
+ artist.name if artist
60
+ end
61
+ end
62
+ class Artist < Sequel::Model
63
+ one_to_many :albums
64
+ def idname() "#{id}#{name}" end
65
+ def name2() "#{name}2" end
66
+ def name3() "#{name}3" end
67
+ end
68
+ class Track < Sequel::Model; end
69
+ class Tag < Sequel::Model; end
70
+ class AlbumInfo < Sequel::Model; end
71
+
@@ -1,79 +1,11 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
-
3
- require 'rubygems'
4
- require 'sequel'
5
-
6
- DB = Sequel.sqlite
7
- Sequel.default_timezone = :utc
8
- DB.create_table(:artists) do
9
- primary_key :id
10
- String :name
11
- end
12
- DB.create_table(:albums) do
13
- primary_key :id
14
- foreign_key :artist_id, :artists
15
- String :name
16
- TrueClass :gold
17
- TrueClass :platinum, :null=>false, :default=>false
18
- Date :release_date
19
- DateTime :created_at
20
- Integer :copies_sold
21
- end
22
- DB.create_table(:album_infos) do
23
- primary_key :id
24
- foreign_key :album_id, :albums
25
- String :info
26
- end
27
- DB.create_table(:tracks) do
28
- primary_key :id
29
- foreign_key :album_id, :albums
30
- String :name
31
- end
32
- DB.create_table(:tags) do
33
- primary_key :id
34
- String :name
35
- end
36
- DB.create_table(:albums_tags) do
37
- foreign_key :album_id, :albums
38
- foreign_key :tag_id, :tags
39
- end
40
-
41
- a = DB[:artists].insert(:name=>'a')
42
- d = DB[:artists].insert(:name=>'d')
43
- b = DB[:albums].insert(:name=>'b', :artist_id=>a, :gold=>false, :release_date=>Date.new(2011, 6, 5), :created_at=>Date.new(2011, 6, 5), :copies_sold=>10)
44
- DB[:tracks].insert(:name=>'m', :album_id=>b)
45
- DB[:tracks].insert(:name=>'n', :album_id=>b)
46
- c = DB[:albums].insert(:name=>'c', :artist_id=>d, :gold=>true, :platinum=>true)
47
- DB[:tracks].insert(:name=>'o', :album_id=>c)
48
- s = DB[:tags].insert(:name=>'s')
49
- t = DB[:tags].insert(:name=>'t')
50
- u = DB[:tags].insert(:name=>'u')
51
- [[b, s], [b, t], [c, t]].each{|k, v| DB[:albums_tags].insert(k, v)}
52
-
53
- Sequel::Model.plugin :forme
54
- class Album < Sequel::Model
55
- many_to_one :artist, :order=>:name
56
- one_to_one :album_info
57
- one_to_many :tracks
58
- many_to_many :tags
59
-
60
- def artist_name
61
- artist.name if artist
62
- end
63
- end
64
- class Artist < Sequel::Model
65
- one_to_many :albums
66
- def idname() "#{id}#{name}" end
67
- end
68
- class Track < Sequel::Model; end
69
- class Tag < Sequel::Model; end
70
- class AlbumInfo < Sequel::Model; end
2
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'sequel_helper.rb')
71
3
 
72
4
  describe "Forme Sequel::Model forms" do
73
5
  before do
74
- @ab = Album[b]
6
+ @ab = Album[1]
75
7
  @b = Forme::Form.new(@ab)
76
- @ac = Album[c]
8
+ @ac = Album[2]
77
9
  @c = Forme::Form.new(@ac)
78
10
  end
79
11
 
@@ -85,6 +17,11 @@ describe "Forme Sequel::Model forms" do
85
17
  @b.form(:class=>:foo, :method=>:get).to_s.should == '<form class="foo forme album" method="get"></form>'
86
18
  end
87
19
 
20
+ specify "should allow an array of classes" do
21
+ @b.form(:class=>[:foo, :bar]).to_s.should == '<form class="foo bar forme album" method="post"></form>'
22
+ @b.form(:class=>[:foo, [:bar, :baz]]).to_s.should == '<form class="foo bar baz forme album" method="post"></form>'
23
+ end
24
+
88
25
  specify "should use a text field for strings" do
89
26
  @b.input(:name).to_s.should == '<label>Name: <input id="album_name" name="album[name]" type="text" value="b"/></label>'
90
27
  @c.input(:name).to_s.should == '<label>Name: <input id="album_name" name="album[name]" type="text" value="c"/></label>'
@@ -138,38 +75,46 @@ describe "Forme Sequel::Model forms" do
138
75
  @c.input(:gold).to_s.should == '<label>Gold: <select id="album_gold" name="album[gold]"><option value=""></option><option selected="selected" value="t">True</option><option value="f">False</option></select></label>'
139
76
  end
140
77
 
78
+ specify "should respect :true_label and :false_label options for tri-valued boolean fields" do
79
+ @b.input(:gold, :true_label=>"Foo", :false_label=>"Bar").to_s.should == '<label>Gold: <select id="album_gold" name="album[gold]"><option value=""></option><option value="t">Foo</option><option selected="selected" value="f">Bar</option></select></label>'
80
+ end
81
+
82
+ specify "should respect :true_value and :false_value options for tri-valued boolean fields" do
83
+ @b.input(:gold, :true_value=>"Foo", :false_value=>"Bar").to_s.should == '<label>Gold: <select id="album_gold" name="album[gold]"><option value=""></option><option value="Foo">True</option><option value="Bar">False</option></select></label>'
84
+ end
85
+
141
86
  specify "should use a checkbox for dual-valued boolean fields" do
142
- @b.input(:platinum).to_s.should == '<label><input id="album_platinum_hidden" name="album[platinum]" type="hidden" value="f"/><input id="album_platinum" name="album[platinum]" type="checkbox" value="t"/> Platinum</label>'
143
- @c.input(:platinum).to_s.should == '<label><input id="album_platinum_hidden" name="album[platinum]" type="hidden" value="f"/><input checked="checked" id="album_platinum" name="album[platinum]" type="checkbox" value="t"/> Platinum</label>'
87
+ @b.input(:platinum).to_s.should == '<input id="album_platinum_hidden" name="album[platinum]" type="hidden" value="f"/><label><input id="album_platinum" name="album[platinum]" type="checkbox" value="t"/> Platinum</label>'
88
+ @c.input(:platinum).to_s.should == '<input id="album_platinum_hidden" name="album[platinum]" type="hidden" value="f"/><label><input checked="checked" id="album_platinum" name="album[platinum]" type="checkbox" value="t"/> Platinum</label>'
144
89
  end
145
90
 
146
91
  specify "should use radio buttons for boolean fields if :as=>:radio is used" do
147
- @b.input(:platinum, :as=>:radio).to_s.should == 'Platinum: <label><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label>'
148
- @c.input(:platinum, :as=>:radio).to_s.should == 'Platinum: <label><input checked="checked" id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label><input id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label>'
92
+ @b.input(:platinum, :as=>:radio).to_s.should == '<span class="label">Platinum</span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label class="option"><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label>'
93
+ @c.input(:platinum, :as=>:radio).to_s.should == '<span class="label">Platinum</span><label class="option"><input checked="checked" id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label class="option"><input id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label>'
149
94
  end
150
95
 
151
96
  specify "should wrap both inputs if :as=>:radio is used" do
152
97
  @b = Forme::Form.new(@ab, :wrapper=>:li)
153
- @b.input(:platinum, :as=>:radio).to_s.should == '<li class="boolean">Platinum: <label><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label></li>'
154
- @b.input(:platinum, :as=>:radio, :wrapper=>:div, :tag_wrapper=>:span).to_s.should == '<div class="boolean">Platinum: <span><label><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label></span><span><label><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label></span></div>'
98
+ @b.input(:platinum, :as=>:radio).to_s.should == '<li class="boolean"><span class="label">Platinum</span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label class="option"><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label></li>'
99
+ @b.input(:platinum, :as=>:radio, :wrapper=>:div, :tag_wrapper=>:span).to_s.should == '<div class="boolean"><span class="label">Platinum</span><span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label></span><span><label class="option"><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label></span></div>'
155
100
  end
156
101
 
157
102
  specify "should handle errors on radio buttons for boolean fields if :as=>:radio is used" do
158
103
  @ab.errors.add(:platinum, 'foo')
159
- @b.input(:platinum, :as=>:radio).to_s.should == 'Platinum: <label><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label><input checked="checked" class="error" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label><span class="error_message">foo</span>'
104
+ @b.input(:platinum, :as=>:radio).to_s.should == '<span class="label">Platinum</span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label class="option"><input checked="checked" class="error" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label><span class="error_message">foo</span>'
160
105
  end
161
106
 
162
107
  specify "should handle Raw :label options if :as=>:radio is used" do
163
- @b.input(:platinum, :as=>:radio, :label=>'Foo:<br />'.extend(Forme::Raw)).to_s.should == 'Foo:<br /><label><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label>'
164
- @b.input(:platinum, :as=>:radio, :label=>'Foo:<br />').to_s.should == 'Foo:&lt;br /&gt;: <label><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label>'
108
+ @b.input(:platinum, :as=>:radio, :label=>'Foo:<br />'.extend(Forme::Raw)).to_s.should == '<span class="label">Foo:<br /></span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label class="option"><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label>'
109
+ @b.input(:platinum, :as=>:radio, :label=>'Foo:<br />').to_s.should == '<span class="label">Foo:&lt;br /&gt;</span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Yes</label><label class="option"><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> No</label>'
165
110
  end
166
111
 
167
112
  specify "should respect :true_label and :false_label options for boolean fields if :as=>:radio is used" do
168
- @b.input(:platinum, :as=>:radio, :true_label=>"Foo", :false_label=>"Bar").to_s.should == 'Platinum: <label><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Foo</label><label><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> Bar</label>'
113
+ @b.input(:platinum, :as=>:radio, :true_label=>"Foo", :false_label=>"Bar").to_s.should == '<span class="label">Platinum</span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="t"/> Foo</label><label class="option"><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="f"/> Bar</label>'
169
114
  end
170
115
 
171
116
  specify "should respect :true_value and :false_value options for boolean fields if :as=>:radio is used" do
172
- @b.input(:platinum, :as=>:radio, :true_value=>"Foo", :false_value=>"Bar").to_s.should == 'Platinum: <label><input id="album_platinum_yes" name="album[platinum]" type="radio" value="Foo"/> Yes</label><label><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="Bar"/> No</label>'
117
+ @b.input(:platinum, :as=>:radio, :true_value=>"Foo", :false_value=>"Bar").to_s.should == '<span class="label">Platinum</span><label class="option"><input id="album_platinum_yes" name="album[platinum]" type="radio" value="Foo"/> Yes</label><label class="option"><input checked="checked" id="album_platinum_no" name="album[platinum]" type="radio" value="Bar"/> No</label>'
173
118
  end
174
119
 
175
120
  specify "should use a select box for many_to_one associations" do
@@ -186,23 +131,23 @@ describe "Forme Sequel::Model forms" do
186
131
  end
187
132
 
188
133
  specify "should use a set of radio buttons for many_to_one associations with :as=>:radio option" do
189
- @b.input(:artist, :as=>:radio).to_s.should == 'Artist: <label><input checked="checked" name="album[artist_id]" type="radio" value="1"/> a</label><label><input name="album[artist_id]" type="radio" value="2"/> d</label>'
190
- @c.input(:artist, :as=>:radio).to_s.should == 'Artist: <label><input name="album[artist_id]" type="radio" value="1"/> a</label><label><input checked="checked" name="album[artist_id]" type="radio" value="2"/> d</label>'
134
+ @b.input(:artist, :as=>:radio).to_s.should == '<span class="label">Artist</span><label class="option"><input checked="checked" id="album_artist_id_1" name="album[artist_id]" type="radio" value="1"/> a</label><label class="option"><input id="album_artist_id_2" name="album[artist_id]" type="radio" value="2"/> d</label>'
135
+ @c.input(:artist, :as=>:radio).to_s.should == '<span class="label">Artist</span><label class="option"><input id="album_artist_id_1" name="album[artist_id]" type="radio" value="1"/> a</label><label class="option"><input checked="checked" id="album_artist_id_2" name="album[artist_id]" type="radio" value="2"/> d</label>'
191
136
  end
192
137
 
193
138
  specify "should handle Raw label for many_to_one associations with :as=>:radio option" do
194
- @b.input(:artist, :as=>:radio, :label=>'Foo:<br />'.extend(Forme::Raw)).to_s.should == 'Foo:<br /><label><input checked="checked" name="album[artist_id]" type="radio" value="1"/> a</label><label><input name="album[artist_id]" type="radio" value="2"/> d</label>'
195
- @b.input(:artist, :as=>:radio, :label=>'Foo<br />').to_s.should == 'Foo&lt;br /&gt;: <label><input checked="checked" name="album[artist_id]" type="radio" value="1"/> a</label><label><input name="album[artist_id]" type="radio" value="2"/> d</label>'
139
+ @b.input(:artist, :as=>:radio, :label=>'Foo:<br />'.extend(Forme::Raw)).to_s.should == '<span class="label">Foo:<br /></span><label class="option"><input checked="checked" id="album_artist_id_1" name="album[artist_id]" type="radio" value="1"/> a</label><label class="option"><input id="album_artist_id_2" name="album[artist_id]" type="radio" value="2"/> d</label>'
140
+ @b.input(:artist, :as=>:radio, :label=>'Foo<br />').to_s.should == '<span class="label">Foo&lt;br /&gt;</span><label class="option"><input checked="checked" id="album_artist_id_1" name="album[artist_id]" type="radio" value="1"/> a</label><label class="option"><input id="album_artist_id_2" name="album[artist_id]" type="radio" value="2"/> d</label>'
196
141
  end
197
142
 
198
143
  specify "should correctly use the forms wrapper for wrapping radio buttons for many_to_one associations with :as=>:radio option" do
199
144
  @b = Forme::Form.new(@ab, :wrapper=>:li)
200
- @b.input(:artist, :as=>:radio).to_s.should == '<li class="many_to_one">Artist: <label><input checked="checked" name="album[artist_id]" type="radio" value="1"/> a</label><label><input name="album[artist_id]" type="radio" value="2"/> d</label></li>'
145
+ @b.input(:artist, :as=>:radio).to_s.should == '<li class="many_to_one"><span class="label">Artist</span><label class="option"><input checked="checked" id="album_artist_id_1" name="album[artist_id]" type="radio" value="1"/> a</label><label class="option"><input id="album_artist_id_2" name="album[artist_id]" type="radio" value="2"/> d</label></li>'
201
146
  end
202
147
 
203
148
  specify "should support custom wrappers for many_to_one associations with :as=>:radio via :tag_wrapper option" do
204
149
  @b = Forme::Form.new(@ab, :wrapper=>:li)
205
- @b.input(:artist, :as=>:radio, :wrapper=>proc{|t, i| i.tag(:div, {}, [t])}, :tag_wrapper=>proc{|t, i| i.tag(:span, {}, [t])}).to_s.should == '<div>Artist: <span><label><input checked="checked" name="album[artist_id]" type="radio" value="1"/> a</label></span><span><label><input name="album[artist_id]" type="radio" value="2"/> d</label></span></div>'
150
+ @b.input(:artist, :as=>:radio, :wrapper=>proc{|t, i| i.tag(:div, {}, [t])}, :tag_wrapper=>proc{|t, i| i.tag(:span, {}, [t])}).to_s.should == '<div><span class="label">Artist</span><span><label class="option"><input checked="checked" id="album_artist_id_1" name="album[artist_id]" type="radio" value="1"/> a</label></span><span><label class="option"><input id="album_artist_id_2" name="album[artist_id]" type="radio" value="2"/> d</label></span></div>'
206
151
  end
207
152
 
208
153
  specify "should respect an :options entry" do
@@ -254,28 +199,28 @@ describe "Forme Sequel::Model forms" do
254
199
  end
255
200
 
256
201
  specify "should use multiple checkboxes for one_to_many associations if :as=>:checkbox" do
257
- @b.input(:tracks, :as=>:checkbox).to_s.should == 'Tracks: <label><input checked="checked" name="album[track_pks][]" type="checkbox" value="1"/> m</label><label><input checked="checked" name="album[track_pks][]" type="checkbox" value="2"/> n</label><label><input name="album[track_pks][]" type="checkbox" value="3"/> o</label>'
258
- @c.input(:tracks, :as=>:checkbox).to_s.should == 'Tracks: <label><input name="album[track_pks][]" type="checkbox" value="1"/> m</label><label><input name="album[track_pks][]" type="checkbox" value="2"/> n</label><label><input checked="checked" name="album[track_pks][]" type="checkbox" value="3"/> o</label>'
202
+ @b.input(:tracks, :as=>:checkbox).to_s.should == '<span class="label">Tracks</span><label class="option"><input checked="checked" id="album_track_pks_1" name="album[track_pks][]" type="checkbox" value="1"/> m</label><label class="option"><input checked="checked" id="album_track_pks_2" name="album[track_pks][]" type="checkbox" value="2"/> n</label><label class="option"><input id="album_track_pks_3" name="album[track_pks][]" type="checkbox" value="3"/> o</label>'
203
+ @c.input(:tracks, :as=>:checkbox).to_s.should == '<span class="label">Tracks</span><label class="option"><input id="album_track_pks_1" name="album[track_pks][]" type="checkbox" value="1"/> m</label><label class="option"><input id="album_track_pks_2" name="album[track_pks][]" type="checkbox" value="2"/> n</label><label class="option"><input checked="checked" id="album_track_pks_3" name="album[track_pks][]" type="checkbox" value="3"/> o</label>'
259
204
  end
260
205
 
261
206
  specify "should use multiple checkboxes for many_to_many associations if :as=>:checkbox" do
262
- @b.input(:tags, :as=>:checkbox).to_s.should == 'Tags: <label><input checked="checked" name="album[tag_pks][]" type="checkbox" value="1"/> s</label><label><input checked="checked" name="album[tag_pks][]" type="checkbox" value="2"/> t</label><label><input name="album[tag_pks][]" type="checkbox" value="3"/> u</label>'
263
- @c.input(:tags, :as=>:checkbox).to_s.should == 'Tags: <label><input name="album[tag_pks][]" type="checkbox" value="1"/> s</label><label><input checked="checked" name="album[tag_pks][]" type="checkbox" value="2"/> t</label><label><input name="album[tag_pks][]" type="checkbox" value="3"/> u</label>'
207
+ @b.input(:tags, :as=>:checkbox).to_s.should == '<span class="label">Tags</span><label class="option"><input checked="checked" id="album_tag_pks_1" name="album[tag_pks][]" type="checkbox" value="1"/> s</label><label class="option"><input checked="checked" id="album_tag_pks_2" name="album[tag_pks][]" type="checkbox" value="2"/> t</label><label class="option"><input id="album_tag_pks_3" name="album[tag_pks][]" type="checkbox" value="3"/> u</label>'
208
+ @c.input(:tags, :as=>:checkbox).to_s.should == '<span class="label">Tags</span><label class="option"><input id="album_tag_pks_1" name="album[tag_pks][]" type="checkbox" value="1"/> s</label><label class="option"><input checked="checked" id="album_tag_pks_2" name="album[tag_pks][]" type="checkbox" value="2"/> t</label><label class="option"><input id="album_tag_pks_3" name="album[tag_pks][]" type="checkbox" value="3"/> u</label>'
264
209
  end
265
210
 
266
211
  specify "should handle Raw label for associations with :as=>:checkbox" do
267
- @b.input(:tracks, :as=>:checkbox, :label=>'Foo<br />:'.extend(Forme::Raw)).to_s.should == 'Foo<br />:<label><input checked="checked" name="album[track_pks][]" type="checkbox" value="1"/> m</label><label><input checked="checked" name="album[track_pks][]" type="checkbox" value="2"/> n</label><label><input name="album[track_pks][]" type="checkbox" value="3"/> o</label>'
268
- @b.input(:tracks, :as=>:checkbox, :label=>'Foo<br />').to_s.should == 'Foo&lt;br /&gt;: <label><input checked="checked" name="album[track_pks][]" type="checkbox" value="1"/> m</label><label><input checked="checked" name="album[track_pks][]" type="checkbox" value="2"/> n</label><label><input name="album[track_pks][]" type="checkbox" value="3"/> o</label>'
212
+ @b.input(:tracks, :as=>:checkbox, :label=>'Foo<br />:'.extend(Forme::Raw)).to_s.should == '<span class="label">Foo<br />:</span><label class="option"><input checked="checked" id="album_track_pks_1" name="album[track_pks][]" type="checkbox" value="1"/> m</label><label class="option"><input checked="checked" id="album_track_pks_2" name="album[track_pks][]" type="checkbox" value="2"/> n</label><label class="option"><input id="album_track_pks_3" name="album[track_pks][]" type="checkbox" value="3"/> o</label>'
213
+ @b.input(:tracks, :as=>:checkbox, :label=>'Foo<br />').to_s.should == '<span class="label">Foo&lt;br /&gt;</span><label class="option"><input checked="checked" id="album_track_pks_1" name="album[track_pks][]" type="checkbox" value="1"/> m</label><label class="option"><input checked="checked" id="album_track_pks_2" name="album[track_pks][]" type="checkbox" value="2"/> n</label><label class="option"><input id="album_track_pks_3" name="album[track_pks][]" type="checkbox" value="3"/> o</label>'
269
214
  end
270
215
 
271
216
  specify "should correctly use the forms wrapper for wrapping radio buttons for one_to_many associations with :as=>:checkbox option" do
272
217
  @b = Forme::Form.new(@ab, :wrapper=>:li)
273
- @b.input(:tracks, :as=>:checkbox).to_s.should == '<li class="one_to_many">Tracks: <label><input checked="checked" name="album[track_pks][]" type="checkbox" value="1"/> m</label><label><input checked="checked" name="album[track_pks][]" type="checkbox" value="2"/> n</label><label><input name="album[track_pks][]" type="checkbox" value="3"/> o</label></li>'
218
+ @b.input(:tracks, :as=>:checkbox).to_s.should == '<li class="one_to_many"><span class="label">Tracks</span><label class="option"><input checked="checked" id="album_track_pks_1" name="album[track_pks][]" type="checkbox" value="1"/> m</label><label class="option"><input checked="checked" id="album_track_pks_2" name="album[track_pks][]" type="checkbox" value="2"/> n</label><label class="option"><input id="album_track_pks_3" name="album[track_pks][]" type="checkbox" value="3"/> o</label></li>'
274
219
  end
275
220
 
276
221
  specify "should support custom wrappers for one_to_many associations with :as=>:checkbox via :tag_wrapper option" do
277
222
  @b = Forme::Form.new(@ab, :wrapper=>:li)
278
- @b.input(:tracks, :as=>:checkbox, :wrapper=>proc{|t, i| i.tag(:div, i.opts[:wrapper_attr], [t])}, :tag_wrapper=>proc{|t, i| i.tag(:span, {}, [t])}).to_s.should == '<div class="one_to_many">Tracks: <span><label><input checked="checked" name="album[track_pks][]" type="checkbox" value="1"/> m</label></span><span><label><input checked="checked" name="album[track_pks][]" type="checkbox" value="2"/> n</label></span><span><label><input name="album[track_pks][]" type="checkbox" value="3"/> o</label></span></div>'
223
+ @b.input(:tracks, :as=>:checkbox, :wrapper=>proc{|t, i| i.tag(:div, i.opts[:wrapper_attr], [t])}, :tag_wrapper=>proc{|t, i| i.tag(:span, {}, [t])}).to_s.should == '<div class="one_to_many"><span class="label">Tracks</span><span><label class="option"><input checked="checked" id="album_track_pks_1" name="album[track_pks][]" type="checkbox" value="1"/> m</label></span><span><label class="option"><input checked="checked" id="album_track_pks_2" name="album[track_pks][]" type="checkbox" value="2"/> n</label></span><span><label class="option"><input id="album_track_pks_3" name="album[track_pks][]" type="checkbox" value="3"/> o</label></span></div>'
279
224
  end
280
225
 
281
226
  specify "should use a text field methods not backed by columns" do