forme 1.3.0 → 1.4.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.
data/lib/forme/erb.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  require 'forme'
2
4
 
3
5
  module Forme
@@ -30,7 +32,7 @@ module Forme
30
32
  # Set the template output object when initializing.
31
33
  def initialize(*)
32
34
  super
33
- @output = @opts[:output] ? @opts[:output] : ''
35
+ @output = @opts[:output] ? @opts[:output] : String.new
34
36
  end
35
37
 
36
38
  # Serialize the tag and inject it into the output.
@@ -76,7 +78,7 @@ module Forme
76
78
  end
77
79
  end
78
80
 
79
- def capture(block='') # :nodoc:
81
+ def capture(block=String.new) # :nodoc:
80
82
  buf_was, @output = @output, block.is_a?(Proc) ? (eval("@_out_buf", block.binding) || @output) : block
81
83
  yield
82
84
  ret = @output
data/lib/forme/form.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Forme
2
4
  # The +Form+ class is the main entry point to the library.
3
5
  # Using the +form+, +input+, +tag+, and +inputs+ methods, one can easily build
data/lib/forme/input.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Forme
2
4
  # High level abstract tag form, transformed by formatters into the lower
3
5
  # level +Tag+ form (or an array of them).
data/lib/forme/rails.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  require 'forme'
2
4
 
3
5
  class ActiveSupport::SafeBuffer
data/lib/forme/raw.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Forme
2
4
  # Empty module for marking objects as "raw", where they will no longer
3
5
  # html escaped by the default serializer.
data/lib/forme/sinatra.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  require 'forme/erb'
2
4
 
3
5
  module Forme
data/lib/forme/tag.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Forme
2
4
  # Low level abstract tag form, where each instance represents a
3
5
  # html tag with attributes and children.
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Forme
2
4
  # Default error handler used by the library, using an "error" class
3
5
  # for the input field and a span tag with an "error_message" class
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Forme
2
4
  # The default formatter used by the library. Any custom formatters should
3
5
  # probably inherit from this formatter unless they have very special needs.
@@ -60,9 +62,14 @@ module Forme
60
62
  @opts = input.opts
61
63
  normalize_options
62
64
 
63
- tag = convert_to_tag(input.type)
64
- tag = wrap_tag_with_label(tag) if input.opts[:label]
65
- tag = wrap_tag_with_error(tag) if input.opts[:error]
65
+ tag = if html = input.opts[:html]
66
+ html = html.call(input) if html.respond_to?(:call)
67
+ form.raw(html)
68
+ else
69
+ convert_to_tag(input.type)
70
+ end
71
+ tag = wrap_tag_with_label(tag) if @opts[:label]
72
+ tag = wrap_tag_with_error(tag) if @opts[:error]
66
73
  tag = wrap(:helper, tag) if input.opts[:help]
67
74
  wrap_tag(tag)
68
75
  end
@@ -220,14 +227,17 @@ module Forme
220
227
  if @opts[:label]
221
228
  @opts[:set_label] = @opts.delete(:label)
222
229
  end
223
- tag_wrapper = @opts.delete(:tag_wrapper) || :default
224
- wrapper = Forme.transformer(:wrapper, @opts, @input.form_opts)
230
+
231
+ tag_wrapper = Forme.transformer(:tag_wrapper, @opts.delete(:tag_wrapper), @input.form_opts) || :default
232
+ wrapper = @opts.fetch(:wrapper){@opts[:wrapper] = @input.form_opts[:set_wrapper] || @input.form_opts[:wrapper]}
233
+ wrapper = Forme.transformer(:wrapper, wrapper)
225
234
 
226
235
  tags = process_select_optgroups(:_format_set_optgroup) do |label, value, sel, attrs|
227
236
  value ||= label
228
237
  r_opts = attrs.merge(tag_attrs).merge(:label=>label||value, :label_attr=>{:class=>:option}, :wrapper=>tag_wrapper)
229
238
  r_opts[:value] ||= value if value
230
239
  r_opts[:checked] ||= :checked if sel
240
+ r_opts[:formatter] = @opts[:formatter] if @opts[:formatter]
231
241
 
232
242
  if name
233
243
  r_opts[:name] ||= name
@@ -244,17 +254,26 @@ module Forme
244
254
  end
245
255
 
246
256
  if @opts[:set_error]
247
- if (last_input = tags.last) && last_input.is_a?(Input)
248
- last_input.opts[:error] = @opts[:set_error]
249
- else
250
- tags << form._tag(:span, {:class=>'error_message'}, [@opts[:set_error]])
251
- end
257
+ _add_set_error(tags)
252
258
  end
