ShadowBelmolve-formtastic 0.2.1 → 0.9.7

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.
Files changed (51) hide show
  1. data/README.textile +191 -176
  2. data/Rakefile +65 -22
  3. data/generators/form/USAGE +16 -0
  4. data/generators/form/form_generator.rb +120 -0
  5. data/generators/form/templates/view__form.html.erb +5 -0
  6. data/generators/form/templates/view__form.html.haml +4 -0
  7. data/generators/formtastic/formtastic_generator.rb +24 -0
  8. data/generators/{formtastic_stylesheets → formtastic}/templates/formtastic.css +2 -0
  9. data/generators/formtastic/templates/formtastic.rb +51 -0
  10. data/generators/{formtastic_stylesheets → formtastic}/templates/formtastic_changes.css +0 -0
  11. data/generators/formtastic_stylesheets/formtastic_stylesheets_generator.rb +5 -10
  12. data/lib/formtastic.rb +1234 -895
  13. data/lib/formtastic/i18n.rb +32 -0
  14. data/lib/locale/en.yml +2 -2
  15. data/rails/init.rb +1 -1
  16. data/spec/buttons_spec.rb +149 -0
  17. data/spec/commit_button_spec.rb +344 -0
  18. data/spec/custom_builder_spec.rb +62 -0
  19. data/spec/custom_macros.rb +561 -0
  20. data/spec/defaults_spec.rb +20 -0
  21. data/spec/error_proc_spec.rb +27 -0
  22. data/spec/errors_spec.rb +85 -0
  23. data/spec/form_helper_spec.rb +120 -0
  24. data/spec/i18n_spec.rb +131 -0
  25. data/spec/include_blank_spec.rb +70 -0
  26. data/spec/input_spec.rb +608 -0
  27. data/spec/inputs/boolean_input_spec.rb +93 -0
  28. data/spec/inputs/check_boxes_input_spec.rb +162 -0
  29. data/spec/inputs/country_input_spec.rb +80 -0
  30. data/spec/inputs/date_input_spec.rb +45 -0
  31. data/spec/inputs/datetime_input_spec.rb +155 -0
  32. data/spec/inputs/file_input_spec.rb +33 -0
  33. data/spec/inputs/hidden_input_spec.rb +52 -0
  34. data/spec/inputs/numeric_input_spec.rb +44 -0
  35. data/spec/inputs/password_input_spec.rb +46 -0
  36. data/spec/inputs/radio_input_spec.rb +149 -0
  37. data/spec/inputs/select_input_spec.rb +459 -0
  38. data/spec/inputs/string_input_spec.rb +47 -0
  39. data/spec/inputs/text_input_spec.rb +33 -0
  40. data/spec/inputs/time_input_spec.rb +44 -0
  41. data/spec/inputs/time_zone_input_spec.rb +102 -0
  42. data/spec/inputs_spec.rb +395 -0
  43. data/spec/label_spec.rb +48 -0
  44. data/spec/nested_forms_spec.rb +50 -0
  45. data/spec/semantic_fields_for_spec.rb +44 -0
  46. data/spec/spec.opts +2 -0
  47. data/spec/spec_helper.rb +212 -0
  48. metadata +121 -16
  49. data/lib/justin_french/formtastic.rb +0 -10
  50. data/spec/formtastic_spec.rb +0 -3072
  51. data/spec/test_helper.rb +0 -14