253
- tags.unshift(form._tag(:span, {:class=>:label}, @opts[:set_label])) if @opts[:set_label]
254
- wrapper.call(tags, form._input(type, opts)) if wrapper
259
+
260
+ tags.unshift(set_label) if @opts[:set_label]
261
+
255
262
  tags
256
263
  end
257
264
 
265
+ def set_label
266
+ form._tag(:span, {:class=>:label}, @opts[:set_label])
267
+ end
268
+
269
+ def _add_set_error(tags)
270
+ if (last_input = tags.last) && last_input.is_a?(Input)
271
+ last_input.opts[:error] = @opts[:set_error]
272
+ else
273
+ tags << form._tag(:span, {:class=>'error_message'}, [@opts[:set_error]])
274
+ end
275
+ end
276
+
258
277
  # Formats a textarea. Respects the following options:
259
278
  # :value :: Sets value as the child of the textarea.
260
279
  def format_textarea
@@ -315,7 +334,7 @@ module Forme
315
334
  unless @attr[:id] || @attr['id']
316
335
  id = namespaced_id(key)
317
336
  if suffix = @opts[:key_id]
318
- id << '_' << suffix.to_s
337
+ id += "_#{suffix}"
319
338
  end
320
339
  @attr[:id] = id
321
340
  end
@@ -503,6 +522,11 @@ module Forme
503
522
  tag(:span, {}, children)
504
523
  end
505
524
 
525
+ # Ignore submit buttons
526
+ def format_submit
527
+ ''
528
+ end
529
+
506
530
  # Use a span with text instead of a text area.
507
531
  def format_textarea
508
532
  tag(:span, {}, @attr[:value])
@@ -1,5 +1,7 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Forme
2
- # Default helper used by the library, using a spam with "helper" class
4
+ # Default helper used by the library, using a span with "helper" class
3
5
  #
4
6
  # Registered as :default.
5
7
  class Helper
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Forme
2
4
  # Default inputs_wrapper used by the library, uses a <fieldset>.
3
5
  #
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Forme
2
4
  # Default labeler used by the library, using implicit labels (where the
3
5
  # label tag encloses the other tag).
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Forme
2
4
  # Default serializer class used by the library. Any other serializer
3
5
  # classes that want to produce html should probably subclass this class.
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Forme
2
4
  # Default wrapper doesn't wrap input in any tag
3
5
  class Wrapper
@@ -25,7 +27,7 @@ module Forme
25
27
  Forme.register_transformer(:wrapper, x, new(x))
26
28
  end
27
29
  end
28
-
30
+
29
31
  class Wrapper::TableRow < Wrapper
30
32
  # Wrap the input in tr and td tags.
31
33
  def call(tag, input)
data/lib/forme/version.rb CHANGED
@@ -1,6 +1,8 @@
1
+ # frozen-string-literal: true
2
+
1
3
  module Forme
2
4
  # Version constant, use <tt>Forme.version</tt> instead.
3
- VERSION = '1.3.0'.freeze
5
+ VERSION = '1.4.0'.freeze
4
6
 
5
7
  # Returns the version as a frozen string (e.g. '0.1.0')
6
8
  def self.version
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  require 'forme/erb'
2
4
 
3
5
  class Roda
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+
1
3
  require 'forme'
2
4
  require 'thread'
3
5
 
@@ -198,7 +200,7 @@ module Sequel # :nodoc:
198
200
  # is required.
199
201
  def handle_label(f)
200
202
  opts[:label] = humanize(field) unless opts.has_key?(:label)
201
- opts[:label] = [opts[:label], form._tag(:abbr, {:title=>'required'}, '*')] if opts[:required]
203
+ opts[:label] = [opts[:label], form._tag(:abbr, {:title=>'required'}, '*')] if opts[:label] && opts[:required]
202
204
  end
203
205
 
204
206
  # Update the attributes and options for any recognized validations
@@ -301,7 +303,9 @@ module Sequel # :nodoc:
301
303
  opts[:array] = true unless opts.has_key?(:array)
302
304
  opts[:key] = field
303
305
  end
304
- opts[:value] = obj.send(ref[:name]).map{|x| x.send(pk)} unless opts.has_key?(:value)
306
+ unless opts.has_key?(:value)
307
+ opts[:value] = obj.respond_to?(field) ? obj.send(field) : obj.send(ref[:name]).map{|x| x.send(pk)}
308
+ end
305
309
  opts[:options] = association_select_options(ref) unless opts.has_key?(:options)
306
310
  handle_label(label)
307
311
  if opts.delete(:as) == :checkbox
@@ -0,0 +1,358 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'sequel_helper.rb')
3
+ require 'forme/bs3'
4
+
5
+ describe "Forme Bootstrap3 (BS3) forms" do
6
+ def sel(opts, s)
7
+ opts.map{|o| "<option #{'selected="selected" ' if o == s}value=\"#{o}\">#{sprintf("%02i", o)}</option>"}.join
8
+ end
9
+
10
+ before do
11
+ @f = Forme::Form.new(:config=>:bs3)
12
+ @ab = Album[1]
13
+ @b = Forme::Form.new(@ab, :config=>:bs3)
14
+ @ac = Album[2]
15
+ @c = Forme::Form.new(@ac, :config=>:bs3)
16
+ end
17
+
18
+ describe 'input[:text]' do
19
+ it "should create a simple input[:text] tag" do
20
+ @f.input(:text).to_s.must_equal '<div class="form-group"><input class="form-control" type="text"/></div>'
21
+ end
22
+
23
+ it "should create an input[:text] tag with a label when ':label => Name'" do
24
+ @f.input(:text, :label=>"Name").to_s.must_equal '<div class="form-group"><label>Name</label> <input class="form-control" type="text"/></div>'
25
+ end
26
+
27
+ it "should create an input[:text] tag with a label when ':class => bar'" do
28
+ @f.input(:text, :label=>"Name", :class=>'bar').to_s.must_equal '<div class="form-group"><label>Name</label> <input class="form-control bar" type="text"/></div>'
29
+ end
30
+
31
+ it "should create an input[:text] tag with a label when ':id => bar'" do
32
+ @f.input(:text, :label=>"Name", :id=>'bar').to_s.must_equal '<div class="form-group"><label for="bar">Name</label> <input class="form-control" id="bar" type="text"/></div>'
33
+ end
34
+
35
+ it "should create an input[:text] tag with a label when ':id => bar' with an error" do
36
+ @f.input(:text, :label=>"Name", :id=>'bar', :class=>'foo', :error=>'input-text-error').to_s.must_equal '<div class="form-group has-error"><label for="bar">Name</label> <input class="form-control foo" id="bar" type="text"/><span class="help-block with-errors">input-text-error</span></div>'
37
+ end
38
+
39
+ describe 'from a Sequel model' do
40
+ it "should create a correct input[:text] tag from Sequel model" do
41
+ @c.input(:name).to_s.must_equal '<div class="form-group string"><label for="album_name">Name</label> <input class="form-control" id="album_name" name="album[name]" type="text" value="c"/></div>'
42
+ end
43
+
44
+ it "should correctly handle an input[:text] tag from Sequel model with error" do
45
+ @ac.errors.add(:name, 'name not valid')
46
+ @c.input(:name).to_s.must_equal '<div class="form-group has-error string"><label for="album_name">Name</label> <input class="form-control" id="album_name" name="album[name]" type="text" value="c"/><span class="help-block with-errors">name not valid</span></div>'
47
+ end
48
+ end
49
+ end
50
+
51
+ describe 'input[:password]' do
52
+ it "should create a simple input[:password] tag" do
53
+ @f.input(:password).to_s.must_equal '<div class="form-group"><input class="form-control" type="password"/></div>'
54
+ end
55
+
56
+ it "should create an input[:password] tag with a label when ':label => Name'" do
57
+ @f.input(:password, :label=>"Name").to_s.must_equal '<div class="form-group"><label>Name</label> <input class="form-control" type="password"/></div>'
58
+ end
59
+
60
+ it "should create an input[:password] tag with a label when ':class => bar'" do
61
+ @f.input(:password, :label=>"Name", :class=>'bar').to_s.must_equal '<div class="form-group"><label>Name</label> <input class="form-control bar" type="password"/></div>'
62
+ end
63
+
64
+ it "should create an input[:password] tag with a label when ':id => bar'" do
65
+ @f.input(:password, :label=>"Name", :id=>'bar').to_s.must_equal '<div class="form-group"><label for="bar">Name</label> <input class="form-control" id="bar" type="password"/></div>'
66
+ end
67
+
68
+ it "should create an input[:password] tag with a label when ':id => bar' with an error" do
69
+ @f.input(:password, :label=>"Name", :id=>'bar', :class=>'foo', :error=>'input-password-error').to_s.must_equal '<div class="form-group has-error"><label for="bar">Name</label> <input class="form-control foo" id="bar" type="password"/><span class="help-block with-errors">input-password-error</span></div>'
70
+ end
71
+ end
72
+
73
+ describe 'input[:email]' do
74
+ it "should create a simple input[:email] tag" do
75
+ @f.input(:email).to_s.must_equal '<div class="form-group"><input class="form-control" type="email"/></div>'
76
+ end
77
+
78
+ it "should create an input[:email] tag with a label when ':label => Name'" do
79
+ @f.input(:email, :label=>"Name").to_s.must_equal '<div class="form-group"><label>Name</label> <input class="form-control" type="email"/></div>'
80
+ end
81
+
82
+ it "should create an input[:email] tag with a label when ':class => bar'" do
83
+ @f.input(:email, :label=>"Name", :class=>'bar').to_s.must_equal '<div class="form-group"><label>Name</label> <input class="form-control bar" type="email"/></div>'
84
+ end
85
+
86
+ it "should create an input[:email] tag with a label when ':id => bar'" do
87
+ @f.input(:email, :label=>"Name", :id=>'bar').to_s.must_equal '<div class="form-group"><label for="bar">Name</label> <input class="form-control" id="bar" type="email"/></div>'
88
+ end
89
+
90
+ it "should create an input[:email] tag with a label when ':id => bar' with an error" do
91
+ @f.input(:email, :label=>"Name", :id=>'bar', :class=>'foo', :error=>'input-email-error').to_s.must_equal '<div class="form-group has-error"><label for="bar">Name</label> <input class="form-control foo" id="bar" type="email"/><span class="help-block with-errors">input-email-error</span></div>'
92
+ end
93
+ end
94
+
95
+ describe 'input[:file]' do
96
+ it "should create a simple input[:file] tag" do
97
+ @f.input(:file).to_s.must_equal '<div class="form-group"><input type="file"/></div>'
98
+ end
99
+
100
+ it "should create an input[:file] tag with a label when ':label => Name'" do
101
+ @f.input(:file, :label=>"Name").to_s.must_equal '<div class="form-group"><label>Name</label> <input type="file"/></div>'
102
+ end
103
+
104
+ it "should create an input[:file] tag with a label when ':class => bar'" do
105
+ @f.input(:file, :label=>"Name", :class=>'bar').to_s.must_equal '<div class="form-group"><label>Name</label> <input class="bar" type="file"/></div>'
106
+ end
107
+
108
+ it "should create an input[:file] tag with a label when ':id => bar'" do
109
+ @f.input(:file, :label=>"Name", :id=>'bar').to_s.must_equal '<div class="form-group"><label for="bar">Name</label> <input id="bar" type="file"/></div>'
110
+ end
111
+
112
+ it "should create an input[:file] tag with a label when ':id => bar' with an error" do
113
+ @f.input(:file, :label=>"Name", :id=>'bar', :class=>'foo', :error=>'input-file-error').to_s.must_equal '<div class="form-group has-error"><label for="bar">Name</label> <input class="foo" id="bar" type="file"/><span class="help-block with-errors">input-file-error</span></div>'
114
+ end
115
+ end
116
+
117
+ describe 'input[:submit]' do
118
+ it "should create a simple input[:submit] tag" do
119
+ @f.input(:submit).to_s.must_equal '<input class="btn btn-default" type="submit"/>'
120
+ end
121
+
122
+ it "should create an input[:submit] tag with the correct value" do
123
+ @f.input(:submit, :value=>'Save').to_s.must_equal '<input class="btn btn-default" type="submit" value="Save"/>'
124
+ end
125
+
126
+ it "should create an input[:submit] tag with the correct class" do
127
+ @f.input(:submit, :value=>'Save', :class=>'btn-primary').to_s.must_equal '<input class="btn btn-primary" type="submit" value="Save"/>'
128
+ end
129
+
130
+ it "should create an input[:submit] tag with the correct id" do
131
+ @f.input(:submit, :value=>'Save', :id=>'foo').to_s.must_equal '<input class="btn btn-default" id="foo" type="submit" value="Save"/>'
132
+ end
133
+
134
+ it "should create an input[:submit] tag without error message " do
135
+ @f.input(:submit, :value=>'Save', :id=>'foo', :error=>'error-message').to_s.must_equal '<input class="btn btn-default" id="foo" type="submit" value="Save"/>'
136
+ end
137
+ end
138
+
139
+ describe 'input[:reset]' do
140
+ it "should create a simple input[:reset] tag" do
141
+ @f.input(:reset).to_s.must_equal '<input class="btn btn-default" type="reset"/>'
142
+ end
143
+
144
+ it "should create an input[:reset] tag with the correct value" do
145
+ @f.input(:reset, :value=>'Save').to_s.must_equal '<input class="btn btn-default" type="reset" value="Save"/>'
146
+ end
147
+
148
+ it "should create an input[:reset] tag with the correct class" do
149
+ @f.input(:reset, :value=>'Save', :class=>'btn-primary').to_s.must_equal '<input class="btn btn-primary" type="reset" value="Save"/>'
150
+ end
151
+
152
+ it "should create an input[:reset] tag with the correct id" do
153
+ @f.input(:reset, :value=>'Save', :id=>'foo').to_s.must_equal '<input class="btn btn-default" id="foo" type="reset" value="Save"/>'
154
+ end
155
+
156
+ it "should create an input[:reset] tag without error message " do
157
+ @f.input(:reset, :value=>'Save', :id=>'foo', :error=>'error-message').to_s.must_equal '<input class="btn btn-default" id="foo" type="reset" value="Save"/>'
158
+ end
159
+ end
160
+
161
+ describe 'textarea' do
162
+ it "should create a simple :textarea tag" do
163
+ @f.input(:textarea).to_s.must_equal '<div class="form-group"><textarea class="form-control"></textarea></div>'
164
+ end
165
+
166
+ it "should create an :textarea tag with the correct value" do
167
+ @f.input(:textarea, :value=>'Bio').to_s.must_equal '<div class="form-group"><textarea class="form-control">Bio</textarea></div>'
168
+ end
169
+
170
+ it "should create an :textarea tag with the correct class" do
171
+ @f.input(:textarea, :class=>'foo').to_s.must_equal '<div class="form-group"><textarea class="form-control foo"></textarea></div>'
172
+ end
173
+
174
+ it "should create an :textarea tag with the correct id" do
175
+ @f.input(:textarea, :id=>'bar').to_s.must_equal '<div class="form-group"><textarea class="form-control" id="bar"></textarea></div>'
176
+ end
177
+
178
+ it "should create a textarea tag without a .has-error and error message span when ':skip_error => true'" do
179
+ @f.input(:textarea, :skip_error=>true).to_s.must_equal '<div class="form-group"><textarea class="form-control"></textarea></div>'
180
+ end
181
+
182
+ it "should create a textarea tag with .has-error and error message when ':error => is-a-string'" do
183
+ @f.input(:textarea, :error=>'input-textarea-error').to_s.must_equal '<div class="form-group has-error"><textarea class="form-control"></textarea><span class="help-block with-errors">input-textarea-error</span></div>'
184
+ end
185
+
186
+ describe 'from a Sequel model' do
187
+ it "should create a correct input[:text] tag from Sequel model" do
188
+ @c.input(:name, :as=>:textarea).to_s.must_equal '<div class="form-group string"><label for="album_name">Name</label> <textarea class="form-control" id="album_name" name="album[name]">c</textarea></div>'
189
+ end
190
+
191
+ it "should correctly handle an input[:text] tag from Sequel model with error" do
192
+ @ac.errors.add(:name, 'name not valid')
193
+ @c.input(:name, :as=>:textarea).to_s.must_equal '<div class="form-group has-error string"><label for="album_name">Name</label> <textarea class="form-control" id="album_name" name="album[name]">c</textarea><span class="help-block with-errors">name not valid</span></div>'
194
+ end
195
+ end
196
+ end
197
+
198
+ describe 'select' do
199
+ it "should create a simple :select tag" do
200
+ @f.input(:select).to_s.must_equal '<div class="form-group"><select class="form-control"></select></div>'
201
+ end
202
+
203
+ it "should create a simple :select tag with options" do
204
+ @f.input(:select, :options=>[[:a, 1], [:b,2]]).to_s.must_equal '<div class="form-group"><select class="form-control"><option value="1">a</option><option value="2">b</option></select></div>'
205
+ end
206
+
207
+ it "should create a simple :select tag with options and the correct value" do
208
+ @f.input(:select, :options=>[[:a, 1], [:b,2]], :value=>2).to_s.must_equal '<div class="form-group"><select class="form-control"><option value="1">a</option><option selected="selected" value="2">b</option></select></div>'
209
+ end
210
+
211
+ it "should support :add_blank option for select inputs" do
212
+ @f.input(:select, :options=>[[:a, 1], [:b, 2]], :add_blank=>true, :value=>1).to_s.must_equal '<div class="form-group"><select class="form-control"><option value=""></option><option selected="selected" value="1">a</option><option value="2">b</option></select></div>'
213
+ end
214
+
215
+ it "should create an :select tag with the correct class" do
216
+ @f.input(:select, :class=>'foo').to_s.must_equal '<div class="form-group"><select class="form-control foo"></select></div>'
217
+ end
218
+
219
+ it "should create an :select tag with the correct id" do
220
+ @f.input(:select, :id=>'bar').to_s.must_equal '<div class="form-group"><select class="form-control" id="bar"></select></div>'
221
+ end
222
+
223
+ it "should create a select tag without .has-error and error message span when ':skip_error => true'" do
224
+ @f.input(:select, :skip_error=>true).to_s.must_equal '<div class="form-group"><select class="form-control"></select></div>'
225
+ end
226
+
227
+ it "should create a select tag with .has-error and error message when ':error => is-a-string'" do
228
+ @f.input(:select, :error=>'input-select-error').to_s.must_equal '<div class="form-group has-error"><select class="form-control"></select><span class="help-block with-errors">input-select-error</span></div>'
229
+ end
230
+
231
+ it "should correctly handle a Sequel model output :as => :select" do
232
+ @b.input(:artist, :as=>:select).to_s.must_equal '<div class="form-group many_to_one"><label for="album_artist_id">Artist</label> <select class="form-control" id="album_artist_id" name="album[artist_id]"><option value=""></option><option selected="selected" value="1">a</option><option value="2">d</option></select></div>'
233
+ end
234
+
235
+ it "should correctly handle a Sequel model output :as => :select with error" do
236
+ @ac.errors.add(:artist, 'error message')
237
+ @c.input(:artist, :as=>:select).to_s.must_equal '<div class="form-group has-error many_to_one"><label for="album_artist_id">Artist</label> <select class="form-control" id="album_artist_id" name="album[artist_id]"><option value=""></option><option value="1">a</option><option selected="selected" value="2">d</option></select><span class="help-block with-errors">error message</span></div>'
238
+ end
239
+
240
+ describe 'from a Sequel model' do
241
+ it "should correctly handle a boolean attribute from a Sequel model" do
242
+ @c.input(:gold).to_s.must_equal '<div class="boolean form-group"><label for="album_gold">Gold</label> <select class="form-control" id="album_gold" name="album[gold]"><option value=""></option><option selected="selected" value="t">True</option><option value="f">False</option></select></div>'
243
+ end
244
+
245
+ it "should correctly handle a boolean attribute from a Sequel model with an error" do
246
+ @ac.errors.add(:gold, 'error message')
247
+ @c.input(:gold).to_s.must_equal '<div class="boolean form-group has-error"><label for="album_gold">Gold</label> <select class="form-control" id="album_gold" name="album[gold]"><option value=""></option><option selected="selected" value="t">True</option><option value="f">False</option></select><span class="help-block with-errors">error message</span></div>'
248
+ end
249
+ end
250
+ end
251
+
252
+ describe 'input[:checkbox]' do
253
+ it "should create a simple input[:checkbox] tag" do
254
+ @f.input(:checkbox).to_s.must_equal '<div class="checkbox"><input type="checkbox"/></div>'
255
+ end
256
+
257
+ it "should create an input[:checkbox] tag with a label when ':label => Gold'" do
258
+ @f.input(:checkbox, :label=>"Gold").to_s.must_equal '<div class="checkbox"><label><input type="checkbox"/> Gold</label></div>'
259
+ end
260
+
261
+ it "should create an input[:checkbox] tag with a label when ':class => bar'" do
262
+ @f.input(:checkbox, :label=>"Gold", :class=>'bar').to_s.must_equal '<div class="checkbox"><label><input class="bar" type="checkbox"/> Gold</label></div>'
263
+ end
264
+
265
+ it "should create an input[:checkbox] tag with a label when ':id => bar'" do
266
+ @f.input(:checkbox, :label=>"Gold", :id=>'bar').to_s.must_equal '<div class="checkbox"><label for="bar"><input id="bar" type="checkbox"/> Gold</label></div>'
267
+ end
268
+
269
+ it "should create an input[:checkbox] tag with a label when ':id => bar' with an error" do
270
+ @f.input(:checkbox, :label=>"Gold", :id=>'bar', :class=>'foo', :error=>'input-checkbox-error').to_s.must_equal '<div class="has-error"><div class="checkbox"><label for="bar"><input class="foo" id="bar" type="checkbox"/> Gold</label></div><span class="help-block with-errors">input-checkbox-error</span></div>'
271
+ end
272
+
273
+ describe 'from a Sequel model' do
274
+ it "should correctly handle a boolean attribute ':as=>:checkbox'" do
275
+ @c.input(:gold, :as=>:checkbox).to_s.must_equal '<div class="boolean checkbox"><label for="album_gold"><input id="album_gold_hidden" name="album[gold]" type="hidden" value="f"/><input checked="checked" id="album_gold" name="album[gold]" type="checkbox" value="t"/> Gold</label></div>'
276
+ end
277
+
278
+ it "should correctly handle a boolean attribute ':as=>:checkbox' with an error" do
279
+ @ac.errors.add(:gold, 'error message')
280
+ @c.input(:gold, :as=>:checkbox).to_s.must_equal '<div class="boolean has-error"><div class="checkbox"><label for="album_gold"><input id="album_gold_hidden" name="album[gold]" type="hidden" value="f"/><input checked="checked" id="album_gold" name="album[gold]" type="checkbox" value="t"/> Gold</label></div><span class="help-block with-errors">error message</span></div>'
281
+ end
282
+ end
283
+ end
284
+
285
+
286
+ describe 'input[:radio]' do
287
+ it "should create a simple input[:radio] tag" do
288
+ @f.input(:radio).to_s.must_equal '<div class="radio"><input type="radio"/></div>'
289
+ end
290
+
291
+ it "should create an input[:radio] tag with a label when ':label => Gold'" do
292
+ @f.input(:radio, :label=>"Gold").to_s.must_equal '<div class="radio"><label><input type="radio"/> Gold</label></div>'
293
+ end
294
+
295
+ it "should create an input[:radio] tag with a label when ':class => bar'" do
296
+ @f.input(:radio, :label=>"Gold", :class=>'bar').to_s.must_equal '<div class="radio"><label><input class="bar" type="radio"/> Gold</label></div>'
297
+ end
298
+
299
+ it "should create an input[:radio] tag with a label when ':id => bar'" do
300
+ @f.input(:radio, :label=>"Gold", :id=>'bar').to_s.must_equal '<div class="radio"><label for="bar"><input id="bar" type="radio"/> Gold</label></div>'
301
+ end
302
+
303
+ it "should create an input[:radio] tag with a label when ':id => bar' with an error" do
304
+ @f.input(:radio, :label=>"Gold", :id=>'bar', :class=>'foo', :error=>'input-radio-error').to_s.must_equal '<div class="has-error"><div class="radio"><label for="bar"><input class="foo" id="bar" type="radio"/> Gold</label></div><span class="help-block with-errors">input-radio-error</span></div>'
305
+ end
306
+
307
+ describe 'from a Sequel model' do
308
+ it "should correctly handle a boolean attribute ':as=>:radio'" do
309
+ @c.input(:gold, :as=>:radio).to_s.must_equal '<div class="boolean radioset"><label>Gold</label><div class="radio"><label class="option" for="album_gold_yes"><input checked="checked" id="album_gold_yes" name="album[gold]" type="radio" value="t"/> Yes</label></div><div class="radio"><label class="option" for="album_gold_no"><input id="album_gold_no" name="album[gold]" type="radio" value="f"/> No</label></div></div>'
310
+ end
311
+
312
+ it "should correctly handle a boolean attribute ':as=>:radio' with an error" do
313
+ @ac.errors.add(:gold, 'error message')
314
+ @c.input(:gold, :as=>:radio).to_s.must_equal '<div class="boolean radioset has-error"><label>Gold</label><div class="radio"><label class="option" for="album_gold_yes"><input checked="checked" id="album_gold_yes" name="album[gold]" type="radio" value="t"/> Yes</label></div><div class="radio"><label class="option" for="album_gold_no"><input id="album_gold_no" name="album[gold]" type="radio" value="f"/> No</label></div><span class="help-block with-errors">error message</span></div>'
315
+ end
316
+ end
317
+ end
318
+
319
+
320
+ it "should correctly handle a :checkboxset tag" do
321
+ @f.input(:checkboxset, :options=>[[:a, 1], [:b,2]]).to_s.must_equal '<div class="checkboxset"><div class="checkbox"><label class="option"><input type="checkbox" value="1"/> a</label></div><div class="checkbox"><label class="option"><input type="checkbox" value="2"/> b</label></div></div>'
322
+ end
323
+
324
+ it "should correctly handle a :checkboxset tag without options" do
325
+ @f.input(:checkboxset, :options=>[]).to_s.must_equal '<div class="checkboxset"></div>'
326
+ end
327
+
328
+ it "should correctly handle a :checkboxset tag with an error - Alternative A: (see BS3 HTML reference)" do
329
+ @f.input(:checkboxset, :options=>[[:a, 1], [:b,2]], :error=>'error message').to_s.must_equal '<div class="checkboxset has-error"><div class="checkbox"><label class="option"><input type="checkbox" value="1"/> a</label></div><div class="checkbox"><label class="option"><input type="checkbox" value="2"/> b</label></div><span class="help-block with-errors">error message</span></div>'
330
+ end
331
+
332
+ it "should correctly handle a :checkboxset tag with an error and label - Alternative A: (see BS3 HTML reference)" do
333
+ @f.input(:checkboxset, :options=>[[:a, 1], [:b,2]], :error=>'error message', :label=>'CheckboxSet').to_s.must_equal '<div class="checkboxset has-error"><label>CheckboxSet</label><div class="checkbox"><label class="option"><input type="checkbox" value="1"/> a</label></div><div class="checkbox"><label class="option"><input type="checkbox" value="2"/> b</label></div><span class="help-block with-errors">error message</span></div>'
334
+ end
335
+
336
+ it "should correctly handle a :radioset tag" do
337
+ @f.input(:radioset, :options=>[[:a, 1], [:b,2]]).to_s.must_equal '<div class="radioset"><div class="radio"><label class="option"><input type="radio" value="1"/> a</label></div><div class="radio"><label class="option"><input type="radio" value="2"/> b</label></div></div>'
338
+ end
339
+
340
+ it "should correctly handle a :radioset tag without options" do
341
+ @f.input(:radioset, :options=>[]).to_s.must_equal '<div class="radioset"></div>'
342
+ end
343
+
344
+ it "should correctly handle a :radioset tag with an error - Alternative A: (see BS3 HTML reference)" do
345
+ @f.input(:radioset, :options=>[[:a, 1], [:b,2]], :error=>'error message').to_s.must_equal '<div class="radioset has-error"><div class="radio"><label class="option"><input type="radio" value="1"/> a</label></div><div class="radio"><label class="option"><input type="radio" value="2"/> b</label></div><span class="help-block with-errors">error message</span></div>'
346
+ end
347
+
348
+ it "should correctly handle a :radioset tag with an error and label - Alternative A: (see BS3 HTML reference)" do
349
+ @f.input(:radioset, :options=>[[:a, 1], [:b,2]], :error=>'error message', :label=>'RadioSet').to_s.must_equal '<div class="radioset has-error"><label>RadioSet</label><div class="radio"><label class="option"><input type="radio" value="1"/> a</label></div><div class="radio"><label class="option"><input type="radio" value="2"/> b</label></div><span class="help-block with-errors">error message</span></div>'
350
+ end
351
+
352
+ it "should use a set of radio buttons for many_to_one associations with :as=>:radio option" do
353
+ @b.input(:artist, :as=>:radio).to_s.must_equal '<div class="many_to_one radioset"><label>Artist</label><div class="radio"><label class="option" for="album_artist_id_1"><input checked="checked" id="album_artist_id_1" name="album[artist_id]" type="radio" value="1"/> a</label></div><div class="radio"><label class="option" for="album_artist_id_2"><input id="album_artist_id_2" name="album[artist_id]" type="radio" value="2"/> d</label></div></div>'
354
+ @b.input(:artist, :as=>:radio, :wrapper=>nil).to_s.must_equal '<label>Artist</label><div class="radio"><label class="option" for="album_artist_id_1"><input checked="checked" id="album_artist_id_1" name="album[artist_id]" type="radio" value="1"/> a</label></div><div class="radio"><label class="option" for="album_artist_id_2"><input id="album_artist_id_2" name="album[artist_id]" type="radio" value="2"/> d</label></div>'
355
+ @c.input(:artist, :as=>:radio).to_s.must_equal '<div class="many_to_one radioset"><label>Artist</label><div class="radio"><label class="option" for="album_artist_id_1"><input id="album_artist_id_1" name="album[artist_id]" type="radio" value="1"/> a</label></div><div class="radio"><label class="option" for="album_artist_id_2"><input checked="checked" id="album_artist_id_2" name="album[artist_id]" type="radio" value="2"/> d</label></div></div>'
356
+ @c.input(:artist, :as=>:radio, :wrapper=>:div).to_s.must_equal '<div class="many_to_one radioset"><label>Artist</label><div class="radio"><label class="option" for="album_artist_id_1"><input id="album_artist_id_1" name="album[artist_id]" type="radio" value="1"/> a</label></div><div class="radio"><label class="option" for="album_artist_id_2"><input checked="checked" id="album_artist_id_2" name="album[artist_id]" type="radio" value="2"/> d</label></div></div>'
357
+ end
358
+ end