@@ -1,10 +0,0 @@
1
- module JustinFrench #:nodoc:
2
- module Formtastic #:nodoc:
3
- class SemanticFormBuilder < ::Formtastic::SemanticFormBuilder #:nodoc:
4
- def initialize(*args)
5
- ::ActiveSupport::Deprecation.warn("JustinFrench::Formtastic::SemanticFormBuilder is deprecated. User Formtastic::SemanticFormBuilder instead", caller)
6
- super
7
- end
8
- end
9
- end
10
- end
@@ -1,3072 +0,0 @@
1
- require File.dirname(__FILE__) + '/test_helper'
2
- require 'formtastic'
3
-
4
- module FormtasticSpecHelper
5
- def default_input_type(column_type, column_name = :generic_column_name)
6
- @new_post.stub!(column_name)
7
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => column_type)) unless column_type.nil?
8
-
9
- semantic_form_for(@new_post) do |builder|
10
- @default_type = builder.send(:default_input_type, column_name)
11
- end
12
-
13
- return @default_type
14
- end
15
- end
16
-
17
- describe 'Formtastic' do
18
-
19
- include ActionView::Helpers::FormHelper
20
- include ActionView::Helpers::FormTagHelper
21
- include ActionView::Helpers::FormOptionsHelper
22
- include ActionView::Helpers::UrlHelper
23
- include ActionView::Helpers::TagHelper
24
- include ActionView::Helpers::TextHelper
25
- include ActionView::Helpers::ActiveRecordHelper
26
- include ActionView::Helpers::RecordIdentificationHelper
27
- include ActionView::Helpers::DateHelper
28
- include ActionView::Helpers::CaptureHelper
29
- include ActiveSupport
30
- include ActionController::PolymorphicRoutes
31
-
32
- include Formtastic::SemanticFormHelper
33
-
34
- attr_accessor :output_buffer
35
-
36
- def protect_against_forgery?; false; end
37
-
38
- before do
39
- Formtastic::SemanticFormBuilder.label_str_method = :humanize
40
-
41
- @output_buffer = ''
42
-
43
- # Resource-oriented styles like form_for(@post) will expect a path method for the object,
44
- # so we're defining some here.
45
- def post_path(o); "/posts/1"; end
46
- def posts_path; "/posts"; end
47
- def new_post_path; "/posts/new"; end
48
-
49
- def author_path(o); "/authors/1"; end
50
- def authors_path; "/authors"; end
51
- def new_author_path; "/authors/new"; end
52
-
53
- # Sometimes we need some classes
54
- class Post;
55
- def id; end
56
- end
57
- class Author; end
58
-
59
- @fred = mock('user')
60
- @fred.stub!(:class).and_return(Author)
61
- @fred.stub!(:to_label).and_return('Fred Smith')
62
- @fred.stub!(:login).and_return('fred_smith')
63
- @fred.stub!(:id).and_return(37)
64
- @fred.stub!(:new_record?).and_return(false)
65
- @fred.stub!(:errors).and_return(mock('errors', :[] => nil))
66
-
67
- @bob = mock('user')
68
- @bob.stub!(:class).and_return(Author)
69
- @bob.stub!(:to_label).and_return('Bob Rock')
70
- @bob.stub!(:login).and_return('bob')
71
- @bob.stub!(:id).and_return(42)
72
- @bob.stub!(:posts).and_return([])
73
- @bob.stub!(:post_ids).and_return([])
74
- @bob.stub!(:new_record?).and_return(false)
75
- @bob.stub!(:errors).and_return(mock('errors', :[] => nil))
76
-
77
- Author.stub!(:find).and_return([@fred, @bob])
78
- Author.stub!(:human_attribute_name).and_return { |column_name| column_name.humanize }
79
- Author.stub!(:human_name).and_return('Author')
80
- Author.stub!(:reflect_on_all_validations).and_return([])
81
- Author.stub!(:reflect_on_association).and_return { |column_name| mock('reflection', :options => {}, :klass => Post, :macro => :has_many) if column_name == :posts }
82
-
83
- # Sometimes we need a mock @post object and some Authors for belongs_to
84
- @new_post = mock('post')
85
- @new_post.stub!(:class).and_return(Post)
86
- @new_post.stub!(:id).and_return(nil)
87
- @new_post.stub!(:new_record?).and_return(true)
88
- @new_post.stub!(:errors).and_return(mock('errors', :[] => nil))
89
- @new_post.stub!(:author).and_return(nil)
90
-
91
- @freds_post = mock('post')
92
- @freds_post.stub!(:class).and_return(Post)
93
- @freds_post.stub!(:to_label).and_return('Fred Smith')
94
- @freds_post.stub!(:id).and_return(19)
95
- @freds_post.stub!(:author).and_return(@fred)
96
- @freds_post.stub!(:author_id).and_return(@fred.id)
97
- @freds_post.stub!(:authors).and_return([@fred])
98
- @freds_post.stub!(:author_ids).and_return([@fred.id])
99
- @freds_post.stub!(:new_record?).and_return(false)
100
- @freds_post.stub!(:errors).and_return(mock('errors', :[] => nil))
101
- @fred.stub!(:posts).and_return([@freds_post])
102
- @fred.stub!(:post_ids).and_return([@freds_post.id])
103
-
104
- Post.stub!(:human_attribute_name).and_return { |column_name| column_name.humanize }
105
- Post.stub!(:human_name).and_return('Post')
106
- Post.stub!(:reflect_on_all_validations).and_return([])
107
- Post.stub!(:reflect_on_association).and_return do |column_name|
108
- case column_name
109
- when :author, :author_status
110
- mock('reflection', :options => {}, :klass => Author, :macro => :belongs_to)
111
- when :authors
112
- mock('reflection', :options => {}, :klass => Author, :macro => :has_and_belongs_to_many)
113
- end
114
- end
115
- Post.stub!(:find).and_return([@freds_post])
116
- end
117
-
118
- describe 'JustinFrench::Formtastic::SemanticFormBuilder' do
119
- require 'justin_french/formtastic'
120
- it 'should be deprecated' do
121
- ::ActiveSupport::Deprecation.should_receive(:warn).with(/JustinFrench\:\:Formtastic\:\:SemanticFormBuilder/, anything())
122
- form_for(@new_post, :builder => JustinFrench::Formtastic::SemanticFormBuilder) do |builder|
123
- end
124
- end
125
- end
126
-
127
- describe 'SemanticFormHelper' do
128
-
129
- describe '#semantic_form_for' do
130
-
131
- it 'yields an instance of SemanticFormBuilder' do
132
- semantic_form_for(:post, Post.new, :url => '/hello') do |builder|
133
- builder.class.should == Formtastic::SemanticFormBuilder
134
- end
135
- end
136
-
137
- it 'adds a class of "formtastic" to the generated form' do
138
- semantic_form_for(:post, Post.new, :url => '/hello') do |builder|
139
- end
140
- output_buffer.should have_tag("form.formtastic")
141
- end
142
-
143
- it 'adds class matching the object name to the generated form when a symbol is provided' do
144
- semantic_form_for(:post, Post.new, :url => '/hello') do |builder|
145
- end
146
- output_buffer.should have_tag("form.post")
147
-
148
- semantic_form_for(:project, :url => '/hello') do |builder|
149
- end
150
- output_buffer.should have_tag("form.project")
151
- end
152
-
153
- it 'adds class matching the object\'s class to the generated form when an object is provided' do
154
- semantic_form_for(@new_post) do |builder|
155
- end
156
- output_buffer.should have_tag("form.post")
157
- end
158
-
159
- describe 'allows :html options' do
160
- before(:each) do
161
- semantic_form_for(:post, Post.new, :url => '/hello', :html => { :id => "something-special", :class => "something-extra", :multipart => true }) do |builder|
162
- end
163
- end
164
-
165
- it 'to add a id of "something-special" to generated form' do
166
- output_buffer.should have_tag("form#something-special")
167
- end
168
-
169
- it 'to add a class of "something-extra" to generated form' do
170
- output_buffer.should have_tag("form.something-extra")
171
- end
172
-
173
- it 'to add enctype="multipart/form-data"' do
174
- output_buffer.should have_tag('form[@enctype="multipart/form-data"]')
175
- end
176
- end
177
-
178
- it 'can be called with a resource-oriented style' do
179
- semantic_form_for(@new_post) do |builder|
180
- builder.object.class.should == Post
181
- builder.object_name.should == "post"
182
- end
183
- end
184
-
185
- it 'can be called with a generic style and instance variable' do
186
- semantic_form_for(:post, @new_post, :url => new_post_path) do |builder|
187
- builder.object.class.should == Post
188
- builder.object_name.to_s.should == "post" # TODO: is this forced .to_s a bad assumption somewhere?
189
- end
190
- end
191
-
192
- it 'can be called with a generic style and inline object' do
193
- semantic_form_for(:post, Post.new, :url => new_post_path) do |builder|
194
- builder.object.class.should == Post
195
- builder.object_name.to_s.should == "post" # TODO: is this forced .to_s a bad assumption somewhere?
196
- end
197
- end
198
-
199
- end
200
-
201
- describe '#semantic_fields_for' do
202
- it 'yields an instance of SemanticFormBuilder' do
203
- semantic_fields_for(:post, Post.new, :url => '/hello') do |builder|
204
- builder.class.should == Formtastic::SemanticFormBuilder
205
- end
206
- end
207
- end
208
-
209
- describe '#semantic_form_remote_for' do
210
- it 'yields an instance of SemanticFormBuilder' do
211
- semantic_form_remote_for(:post, Post.new, :url => '/hello') do |builder|
212
- builder.class.should == Formtastic::SemanticFormBuilder
213
- end
214
- end
215
- end
216
-
217
- describe '#semantic_form_for_remote' do
218
- it 'yields an instance of SemanticFormBuilder' do
219
- semantic_form_remote_for(:post, Post.new, :url => '/hello') do |builder|
220
- builder.class.should == Formtastic::SemanticFormBuilder
221
- end
222
- end
223
- end
224
-
225
- end
226
-
227
- describe 'SemanticFormBuilder' do
228
-
229
- include FormtasticSpecHelper
230
-
231
- describe "@@builder" do
232
- before do
233
- @new_post.stub!(:title)
234
- @new_post.stub!(:body)
235
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
236
- end
237
-
238
- after do
239
- Formtastic::SemanticFormHelper.builder = Formtastic::SemanticFormBuilder
240
- end
241
-
242
- it "can be overridden" do
243
-
244
- class CustomFormBuilder < Formtastic::SemanticFormBuilder
245
- def custom(arg1, arg2, options = {})
246
- [arg1, arg2, options]
247
- end
248
- end
249
-
250
- Formtastic::SemanticFormHelper.builder = CustomFormBuilder
251
-
252
- semantic_form_for(@new_post) do |builder|
253
- builder.class.should == CustomFormBuilder
254
- builder.custom("one", "two").should == ["one", "two", {}]
255
- end
256
- end
257
-
258
- end
259
-
260
- describe 'Formtastic::SemanticFormBuilder#semantic_fields_for' do
261
- before do
262
- @new_post.stub!(:author).and_return(Author.new)
263
- end
264
-
265
- it 'yields an instance of SemanticFormBuilder' do
266
- semantic_form_for(@new_post) do |builder|
267
- builder.semantic_fields_for(:author) do |nested_builder|
268
- nested_builder.class.should == Formtastic::SemanticFormBuilder
269
- end
270
- end
271
- end
272
-
273
- it 'nests the object name' do
274
- semantic_form_for(@new_post) do |builder|
275
- builder.semantic_fields_for(@bob) do |nested_builder|
276
- nested_builder.object_name.should == 'post[author]'
277
- end
278
- end
279
- end
280
-
281
- it 'should sanitize html id for li tag' do
282
- @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
283
- semantic_form_for(@new_post) do |builder|
284
- builder.semantic_fields_for(@bob, :index => 1) do |nested_builder|
285
- concat(nested_builder.inputs(:login))
286
- end
287
- end
288
- output_buffer.should have_tag('form fieldset.inputs #post_author_1_login_input')
289
- output_buffer.should_not have_tag('form fieldset.inputs #post[author]_1_login_input')
290
- end
291
- end
292
-
293
- describe '#label' do
294
- it 'should humanize the given attribute' do
295
- semantic_form_for(@new_post) do |builder|
296
- builder.label(:login).should have_tag('label', :with => /Login/)
297
- end
298
- end
299
-
300
- it 'should be printed as span' do
301
- semantic_form_for(@new_post) do |builder|
302
- builder.label(:login, nil, { :required => true, :as_span => true }).should have_tag('span.label abbr')
303
- end
304
- end
305
-
306
- describe 'when required is given' do
307
- it 'should append a required note' do
308
- semantic_form_for(@new_post) do |builder|
309
- builder.label(:login, nil, :required => true).should have_tag('label abbr')
310
- end
311
- end
312
-
313
- it 'should allow require option to be given as second argument' do
314
- semantic_form_for(@new_post) do |builder|
315
- builder.label(:login, :required => true).should have_tag('label abbr')
316
- end
317
- end
318
- end
319
-
320
- describe 'when label is given' do
321
- it 'should allow the text to be given as label option' do
322
- semantic_form_for(@new_post) do |builder|
323
- builder.label(:login, :required => true, :label => 'My label').should have_tag('label', :with => /My label/)
324
- end
325
- end
326
-
327
- it 'should return nil if label is false' do
328
- semantic_form_for(@new_post) do |builder|
329
- builder.label(:login, :label => false).should be_blank
330
- end
331
- end
332
- end
333
- end
334
-
335
- describe '#errors_on' do
336
- before(:each) do
337
- @title_errors = ['must not be blank', 'must be longer than 10 characters', 'must be awesome']
338
- @errors = mock('errors')
339
- @errors.stub!(:[]).with(:title).and_return(@title_errors)
340
- @errors.stub!(:[]).with(:body).and_return(nil)
341
- @new_post.stub!(:errors).and_return(@errors)
342
- end
343
-
344
- describe 'and the errors will be displayed as a sentence' do
345
- it 'should render a paragraph with the errors joined into a sentence' do
346
- Formtastic::SemanticFormBuilder.inline_errors = :sentence
347
- semantic_form_for(@new_post) do |builder|
348
- builder.errors_on(:title).should have_tag('p.inline-errors', @title_errors.to_sentence)
349
- end
350
- end
351
- end
352
-
353
- describe 'and the errors will be displayed as a list' do
354
- it 'should render an unordered list with the class errors' do
355
- Formtastic::SemanticFormBuilder.inline_errors = :list
356
- semantic_form_for(@new_post) do |builder|
357
- builder.errors_on(:title).should have_tag('ul.errors')
358
- end
359
- end
360
-
361
- it 'should include a list element for each of the errors within the unordered list' do
362
- Formtastic::SemanticFormBuilder.inline_errors = :list
363
- semantic_form_for(@new_post) do |builder|
364
- @title_errors.each do |error|
365
- builder.errors_on(:title).should have_tag('ul.errors li', error)
366
- end
367
- end
368
- end
369
- end
370
-
371
- describe 'but the errors will not be shown' do
372
- it 'should return nil' do
373
- Formtastic::SemanticFormBuilder.inline_errors = :none
374
- semantic_form_for(@new_post) do |builder|
375
- builder.errors_on(:title).should be_nil
376
- end
377
- end
378
- end
379
-
380
- describe 'and no error is found on the method' do
381
- it 'should return nil' do
382
- Formtastic::SemanticFormBuilder.inline_errors = :sentence
383
- semantic_form_for(@new_post) do |builder|
384
- builder.errors_on(:body).should be_nil
385
- end
386
- end
387
- end
388
- end
389
-
390
- describe '#input' do
391
-
392
- before do
393
- @new_post.stub!(:title)
394
- @new_post.stub!(:body)
395
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
396
- end
397
-
398
- describe 'with inline order customization' do
399
- it 'should allow input, hints, errors as order' do
400
- Formtastic::SemanticFormBuilder.inline_order = [:input, :hints, :errors]
401
-
402
- semantic_form_for(@new_post) do |builder|
403
- builder.should_receive(:inline_input_for).once.ordered
404
- builder.should_receive(:inline_hints_for).once.ordered
405
- builder.should_receive(:inline_errors_for).once.ordered
406
- concat(builder.input(:title))
407
- end
408
- end
409
-
410
- it 'should allow hints, input, errors as order' do
411
- Formtastic::SemanticFormBuilder.inline_order = [:hints, :input, :errors]
412
-
413
- semantic_form_for(@new_post) do |builder|
414
- builder.should_receive(:inline_hints_for).once.ordered
415
- builder.should_receive(:inline_input_for).once.ordered
416
- builder.should_receive(:inline_errors_for).once.ordered
417
- concat(builder.input(:title))
418
- end
419
- end
420
- end
421
-
422
- describe 'arguments and options' do
423
-
424
- it 'should require the first argument (the method on form\'s object)' do
425
- lambda {
426
- semantic_form_for(@new_post) do |builder|
427
- concat(builder.input()) # no args passed in at all
428
- end
429
- }.should raise_error(ArgumentError)
430
- end
431
-
432
- describe ':required option' do
433
-
434
- describe 'when true' do
435
-
436
- before do
437
- @string = Formtastic::SemanticFormBuilder.required_string = " required yo!" # ensure there's something in the string
438
- @new_post.class.should_not_receive(:reflect_on_all_validations)
439
- end
440
-
441
- after do
442
- Formtastic::SemanticFormBuilder.required_string = %{<abbr title="required">*</abbr>}
443
- end
444
-
445
- it 'should set a "required" class' do
446
- semantic_form_for(@new_post) do |builder|
447
- concat(builder.input(:title, :required => true))
448
- end
449
- output_buffer.should_not have_tag('form li.optional')
450
- output_buffer.should have_tag('form li.required')
451
- end
452
-
453
- it 'should append the "required" string to the label' do
454
- semantic_form_for(@new_post) do |builder|
455
- concat(builder.input(:title, :required => true))
456
- end
457
- output_buffer.should have_tag('form li.required label', /#{@string}$/)
458
- end
459
-
460
- end
461
-
462
- describe 'when false' do
463
-
464
- before do
465
- @string = Formtastic::SemanticFormBuilder.optional_string = " optional yo!" # ensure there's something in the string
466
- @new_post.class.should_not_receive(:reflect_on_all_validations)
467
- end
468
-
469
- after do
470
- Formtastic::SemanticFormBuilder.optional_string = ''
471
- end
472
-
473
- it 'should set an "optional" class' do
474
- semantic_form_for(@new_post) do |builder|
475
- concat(builder.input(:title, :required => false))
476
- end
477
- output_buffer.should_not have_tag('form li.required')
478
- output_buffer.should have_tag('form li.optional')
479
- end
480
-
481
- it 'should append the "optional" string to the label' do
482
- semantic_form_for(@new_post) do |builder|
483
- concat(builder.input(:title, :required => false))
484
- end
485
- output_buffer.should have_tag('form li.optional label', /#{@string}$/)
486
- end
487
-
488
- end
489
-
490
- describe 'when not provided' do
491
-
492
- describe 'and an object was not given' do
493
-
494
- it 'should use the default value' do
495
- Formtastic::SemanticFormBuilder.all_fields_required_by_default.should == true
496
- Formtastic::SemanticFormBuilder.all_fields_required_by_default = false
497
-
498
- semantic_form_for(:project, :url => 'http://test.host/') do |builder|
499
- concat(builder.input(:title))
500
- end
501
- output_buffer.should_not have_tag('form li.required')
502
- output_buffer.should have_tag('form li.optional')
503
-
504
- Formtastic::SemanticFormBuilder.all_fields_required_by_default = true
505
- end
506
-
507
- end
508
-
509
- describe 'and an object was given' do
510
-
511
- describe 'and the validation reflection plugin is available' do
512
-
513
- before do
514
- @new_post.class.stub!(:method_defined?).with(:reflect_on_all_validations).and_return(true)
515
- end
516
-
517
- describe 'and validates_presence_of was called for the method' do
518
- before do
519
- @new_post.class.should_receive(:reflect_on_all_validations).and_return([
520
- mock('MacroReflection', :macro => :validates_presence_of, :name => :title)
521
- ])
522
- end
523
-
524
- it 'should be required' do
525
- semantic_form_for(@new_post) do |builder|
526
- concat(builder.input(:title))
527
- end
528
- output_buffer.should have_tag('form li.required')
529
- output_buffer.should_not have_tag('form li.optional')
530
- end
531
- end
532
-
533
- describe 'and validates_presence_of was not called for the method' do
534
- before do
535
- @new_post.class.should_receive(:reflect_on_all_validations).and_return([])
536
- end
537
-
538
- it 'should not be required' do
539
- semantic_form_for(@new_post) do |builder|
540
- concat(builder.input(:title))
541
- end
542
- output_buffer.should_not have_tag('form li.required')
543
- output_buffer.should have_tag('form li.optional')
544
- end
545
- end
546
-
547
- end
548
-
549
- describe 'and the validation reflection plugin is not available' do
550
-
551
- it 'should use the default value' do
552
- Formtastic::SemanticFormBuilder.all_fields_required_by_default.should == true
553
- Formtastic::SemanticFormBuilder.all_fields_required_by_default = false
554
-
555
- semantic_form_for(@new_post) do |builder|
556
- concat(builder.input(:title))
557
- end
558
- output_buffer.should_not have_tag('form li.required')
559
- output_buffer.should have_tag('form li.optional')
560
-
561
- Formtastic::SemanticFormBuilder.all_fields_required_by_default = true
562
- end
563
-
564
- end
565
-
566
- end
567
-
568
- end
569
-
570
- end
571
-
572
- describe ':as option' do
573
-
574
- describe 'when not provided' do
575
-
576
- it 'should default to a string for forms without objects unless column is password' do
577
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
578
- concat(builder.input(:anything))
579
- end
580
- output_buffer.should have_tag('form li.string')
581
- end
582
-
583
- it 'should default to password for forms without objects if column is password' do
584
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
585
- concat(builder.input(:password))
586
- concat(builder.input(:password_confirmation))
587
- concat(builder.input(:confirm_password))
588
- end
589
- output_buffer.should have_tag('form li.password', :count => 3)
590
- end
591
-
592
- it 'should default to a string for methods on objects that don\'t respond to "column_for_attribute"' do
593
- @new_post.stub!(:method_without_a_database_column)
594
- @new_post.stub!(:column_for_attribute).and_return(nil)
595
- default_input_type(nil, :method_without_a_database_column).should == :string
596
- end
597
-
598
- it 'should default to :password for methods that don\'t have a column in the database but "password" is in the method name' do
599
- @new_post.stub!(:password_method_without_a_database_column)
600
- @new_post.stub!(:column_for_attribute).and_return(nil)
601
- default_input_type(nil, :password_method_without_a_database_column).should == :password
602
- end
603
-
604
- it 'should default to :password for methods on objects that don\'t respond to "column_for_attribute" but "password" is in the method name' do
605
- @new_post.stub!(:password_method_without_a_database_column)
606
- @new_post.stub!(:column_for_attribute).and_return(nil)
607
- default_input_type(nil, :password_method_without_a_database_column).should == :password
608
- end
609
-
610
- it 'should default to :select for column names ending in "_id"' do
611
- default_input_type(:integer, :user_id).should == :select
612
- default_input_type(:integer, :section_id).should == :select
613
- end
614
-
615
- it 'should default to :password for :string column types with "password" in the method name' do
616
- default_input_type(:string, :password).should == :password
617
- default_input_type(:string, :hashed_password).should == :password
618
- default_input_type(:string, :password_hash).should == :password
619
- end
620
-
621
- it 'should default to :text for :text column types' do
622
- default_input_type(:text).should == :text
623
- end
624
-
625
- it 'should default to :date for :date column types' do
626
- default_input_type(:date).should == :date
627
- end
628
-
629
- it 'should default to :datetime for :datetime and :timestamp column types' do
630
- default_input_type(:datetime).should == :datetime
631
- default_input_type(:timestamp).should == :datetime
632
- end
633
-
634
- it 'should default to :time for :time column types' do
635
- default_input_type(:time).should == :time
636
- end
637
-
638
- it 'should default to :boolean for :boolean column types' do
639
- default_input_type(:boolean).should == :boolean
640
- end
641
-
642
- it 'should default to :string for :string column types' do
643
- default_input_type(:string).should == :string
644
- end
645
-
646
- it 'should default to :numeric for :integer, :float and :decimal column types' do
647
- default_input_type(:integer).should == :numeric
648
- default_input_type(:float).should == :numeric
649
- default_input_type(:decimal).should == :numeric
650
- end
651
-
652
- it 'should default to :country for :string columns named country' do
653
- default_input_type(:string, :country).should == :country
654
- end
655
-
656
- describe 'defaulting to file column' do
657
- Formtastic::SemanticFormBuilder.file_methods.each do |method|
658
- it "should default to :file for attributes that respond to ##{method}" do
659
- @new_post.stub!(:column_for_attribute).and_return(nil)
660
- column = mock('column')
661
-
662
- Formtastic::SemanticFormBuilder.file_methods.each do |test|
663
- column.stub!(:respond_to?).with(test).and_return(method == test)
664
- end
665
-
666
- @new_post.should_receive(method).and_return(column)
667
-
668
- semantic_form_for(@new_post) do |builder|
669
- builder.send(:default_input_type, method).should == :file
670
- end
671
- end
672
- end
673
-
674
- end
675
- end
676
-
677
- it 'should call the corresponding input method' do
678
- [:select, :time_zone, :radio, :date, :datetime, :time, :boolean, :check_boxes, :hidden].each do |input_style|
679
- @new_post.stub!(:generic_column_name)
680
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
681
- semantic_form_for(@new_post) do |builder|
682
- builder.should_receive(:"#{input_style}_input").once.and_return("fake HTML output from #input")
683
- concat(builder.input(:generic_column_name, :as => input_style))
684
- end
685
- end
686
-
687
- Formtastic::SemanticFormBuilder::INPUT_MAPPINGS.keys.each do |input_style|
688
- @new_post.stub!(:generic_column_name)
689
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
690
- semantic_form_for(@new_post) do |builder|
691
- builder.should_receive(:input_simple).once.and_return("fake HTML output from #input")
692
- concat(builder.input(:generic_column_name, :as => input_style))
693
- end
694
- end
695
- end
696
-
697
- end
698
-
699
- describe ':label option' do
700
-
701
- describe 'when provided' do
702
- it 'should be passed down to the label tag' do
703
- semantic_form_for(@new_post) do |builder|
704
- concat(builder.input(:title, :label => "Kustom"))
705
- end
706
- output_buffer.should have_tag("form li label", /Kustom/)
707
- end
708
-
709
- it 'should not generate a label if false' do
710
- semantic_form_for(@new_post) do |builder|
711
- concat(builder.input(:title, :label => false))
712
- end
713
- output_buffer.should_not have_tag("form li label")
714
- end
715
-
716
- it 'should be dupped if frozen' do
717
- semantic_form_for(@new_post) do |builder|
718
- concat(builder.input(:title, :label => "Kustom".freeze))
719
- end
720
- output_buffer.should have_tag("form li label", /Kustom/)
721
- end
722
- end
723
-
724
- describe 'when not provided' do
725
- describe 'when localized label is NOT provided' do
726
- describe 'and object is not given' do
727
- it 'should default the humanized method name, passing it down to the label tag' do
728
- Formtastic::SemanticFormBuilder.label_str_method = :humanize
729
-
730
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
731
- concat(builder.input(:meta_description))
732
- end
733
-
734
- output_buffer.should have_tag("form li label", /#{'meta_description'.humanize}/)
735
- end
736
- end
737
-
738
- describe 'and object is given' do
739
- it 'should delegate the label logic to class human attribute name and pass it down to the label tag' do
740
- @new_post.stub!(:meta_description) # a two word method name
741
- @new_post.class.should_receive(:human_attribute_name).with('meta_description').and_return('meta_description'.humanize)
742
-
743
- semantic_form_for(@new_post) do |builder|
744
- concat(builder.input(:meta_description))
745
- end
746
-
747
- output_buffer.should have_tag("form li label", /#{'meta_description'.humanize}/)
748
- end
749
- end
750
- end
751
-
752
- describe 'when localized label is provided' do
753
- before do
754
- @localized_label_text = 'Localized title'
755
- @default_localized_label_text = 'Default localized title'
756
- ::I18n.backend.store_translations :en,
757
- :formtastic => {
758
- :labels => {
759
- :title => @default_localized_label_text,
760
- :post => {
761
- :title => @localized_label_text
762
- }
763
- }
764
- }
765
- ::Formtastic::SemanticFormBuilder.i18n_lookups_by_default = false
766
- end
767
-
768
- it 'should render a label with localized label (I18n)' do
769
- semantic_form_for(@new_post) do |builder|
770
- concat(builder.input(:title, :label => true))
771
- end
772
- output_buffer.should have_tag('form li label', @localized_label_text)
773
- end
774
-
775
- it 'should render a hint paragraph containing an optional localized label (I18n) if first is not set' do
776
- ::I18n.backend.store_translations :en,
777
- :formtastic => {
778
- :labels => {
779
- :post => {
780
- :title => nil
781
- }
782
- }
783
- }
784
- semantic_form_for(@new_post) do |builder|
785
- concat(builder.input(:title, :label => true))
786
- end
787
- output_buffer.should have_tag('form li label', @default_localized_label_text)
788
- end
789
- end
790
- end
791
-
792
- end
793
-
794
- describe ':hint option' do
795
-
796
- describe 'when provided' do
797
- it 'should be passed down to the paragraph tag' do
798
- hint_text = "this is the title of the post"
799
- semantic_form_for(@new_post) do |builder|
800
- concat(builder.input(:title, :hint => hint_text))
801
- end
802
- output_buffer.should have_tag("form li p.inline-hints", hint_text)
803
- end
804
- end
805
-
806
- describe 'when not provided' do
807
- describe 'when localized hint (I18n) is provided' do
808
- before do
809
- @localized_hint_text = "This is the localized hint."
810
- @default_localized_hint_text = "This is the default localized hint."
811
- ::I18n.backend.store_translations :en,
812
- :formtastic => {
813
- :hints => {
814
- :title => @default_localized_hint_text,
815
- :post => {
816
- :title => @localized_hint_text
817
- }
818
- }
819
- }
820
- ::Formtastic::SemanticFormBuilder.i18n_lookups_by_default = false
821
- end
822
-
823
- describe 'when provided value (hint value) is set to TRUE' do
824
- it 'should render a hint paragraph containing a localized hint (I18n)' do
825
- semantic_form_for(@new_post) do |builder|
826
- concat(builder.input(:title, :hint => true))
827
- end
828
- output_buffer.should have_tag('form li p.inline-hints', @localized_hint_text)
829
- end
830
-
831
- it 'should render a hint paragraph containing an optional localized hint (I18n) if first is not set' do
832
- ::I18n.backend.store_translations :en,
833
- :formtastic => {
834
- :hints => {
835
- :post => {
836
- :title => nil
837
- }
838
- }
839
- }
840
- semantic_form_for(@new_post) do |builder|
841
- concat(builder.input(:title, :hint => true))
842
- end
843
- output_buffer.should have_tag('form li p.inline-hints', @default_localized_hint_text)
844
- end
845
- end
846
-
847
- describe 'when provided value (label value) is set to FALSE' do
848
- it 'should not render a hint paragraph' do
849
- semantic_form_for(@new_post) do |builder|
850
- concat(builder.input(:title, :hint => false))
851
- end
852
- output_buffer.should_not have_tag('form li p.inline-hints', @localized_hint_text)
853
- end
854
- end
855
- end
856
-
857
- describe 'when localized hint (I18n) is not provided' do
858
- it 'should not render a hint paragraph' do
859
- semantic_form_for(@new_post) do |builder|
860
- concat(builder.input(:title))
861
- end
862
- output_buffer.should_not have_tag('form li p.inline-hints')
863
- end
864
- end
865
- end
866
-
867
- end
868
-
869
- describe ':wrapper_html option' do
870
-
871
- describe 'when provided' do
872
- it 'should be passed down to the li tag' do
873
- semantic_form_for(@new_post) do |builder|
874
- concat(builder.input(:title, :wrapper_html => {:id => :another_id}))
875
- end
876
- output_buffer.should have_tag("form li#another_id")
877
- end
878
-
879
- it 'should append given classes to li default classes' do
880
- semantic_form_for(@new_post) do |builder|
881
- concat(builder.input(:title, :wrapper_html => {:class => :another_class}, :required => true))
882
- end
883
- output_buffer.should have_tag("form li.string")
884
- output_buffer.should have_tag("form li.required")
885
- output_buffer.should have_tag("form li.another_class")
886
- end
887
-
888
- it 'should allow classes to be an array' do
889
- semantic_form_for(@new_post) do |builder|
890
- concat(builder.input(:title, :wrapper_html => {:class => [ :my_class, :another_class ]}))
891
- end
892
- output_buffer.should have_tag("form li.string")
893
- output_buffer.should have_tag("form li.my_class")
894
- output_buffer.should have_tag("form li.another_class")
895
- end
896
- end
897
-
898
- describe 'when not provided' do
899
- it 'should use default id and class' do
900
- semantic_form_for(@new_post) do |builder|
901
- concat(builder.input(:title))
902
- end
903
- output_buffer.should have_tag("form li#post_title_input")
904
- output_buffer.should have_tag("form li.string")
905
- end
906
- end
907
-
908
- end
909
- end
910
-
911
- describe ':as any type of input' do
912
-
913
- it 'should create a list item for each input' do
914
- semantic_form_for(@new_post) do |builder|
915
- concat(builder.input(:title))
916
- concat(builder.input(:body))
917
- end
918
- output_buffer.should have_tag('form li', :count => 2)
919
- end
920
-
921
- describe 'when there are errors on the object for this method' do
922
- before do
923
- @title_errors = ['must not be blank', 'must be longer than 10 characters', 'must be awesome']
924
- @errors = mock('errors')
925
- @errors.stub!(:[]).with(:title).and_return(@title_errors)
926
- @new_post.stub!(:errors).and_return(@errors)
927
- end
928
-
929
- it 'should apply an errors class to the list item' do
930
- semantic_form_for(@new_post) do |builder|
931
- concat(builder.input(:title))
932
- end
933
- output_buffer.should have_tag('form li.error')
934
- end
935
-
936
- it 'should not wrap the input with the Rails default error wrapping' do
937
- semantic_form_for(@new_post) do |builder|
938
- concat(builder.input(:title))
939
- end
940
- output_buffer.should_not have_tag('div.fieldWithErrors')
941
- end
942
-
943
- it 'should render a paragraph for the errors' do
944
- Formtastic::SemanticFormBuilder.inline_errors = :sentence
945
- semantic_form_for(@new_post) do |builder|
946
- concat(builder.input(:title))
947
- end
948
- output_buffer.should have_tag('form li.error p.inline-errors')
949
- end
950
-
951
- it 'should not display an error list' do
952
- Formtastic::SemanticFormBuilder.inline_errors = :list
953
- semantic_form_for(@new_post) do |builder|
954
- concat(builder.input(:title))
955
- end
956
- output_buffer.should have_tag('form li.error ul.errors')
957
- end
958
- end
959
-
960
- describe 'when there are no errors on the object for this method' do
961
- before do
962
- semantic_form_for(@new_post) do |builder|
963
- concat(builder.input(:title))
964
- end
965
- end
966
-
967
- it 'should not apply an errors class to the list item' do
968
- output_buffer.should_not have_tag('form li.error')
969
- end
970
-
971
- it 'should not render a paragraph for the errors' do
972
- output_buffer.should_not have_tag('form li.error p.inline-errors')
973
- end
974
-
975
- it 'should not display an error list' do
976
- output_buffer.should_not have_tag('form li.error ul.errors')
977
- end
978
- end
979
-
980
- describe 'when no object is provided' do
981
- before do
982
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
983
- concat(builder.input(:title))
984
- end
985
- end
986
-
987
- it 'should not apply an errors class to the list item' do
988
- output_buffer.should_not have_tag('form li.error')
989
- end
990
-
991
- it 'should not render a paragraph for the errors' do
992
- output_buffer.should_not have_tag('form li.error p.inline-errors')
993
- end
994
-
995
- it 'should not display an error list' do
996
- output_buffer.should_not have_tag('form li.error ul.errors')
997
- end
998
- end
999
- end
1000
-
1001
- # Test string_mappings: :string, :password and :numeric
1002
- string_mappings = Formtastic::SemanticFormBuilder::INPUT_MAPPINGS.slice(*Formtastic::SemanticFormBuilder::STRING_MAPPINGS)
1003
- string_mappings.each do |type, template_method|
1004
- describe ":as => #{type.inspect}" do
1005
-
1006
- before do
1007
- @new_post.stub!(:title)
1008
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => type, :limit => 50))
1009
-
1010
- semantic_form_for(@new_post) do |builder|
1011
- concat(builder.input(:title, :as => type))
1012
- end
1013
- end
1014
-
1015
- it "should have a #{type} class on the wrapper" do
1016
- output_buffer.should have_tag("form li.#{type}")
1017
- end
1018
-
1019
- it 'should have a post_title_input id on the wrapper' do
1020
- output_buffer.should have_tag('form li#post_title_input')
1021
- end
1022
-
1023
- it 'should generate a label for the input' do
1024
- output_buffer.should have_tag('form li label')
1025
- output_buffer.should have_tag('form li label[@for="post_title"')
1026
- output_buffer.should have_tag('form li label', /Title/)
1027
- end
1028
-
1029
- input_type = template_method.to_s.split('_').first
1030
-
1031
- it "should generate a #{input_type} input" do
1032
- output_buffer.should have_tag("form li input")
1033
- output_buffer.should have_tag("form li input#post_title")
1034
- output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
1035
- output_buffer.should have_tag("form li input[@name=\"post[title]\"]")
1036
- end
1037
-
1038
- unless type == :numeric
1039
- it 'should have a maxlength matching the column limit' do
1040
- @new_post.column_for_attribute(:title).limit.should == 50
1041
- output_buffer.should have_tag("form li input[@maxlength='50']")
1042
- end
1043
-
1044
- it 'should use default_text_field_size for columns longer than default_text_field_size' do
1045
- default_size = Formtastic::SemanticFormBuilder.default_text_field_size
1046
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => type, :limit => default_size * 2))
1047
-
1048
- semantic_form_for(@new_post) do |builder|
1049
- concat(builder.input(:title, :as => type))
1050
- end
1051
-
1052
- output_buffer.should have_tag("form li input[@size='#{default_size}']")
1053
- end
1054
-
1055
- it 'should use the column size for columns shorter than default_text_field_size' do
1056
- column_limit_shorted_than_default = 1
1057
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => type, :limit => column_limit_shorted_than_default))
1058
-
1059
- semantic_form_for(@new_post) do |builder|
1060
- concat(builder.input(:title, :as => type))
1061
- end
1062
-
1063
- output_buffer.should have_tag("form li input[@size='#{column_limit_shorted_than_default}']")
1064
- end
1065
- end
1066
-
1067
- it 'should use default_text_field_size for methods without database columns' do
1068
- default_size = Formtastic::SemanticFormBuilder.default_text_field_size
1069
- @new_post.stub!(:column_for_attribute).and_return(nil) # Return a nil column
1070
-
1071
- semantic_form_for(@new_post) do |builder|
1072
- concat(builder.input(:title, :as => type))
1073
- end
1074
-
1075
- output_buffer.should have_tag("form li input[@size='#{default_size}']")
1076
- end
1077
-
1078
- it 'should use input_html to style inputs' do
1079
- semantic_form_for(@new_post) do |builder|
1080
- concat(builder.input(:title, :as => type, :input_html => { :class => 'myclass' }))
1081
- end
1082
- output_buffer.should have_tag("form li input.myclass")
1083
- end
1084
-
1085
- it 'should consider input_html :id in labels' do
1086
- semantic_form_for(@new_post) do |builder|
1087
- concat(builder.input(:title, :as => type, :input_html => { :id => 'myid' }))
1088
- end
1089
- output_buffer.should have_tag('form li label[@for="myid"]')
1090
- end
1091
-
1092
- it 'should generate input and labels even if no object is given' do
1093
- semantic_form_for(:project, :url => 'http://test.host/') do |builder|
1094
- concat(builder.input(:title, :as => type))
1095
- end
1096
-
1097
- output_buffer.should have_tag('form li label')
1098
- output_buffer.should have_tag('form li label[@for="project_title"')
1099
- output_buffer.should have_tag('form li label', /Title/)
1100
-
1101
- output_buffer.should have_tag("form li input")
1102
- output_buffer.should have_tag("form li input#project_title")
1103
- output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
1104
- output_buffer.should have_tag("form li input[@name=\"project[title]\"]")
1105
- end
1106
-
1107
- end
1108
- end
1109
-
1110
- # Test other mappings that are not strings: :text and :file.
1111
- other_mappings = Formtastic::SemanticFormBuilder::INPUT_MAPPINGS.except(*Formtastic::SemanticFormBuilder::STRING_MAPPINGS)
1112
- other_mappings.each do |type, template_method|
1113
- describe ":as => #{type.inspect}" do
1114
-
1115
- before do
1116
- @new_post.stub!(:body)
1117
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => type))
1118
-
1119
- semantic_form_for(@new_post) do |builder|
1120
- concat(builder.input(:body, :as => type))
1121
- end
1122
- end
1123
-
1124
- it "should have a #{type} class on the wrapper" do
1125
- output_buffer.should have_tag('form li.#{type}')
1126
- end
1127
-
1128
- it 'should have a post_title_input id on the wrapper' do
1129
- output_buffer.should have_tag('form li#post_body_input')
1130
- end
1131
-
1132
- it 'should generate a label for the input' do
1133
- output_buffer.should have_tag('form li label')
1134
- output_buffer.should have_tag('form li label[@for="post_body"')
1135
- output_buffer.should have_tag('form li label', /Body/)
1136
- end
1137
-
1138
- input_type = template_method.to_s.gsub(/_field|_/, '')
1139
-
1140
- if template_method.to_s =~ /_field$/ # password_field
1141
-
1142
- it "should generate a #{input_type} input" do
1143
- output_buffer.should have_tag("form li input")
1144
- output_buffer.should have_tag("form li input#post_body")
1145
- output_buffer.should have_tag("form li input[@name=\"post[body]\"]")
1146
- output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
1147
- end
1148
-
1149
- it 'should use input_html to style inputs' do
1150
- semantic_form_for(@new_post) do |builder|
1151
- concat(builder.input(:title, :as => type, :input_html => { :class => 'myclass' }))
1152
- end
1153
- output_buffer.should have_tag("form li input.myclass")
1154
- end
1155
-
1156
- else # text_area
1157
-
1158
- it "should generate a #{input_type} input" do
1159
- output_buffer.should have_tag("form li #{input_type}")
1160
- output_buffer.should have_tag("form li #{input_type}#post_body")
1161
- output_buffer.should have_tag("form li #{input_type}[@name=\"post[body]\"]")
1162
- end
1163
-
1164
- it 'should use input_html to style inputs' do
1165
- semantic_form_for(@new_post) do |builder|
1166
- concat(builder.input(:title, :as => type, :input_html => { :class => 'myclass' }))
1167
- end
1168
- output_buffer.should have_tag("form li #{input_type}.myclass")
1169
- end
1170
-
1171
- end
1172
-
1173
- describe 'when no object is given' do
1174
- before(:each) do
1175
- semantic_form_for(:project, :url => 'http://test.host/') do |builder|
1176
- concat(builder.input(:title, :as => type))
1177
- end
1178
- end
1179
-
1180
- it 'should generate input' do
1181
- if template_method.to_s =~ /_field$/ # password_field
1182
- output_buffer.should have_tag("form li input")
1183
- output_buffer.should have_tag("form li input#project_title")
1184
- output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
1185
- output_buffer.should have_tag("form li input[@name=\"project[title]\"]")
1186
- else
1187
- output_buffer.should have_tag("form li #{input_type}")
1188
- output_buffer.should have_tag("form li #{input_type}#project_title")
1189
- output_buffer.should have_tag("form li #{input_type}[@name=\"project[title]\"]")
1190
- end
1191
- end
1192
-
1193
- it 'should generate labels' do
1194
- output_buffer.should have_tag('form li label')
1195
- output_buffer.should have_tag('form li label[@for="project_title"')
1196
- output_buffer.should have_tag('form li label', /Title/)
1197
- end
1198
- end
1199
-
1200
- end
1201
- end
1202
-
1203
- describe ":as => :hidden" do
1204
- before do
1205
- @new_post.stub!(:hidden)
1206
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string))
1207
-
1208
- semantic_form_for(@new_post) do |builder|
1209
- concat(builder.input(:hidden, :as => :hidden))
1210
- end
1211
- end
1212
-
1213
- it "should have a hidden class on the wrapper" do
1214
- output_buffer.should have_tag('form li.hidden')
1215
- end
1216
-
1217
- it 'should have a post_hidden_input id on the wrapper' do
1218
- output_buffer.should have_tag('form li#post_hidden_input')
1219
- end
1220
-
1221
- it 'should not generate a label for the input' do
1222
- output_buffer.should_not have_tag('form li label')
1223
- end
1224
-
1225
- it "should generate a input field" do
1226
- output_buffer.should have_tag("form li input#post_hidden")
1227
- output_buffer.should have_tag("form li input[@type=\"hidden\"]")
1228
- output_buffer.should have_tag("form li input[@name=\"post[hidden]\"]")
1229
- end
1230
- end
1231
-
1232
- describe ":as => :time_zone" do
1233
- before do
1234
- @new_post.stub!(:time_zone)
1235
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string))
1236
-
1237
- semantic_form_for(@new_post) do |builder|
1238
- concat(builder.input(:time_zone))
1239
- end
1240
- end
1241
-
1242
- it "should have a time_zone class on the wrapper" do
1243
- output_buffer.should have_tag('form li.time_zone')
1244
- end
1245
-
1246
- it 'should have a post_title_input id on the wrapper' do
1247
- output_buffer.should have_tag('form li#post_time_zone_input')
1248
- end
1249
-
1250
- it 'should generate a label for the input' do
1251
- output_buffer.should have_tag('form li label')
1252
- output_buffer.should have_tag('form li label[@for="post_time_zone"')
1253
- output_buffer.should have_tag('form li label', /Time zone/)
1254
- end
1255
-
1256
- it "should generate a select" do
1257
- output_buffer.should have_tag("form li select")
1258
- output_buffer.should have_tag("form li select#post_time_zone")
1259
- output_buffer.should have_tag("form li select[@name=\"post[time_zone]\"]")
1260
- end
1261
-
1262
- it 'should use input_html to style inputs' do
1263
- semantic_form_for(@new_post) do |builder|
1264
- concat(builder.input(:time_zone, :input_html => { :class => 'myclass' }))
1265
- end
1266
- output_buffer.should have_tag("form li select.myclass")
1267
- end
1268
-
1269
- describe 'when no object is given' do
1270
- before(:each) do
1271
- semantic_form_for(:project, :url => 'http://test.host/') do |builder|
1272
- concat(builder.input(:time_zone, :as => :time_zone))
1273
- end
1274
- end
1275
-
1276
- it 'should generate labels' do
1277
- output_buffer.should have_tag('form li label')
1278
- output_buffer.should have_tag('form li label[@for="project_time_zone"')
1279
- output_buffer.should have_tag('form li label', /Time zone/)
1280
- end
1281
-
1282
- it 'should generate select inputs' do
1283
- output_buffer.should have_tag("form li select")
1284
- output_buffer.should have_tag("form li select#project_time_zone")
1285
- output_buffer.should have_tag("form li select[@name=\"project[time_zone]\"]")
1286
- end
1287
- end
1288
- end
1289
-
1290
- describe ":as => :country" do
1291
-
1292
- before do
1293
- @new_post.stub!(:country)
1294
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string))
1295
- end
1296
-
1297
- describe "when country_select is not available as a helper from a plugin" do
1298
-
1299
- it "should raise an error, sugesting the author installs a plugin" do
1300
- lambda {
1301
- semantic_form_for(@new_post) do |builder|
1302
- concat(builder.input(:country, :as => :country))
1303
- end
1304
- }.should raise_error
1305
- end
1306
-
1307
- end
1308
-
1309
- describe "when country_select is available as a helper (from a plugin)" do
1310
-
1311
- before do
1312
- semantic_form_for(@new_post) do |builder|
1313
- builder.stub!(:country_select).and_return("<select><option>...</option></select>")
1314
- concat(builder.input(:country, :as => :country))
1315
- end
1316
- end
1317
-
1318
- it "should have a time_zone class on the wrapper" do
1319
- output_buffer.should have_tag('form li.country')
1320
- end
1321
-
1322
- it 'should have a post_title_input id on the wrapper' do
1323
- output_buffer.should have_tag('form li#post_country_input')
1324
- end
1325
-
1326
- it 'should generate a label for the input' do
1327
- output_buffer.should have_tag('form li label')
1328
- output_buffer.should have_tag('form li label[@for="post_country"')
1329
- output_buffer.should have_tag('form li label', /Country/)
1330
- end
1331
-
1332
- it "should generate a select" do
1333
- output_buffer.should have_tag("form li select")
1334
- end
1335
-
1336
- end
1337
-
1338
- describe ":priority_countries option" do
1339
-
1340
- it "should be passed down to the country_select helper when provided" do
1341
- priority_countries = ["Foo", "Bah"]
1342
- semantic_form_for(@new_post) do |builder|
1343
- builder.stub!(:country_select).and_return("<select><option>...</option></select>")
1344
- builder.should_receive(:country_select).with(:country, priority_countries, {}, {}).and_return("<select><option>...</option></select>")
1345
-
1346
- concat(builder.input(:country, :as => :country, :priority_countries => priority_countries))
1347
- end
1348
- end
1349
-
1350
- it "should default to the @@priority_countries config when absent" do
1351
- priority_countries = Formtastic::SemanticFormBuilder.priority_countries
1352
- priority_countries.should_not be_empty
1353
- priority_countries.should_not be_nil
1354
-
1355
- semantic_form_for(@new_post) do |builder|
1356
- builder.stub!(:country_select).and_return("<select><option>...</option></select>")
1357
- builder.should_receive(:country_select).with(:country, priority_countries, {}, {}).and_return("<select><option>...</option></select>")
1358
-
1359
- concat(builder.input(:country, :as => :country))
1360
- end
1361
- end
1362
-
1363
- end
1364
-
1365
- end
1366
-
1367
- describe ':as => :radio' do
1368
-
1369
- before do
1370
- @new_post.stub!(:author).and_return(@bob)
1371
- @new_post.stub!(:author_id).and_return(@bob.id)
1372
- Post.stub!(:reflect_on_association).and_return { |column_name| mock('reflection', :options => {}, :klass => Author, :macro => :belongs_to) }
1373
- end
1374
-
1375
- describe 'for belongs_to association' do
1376
- before do
1377
- semantic_form_for(@new_post) do |builder|
1378
- concat(builder.input(:author, :as => :radio, :value_as_class => true))
1379
- end
1380
- end
1381
-
1382
- it 'should have a radio class on the wrapper' do
1383
- output_buffer.should have_tag('form li.radio')
1384
- end
1385
-
1386
- it 'should have a post_author_input id on the wrapper' do
1387
- output_buffer.should have_tag('form li#post_author_input')
1388
- end
1389
-
1390
- it 'should generate a fieldset and legend containing label text for the input' do
1391
- output_buffer.should have_tag('form li fieldset')
1392
- output_buffer.should have_tag('form li fieldset legend')
1393
- output_buffer.should have_tag('form li fieldset legend', /Author/)
1394
- end
1395
-
1396
- it 'should generate an ordered list with a list item for each choice' do
1397
- output_buffer.should have_tag('form li fieldset ol')
1398
- output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
1399
- end
1400
-
1401
- it 'should have one option with a "checked" attribute' do
1402
- output_buffer.should have_tag('form li input[@checked]', :count => 1)
1403
- end
1404
-
1405
- describe "each choice" do
1406
-
1407
- it 'should contain a label for the radio input with a nested input and label text' do
1408
- Author.find(:all).each do |author|
1409
- output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
1410
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_id_#{author.id}']")
1411
- end
1412
- end
1413
-
1414
- it 'should use values as li.class when value_as_class is true' do
1415
- Author.find(:all).each do |author|
1416
- output_buffer.should have_tag("form li fieldset ol li.#{author.id} label")
1417
- end
1418
- end
1419
-
1420
- it "should have a radio input" do
1421
- Author.find(:all).each do |author|
1422
- output_buffer.should have_tag("form li fieldset ol li label input#post_author_id_#{author.id}")
1423
- output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
1424
- output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
1425
- output_buffer.should have_tag("form li fieldset ol li label input[@name='post[author_id]']")
1426
- end
1427
- end
1428
-
1429
- it "should mark input as checked if it's the the existing choice" do
1430
- @new_post.author_id.should == @bob.id
1431
- @new_post.author.id.should == @bob.id
1432
- @new_post.author.should == @bob
1433
-
1434
- semantic_form_for(@new_post) do |builder|
1435
- concat(builder.input(:author, :as => :radio))
1436
- end
1437
-
1438
- output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
1439
- end
1440
- end
1441
-
1442
- describe 'and no object is given' do
1443
- before(:each) do
1444
- output_buffer.replace ''
1445
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
1446
- concat(builder.input(:author_id, :as => :radio, :collection => Author.find(:all)))
1447
- end
1448
- end
1449
-
1450
- it 'should generate a fieldset with legend' do
1451
- output_buffer.should have_tag('form li fieldset legend', /Author/)
1452
- end
1453
-
1454
- it 'shold generate an li tag for each item in the collection' do
1455
- output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
1456
- end
1457
-
1458
- it 'should generate labels for each item' do
1459
- Author.find(:all).each do |author|
1460
- output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
1461
- output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
1462
- end
1463
- end
1464
-
1465
- it 'should generate inputs for each item' do
1466
- Author.find(:all).each do |author|
1467
- output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
1468
- output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
1469
- output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
1470
- output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id]']")
1471
- end
1472
- end
1473
- end
1474
- end
1475
- end
1476
-
1477
- describe ':as => :select' do
1478
-
1479
- before do
1480
- @new_post.stub!(:author).and_return(@bob)
1481
- @new_post.stub!(:author_id).and_return(@bob.id)
1482
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
1483
- end
1484
-
1485
- describe 'for a belongs_to association' do
1486
- before do
1487
- semantic_form_for(@new_post) do |builder|
1488
- concat(builder.input(:author, :as => :select))
1489
- end
1490
- end
1491
-
1492
- it 'should have a select class on the wrapper' do
1493
- output_buffer.should have_tag('form li.select')
1494
- end
1495
-
1496
- it 'should have a post_author_input id on the wrapper' do
1497
- output_buffer.should have_tag('form li#post_author_input')
1498
- end
1499
-
1500
- it 'should have a label inside the wrapper' do
1501
- output_buffer.should have_tag('form li label')
1502
- output_buffer.should have_tag('form li label', /Author/)
1503
- output_buffer.should have_tag("form li label[@for='post_author_id']")
1504
- end
1505
-
1506
- it 'should have a select inside the wrapper' do
1507
- output_buffer.should have_tag('form li select')
1508
- output_buffer.should have_tag('form li select#post_author_id')
1509
- end
1510
-
1511
- it 'should not create a multi-select' do
1512
- output_buffer.should_not have_tag('form li select[@multiple]')
1513
- end
1514
-
1515
- it 'should create a select without size' do
1516
- output_buffer.should_not have_tag('form li select[@size]')
1517
- end
1518
-
1519
- it 'should have a blank option' do
1520
- output_buffer.should have_tag("form li select option[@value='']")
1521
- end
1522
-
1523
- it 'should have a select option for each Author' do
1524
- output_buffer.should have_tag('form li select option', :count => Author.find(:all).size + 1)
1525
- Author.find(:all).each do |author|
1526
- output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
1527
- end
1528
- end
1529
-
1530
- it 'should have one option with a "selected" attribute' do
1531
- output_buffer.should have_tag('form li select option[@selected]', :count => 1)
1532
- end
1533
-
1534
- it 'should not singularize the association name' do
1535
- @new_post.stub!(:author_status).and_return(@bob)
1536
- @new_post.stub!(:author_status_id).and_return(@bob.id)
1537
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
1538
-
1539
- semantic_form_for(@new_post) do |builder|
1540
- concat(builder.input(:author_status, :as => :select))
1541
- end
1542
-
1543
- output_buffer.should have_tag('form li select#post_author_status_id')
1544
- end
1545
- end
1546
-
1547
- describe 'for a has_many association' do
1548
- before do
1549
- semantic_form_for(@fred) do |builder|
1550
- concat(builder.input(:posts, :as => :select))
1551
- end
1552
- end
1553
-
1554
- it 'should have a select class on the wrapper' do
1555
- output_buffer.should have_tag('form li.select')
1556
- end
1557
-
1558
- it 'should have a post_author_input id on the wrapper' do
1559
- output_buffer.should have_tag('form li#author_posts_input')
1560
- end
1561
-
1562
- it 'should have a label inside the wrapper' do
1563
- output_buffer.should have_tag('form li label')
1564
- output_buffer.should have_tag('form li label', /Post/)
1565
- output_buffer.should have_tag("form li label[@for='author_post_ids']")
1566
- end
1567
-
1568
- it 'should have a select inside the wrapper' do
1569
- output_buffer.should have_tag('form li select')
1570
- output_buffer.should have_tag('form li select#author_post_ids')
1571
- end
1572
-
1573
- it 'should have a multi-select select' do
1574
- output_buffer.should have_tag('form li select[@multiple="multiple"]')
1575
- end
1576
-
1577
- it 'should have a select option for each Post' do
1578
- output_buffer.should have_tag('form li select option', :count => Post.find(:all).size)
1579
- Post.find(:all).each do |post|
1580
- output_buffer.should have_tag("form li select option[@value='#{post.id}']", /#{post.to_label}/)
1581
- end
1582
- end
1583
-
1584
- it 'should not have a blank option' do
1585
- output_buffer.should_not have_tag("form li select option[@value='']")
1586
- end
1587
-
1588
- it 'should have one option with a "selected" attribute' do
1589
- output_buffer.should have_tag('form li select option[@selected]', :count => 1)
1590
- end
1591
- end
1592
-
1593
- describe 'for a has_and_belongs_to_many association' do
1594
- before do
1595
- semantic_form_for(@freds_post) do |builder|
1596
- concat(builder.input(:authors, :as => :select))
1597
- end
1598
- end
1599
-
1600
- it 'should have a select class on the wrapper' do
1601
- output_buffer.should have_tag('form li.select')
1602
- end
1603
-
1604
- it 'should have a post_author_input id on the wrapper' do
1605
- output_buffer.should have_tag('form li#post_authors_input')
1606
- end
1607
-
1608
- it 'should have a label inside the wrapper' do
1609
- output_buffer.should have_tag('form li label')
1610
- output_buffer.should have_tag('form li label', /Author/)
1611
- output_buffer.should have_tag("form li label[@for='post_author_ids']")
1612
- end
1613
-
1614
- it 'should have a select inside the wrapper' do
1615
- output_buffer.should have_tag('form li select')
1616
- output_buffer.should have_tag('form li select#post_author_ids')
1617
- end
1618
-
1619
- it 'should have a multi-select select' do
1620
- output_buffer.should have_tag('form li select[@multiple="multiple"]')
1621
- end
1622
-
1623
- it 'should have a select option for each Author' do
1624
- output_buffer.should have_tag('form li select option', :count => Author.find(:all).size)
1625
- Author.find(:all).each do |author|
1626
- output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
1627
- end
1628
- end
1629
-
1630
- it 'should not have a blank option' do
1631
- output_buffer.should_not have_tag("form li select option[@value='']")
1632
- end
1633
-
1634
- it 'should have one option with a "selected" attribute' do
1635
- output_buffer.should have_tag('form li select option[@selected]', :count => 1)
1636
- end
1637
- end
1638
-
1639
- describe 'when :include_blank is not set' do
1640
- before do
1641
- @new_post.stub!(:author_id).and_return(nil)
1642
- semantic_form_for(@new_post) do |builder|
1643
- concat(builder.input(:author, :as => :select))
1644
- end
1645
- end
1646
-
1647
- it 'should have a blank option by default' do
1648
- output_buffer.should have_tag("form li select option[@value='']", "")
1649
- end
1650
- end
1651
-
1652
- describe 'when :include_blank is set to false' do
1653
- before do
1654
- @new_post.stub!(:author_id).and_return(nil)
1655
- semantic_form_for(@new_post) do |builder|
1656
- concat(builder.input(:author, :as => :select, :include_blank => false))
1657
- end
1658
- end
1659
-
1660
- it 'should not have a blank option' do
1661
- output_buffer.should_not have_tag("form li select option[@value='']", "")
1662
- end
1663
- end
1664
-
1665
- describe 'when :prompt => "choose something" is set' do
1666
- before do
1667
- @new_post.stub!(:author_id).and_return(nil)
1668
- semantic_form_for(@new_post) do |builder|
1669
- concat(builder.input(:author, :as => :select, :prompt => "choose author"))
1670
- end
1671
- end
1672
-
1673
- it 'should have a select with prompt' do
1674
- output_buffer.should have_tag("form li select option[@value='']", /choose author/)
1675
- end
1676
-
1677
- it 'should not have a blank select option' do
1678
- output_buffer.should_not have_tag("form li select option[@value='']", "")
1679
- end
1680
- end
1681
-
1682
- describe 'when no object is given' do
1683
- before(:each) do
1684
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
1685
- concat(builder.input(:author, :as => :select, :collection => Author.find(:all)))
1686
- end
1687
- end
1688
-
1689
- it 'should generate label' do
1690
- output_buffer.should have_tag('form li label', /Author/)
1691
- output_buffer.should have_tag("form li label[@for='project_author']")
1692
- end
1693
-
1694
- it 'should generate select inputs' do
1695
- output_buffer.should have_tag('form li select#project_author')
1696
- output_buffer.should have_tag('form li select option', :count => Author.find(:all).size + 1)
1697
- end
1698
-
1699
- it 'should generate an option to each item' do
1700
- Author.find(:all).each do |author|
1701
- output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
1702
- end
1703
- end
1704
- end
1705
- end
1706
-
1707
- describe ':as => :check_boxes' do
1708
-
1709
- describe 'for a has_many association' do
1710
- before do
1711
- semantic_form_for(@fred) do |builder|
1712
- concat(builder.input(:posts, :as => :check_boxes, :value_as_class => true))
1713
- end
1714
- end
1715
-
1716
- it 'should have a check_boxes class on the wrapper' do
1717
- output_buffer.should have_tag('form li.check_boxes')
1718
- end
1719
-
1720
- it 'should have a author_posts_input id on the wrapper' do
1721
- output_buffer.should have_tag('form li#author_posts_input')
1722
- end
1723
-
1724
- it 'should generate a fieldset and legend containing label text for the input' do
1725
- output_buffer.should have_tag('form li fieldset')
1726
- output_buffer.should have_tag('form li fieldset legend')
1727
- output_buffer.should have_tag('form li fieldset legend', /Posts/)
1728
- end
1729
-
1730
- it 'should generate an ordered list with a list item for each choice' do
1731
- output_buffer.should have_tag('form li fieldset ol')
1732
- output_buffer.should have_tag('form li fieldset ol li', :count => Post.find(:all).size)
1733
- end
1734
-
1735
- it 'should have one option with a "checked" attribute' do
1736
- output_buffer.should have_tag('form li input[@checked]', :count => 1)
1737
- end
1738
-
1739
- it 'should generate hidden inputs with default value blank' do
1740
- output_buffer.should have_tag("form li fieldset ol li label input[@type='hidden'][@value='']", :count => Post.find(:all).size)
1741
- end
1742
-
1743
- describe "each choice" do
1744
-
1745
- it 'should contain a label for the radio input with a nested input and label text' do
1746
- Post.find(:all).each do |post|
1747
- output_buffer.should have_tag('form li fieldset ol li label', /#{post.to_label}/)
1748
- output_buffer.should have_tag("form li fieldset ol li label[@for='author_post_ids_#{post.id}']")
1749
- end
1750
- end
1751
-
1752
- it 'should use values as li.class when value_as_class is true' do
1753
- Post.find(:all).each do |post|
1754
- output_buffer.should have_tag("form li fieldset ol li.#{post.id} label")
1755
- end
1756
- end
1757
-
1758
- it 'should have a checkbox input for each post' do
1759
- Post.find(:all).each do |post|
1760
- output_buffer.should have_tag("form li fieldset ol li label input#author_post_ids_#{post.id}")
1761
- output_buffer.should have_tag("form li fieldset ol li label input[@name='author[post_ids][]']", :count => 2)
1762
- end
1763
- end
1764
-
1765
- it "should mark input as checked if it's the the existing choice" do
1766
- Post.find(:all).include?(@fred.posts.first).should be_true
1767
- output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
1768
- end
1769
- end
1770
-
1771
- describe 'and no object is given' do
1772
- before(:each) do
1773
- output_buffer.replace ''
1774
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
1775
- concat(builder.input(:author_id, :as => :check_boxes, :collection => Author.find(:all)))
1776
- end
1777
- end
1778
-
1779
- it 'should generate a fieldset with legend' do
1780
- output_buffer.should have_tag('form li fieldset legend', /Author/)
1781
- end
1782
-
1783
- it 'shold generate an li tag for each item in the collection' do
1784
- output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
1785
- end
1786
-
1787
- it 'should generate labels for each item' do
1788
- Author.find(:all).each do |author|
1789
- output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
1790
- output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
1791
- end
1792
- end
1793
-
1794
- it 'should generate inputs for each item' do
1795
- Author.find(:all).each do |author|
1796
- output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
1797
- output_buffer.should have_tag("form li fieldset ol li label input[@type='checkbox']")
1798
- output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
1799
- output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id][]']")
1800
- end
1801
- end
1802
- end
1803
- end
1804
- end
1805
-
1806
- describe 'for collections' do
1807
-
1808
- before do
1809
- @new_post.stub!(:author).and_return(@bob)
1810
- @new_post.stub!(:author_id).and_return(@bob.id)
1811
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
1812
- end
1813
-
1814
- { :select => :option, :radio => :input, :check_boxes => :'input[@type="checkbox"]' }.each do |type, countable|
1815
-
1816
- describe ":as => #{type.inspect}" do
1817
- describe 'when the :collection option is not provided' do
1818
- it 'should perform a basic find on the association class' do
1819
- Author.should_receive(:find)
1820
-
1821
- semantic_form_for(@new_post) do |builder|
1822
- concat(builder.input(:author, :as => type))
1823
- end
1824
- end
1825
-
1826
- it 'should show a deprecation warning if user gives the association using _id' do
1827
- # Check for deprecation message
1828
- ::ActiveSupport::Deprecation.should_receive(:warn).with(/association/, anything())
1829
-
1830
- Author.should_receive(:find)
1831
- semantic_form_for(@new_post) do |builder|
1832
- concat(builder.input(:author_id, :as => type))
1833
- end
1834
- end
1835
- end
1836
-
1837
- describe 'when the :collection option is provided' do
1838
-
1839
- before do
1840
- @authors = Author.find(:all) * 2
1841
- output_buffer.replace '' # clears the output_buffer from the before block, hax!
1842
- end
1843
-
1844
- it 'should not call find() on the parent class' do
1845
- Author.should_not_receive(:find)
1846
- semantic_form_for(@new_post) do |builder|
1847
- concat(builder.input(:author, :as => type, :collection => @authors))
1848
- end
1849
- end
1850
-
1851
- it 'should use the provided collection' do
1852
- semantic_form_for(@new_post) do |builder|
1853
- concat(builder.input(:author, :as => type, :collection => @authors))
1854
- end
1855
- output_buffer.should have_tag("form li.#{type} #{countable}", :count => @authors.size + (type == :select ? 1 : 0))
1856
- end
1857
-
1858
- describe 'and the :collection is an array of strings' do
1859
- before do
1860
- @new_post.stub!(:category_name).and_return('')
1861
- @categories = [ 'General', 'Design', 'Development' ]
1862
- end
1863
-
1864
- it "should use the string as the label text and value for each #{countable}" do
1865
- semantic_form_for(@new_post) do |builder|
1866
- concat(builder.input(:category_name, :as => type, :collection => @categories))
1867
- end
1868
-
1869
- @categories.each do |value|
1870
- output_buffer.should have_tag("form li.#{type}", /#{value}/)
1871
- output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value}']")
1872
- end
1873
- end
1874
-
1875
- if type == :radio
1876
- it 'should generate a sanitized label for attribute' do
1877
- @bob.stub!(:category_name).and_return(@categories)
1878
- semantic_form_for(@new_post) do |builder|
1879
- builder.semantic_fields_for(@bob) do |bob_builder|
1880
- concat(bob_builder.input(:category_name, :as => type, :collection => @categories))
1881
- end
1882
- end
1883
-
1884
- @categories.each do |item|
1885
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_#{item.downcase}']")
1886
- end
1887
- end
1888
- end
1889
- end
1890
-
1891
- describe 'and the :collection is a hash of strings' do
1892
- before do
1893
- @new_post.stub!(:category_name).and_return('')
1894
- @categories = { 'General' => 'gen', 'Design' => 'des','Development' => 'dev' }
1895
- end
1896
-
1897
- it "should use the key as the label text and the hash value as the value attribute for each #{countable}" do
1898
- semantic_form_for(@new_post) do |builder|
1899
- concat(builder.input(:category_name, :as => type, :collection => @categories))
1900
- end
1901
-
1902
- @categories.each do |label, value|
1903
- output_buffer.should have_tag("form li.#{type}", /#{label}/)
1904
- output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value}']")
1905
- end
1906
- end
1907
- end
1908
-
1909
- describe 'and the :collection is an array of arrays' do
1910
- before do
1911
- @new_post.stub!(:category_name).and_return('')
1912
- @categories = { 'General' => 'gen', 'Design' => 'des','Development' => 'dev' }.to_a
1913
- end
1914
-
1915
- it "should use the first value as the label text and the last value as the value attribute for #{countable}" do
1916
- semantic_form_for(@new_post) do |builder|
1917
- concat(builder.input(:category_name, :as => type, :collection => @categories))
1918
- end
1919
-
1920
- @categories.each do |text, value|
1921
- label = type == :select ? :option : :label
1922
- output_buffer.should have_tag("form li.#{type} #{label}", /#{text}/i)
1923
- output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value.to_s}']")
1924
- end
1925
- end
1926
- end
1927
-
1928
- describe 'and the :collection is an array of symbols' do
1929
- before do
1930
- @new_post.stub!(:category_name).and_return('')
1931
- @categories = [ :General, :Design, :Development ]
1932
- end
1933
-
1934
- it "should use the symbol as the label text and value for each #{countable}" do
1935
- semantic_form_for(@new_post) do |builder|
1936
- concat(builder.input(:category_name, :as => type, :collection => @categories))
1937
- end
1938
-
1939
- @categories.each do |value|
1940
- label = type == :select ? :option : :label
1941
- output_buffer.should have_tag("form li.#{type} #{label}", /#{value}/i)
1942
- output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value.to_s}']")
1943
- end
1944
- end
1945
- end
1946
-
1947
- describe 'when the :label_method option is provided' do
1948
- before do
1949
- semantic_form_for(@new_post) do |builder|
1950
- concat(builder.input(:author, :as => type, :label_method => :login))
1951
- end
1952
- end
1953
-
1954
- it 'should have options with text content from the specified method' do
1955
- Author.find(:all).each do |author|
1956
- output_buffer.should have_tag("form li.#{type}", /#{author.login}/)
1957
- end
1958
- end
1959
- end
1960
-
1961
- describe 'when the :label_method option is not provided' do
1962
- Formtastic::SemanticFormBuilder.collection_label_methods.each do |label_method|
1963
-
1964
- describe "when the collection objects respond to #{label_method}" do
1965
- before do
1966
- @fred.stub!(:respond_to?).and_return { |m| m.to_s == label_method }
1967
- Author.find(:all).each { |a| a.stub!(label_method).and_return('The Label Text') }
1968
-
1969
- semantic_form_for(@new_post) do |builder|
1970
- concat(builder.input(:author, :as => type))
1971
- end
1972
- end
1973
-
1974
- it "should render the options with #{label_method} as the label" do
1975
- Author.find(:all).each do |author|
1976
- output_buffer.should have_tag("form li.#{type}", /The Label Text/)
1977
- end
1978
- end
1979
- end
1980
-
1981
- end
1982
- end
1983
-
1984
- describe 'when the :value_method option is provided' do
1985
- before do
1986
- semantic_form_for(@new_post) do |builder|
1987
- concat(builder.input(:author, :as => type, :value_method => :login))
1988
- end
1989
- end
1990
-
1991
- it 'should have options with values from specified method' do
1992
- Author.find(:all).each do |author|
1993
- output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{author.login}']")
1994
- end
1995
- end
1996
- end
1997
-
1998
- end
1999
- end
2000
- end
2001
-
2002
- describe 'for boolean attributes' do
2003
-
2004
- { :select => :option, :radio => :input }.each do |type, countable|
2005
- checked_or_selected = { :select => :selected, :radio => :checked }[type]
2006
-
2007
- describe ":as => #{type.inspect}" do
2008
-
2009
- before do
2010
- @new_post.stub!(:allow_comments)
2011
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
2012
-
2013
- semantic_form_for(@new_post) do |builder|
2014
- concat(builder.input(:allow_comments, :as => type))
2015
- end
2016
- end
2017
-
2018
- it "should have a #{type} class on the wrapper" do
2019
- output_buffer.should have_tag("form li.#{type}")
2020
- end
2021
-
2022
- it 'should have a post_allow_comments_input id on the wrapper' do
2023
- output_buffer.should have_tag('form li#post_allow_comments_input')
2024
- end
2025
-
2026
- it 'should generate a fieldset containing a legend' do
2027
- output_buffer.should have_tag("form li.#{type}", /Allow comments/)
2028
- end
2029
-
2030
- it "should generate two #{countable}" do
2031
- output_buffer.should have_tag("form li.#{type} #{countable}", :count => (type == :select ? 3 : 2))
2032
- output_buffer.should have_tag(%{form li.#{type} #{countable}[@value="true"]})
2033
- output_buffer.should have_tag(%{form li.#{type} #{countable}[@value="false"]})
2034
- end
2035
-
2036
- describe 'when the locale sets the label text' do
2037
- before do
2038
- I18n.backend.store_translations 'en', :formtastic => {:yes => 'Absolutely!', :no => 'Never!'}
2039
-
2040
- semantic_form_for(@new_post) do |builder|
2041
- concat(builder.input(:allow_comments, :as => type))
2042
- end
2043
- end
2044
-
2045
- after do
2046
- I18n.backend.store_translations 'en', :formtastic => {:yes => nil, :no => nil}
2047
- end
2048
-
2049
- it 'should allow translation of the labels' do
2050
- output_buffer.should have_tag("form li.#{type}", /Absolutely\!/)
2051
- output_buffer.should have_tag("form li.#{type}", /Never\!/)
2052
- end
2053
- end
2054
-
2055
- describe 'when the value is nil' do
2056
- before do
2057
- @new_post.stub!(:allow_comments).and_return(nil)
2058
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
2059
-
2060
- semantic_form_for(@new_post) do |builder|
2061
- concat(builder.input(:allow_comments, :as => type))
2062
- end
2063
- end
2064
-
2065
- it "should not mark either #{countable} as #{checked_or_selected}" do
2066
- output_buffer.should_not have_tag(%{form li.#{type} input[@#{checked_or_selected}="#{checked_or_selected}"]})
2067
- end
2068
- end
2069
-
2070
- describe 'when the value is true' do
2071
- before do
2072
- @new_post.stub!(:allow_comments).and_return(true)
2073
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
2074
- semantic_form_for(@new_post) do |builder|
2075
- concat(builder.input(:allow_comments, :as => type))
2076
- end
2077
- end
2078
-
2079
- it "should mark the true #{countable} as #{checked_or_selected}" do
2080
- output_buffer.should have_tag(%{form li.#{type} #{countable}[@value="true"][@#{checked_or_selected}="#{checked_or_selected}"]}, :count => 1)
2081
- end
2082
-
2083
- it "should not mark the false #{countable} as #{checked_or_selected}" do
2084
- output_buffer.should_not have_tag(%{form li.#{type} #{countable}[@value="false"][@#{checked_or_selected}="#{checked_or_selected}"]})
2085
- end
2086
- end
2087
-
2088
- describe 'when the value is false' do
2089
- before do
2090
- @new_post.stub!(:allow_comments).and_return(false)
2091
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
2092
- semantic_form_for(@new_post) do |builder|
2093
- concat(builder.input(:allow_comments, :as => type))
2094
- end
2095
- end
2096
-
2097
- it "should not mark the true #{countable} as #{checked_or_selected}" do
2098
- output_buffer.should_not have_tag(%{form li.#{type} #{countable}[@value="true"][@#{checked_or_selected}="#{checked_or_selected}"]})
2099
- end
2100
-
2101
- it "should mark the false #{countable} as #{checked_or_selected}" do
2102
- output_buffer.should have_tag(%{form li.#{type} #{countable}[@value="false"][@#{checked_or_selected}="#{checked_or_selected}"]}, :count => 1)
2103
- end
2104
- end
2105
-
2106
- describe 'when :true and :false options are provided' do
2107
- before do
2108
- @new_post.stub!(:allow_comments)
2109
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
2110
- semantic_form_for(@new_post) do |builder|
2111
- concat(builder.input(:allow_comments, :as => type, :true => "Absolutely", :false => "No Way"))
2112
- end
2113
- end
2114
-
2115
- it 'should use them as labels' do
2116
- output_buffer.should have_tag("form li.#{type}", /Absolutely/)
2117
- output_buffer.should have_tag("form li.#{type}", /No Way/)
2118
- end
2119
- end
2120
- end
2121
-
2122
- end
2123
- end
2124
- end
2125
-
2126
- describe ':as => :date' do
2127
-
2128
- before do
2129
- @new_post.stub!(:publish_at)
2130
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :date))
2131
-
2132
- semantic_form_for(@new_post) do |@builder|
2133
- concat(@builder.input(:publish_at, :as => :date))
2134
- end
2135
- end
2136
-
2137
- it 'should have a date class on the wrapper li' do
2138
- output_buffer.should have_tag('form li.date')
2139
- end
2140
-
2141
- it 'should have a fieldset inside the li wrapper' do
2142
- output_buffer.should have_tag('form li.date fieldset')
2143
- end
2144
-
2145
- it 'should have a legend containing the label text inside the fieldset' do
2146
- output_buffer.should have_tag('form li.date fieldset legend', /Publish at/)
2147
- end
2148
-
2149
- it 'should have an ordered list of three items inside the fieldset' do
2150
- output_buffer.should have_tag('form li.date fieldset ol')
2151
- output_buffer.should have_tag('form li.date fieldset ol li', :count => 3)
2152
- end
2153
-
2154
- it 'should have three labels for year, month and day' do
2155
- output_buffer.should have_tag('form li.date fieldset ol li label', :count => 3)
2156
- output_buffer.should have_tag('form li.date fieldset ol li label', /year/i)
2157
- output_buffer.should have_tag('form li.date fieldset ol li label', /month/i)
2158
- output_buffer.should have_tag('form li.date fieldset ol li label', /day/i)
2159
- end
2160
-
2161
- it 'should have three selects for year, month and day' do
2162
- output_buffer.should have_tag('form li.date fieldset ol li select', :count => 3)
2163
- end
2164
- end
2165
-
2166
- describe ':as => :datetime' do
2167
-
2168
- before do
2169
- @new_post.stub!(:publish_at)
2170
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :datetime))
2171
-
2172
- semantic_form_for(@new_post) do |builder|
2173
- concat(builder.input(:publish_at, :as => :datetime))
2174
- end
2175
- end
2176
-
2177
- it 'should have a datetime class on the wrapper li' do
2178
- output_buffer.should have_tag('form li.datetime')
2179
- end
2180
-
2181
- it 'should have a fieldset inside the li wrapper' do
2182
- output_buffer.should have_tag('form li.datetime fieldset')
2183
- end
2184
-
2185
- it 'should have a legend containing the label text inside the fieldset' do
2186
- output_buffer.should have_tag('form li.datetime fieldset legend', /Publish at/)
2187
- end
2188
-
2189
- it 'should have an ordered list of five items inside the fieldset' do
2190
- output_buffer.should have_tag('form li.datetime fieldset ol')
2191
- output_buffer.should have_tag('form li.datetime fieldset ol li', :count => 5)
2192
- end
2193
-
2194
- it 'should have five labels for year, month, day, hour and minute' do
2195
- output_buffer.should have_tag('form li.datetime fieldset ol li label', :count => 5)
2196
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /year/i)
2197
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /month/i)
2198
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /day/i)
2199
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /hour/i)
2200
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /minute/i)
2201
- end
2202
-
2203
- it 'should have five selects for year, month, day, hour and minute' do
2204
- output_buffer.should have_tag('form li.datetime fieldset ol li select', :count => 5)
2205
- end
2206
-
2207
- it 'should generate a sanitized label and matching ids for attribute' do
2208
- @bob.stub!(:publish_at)
2209
- @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :datetime))
2210
-
2211
- semantic_form_for(@new_post) do |builder|
2212
- builder.semantic_fields_for(@bob, :index => 10) do |bob_builder|
2213
- concat(bob_builder.input(:publish_at, :as => :datetime))
2214
- end
2215
- end
2216
-
2217
- 1.upto(5) do |i|
2218
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_10_publish_at_#{i}i']")
2219
- output_buffer.should have_tag("form li fieldset ol li #post_author_10_publish_at_#{i}i")
2220
- end
2221
- end
2222
-
2223
- describe 'when :discard_input => true is set' do
2224
- it 'should use default hidden value equals to 1 when attribute returns nil' do
2225
- semantic_form_for(@new_post) do |builder|
2226
- concat(builder.input(:publish_at, :as => :datetime, :discard_day => true))
2227
- end
2228
-
2229
- output_buffer.should have_tag("form li input[@type='hidden'][@value='1']")
2230
- end
2231
-
2232
- it 'should use default attribute value when it is not nil' do
2233
- @new_post.stub!(:publish_at).and_return(Date.new(2007,12,27))
2234
- semantic_form_for(@new_post) do |builder|
2235
- concat(builder.input(:publish_at, :as => :datetime, :discard_day => true))
2236
- end
2237
-
2238
- output_buffer.should have_tag("form li input[@type='hidden'][@value='27']")
2239
- end
2240
- end
2241
-
2242
- describe 'when :include_blank => true is set' do
2243
- before do
2244
- semantic_form_for(@new_post) do |builder|
2245
- concat(builder.input(:publish_at, :as => :datetime, :include_blank => true))
2246
- end
2247
- end
2248
-
2249
- it 'should have a blank select option' do
2250
- output_buffer.should have_tag("option[@value='']", "")
2251
- end
2252
- end
2253
-
2254
- describe 'inputs order' do
2255
- it 'should have a default' do
2256
- semantic_form_for(@new_post) do |builder|
2257
- self.should_receive(:select_year).once.ordered.and_return('')
2258
- self.should_receive(:select_month).once.ordered.and_return('')
2259
- self.should_receive(:select_day).once.ordered.and_return('')
2260
- builder.input(:publish_at, :as => :datetime)
2261
- end
2262
- end
2263
-
2264
- it 'should be specified with :order option' do
2265
- I18n.backend.store_translations 'en', :date => { :order => [:month, :year, :day] }
2266
- semantic_form_for(@new_post) do |builder|
2267
- self.should_receive(:select_month).once.ordered.and_return('')
2268
- self.should_receive(:select_year).once.ordered.and_return('')
2269
- self.should_receive(:select_day).once.ordered.and_return('')
2270
- builder.input(:publish_at, :as => :datetime)
2271
- end
2272
- end
2273
-
2274
- it 'should be changed through I18n' do
2275
- semantic_form_for(@new_post) do |builder|
2276
- self.should_receive(:select_day).once.ordered.and_return('')
2277
- self.should_receive(:select_month).once.ordered.and_return('')
2278
- self.should_receive(:select_year).once.ordered.and_return('')
2279
- builder.input(:publish_at, :as => :datetime, :order => [:day, :month, :year])
2280
- end
2281
- end
2282
- end
2283
-
2284
- describe 'when the locale changes the label text' do
2285
- before do
2286
- I18n.backend.store_translations 'en', :datetime => {:prompts => {
2287
- :year => 'The Year', :month => 'The Month', :day => 'The Day',
2288
- :hour => 'The Hour', :minute => 'The Minute'
2289
- }}
2290
- semantic_form_for(@new_post) do |builder|
2291
- concat(builder.input(:publish_at, :as => :datetime))
2292
- end
2293
- end
2294
-
2295
- after do
2296
- I18n.backend.store_translations 'en', :formtastic => {
2297
- :year => nil, :month => nil, :day => nil,
2298
- :hour => nil, :minute => nil
2299
- }
2300
- end
2301
-
2302
- it 'should have translated labels for year, month, day, hour and minute' do
2303
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Year/)
2304
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Month/)
2305
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Day/)
2306
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Hour/)
2307
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Minute/)
2308
- end
2309
- end
2310
-
2311
- describe 'when no object is given' do
2312
- before(:each) do
2313
- output_buffer.replace ''
2314
- semantic_form_for(:project, :url => 'http://test.host') do |@builder|
2315
- concat(@builder.input(:publish_at, :as => :datetime))
2316
- end
2317
- end
2318
-
2319
- it 'should have fieldset with legend' do
2320
- output_buffer.should have_tag('form li.datetime fieldset legend', /Publish at/)
2321
- end
2322
-
2323
- it 'should have labels for each input' do
2324
- output_buffer.should have_tag('form li.datetime fieldset ol li label', :count => 5)
2325
- end
2326
-
2327
- it 'should have selects for each inputs' do
2328
- output_buffer.should have_tag('form li.datetime fieldset ol li select', :count => 5)
2329
- end
2330
- end
2331
- end
2332
-
2333
- describe ':as => :time' do
2334
- before do
2335
- @new_post.stub!(:publish_at)
2336
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :time))
2337
-
2338
- semantic_form_for(@new_post) do |builder|
2339
- concat(builder.input(:publish_at, :as => :time))
2340
- end
2341
- end
2342
-
2343
- it 'should have a time class on the wrapper li' do
2344
- output_buffer.should have_tag('form li.time')
2345
- end
2346
-
2347
- it 'should have a fieldset inside the li wrapper' do
2348
- output_buffer.should have_tag('form li.time fieldset')
2349
- end
2350
-
2351
- it 'should have a legend containing the label text inside the fieldset' do
2352
- output_buffer.should have_tag('form li.time fieldset legend', /Publish at/)
2353
- end
2354
-
2355
- it 'should have an ordered list of two items inside the fieldset' do
2356
- output_buffer.should have_tag('form li.time fieldset ol')
2357
- output_buffer.should have_tag('form li.time fieldset ol li', :count => 2)
2358
- end
2359
-
2360
- it 'should have five labels for hour and minute' do
2361
- output_buffer.should have_tag('form li.time fieldset ol li label', :count => 2)
2362
- output_buffer.should have_tag('form li.time fieldset ol li label', /hour/i)
2363
- output_buffer.should have_tag('form li.time fieldset ol li label', /minute/i)
2364
- end
2365
-
2366
- it 'should have two selects for hour and minute' do
2367
- #output_buffer.should have_tag('form li.time fieldset ol li select', :count => 2)
2368
- output_buffer.should have_tag('form li.time fieldset ol li', :count => 2)
2369
- end
2370
- end
2371
-
2372
- [:boolean_select, :boolean_radio].each do |type|
2373
- describe ":as => #{type.inspect}" do
2374
- it 'should show a deprecation warning' do
2375
- @new_post.stub!(:allow_comments)
2376
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
2377
-
2378
- ::ActiveSupport::Deprecation.should_receive(:warn).with(/select|radio/, anything())
2379
-
2380
- semantic_form_for(@new_post) do |builder|
2381
- concat(builder.input(:allow_comments, :as => type))
2382
- end
2383
- end
2384
- end
2385
- end
2386
-
2387
- describe ':as => :boolean' do
2388
-
2389
- before do
2390
- @new_post.stub!(:allow_comments)
2391
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
2392
-
2393
- semantic_form_for(@new_post) do |builder|
2394
- concat(builder.input(:allow_comments, :as => :boolean))
2395
- end
2396
- end
2397
-
2398
- it 'should have a boolean class on the wrapper' do
2399
- output_buffer.should have_tag('form li.boolean')
2400
- end
2401
-
2402
- it 'should have a post_allow_comments_input id on the wrapper' do
2403
- output_buffer.should have_tag('form li#post_allow_comments_input')
2404
- end
2405
-
2406
- it 'should generate a label containing the input' do
2407
- output_buffer.should have_tag('form li label')
2408
- output_buffer.should have_tag('form li label[@for="post_allow_comments"')
2409
- output_buffer.should have_tag('form li label', /Allow comments/)
2410
- output_buffer.should have_tag('form li label input[@type="checkbox"]')
2411
- end
2412
-
2413
- it 'should generate a checkbox input' do
2414
- output_buffer.should have_tag('form li label input')
2415
- output_buffer.should have_tag('form li label input#post_allow_comments')
2416
- output_buffer.should have_tag('form li label input[@type="checkbox"]')
2417
- output_buffer.should have_tag('form li label input[@name="post[allow_comments]"]')
2418
- output_buffer.should have_tag('form li label input[@type="checkbox"][@value="1"]')
2419
- end
2420
-
2421
- it 'should allow checked and unchecked values to be sent' do
2422
- semantic_form_for(@new_post) do |builder|
2423
- concat(builder.input(:allow_comments, :as => :boolean, :checked_value => 'checked', :unchecked_value => 'unchecked'))
2424
- end
2425
-
2426
- output_buffer.should have_tag('form li label input[@type="checkbox"][@value="checked"]')
2427
- output_buffer.should have_tag('form li label input[@type="hidden"][@value="unchecked"]')
2428
- end
2429
-
2430
- it 'should generate a label and a checkbox even if no object is given' do
2431
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
2432
- concat(builder.input(:allow_comments, :as => :boolean))
2433
- end
2434
-
2435
- output_buffer.should have_tag('form li label[@for="project_allow_comments"')
2436
- output_buffer.should have_tag('form li label', /Allow comments/)
2437
- output_buffer.should have_tag('form li label input[@type="checkbox"]')
2438
-
2439
- output_buffer.should have_tag('form li label input#project_allow_comments')
2440
- output_buffer.should have_tag('form li label input[@type="checkbox"]')
2441
- output_buffer.should have_tag('form li label input[@name="project[allow_comments]"]')
2442
- end
2443
-
2444
- end
2445
- end
2446
-
2447
- describe '#inputs' do
2448
-
2449
- describe 'with a block' do
2450
-
2451
- describe 'when no options are provided' do
2452
- before do
2453
- output_buffer.replace 'before_builder' # clear the output buffer and sets before_builder
2454
- semantic_form_for(@new_post) do |builder|
2455
- @inputs_output = builder.inputs do
2456
- concat('hello')
2457
- end
2458
- end
2459
- end
2460
-
2461
- it 'should output just the content wrapped in inputs, not the whole template' do
2462
- output_buffer.should =~ /before_builder/
2463
- @inputs_output.should_not =~ /before_builder/
2464
- end
2465
-
2466
- it 'should render a fieldset inside the form, with a class of "inputs"' do
2467
- output_buffer.should have_tag("form fieldset.inputs")
2468
- end
2469
-
2470
- it 'should render an ol inside the fieldset' do
2471
- output_buffer.should have_tag("form fieldset.inputs ol")
2472
- end
2473
-
2474
- it 'should render the contents of the block inside the ol' do
2475
- output_buffer.should have_tag("form fieldset.inputs ol", /hello/)
2476
- end
2477
-
2478
- it 'should not render a legend inside the fieldset' do
2479
- output_buffer.should_not have_tag("form fieldset.inputs legend")
2480
- end
2481
-
2482
- it 'should render a fieldset even if no object is given' do
2483
- semantic_form_for(:project, :url => 'http://test.host/') do |builder|
2484
- @inputs_output = builder.inputs do
2485
- concat('bye')
2486
- end
2487
- end
2488
-
2489
- output_buffer.should have_tag("form fieldset.inputs ol", /bye/)
2490
- end
2491
- end
2492
-
2493
- describe 'when a :for option is provided' do
2494
- it 'should render nested inputs' do
2495
- @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
2496
-
2497
- semantic_form_for(@new_post) do |builder|
2498
- builder.inputs :for => [:author, @bob] do |bob_builder|
2499
- concat(bob_builder.input(:login))
2500
- end
2501
- end
2502
-
2503
- output_buffer.should have_tag("form fieldset.inputs #post_author_login")
2504
- output_buffer.should_not have_tag("form fieldset.inputs #author_login")
2505
- end
2506
-
2507
- it 'should raise an error if :for and block with no argument is given' do
2508
- semantic_form_for(@new_post) do |builder|
2509
- proc {
2510
- builder.inputs(:for => [:author, @bob]) do
2511
- #
2512
- end
2513
- }.should raise_error(ArgumentError, 'You gave :for option with a block to inputs method, ' <<
2514
- 'but the block does not accept any argument.')
2515
- end
2516
- end
2517
-
2518
- it 'should pass options down to semantic_fields_for' do
2519
- @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
2520
-
2521
- semantic_form_for(@new_post) do |builder|
2522
- builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
2523
- concat(bob_builder.input(:login))
2524
- end
2525
- end
2526
-
2527
- output_buffer.should have_tag('form fieldset ol li #post_author_10_login')
2528
- end
2529
-
2530
- it 'should not add builder as a fieldset attribute tag' do
2531
- semantic_form_for(@new_post) do |builder|
2532
- builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
2533
- concat('input')
2534
- end
2535
- end
2536
-
2537
- output_buffer.should_not have_tag('fieldset[@builder="Formtastic::SemanticFormHelper"]')
2538
- end
2539
-
2540
- it 'should send parent_builder as an option to allow child index interpolation' do
2541
- semantic_form_for(@new_post) do |builder|
2542
- builder.instance_variable_set('@nested_child_index', 0)
2543
- builder.inputs :for => [:author, @bob], :name => 'Author #%i' do |bob_builder|
2544
- concat('input')
2545
- end
2546
- end
2547
-
2548
- output_buffer.should have_tag('fieldset legend', 'Author #1')
2549
- end
2550
-
2551
- it 'should also provide child index interpolation when nested child index is a hash' do
2552
- semantic_form_for(@new_post) do |builder|
2553
- builder.instance_variable_set('@nested_child_index', :author => 10)
2554
- builder.inputs :for => [:author, @bob], :name => 'Author #%i' do |bob_builder|
2555
- concat('input')
2556
- end
2557
- end
2558
-
2559
- output_buffer.should have_tag('fieldset legend', 'Author #11')
2560
- end
2561
- end
2562
-
2563
- describe 'when a :name option is provided' do
2564
- before do
2565
- @legend_text = "Advanced options"
2566
-
2567
- semantic_form_for(@new_post) do |builder|
2568
- builder.inputs :name => @legend_text do
2569
- end
2570
- end
2571
- end
2572
-
2573
- it 'should render a fieldset inside the form' do
2574
- output_buffer.should have_tag("form fieldset legend", /#{@legend_text}/)
2575
- end
2576
- end
2577
-
2578
- describe 'when other options are provided' do
2579
- before do
2580
- @id_option = 'advanced'
2581
- @class_option = 'wide'
2582
-
2583
- semantic_form_for(@new_post) do |builder|
2584
- builder.inputs :id => @id_option, :class => @class_option do
2585
- end
2586
- end
2587
- end
2588
-
2589
- it 'should pass the options into the fieldset tag as attributes' do
2590
- output_buffer.should have_tag("form fieldset##{@id_option}")
2591
- output_buffer.should have_tag("form fieldset.#{@class_option}")
2592
- end
2593
- end
2594
-
2595
- end
2596
-
2597
- describe 'without a block' do
2598
-
2599
- before do
2600
- Post.stub!(:reflections).and_return({:author => mock('reflection', :options => {}, :macro => :belongs_to),
2601
- :comments => mock('reflection', :options => {}, :macro => :has_many) })
2602
- Post.stub!(:content_columns).and_return([mock('column', :name => 'title'), mock('column', :name => 'body'), mock('column', :name => 'created_at')])
2603
- Author.stub!(:find).and_return([@fred, @bob])
2604
-
2605
- @new_post.stub!(:title)
2606
- @new_post.stub!(:body)
2607
- @new_post.stub!(:author_id)
2608
-
2609
- @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :string, :limit => 255))
2610
- @new_post.stub!(:column_for_attribute).with(:body).and_return(mock('column', :type => :text))
2611
- @new_post.stub!(:column_for_attribute).with(:created_at).and_return(mock('column', :type => :datetime))
2612
- @new_post.stub!(:column_for_attribute).with(:author).and_return(nil)
2613
- end
2614
-
2615
- describe 'with no args' do
2616
- before do
2617
- semantic_form_for(@new_post) do |builder|
2618
- concat(builder.inputs)
2619
- end
2620
- end
2621
-
2622
- it 'should render a form' do
2623
- output_buffer.should have_tag('form')
2624
- end
2625
-
2626
- it 'should render a fieldset inside the form' do
2627
- output_buffer.should have_tag('form > fieldset.inputs')
2628
- end
2629
-
2630
- it 'should not render a legend in the fieldset' do
2631
- output_buffer.should_not have_tag('form > fieldset.inputs > legend')
2632
- end
2633
-
2634
- it 'should render an ol in the fieldset' do
2635
- output_buffer.should have_tag('form > fieldset.inputs > ol')
2636
- end
2637
-
2638
- it 'should render a list item in the ol for each column and reflection' do
2639
- # Remove the :has_many macro and :created_at column
2640
- count = Post.content_columns.size + Post.reflections.size - 2
2641
- output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => count)
2642
- end
2643
-
2644
- it 'should render a string list item for title' do
2645
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
2646
- end
2647
-
2648
- it 'should render a text list item for body' do
2649
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
2650
- end
2651
-
2652
- it 'should render a select list item for author_id' do
2653
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.select', :count => 1)
2654
- end
2655
-
2656
- it 'should not render timestamps inputs by default' do
2657
- output_buffer.should_not have_tag('form > fieldset.inputs > ol > li.datetime')
2658
- end
2659
- end
2660
-
2661
- describe 'with column names as args' do
2662
- describe 'and an object is given' do
2663
- it 'should render a form with a fieldset containing two list items' do
2664
- semantic_form_for(@new_post) do |builder|
2665
- concat(builder.inputs(:title, :body))
2666
- end
2667
-
2668
- output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 2)
2669
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
2670
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
2671
- end
2672
- end
2673
-
2674
- describe 'and no object is given' do
2675
- it 'should render a form with a fieldset containing two list items' do
2676
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
2677
- concat(builder.inputs(:title, :body))
2678
- end
2679
-
2680
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.string', :count => 2)
2681
- end
2682
- end
2683
- end
2684
-
2685
- describe 'when a :for option is provided' do
2686
- describe 'and an object is given' do
2687
- it 'should render nested inputs' do
2688
- @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
2689
-
2690
- semantic_form_for(@new_post) do |builder|
2691
- concat(builder.inputs(:login, :for => @bob))
2692
- end
2693
-
2694
- output_buffer.should have_tag("form fieldset.inputs #post_author_login")
2695
- output_buffer.should_not have_tag("form fieldset.inputs #author_login")
2696
- end
2697
- end
2698
-
2699
- describe 'and no object is given' do
2700
- it 'should render nested inputs' do
2701
- semantic_form_for(:project, :url => 'http://test.host/') do |builder|
2702
- concat(builder.inputs(:login, :for => @bob))
2703
- end
2704
-
2705
- output_buffer.should have_tag("form fieldset.inputs #project_author_login")
2706
- output_buffer.should_not have_tag("form fieldset.inputs #project_login")
2707
- end
2708
- end
2709
- end
2710
-
2711
- describe 'with column names and an options hash as args' do
2712
- before do
2713
- semantic_form_for(@new_post) do |builder|
2714
- concat(builder.inputs(:title, :body, :name => "Legendary Legend Text", :id => "my-id"))
2715
- end
2716
- end
2717
-
2718
- it 'should render a form with a fieldset containing two list items' do
2719
- output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 2)
2720
- end
2721
-
2722
- it 'should pass the options down to the fieldset' do
2723
- output_buffer.should have_tag('form > fieldset#my-id.inputs')
2724
- end
2725
-
2726
- it 'should use the special :name option as a text for the legend tag' do
2727
- output_buffer.should have_tag('form > fieldset#my-id.inputs > legend', /Legendary Legend Text/)
2728
- end
2729
- end
2730
-
2731
- end
2732
-
2733
- end
2734
-
2735
- describe '#buttons' do
2736
-
2737
- describe 'with a block' do
2738
- describe 'when no options are provided' do
2739
- before do
2740
- semantic_form_for(@new_post) do |builder|
2741
- builder.buttons do
2742
- concat('hello')
2743
- end
2744
- end
2745
- end
2746
-
2747
- it 'should render a fieldset inside the form, with a class of "inputs"' do
2748
- output_buffer.should have_tag("form fieldset.buttons")
2749
- end
2750
-
2751
- it 'should render an ol inside the fieldset' do
2752
- output_buffer.should have_tag("form fieldset.buttons ol")
2753
- end
2754
-
2755
- it 'should render the contents of the block inside the ol' do
2756
- output_buffer.should have_tag("form fieldset.buttons ol", /hello/)
2757
- end
2758
-
2759
- it 'should not render a legend inside the fieldset' do
2760
- output_buffer.should_not have_tag("form fieldset.buttons legend")
2761
- end
2762
- end
2763
-
2764
- describe 'when a :name option is provided' do
2765
- before do
2766
- @legend_text = "Advanced options"
2767
-
2768
- semantic_form_for(@new_post) do |builder|
2769
- builder.buttons :name => @legend_text do
2770
- end
2771
- end
2772
- end
2773
- it 'should render a fieldset inside the form' do
2774
- output_buffer.should have_tag("form fieldset legend", /#{@legend_text}/)
2775
- end
2776
- end
2777
-
2778
- describe 'when other options are provided' do
2779
- before do
2780
- @id_option = 'advanced'
2781
- @class_option = 'wide'
2782
-
2783
- semantic_form_for(@new_post) do |builder|
2784
- builder.buttons :id => @id_option, :class => @class_option do
2785
- end
2786
- end
2787
- end
2788
- it 'should pass the options into the fieldset tag as attributes' do
2789
- output_buffer.should have_tag("form fieldset##{@id_option}")
2790
- output_buffer.should have_tag("form fieldset.#{@class_option}")
2791
- end
2792
- end
2793
-
2794
- end
2795
-
2796
- describe 'without a block' do
2797
-
2798
- describe 'with no args (default buttons)' do
2799
-
2800
- before do
2801
- semantic_form_for(@new_post) do |builder|
2802
- concat(builder.buttons)
2803
- end
2804
- end
2805
-
2806
- it 'should render a form' do
2807
- output_buffer.should have_tag('form')
2808
- end
2809
-
2810
- it 'should render a buttons fieldset inside the form' do
2811
- output_buffer.should have_tag('form fieldset.buttons')
2812
- end
2813
-
2814
- it 'should not render a legend in the fieldset' do
2815
- output_buffer.should_not have_tag('form fieldset.buttons legend')
2816
- end
2817
-
2818
- it 'should render an ol in the fieldset' do
2819
- output_buffer.should have_tag('form fieldset.buttons ol')
2820
- end
2821
-
2822
- it 'should render a list item in the ol for each default button' do
2823
- output_buffer.should have_tag('form fieldset.buttons ol li', :count => 1)
2824
- end
2825
-
2826
- it 'should render a commit list item for the commit button' do
2827
- output_buffer.should have_tag('form fieldset.buttons ol li.commit')
2828
- end
2829
-
2830
- end
2831
-
2832
- describe 'with button names as args' do
2833
-
2834
- before do
2835
- semantic_form_for(@new_post) do |builder|
2836
- concat(builder.buttons(:commit))
2837
- end
2838
- end
2839
-
2840
- it 'should render a form with a fieldset containing a list item for each button arg' do
2841
- output_buffer.should have_tag('form > fieldset.buttons > ol > li', :count => 1)
2842
- output_buffer.should have_tag('form > fieldset.buttons > ol > li.commit')
2843
- end
2844
-
2845
- end
2846
-
2847
- describe 'with button names as args and an options hash' do
2848
-
2849
- before do
2850
- semantic_form_for(@new_post) do |builder|
2851
- concat(builder.buttons(:commit, :name => "Now click a button", :id => "my-id"))
2852
- end
2853
- end
2854
-
2855
- it 'should render a form with a fieldset containing a list item for each button arg' do
2856
- output_buffer.should have_tag('form > fieldset.buttons > ol > li', :count => 1)
2857
- output_buffer.should have_tag('form > fieldset.buttons > ol > li.commit', :count => 1)
2858
- end
2859
-
2860
- it 'should pass the options down to the fieldset' do
2861
- output_buffer.should have_tag('form > fieldset#my-id.buttons')
2862
- end
2863
-
2864
- it 'should use the special :name option as a text for the legend tag' do
2865
- output_buffer.should have_tag('form > fieldset#my-id.buttons > legend', /Now click a button/)
2866
- end
2867
-
2868
- end
2869
-
2870
- end
2871
-
2872
- end
2873
-
2874
- describe '#commit_button' do
2875
-
2876
- describe 'when used on any record' do
2877
-
2878
- before do
2879
- @new_post.stub!(:new_record?).and_return(false)
2880
- semantic_form_for(@new_post) do |builder|
2881
- concat(builder.commit_button)
2882
- end
2883
- end
2884
-
2885
- it 'should render a commit li' do
2886
- output_buffer.should have_tag('li.commit')
2887
- end
2888
-
2889
- it 'should render an input with a type attribute of "submit"' do
2890
- output_buffer.should have_tag('li.commit input[@type="submit"]')
2891
- end
2892
-
2893
- it 'should render an input with a name attribute of "commit"' do
2894
- output_buffer.should have_tag('li.commit input[@name="commit"]')
2895
- end
2896
-
2897
- it 'should pass options given in :button_html to the button' do
2898
- @new_post.stub!(:new_record?).and_return(false)
2899
- semantic_form_for(@new_post) do |builder|
2900
- concat(builder.commit_button('text', :button_html => {:class => 'my_class', :id => 'my_id'}))
2901
- end
2902
-
2903
- output_buffer.should have_tag('li.commit input#my_id')
2904
- output_buffer.should have_tag('li.commit input.my_class')
2905
- end
2906
-
2907
- end
2908
-
2909
- describe 'when the first option is a string and the second is a hash' do
2910
-
2911
- before do
2912
- @new_post.stub!(:new_record?).and_return(false)
2913
- semantic_form_for(@new_post) do |builder|
2914
- concat(builder.commit_button("a string", :button_html => { :class => "pretty"}))
2915
- end
2916
- end
2917
-
2918
- it "should render the string as the value of the button" do
2919
- output_buffer.should have_tag('li input[@value="a string"]')
2920
- end
2921
-
2922
- it "should deal with the options hash" do
2923
- output_buffer.should have_tag('li input.pretty')
2924
- end
2925
-
2926
- end
2927
-
2928
- describe 'when the first option is a hash' do
2929
-
2930
- before do
2931
- @new_post.stub!(:new_record?).and_return(false)
2932
- semantic_form_for(@new_post) do |builder|
2933
- concat(builder.commit_button(:button_html => { :class => "pretty"}))
2934
- end
2935
- end
2936
-
2937
- it "should deal with the options hash" do
2938
- output_buffer.should have_tag('li input.pretty')
2939
- end
2940
-
2941
- end
2942
-
2943
- describe 'when used on an existing record' do
2944
-
2945
- it 'should render an input with a value attribute of "Save Post"' do
2946
- @new_post.stub!(:new_record?).and_return(false)
2947
- semantic_form_for(@new_post) do |builder|
2948
- concat(builder.commit_button)
2949
- end
2950
- output_buffer.should have_tag('li.commit input[@value="Save Post"]')
2951
- end
2952
-
2953
- describe 'when the locale sets the label text' do
2954
- before do
2955
- I18n.backend.store_translations 'en', :formtastic => {:save => 'Save Changes To' }
2956
- @new_post.stub!(:new_record?).and_return(false)
2957
- semantic_form_for(@new_post) do |builder|
2958
- concat(builder.commit_button)
2959
- end
2960
- end
2961
-
2962
- after do
2963
- I18n.backend.store_translations 'en', :formtastic => {:save => nil}
2964
- end
2965
-
2966
- it 'should allow translation of the labels' do
2967
- output_buffer.should have_tag('li.commit input[@value="Save Changes To Post"]')
2968
- end
2969
- end
2970
- end
2971
-
2972
- describe 'when used on a new record' do
2973
-
2974
- it 'should render an input with a value attribute of "Create Post"' do
2975
- @new_post.stub!(:new_record?).and_return(true)
2976
- semantic_form_for(@new_post) do |builder|
2977
- concat(builder.commit_button)
2978
- end
2979
- output_buffer.should have_tag('li.commit input[@value="Create Post"]')
2980
- end
2981
-
2982
- describe 'when the locale sets the label text' do
2983
- before do
2984
- I18n.backend.store_translations 'en', :formtastic => {:create => 'Make' }
2985
- semantic_form_for(@new_post) do |builder|
2986
- concat(builder.commit_button)
2987
- end
2988
- end
2989
-
2990
- after do
2991
- I18n.backend.store_translations 'en', :formtastic => {:create => nil}
2992
- end
2993
-
2994
- it 'should allow translation of the labels' do
2995
- output_buffer.should have_tag('li.commit input[@value="Make Post"]')
2996
- end
2997
- end
2998
-
2999
- end
3000
-
3001
- describe 'when used without object' do
3002
-
3003
- it 'should render an input with a value attribute of "Submit"' do
3004
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
3005
- concat(builder.commit_button)
3006
- end
3007
-
3008
- output_buffer.should have_tag('li.commit input[@value="Submit Project"]')
3009
- end
3010
-
3011
- describe 'when the locale sets the label text' do
3012
- before do
3013
- I18n.backend.store_translations 'en', :formtastic => { :submit => 'Send' }
3014
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
3015
- concat(builder.commit_button)
3016
- end
3017
- end
3018
-
3019
- after do
3020
- I18n.backend.store_translations 'en', :formtastic => {:submit => nil}
3021
- end
3022
-
3023
- it 'should allow translation of the labels' do
3024
- output_buffer.should have_tag('li.commit input[@value="Send Project"]')
3025
- end
3026
- end
3027
-
3028
- end
3029
-
3030
- end
3031
-
3032
- describe "Nested Js Helpers" do
3033
-
3034
- it "should have a add method" do
3035
- @new_post.stub!(:authors).and_return(@mock_authors = mock("Authors", :build => []))
3036
-
3037
- semantic_form_for(@new_post) do |builder|
3038
- builder.inputs :name => "Contacts" do
3039
- concat(builder.add_associated_link(:name, :authors))
3040
- end
3041
- end
3042
-
3043
- output_buffer.should eql("<form action=\"/posts\" class=\"formtastic post\" id=\"new_post\" method=\"post\"><fieldset class=\"inputs\"><legend><span>Contacts</span></legend><ol><a href=\"#\" onclick=\"if (typeof formtastic_next_array_id == 'undefined') formtastic_next_array_id = 0;\n $('#arrays').append($.template(null), { number: --formtastic_next_array_id});; return false;\">name</a></ol></fieldset></form>")
3044
- end
3045
-
3046
- it "should have a remove method" do
3047
- semantic_form_for(@new_post) do |builder|
3048
- builder.semantic_fields_for(:links) do |link_builder|
3049
- concat(link_builder.remove_link("Remove"))
3050
- end
3051
- end
3052
-
3053
- output_buffer.should eql("<form action=\"/posts\" class=\"formtastic post\" id=\"new_post\" method=\"post\"><input id=\"post_links__delete\" name=\"post[links][_delete]\" type=\"hidden\" /><a href=\"#\" onclick=\";$(this).parents('.nil_class').hide(); $(this).prev(':input').val('1');; return false;\">Remove</a></form>")
3054
- end
3055
-
3056
- it "should have a show method" do
3057
- @new_post.stub!(:authors).and_return(@mock_authors = mock("Authors"))
3058
- pending
3059
- semantic_form_for(@new_post) do |builder|
3060
- builder.inputs :name => "Contacts" do
3061
- concat(builder.render_associated_form @new_post.authors)
3062
- end
3063
- end
3064
-
3065
- output_buffer.should eql("<form action=\"/posts\" class=\"formtastic post\" id=\"new_post\" method=\"post\"><fieldset class=\"inputs\"><legend><span>Contacts</span></legend><ol><a href=\"#\" onclick=\"if (typeof formtastic_next_array_id == 'undefined') formtastic_next_array_id = 0;\n $('#arrays').append($.template(null), { number: --formtastic_next_array_id});; return false;\">name</a></ol></fieldset></form>")
3066
- end
3067
-
3068
- end
3069
-
3070
- end
3071
-
3072
- end