clearance 0.8.8 → 0.9.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of clearance might be problematic. Click here for more details.

Files changed (94) hide show
  1. data/CHANGELOG.md +8 -0
  2. data/README.md +27 -32
  3. data/Rakefile +25 -31
  4. data/app/controllers/clearance/passwords_controller.rb +1 -1
  5. data/app/controllers/clearance/sessions_controller.rb +1 -1
  6. data/app/models/clearance_mailer.rb +4 -4
  7. data/app/views/passwords/edit.html.erb +1 -1
  8. data/app/views/passwords/new.html.erb +2 -2
  9. data/app/views/sessions/new.html.erb +1 -1
  10. data/app/views/users/_form.html.erb +1 -1
  11. data/app/views/users/new.html.erb +1 -1
  12. data/config/routes.rb +30 -0
  13. data/lib/clearance.rb +2 -1
  14. data/lib/clearance/authentication.rb +2 -2
  15. data/lib/clearance/configuration.rb +10 -3
  16. data/lib/clearance/engine.rb +8 -0
  17. data/lib/clearance/user.rb +5 -6
  18. data/lib/rails/generators/clearance_features_generator.rb +20 -0
  19. data/{generators/clearance_features/templates → lib/rails/generators/clearance_features_templates}/features/password_reset.feature +1 -1
  20. data/{generators/clearance_features/templates → lib/rails/generators/clearance_features_templates}/features/sign_in.feature +0 -0
  21. data/{generators/clearance_features/templates → lib/rails/generators/clearance_features_templates}/features/sign_out.feature +0 -0
  22. data/{generators/clearance_features/templates → lib/rails/generators/clearance_features_templates}/features/sign_up.feature +0 -0
  23. data/{generators/clearance_features/templates → lib/rails/generators/clearance_features_templates}/features/step_definitions/clearance_steps.rb +13 -5
  24. data/lib/rails/generators/clearance_generator.rb +68 -0
  25. data/{generators/clearance/templates → lib/rails/generators/clearance_templates}/README +0 -0
  26. data/{generators/clearance/templates → lib/rails/generators/clearance_templates}/clearance.rb +0 -0
  27. data/{generators/clearance/templates → lib/rails/generators/clearance_templates}/factories.rb +0 -0
  28. data/{generators/clearance/templates → lib/rails/generators/clearance_templates}/migrations/create_users.rb +0 -1
  29. data/{generators/clearance/templates → lib/rails/generators/clearance_templates}/migrations/update_users.rb +0 -1
  30. data/{generators/clearance/templates → lib/rails/generators/clearance_templates}/user.rb +0 -0
  31. data/lib/rails/generators/clearance_views_generator.rb +14 -0
  32. data/{generators/clearance_views/templates/formtastic → lib/rails/generators/clearance_views_templates/formtastic/erb}/passwords/edit.html.erb +3 -3
  33. data/{generators/clearance_views/templates/formtastic → lib/rails/generators/clearance_views_templates/formtastic/erb}/passwords/new.html.erb +3 -3
  34. data/{generators/clearance_views/templates/formtastic → lib/rails/generators/clearance_views_templates/formtastic/erb}/sessions/new.html.erb +3 -3
  35. data/{generators/clearance_views/templates/formtastic → lib/rails/generators/clearance_views_templates/formtastic/erb}/users/_inputs.html.erb +1 -1
  36. data/{generators/clearance_views/templates/formtastic → lib/rails/generators/clearance_views_templates/formtastic/erb}/users/new.html.erb +2 -2
  37. data/shoulda_macros/clearance.rb +9 -17
  38. data/test/controllers/confirmations_controller_test.rb +6 -6
  39. data/test/controllers/passwords_controller_test.rb +10 -10
  40. data/test/controllers/sessions_controller_test.rb +57 -16
  41. data/test/controllers/users_controller_test.rb +12 -8
  42. data/test/models/clearance_mailer_test.rb +2 -2
  43. data/test/models/user_test.rb +14 -7
  44. data/test/rails_root/app/helpers/application_helper.rb +0 -3
  45. data/test/rails_root/config/application.rb +46 -0
  46. data/test/rails_root/config/boot.rb +5 -109
  47. data/test/rails_root/config/environment.rb +5 -15
  48. data/test/rails_root/config/environments/development.rb +15 -15
  49. data/test/rails_root/config/environments/production.rb +42 -1
  50. data/test/rails_root/config/environments/test.rb +25 -29
  51. data/test/rails_root/config/initializers/backtrace_silencers.rb +7 -0
  52. data/test/rails_root/config/initializers/inflections.rb +1 -1
  53. data/test/rails_root/config/initializers/secret_token.rb +7 -0
  54. data/test/rails_root/config/initializers/session_store.rb +8 -0
  55. data/test/rails_root/config/routes.rb +57 -2
  56. data/test/rails_root/features/step_definitions/web_steps.rb +125 -165
  57. data/test/rails_root/features/support/env.rb +24 -14
  58. data/test/rails_root/features/support/paths.rb +26 -4
  59. data/test/rails_root/test/functional/accounts_controller_test.rb +0 -1
  60. data/test/rails_root/test/performance/browsing_test.rb +9 -0
  61. data/test/rails_root/test/test_helper.rb +13 -0
  62. data/test/rails_root/vendor/plugins/dynamic_form/init.rb +5 -0
  63. data/test/rails_root/vendor/plugins/dynamic_form/lib/action_view/helpers/dynamic_form.rb +300 -0
  64. data/test/rails_root/vendor/plugins/dynamic_form/test/dynamic_form_i18n_test.rb +42 -0
  65. data/test/rails_root/vendor/plugins/dynamic_form/test/dynamic_form_test.rb +370 -0
  66. data/test/rails_root/vendor/plugins/dynamic_form/test/test_helper.rb +9 -0
  67. data/test/test_helper.rb +30 -1
  68. metadata +104 -49
  69. data/VERSION +0 -1
  70. data/generators/clearance/USAGE +0 -1
  71. data/generators/clearance/clearance_generator.rb +0 -68
  72. data/generators/clearance/lib/insert_commands.rb +0 -33
  73. data/generators/clearance/lib/rake_commands.rb +0 -22
  74. data/generators/clearance_features/USAGE +0 -1
  75. data/generators/clearance_features/clearance_features_generator.rb +0 -19
  76. data/generators/clearance_features/templates/features/support/paths.rb +0 -23
  77. data/generators/clearance_views/USAGE +0 -0
  78. data/generators/clearance_views/clearance_views_generator.rb +0 -27
  79. data/lib/clearance/routes.rb +0 -49
  80. data/test/rails_root/app/helpers/confirmations_helper.rb +0 -2
  81. data/test/rails_root/app/helpers/passwords_helper.rb +0 -2
  82. data/test/rails_root/config/initializers/requires.rb +0 -13
  83. data/test/rails_root/config/initializers/time_formats.rb +0 -4
  84. data/test/rails_root/db/migrate/20100225210436_clearance_create_users.rb +0 -21
  85. data/test/rails_root/features/step_definitions/clearance_steps.rb +0 -122
  86. data/test/rails_root/features/step_definitions/factory_girl_steps.rb +0 -5
  87. data/test/rails_root/public/dispatch.rb +0 -10
  88. data/test/rails_root/script/create_project.rb +0 -52
  89. data/test/rails_root/vendor/gems/justinfrench-formtastic-0.2.1/generators/formtastic_stylesheets/formtastic_stylesheets_generator.rb +0 -21
  90. data/test/rails_root/vendor/gems/justinfrench-formtastic-0.2.1/lib/formtastic.rb +0 -1236
  91. data/test/rails_root/vendor/gems/justinfrench-formtastic-0.2.1/lib/justin_french/formtastic.rb +0 -10
  92. data/test/rails_root/vendor/gems/justinfrench-formtastic-0.2.1/rails/init.rb +0 -3
  93. data/test/rails_root/vendor/gems/justinfrench-formtastic-0.2.1/spec/formtastic_spec.rb +0 -2900
  94. data/test/rails_root/vendor/gems/justinfrench-formtastic-0.2.1/spec/test_helper.rb +0 -14
@@ -1,10 +0,0 @@
1
- module JustinFrench
2
- module Formtastic
3
- class SemanticFormBuilder < ::Formtastic::SemanticFormBuilder
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,3 +0,0 @@
1
- require File.join(File.dirname(__FILE__), *%w[.. lib formtastic])
2
- require File.join(File.dirname(__FILE__), *%w[.. lib justin_french formtastic])
3
- ActionView::Base.send :include, Formtastic::SemanticFormHelper
@@ -1,2900 +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', :on => 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', :on => 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', :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', :on => 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', :on => 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', :klass => Author, :macro => :belongs_to)
111
- when :authors
112
- mock('reflection', :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_nil
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!(:on).with('title').and_return(@title_errors)
340
- @errors.stub!(:on).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' 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 a string for methods on objects that don\'t respond to "column_for_attribute"' do
584
- @new_post.stub!(:method_without_a_database_column)
585
- @new_post.stub!(:column_for_attribute).and_return(nil)
586
- default_input_type(nil, :method_without_a_database_column).should == :string
587
- end
588
-
589
- it 'should default to :password for methods that don\'t have a column in the database but "password" is in the method name' do
590
- @new_post.stub!(:password_method_without_a_database_column)
591
- @new_post.stub!(:column_for_attribute).and_return(nil)
592
- default_input_type(nil, :password_method_without_a_database_column).should == :password
593
- end
594
-
595
- 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
596
- @new_post.stub!(:password_method_without_a_database_column)
597
- @new_post.stub!(:column_for_attribute).and_return(nil)
598
- default_input_type(nil, :password_method_without_a_database_column).should == :password
599
- end
600
-
601
- it 'should default to :select for column names ending in "_id"' do
602
- default_input_type(:integer, :user_id).should == :select
603
- default_input_type(:integer, :section_id).should == :select
604
- end
605
-
606
- it 'should default to :password for :string column types with "password" in the method name' do
607
- default_input_type(:string, :password).should == :password
608
- default_input_type(:string, :hashed_password).should == :password
609
- default_input_type(:string, :password_hash).should == :password
610
- end
611
-
612
- it 'should default to :text for :text column types' do
613
- default_input_type(:text).should == :text
614
- end
615
-
616
- it 'should default to :date for :date column types' do
617
- default_input_type(:date).should == :date
618
- end
619
-
620
- it 'should default to :datetime for :datetime and :timestamp column types' do
621
- default_input_type(:datetime).should == :datetime
622
- default_input_type(:timestamp).should == :datetime
623
- end
624
-
625
- it 'should default to :time for :time column types' do
626
- default_input_type(:time).should == :time
627
- end
628
-
629
- it 'should default to :boolean for :boolean column types' do
630
- default_input_type(:boolean).should == :boolean
631
- end
632
-
633
- it 'should default to :string for :string column types' do
634
- default_input_type(:string).should == :string
635
- end
636
-
637
- it 'should default to :numeric for :integer, :float and :decimal column types' do
638
- default_input_type(:integer).should == :numeric
639
- default_input_type(:float).should == :numeric
640
- default_input_type(:decimal).should == :numeric
641
- end
642
-
643
- it 'should default to :country for :string columns named country' do
644
- default_input_type(:string, :country).should == :country
645
- end
646
-
647
- describe 'defaulting to file column' do
648
- Formtastic::SemanticFormBuilder.file_methods.each do |method|
649
- it "should default to :file for attributes that respond to ##{method}" do
650
- @new_post.stub!(:column_for_attribute).and_return(nil)
651
- column = mock('column')
652
-
653
- Formtastic::SemanticFormBuilder.file_methods.each do |test|
654
- column.stub!(:respond_to?).with(test).and_return(method == test)
655
- end
656
-
657
- @new_post.should_receive(method).and_return(column)
658
-
659
- semantic_form_for(@new_post) do |builder|
660
- builder.send(:default_input_type, method).should == :file
661
- end
662
- end
663
- end
664
-
665
- end
666
- end
667
-
668
- it 'should call the corresponding input method' do
669
- [:select, :time_zone, :radio, :date, :datetime, :time, :boolean, :check_boxes, :hidden].each do |input_style|
670
- @new_post.stub!(:generic_column_name)
671
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
672
- semantic_form_for(@new_post) do |builder|
673
- builder.should_receive(:"#{input_style}_input").once.and_return("fake HTML output from #input")
674
- concat(builder.input(:generic_column_name, :as => input_style))
675
- end
676
- end
677
-
678
- Formtastic::SemanticFormBuilder::INPUT_MAPPINGS.keys.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_simple).once.and_return("fake HTML output from #input")
683
- concat(builder.input(:generic_column_name, :as => input_style))
684
- end
685
- end
686
- end
687
-
688
- end
689
-
690
- describe ':label option' do
691
-
692
- describe 'when provided' do
693
-
694
- it 'should be passed down to the label tag' do
695
- semantic_form_for(@new_post) do |builder|
696
- concat(builder.input(:title, :label => "Kustom"))
697
- end
698
- output_buffer.should have_tag("form li label", /Kustom/)
699
- end
700
-
701
- end
702
-
703
- describe 'when not provided' do
704
- describe 'and object is not given' do
705
- it 'should default the humanized method name, passing it down to the label tag' do
706
- Formtastic::SemanticFormBuilder.label_str_method = :humanize
707
-
708
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
709
- concat(builder.input(:meta_description))
710
- end
711
-
712
- output_buffer.should have_tag("form li label", /#{'meta_description'.humanize}/)
713
- end
714
- end
715
-
716
- describe 'and object is given' do
717
- it 'should delegate the label logic to class human attribute name and pass it down to the label tag' do
718
- @new_post.stub!(:meta_description) # a two word method name
719
- @new_post.class.should_receive(:human_attribute_name).with('meta_description').and_return('meta_description'.humanize)
720
-
721
- semantic_form_for(@new_post) do |builder|
722
- concat(builder.input(:meta_description))
723
- end
724
-
725
- output_buffer.should have_tag("form li label", /#{'meta_description'.humanize}/)
726
- end
727
- end
728
- end
729
-
730
- end
731
-
732
- describe ':hint option' do
733
-
734
- describe 'when provided' do
735
- it 'should be passed down to the paragraph tag' do
736
- hint_text = "this is the title of the post"
737
- semantic_form_for(@new_post) do |builder|
738
- concat(builder.input(:title, :hint => hint_text))
739
- end
740
- output_buffer.should have_tag("form li p.inline-hints", hint_text)
741
- end
742
- end
743
-
744
- describe 'when not provided' do
745
- it 'should not render a hint paragraph' do
746
- hint_text = "this is the title of the post"
747
- semantic_form_for(@new_post) do |builder|
748
- concat(builder.input(:title))
749
- end
750
- output_buffer.should_not have_tag("form li p.inline-hints")
751
- end
752
- end
753
-
754
- end
755
-
756
- describe ':wrapper_html option' do
757
-
758
- describe 'when provided' do
759
- it 'should be passed down to the li tag' do
760
- semantic_form_for(@new_post) do |builder|
761
- concat(builder.input(:title, :wrapper_html => {:id => :another_id}))
762
- end
763
- output_buffer.should have_tag("form li#another_id")
764
- end
765
-
766
- it 'should append given classes to li default classes' do
767
- semantic_form_for(@new_post) do |builder|
768
- concat(builder.input(:title, :wrapper_html => {:class => :another_class}, :required => true))
769
- end
770
- output_buffer.should have_tag("form li.string")
771
- output_buffer.should have_tag("form li.required")
772
- output_buffer.should have_tag("form li.another_class")
773
- end
774
-
775
- it 'should allow classes to be an array' do
776
- semantic_form_for(@new_post) do |builder|
777
- concat(builder.input(:title, :wrapper_html => {:class => [ :my_class, :another_class ]}))
778
- end
779
- output_buffer.should have_tag("form li.string")
780
- output_buffer.should have_tag("form li.my_class")
781
- output_buffer.should have_tag("form li.another_class")
782
- end
783
- end
784
-
785
- describe 'when not provided' do
786
- it 'should use default id and class' do
787
- semantic_form_for(@new_post) do |builder|
788
- concat(builder.input(:title))
789
- end
790
- output_buffer.should have_tag("form li#post_title_input")
791
- output_buffer.should have_tag("form li.string")
792
- end
793
- end
794
-
795
- end
796
- end
797
-
798
- describe ':as any type of input' do
799
-
800
- it 'should create a list item for each input' do
801
- semantic_form_for(@new_post) do |builder|
802
- concat(builder.input(:title))
803
- concat(builder.input(:body))
804
- end
805
- output_buffer.should have_tag('form li', :count => 2)
806
- end
807
-
808
- describe 'when there are errors on the object for this method' do
809
- before do
810
- @title_errors = ['must not be blank', 'must be longer than 10 characters', 'must be awesome']
811
- @errors = mock('errors')
812
- @errors.stub!(:on).with('title').and_return(@title_errors)
813
- @new_post.stub!(:errors).and_return(@errors)
814
- end
815
-
816
- it 'should apply an errors class to the list item' do
817
- semantic_form_for(@new_post) do |builder|
818
- concat(builder.input(:title))
819
- end
820
- output_buffer.should have_tag('form li.error')
821
- end
822
-
823
- it 'should not wrap the input with the Rails default error wrapping' do
824
- semantic_form_for(@new_post) do |builder|
825
- concat(builder.input(:title))
826
- end
827
- output_buffer.should_not have_tag('div.fieldWithErrors')
828
- end
829
-
830
- it 'should render a paragraph for the errors' do
831
- Formtastic::SemanticFormBuilder.inline_errors = :sentence
832
- semantic_form_for(@new_post) do |builder|
833
- concat(builder.input(:title))
834
- end
835
- output_buffer.should have_tag('form li.error p.inline-errors')
836
- end
837
-
838
- it 'should not display an error list' do
839
- Formtastic::SemanticFormBuilder.inline_errors = :list
840
- semantic_form_for(@new_post) do |builder|
841
- concat(builder.input(:title))
842
- end
843
- output_buffer.should have_tag('form li.error ul.errors')
844
- end
845
- end
846
-
847
- describe 'when there are no errors on the object for this method' do
848
- before do
849
- semantic_form_for(@new_post) do |builder|
850
- concat(builder.input(:title))
851
- end
852
- end
853
-
854
- it 'should not apply an errors class to the list item' do
855
- output_buffer.should_not have_tag('form li.error')
856
- end
857
-
858
- it 'should not render a paragraph for the errors' do
859
- output_buffer.should_not have_tag('form li.error p.inline-errors')
860
- end
861
-
862
- it 'should not display an error list' do
863
- output_buffer.should_not have_tag('form li.error ul.errors')
864
- end
865
- end
866
-
867
- describe 'when no object is provided' do
868
- before do
869
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
870
- concat(builder.input(:title))
871
- end
872
- end
873
-
874
- it 'should not apply an errors class to the list item' do
875
- output_buffer.should_not have_tag('form li.error')
876
- end
877
-
878
- it 'should not render a paragraph for the errors' do
879
- output_buffer.should_not have_tag('form li.error p.inline-errors')
880
- end
881
-
882
- it 'should not display an error list' do
883
- output_buffer.should_not have_tag('form li.error ul.errors')
884
- end
885
- end
886
- end
887
-
888
- # Test string_mappings: :string, :password and :numeric
889
- string_mappings = Formtastic::SemanticFormBuilder::INPUT_MAPPINGS.slice(*Formtastic::SemanticFormBuilder::STRING_MAPPINGS)
890
- string_mappings.each do |type, template_method|
891
- describe ":as => #{type.inspect}" do
892
-
893
- before do
894
- @new_post.stub!(:title)
895
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => type, :limit => 50))
896
-
897
- semantic_form_for(@new_post) do |builder|
898
- concat(builder.input(:title, :as => type))
899
- end
900
- end
901
-
902
- it "should have a #{type} class on the wrapper" do
903
- output_buffer.should have_tag("form li.#{type}")
904
- end
905
-
906
- it 'should have a post_title_input id on the wrapper' do
907
- output_buffer.should have_tag('form li#post_title_input')
908
- end
909
-
910
- it 'should generate a label for the input' do
911
- output_buffer.should have_tag('form li label')
912
- output_buffer.should have_tag('form li label[@for="post_title"')
913
- output_buffer.should have_tag('form li label', /Title/)
914
- end
915
-
916
- input_type = template_method.to_s.split('_').first
917
-
918
- it "should generate a #{input_type} input" do
919
- output_buffer.should have_tag("form li input")
920
- output_buffer.should have_tag("form li input#post_title")
921
- output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
922
- output_buffer.should have_tag("form li input[@name=\"post[title]\"]")
923
- end
924
-
925
- it 'should have a maxlength matching the column limit' do
926
- @new_post.column_for_attribute(:title).limit.should == 50
927
- output_buffer.should have_tag("form li input[@maxlength='50']")
928
- end
929
-
930
- it 'should use default_text_field_size for columns longer than default_text_field_size' do
931
- default_size = Formtastic::SemanticFormBuilder.default_text_field_size
932
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => type, :limit => default_size * 2))
933
-
934
- semantic_form_for(@new_post) do |builder|
935
- concat(builder.input(:title, :as => type))
936
- end
937
-
938
- output_buffer.should have_tag("form li input[@size='#{default_size}']")
939
- end
940
-
941
- it 'should use the column size for columns shorter than default_text_field_size' do
942
- column_limit_shorted_than_default = 1
943
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => type, :limit => column_limit_shorted_than_default))
944
-
945
- semantic_form_for(@new_post) do |builder|
946
- concat(builder.input(:title, :as => type))
947
- end
948
-
949
- output_buffer.should have_tag("form li input[@size='#{column_limit_shorted_than_default}']")
950
- end
951
-
952
- it 'should use default_text_field_size for methods without database columns' do
953
- default_size = Formtastic::SemanticFormBuilder.default_text_field_size
954
- @new_post.stub!(:column_for_attribute).and_return(nil) # Return a nil column
955
-
956
- semantic_form_for(@new_post) do |builder|
957
- concat(builder.input(:title, :as => type))
958
- end
959
-
960
- output_buffer.should have_tag("form li input[@size='#{default_size}']")
961
- end
962
-
963
- it 'should use input_html to style inputs' do
964
- semantic_form_for(@new_post) do |builder|
965
- concat(builder.input(:title, :as => type, :input_html => { :class => 'myclass' }))
966
- end
967
- output_buffer.should have_tag("form li input.myclass")
968
- end
969
-
970
- it 'should generate input and labels even if no object is given' do
971
- semantic_form_for(:project, :url => 'http://test.host/') do |builder|
972
- concat(builder.input(:title, :as => type))
973
- end
974
-
975
- output_buffer.should have_tag('form li label')
976
- output_buffer.should have_tag('form li label[@for="project_title"')
977
- output_buffer.should have_tag('form li label', /Title/)
978
-
979
- output_buffer.should have_tag("form li input")
980
- output_buffer.should have_tag("form li input#project_title")
981
- output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
982
- output_buffer.should have_tag("form li input[@name=\"project[title]\"]")
983
- end
984
-
985
- end
986
- end
987
-
988
- # Test other mappings that are not strings: :text and :file.
989
- other_mappings = Formtastic::SemanticFormBuilder::INPUT_MAPPINGS.except(*Formtastic::SemanticFormBuilder::STRING_MAPPINGS)
990
- other_mappings.each do |type, template_method|
991
- describe ":as => #{type.inspect}" do
992
-
993
- before do
994
- @new_post.stub!(:body)
995
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => type))
996
-
997
- semantic_form_for(@new_post) do |builder|
998
- concat(builder.input(:body, :as => type))
999
- end
1000
- end
1001
-
1002
- it "should have a #{type} class on the wrapper" do
1003
- output_buffer.should have_tag('form li.#{type}')
1004
- end
1005
-
1006
- it 'should have a post_title_input id on the wrapper' do
1007
- output_buffer.should have_tag('form li#post_body_input')
1008
- end
1009
-
1010
- it 'should generate a label for the input' do
1011
- output_buffer.should have_tag('form li label')
1012
- output_buffer.should have_tag('form li label[@for="post_body"')
1013
- output_buffer.should have_tag('form li label', /Body/)
1014
- end
1015
-
1016
- input_type = template_method.to_s.gsub(/_field|_/, '')
1017
-
1018
- if template_method.to_s =~ /_field$/ # password_field
1019
-
1020
- it "should generate a #{input_type} input" do
1021
- output_buffer.should have_tag("form li input")
1022
- output_buffer.should have_tag("form li input#post_body")
1023
- output_buffer.should have_tag("form li input[@name=\"post[body]\"]")
1024
- output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
1025
- end
1026
-
1027
- it 'should use input_html to style inputs' do
1028
- semantic_form_for(@new_post) do |builder|
1029
- concat(builder.input(:title, :as => type, :input_html => { :class => 'myclass' }))
1030
- end
1031
- output_buffer.should have_tag("form li input.myclass")
1032
- end
1033
-
1034
- else # text_area
1035
-
1036
- it "should generate a #{input_type} input" do
1037
- output_buffer.should have_tag("form li #{input_type}")
1038
- output_buffer.should have_tag("form li #{input_type}#post_body")
1039
- output_buffer.should have_tag("form li #{input_type}[@name=\"post[body]\"]")
1040
- end
1041
-
1042
- it 'should use input_html to style inputs' do
1043
- semantic_form_for(@new_post) do |builder|
1044
- concat(builder.input(:title, :as => type, :input_html => { :class => 'myclass' }))
1045
- end
1046
- output_buffer.should have_tag("form li #{input_type}.myclass")
1047
- end
1048
-
1049
- end
1050
-
1051
- describe 'when no object is given' do
1052
- before(:each) do
1053
- semantic_form_for(:project, :url => 'http://test.host/') do |builder|
1054
- concat(builder.input(:title, :as => type))
1055
- end
1056
- end
1057
-
1058
- it 'should generate input' do
1059
- if template_method.to_s =~ /_field$/ # password_field
1060
- output_buffer.should have_tag("form li input")
1061
- output_buffer.should have_tag("form li input#project_title")
1062
- output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
1063
- output_buffer.should have_tag("form li input[@name=\"project[title]\"]")
1064
- else
1065
- output_buffer.should have_tag("form li #{input_type}")
1066
- output_buffer.should have_tag("form li #{input_type}#project_title")
1067
- output_buffer.should have_tag("form li #{input_type}[@name=\"project[title]\"]")
1068
- end
1069
- end
1070
-
1071
- it 'should generate labels' do
1072
- output_buffer.should have_tag('form li label')
1073
- output_buffer.should have_tag('form li label[@for="project_title"')
1074
- output_buffer.should have_tag('form li label', /Title/)
1075
- end
1076
- end
1077
-
1078
- end
1079
- end
1080
-
1081
- describe ":as => :hidden" do
1082
- before do
1083
- @new_post.stub!(:hidden)
1084
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string))
1085
-
1086
- semantic_form_for(@new_post) do |builder|
1087
- concat(builder.input(:hidden, :as => :hidden))
1088
- end
1089
- end
1090
-
1091
- it "should have a hidden class on the wrapper" do
1092
- output_buffer.should have_tag('form li.hidden')
1093
- end
1094
-
1095
- it 'should have a post_hidden_input id on the wrapper' do
1096
- output_buffer.should have_tag('form li#post_hidden_input')
1097
- end
1098
-
1099
- it 'should not generate a label for the input' do
1100
- output_buffer.should_not have_tag('form li label')
1101
- end
1102
-
1103
- it "should generate a input field" do
1104
- output_buffer.should have_tag("form li input#post_hidden")
1105
- output_buffer.should have_tag("form li input[@type=\"hidden\"]")
1106
- output_buffer.should have_tag("form li input[@name=\"post[hidden]\"]")
1107
- end
1108
- end
1109
-
1110
- describe ":as => :time_zone" do
1111
- before do
1112
- @new_post.stub!(:time_zone)
1113
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string))
1114
-
1115
- semantic_form_for(@new_post) do |builder|
1116
- concat(builder.input(:time_zone))
1117
- end
1118
- end
1119
-
1120
- it "should have a time_zone class on the wrapper" do
1121
- output_buffer.should have_tag('form li.time_zone')
1122
- end
1123
-
1124
- it 'should have a post_title_input id on the wrapper' do
1125
- output_buffer.should have_tag('form li#post_time_zone_input')
1126
- end
1127
-
1128
- it 'should generate a label for the input' do
1129
- output_buffer.should have_tag('form li label')
1130
- output_buffer.should have_tag('form li label[@for="post_time_zone"')
1131
- output_buffer.should have_tag('form li label', /Time zone/)
1132
- end
1133
-
1134
- it "should generate a select" do
1135
- output_buffer.should have_tag("form li select")
1136
- output_buffer.should have_tag("form li select#post_time_zone")
1137
- output_buffer.should have_tag("form li select[@name=\"post[time_zone]\"]")
1138
- end
1139
-
1140
- it 'should use input_html to style inputs' do
1141
- semantic_form_for(@new_post) do |builder|
1142
- concat(builder.input(:time_zone, :input_html => { :class => 'myclass' }))
1143
- end
1144
- output_buffer.should have_tag("form li select.myclass")
1145
- end
1146
-
1147
- describe 'when no object is given' do
1148
- before(:each) do
1149
- semantic_form_for(:project, :url => 'http://test.host/') do |builder|
1150
- concat(builder.input(:time_zone, :as => :time_zone))
1151
- end
1152
- end
1153
-
1154
- it 'should generate labels' do
1155
- output_buffer.should have_tag('form li label')
1156
- output_buffer.should have_tag('form li label[@for="project_time_zone"')
1157
- output_buffer.should have_tag('form li label', /Time zone/)
1158
- end
1159
-
1160
- it 'should generate select inputs' do
1161
- output_buffer.should have_tag("form li select")
1162
- output_buffer.should have_tag("form li select#project_time_zone")
1163
- output_buffer.should have_tag("form li select[@name=\"project[time_zone]\"]")
1164
- end
1165
- end
1166
- end
1167
-
1168
- describe ":as => :country" do
1169
-
1170
- before do
1171
- @new_post.stub!(:country)
1172
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string))
1173
- end
1174
-
1175
- describe "when country_select is not available as a helper from a plugin" do
1176
-
1177
- it "should raise an error, sugesting the author installs a plugin" do
1178
- lambda {
1179
- semantic_form_for(@new_post) do |builder|
1180
- concat(builder.input(:country, :as => :country))
1181
- end
1182
- }.should raise_error
1183
- end
1184
-
1185
- end
1186
-
1187
- describe "when country_select is available as a helper (from a plugin)" do
1188
-
1189
- before do
1190
- semantic_form_for(@new_post) do |builder|
1191
- builder.stub!(:country_select).and_return("<select><option>...</option></select>")
1192
- concat(builder.input(:country, :as => :country))
1193
- end
1194
- end
1195
-
1196
- it "should have a time_zone class on the wrapper" do
1197
- output_buffer.should have_tag('form li.country')
1198
- end
1199
-
1200
- it 'should have a post_title_input id on the wrapper' do
1201
- output_buffer.should have_tag('form li#post_country_input')
1202
- end
1203
-
1204
- it 'should generate a label for the input' do
1205
- output_buffer.should have_tag('form li label')
1206
- output_buffer.should have_tag('form li label[@for="post_country"')
1207
- output_buffer.should have_tag('form li label', /Country/)
1208
- end
1209
-
1210
- it "should generate a select" do
1211
- output_buffer.should have_tag("form li select")
1212
- end
1213
-
1214
- end
1215
-
1216
- describe ":priority_countries option" do
1217
-
1218
- it "should be passed down to the country_select helper when provided" do
1219
- priority_countries = ["Foo", "Bah"]
1220
- semantic_form_for(@new_post) do |builder|
1221
- builder.stub!(:country_select).and_return("<select><option>...</option></select>")
1222
- builder.should_receive(:country_select).with(:country, priority_countries, {}, {}).and_return("<select><option>...</option></select>")
1223
-
1224
- concat(builder.input(:country, :as => :country, :priority_countries => priority_countries))
1225
- end
1226
- end
1227
-
1228
- it "should default to the @@priority_countries config when absent" do
1229
- priority_countries = Formtastic::SemanticFormBuilder.priority_countries
1230
- priority_countries.should_not be_empty
1231
- priority_countries.should_not be_nil
1232
-
1233
- semantic_form_for(@new_post) do |builder|
1234
- builder.stub!(:country_select).and_return("<select><option>...</option></select>")
1235
- builder.should_receive(:country_select).with(:country, priority_countries, {}, {}).and_return("<select><option>...</option></select>")
1236
-
1237
- concat(builder.input(:country, :as => :country))
1238
- end
1239
- end
1240
-
1241
- end
1242
-
1243
- end
1244
-
1245
- describe ':as => :radio' do
1246
-
1247
- before do
1248
- @new_post.stub!(:author).and_return(@bob)
1249
- @new_post.stub!(:author_id).and_return(@bob.id)
1250
- Post.stub!(:reflect_on_association).and_return { |column_name| mock('reflection', :klass => Author, :macro => :belongs_to) }
1251
- end
1252
-
1253
- describe 'for belongs_to association' do
1254
- before do
1255
- semantic_form_for(@new_post) do |builder|
1256
- concat(builder.input(:author, :as => :radio, :value_as_class => true))
1257
- end
1258
- end
1259
-
1260
- it 'should have a radio class on the wrapper' do
1261
- output_buffer.should have_tag('form li.radio')
1262
- end
1263
-
1264
- it 'should have a post_author_input id on the wrapper' do
1265
- output_buffer.should have_tag('form li#post_author_input')
1266
- end
1267
-
1268
- it 'should generate a fieldset and legend containing label text for the input' do
1269
- output_buffer.should have_tag('form li fieldset')
1270
- output_buffer.should have_tag('form li fieldset legend')
1271
- output_buffer.should have_tag('form li fieldset legend', /Author/)
1272
- end
1273
-
1274
- it 'should generate an ordered list with a list item for each choice' do
1275
- output_buffer.should have_tag('form li fieldset ol')
1276
- output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
1277
- end
1278
-
1279
- it 'should have one option with a "checked" attribute' do
1280
- output_buffer.should have_tag('form li input[@checked]', :count => 1)
1281
- end
1282
-
1283
- describe "each choice" do
1284
-
1285
- it 'should contain a label for the radio input with a nested input and label text' do
1286
- Author.find(:all).each do |author|
1287
- output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
1288
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_id_#{author.id}']")
1289
- end
1290
- end
1291
-
1292
- it 'should use values as li.class when value_as_class is true' do
1293
- Author.find(:all).each do |author|
1294
- output_buffer.should have_tag("form li fieldset ol li.#{author.id} label")
1295
- end
1296
- end
1297
-
1298
- it "should have a radio input" do
1299
- Author.find(:all).each do |author|
1300
- output_buffer.should have_tag("form li fieldset ol li label input#post_author_id_#{author.id}")
1301
- output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
1302
- output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
1303
- output_buffer.should have_tag("form li fieldset ol li label input[@name='post[author_id]']")
1304
- end
1305
- end
1306
-
1307
- it "should mark input as checked if it's the the existing choice" do
1308
- @new_post.author_id.should == @bob.id
1309
- @new_post.author.id.should == @bob.id
1310
- @new_post.author.should == @bob
1311
-
1312
- semantic_form_for(@new_post) do |builder|
1313
- concat(builder.input(:author, :as => :radio))
1314
- end
1315
-
1316
- output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
1317
- end
1318
- end
1319
-
1320
- describe 'and no object is given' do
1321
- before(:each) do
1322
- output_buffer.replace ''
1323
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
1324
- concat(builder.input(:author_id, :as => :radio, :collection => Author.find(:all)))
1325
- end
1326
- end
1327
-
1328
- it 'should generate a fieldset with legend' do
1329
- output_buffer.should have_tag('form li fieldset legend', /Author/)
1330
- end
1331
-
1332
- it 'shold generate an li tag for each item in the collection' do
1333
- output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
1334
- end
1335
-
1336
- it 'should generate labels for each item' do
1337
- Author.find(:all).each do |author|
1338
- output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
1339
- output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
1340
- end
1341
- end
1342
-
1343
- it 'should generate inputs for each item' do
1344
- Author.find(:all).each do |author|
1345
- output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
1346
- output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
1347
- output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
1348
- output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id]']")
1349
- end
1350
- end
1351
- end
1352
- end
1353
- end
1354
-
1355
- describe ':as => :select' do
1356
-
1357
- before do
1358
- @new_post.stub!(:author).and_return(@bob)
1359
- @new_post.stub!(:author_id).and_return(@bob.id)
1360
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
1361
- end
1362
-
1363
- describe 'for a belongs_to association' do
1364
- before do
1365
- semantic_form_for(@new_post) do |builder|
1366
- concat(builder.input(:author, :as => :select))
1367
- end
1368
- end
1369
-
1370
- it 'should have a select class on the wrapper' do
1371
- output_buffer.should have_tag('form li.select')
1372
- end
1373
-
1374
- it 'should have a post_author_input id on the wrapper' do
1375
- output_buffer.should have_tag('form li#post_author_input')
1376
- end
1377
-
1378
- it 'should have a label inside the wrapper' do
1379
- output_buffer.should have_tag('form li label')
1380
- output_buffer.should have_tag('form li label', /Author/)
1381
- output_buffer.should have_tag("form li label[@for='post_author_id']")
1382
- end
1383
-
1384
- it 'should have a select inside the wrapper' do
1385
- output_buffer.should have_tag('form li select')
1386
- output_buffer.should have_tag('form li select#post_author_id')
1387
- end
1388
-
1389
- it 'should not create a multi-select' do
1390
- output_buffer.should_not have_tag('form li select[@multiple]')
1391
- end
1392
-
1393
- it 'should create a select without size' do
1394
- output_buffer.should_not have_tag('form li select[@size]')
1395
- end
1396
-
1397
- it 'should have a select option for each Author' do
1398
- output_buffer.should have_tag('form li select option', :count => Author.find(:all).size + 1)
1399
- Author.find(:all).each do |author|
1400
- output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
1401
- end
1402
- end
1403
-
1404
- it 'should have one option with a "selected" attribute' do
1405
- output_buffer.should have_tag('form li select option[@selected]', :count => 1)
1406
- end
1407
-
1408
- it 'should not singularize the association name' do
1409
- @new_post.stub!(:author_status).and_return(@bob)
1410
- @new_post.stub!(:author_status_id).and_return(@bob.id)
1411
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
1412
-
1413
- semantic_form_for(@new_post) do |builder|
1414
- concat(builder.input(:author_status, :as => :select))
1415
- end
1416
-
1417
- output_buffer.should have_tag('form li select#post_author_status_id')
1418
- end
1419
- end
1420
-
1421
- describe 'for a has_many association' do
1422
- before do
1423
- semantic_form_for(@fred) do |builder|
1424
- concat(builder.input(:posts, :as => :select))
1425
- end
1426
- end
1427
-
1428
- it 'should have a select class on the wrapper' do
1429
- output_buffer.should have_tag('form li.select')
1430
- end
1431
-
1432
- it 'should have a post_author_input id on the wrapper' do
1433
- output_buffer.should have_tag('form li#author_posts_input')
1434
- end
1435
-
1436
- it 'should have a label inside the wrapper' do
1437
- output_buffer.should have_tag('form li label')
1438
- output_buffer.should have_tag('form li label', /Post ids/)
1439
- output_buffer.should have_tag("form li label[@for='author_post_ids']")
1440
- end
1441
-
1442
- it 'should have a select inside the wrapper' do
1443
- output_buffer.should have_tag('form li select')
1444
- output_buffer.should have_tag('form li select#author_post_ids')
1445
- end
1446
-
1447
- it 'should have a multi-select select' do
1448
- output_buffer.should have_tag('form li select[@multiple="multiple"]')
1449
- end
1450
-
1451
- it 'should have a select option for each Post' do
1452
- output_buffer.should have_tag('form li select option', :count => Post.find(:all).size + 1)
1453
- Post.find(:all).each do |post|
1454
- output_buffer.should have_tag("form li select option[@value='#{post.id}']", /#{post.to_label}/)
1455
- end
1456
- end
1457
-
1458
- it 'should have one option with a "selected" attribute' do
1459
- output_buffer.should have_tag('form li select option[@selected]', :count => 1)
1460
- end
1461
- end
1462
-
1463
- describe 'for a has_and_belongs_to_many association' do
1464
- before do
1465
- semantic_form_for(@freds_post) do |builder|
1466
- concat(builder.input(:authors, :as => :select))
1467
- end
1468
- end
1469
-
1470
- it 'should have a select class on the wrapper' do
1471
- output_buffer.should have_tag('form li.select')
1472
- end
1473
-
1474
- it 'should have a post_author_input id on the wrapper' do
1475
- output_buffer.should have_tag('form li#post_authors_input')
1476
- end
1477
-
1478
- it 'should have a label inside the wrapper' do
1479
- output_buffer.should have_tag('form li label')
1480
- output_buffer.should have_tag('form li label', /Author ids/)
1481
- output_buffer.should have_tag("form li label[@for='post_author_ids']")
1482
- end
1483
-
1484
- it 'should have a select inside the wrapper' do
1485
- output_buffer.should have_tag('form li select')
1486
- output_buffer.should have_tag('form li select#post_author_ids')
1487
- end
1488
-
1489
- it 'should have a multi-select select' do
1490
- output_buffer.should have_tag('form li select[@multiple="multiple"]')
1491
- end
1492
-
1493
- it 'should have a select option for each Author' do
1494
- output_buffer.should have_tag('form li select option', :count => Author.find(:all).size + 1)
1495
- Author.find(:all).each do |author|
1496
- output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
1497
- end
1498
- end
1499
-
1500
- it 'should have one option with a "selected" attribute' do
1501
- output_buffer.should have_tag('form li select option[@selected]', :count => 1)
1502
- end
1503
- end
1504
-
1505
- describe 'when :include_blank is not set' do
1506
- before do
1507
- @new_post.stub!(:author_id).and_return(nil)
1508
- semantic_form_for(@new_post) do |builder|
1509
- concat(builder.input(:author, :as => :select))
1510
- end
1511
- end
1512
-
1513
- it 'should have a blank option by default' do
1514
- output_buffer.should have_tag("form li select option[@value='']", "")
1515
- end
1516
- end
1517
-
1518
- describe 'when :include_blank is set to false' do
1519
- before do
1520
- @new_post.stub!(:author_id).and_return(nil)
1521
- semantic_form_for(@new_post) do |builder|
1522
- concat(builder.input(:author, :as => :select, :include_blank => false))
1523
- end
1524
- end
1525
-
1526
- it 'should not have a blank option' do
1527
- output_buffer.should_not have_tag("form li select option[@value='']", "")
1528
- end
1529
- end
1530
-
1531
- describe 'when :prompt => "choose something" is set' do
1532
- before do
1533
- @new_post.stub!(:author_id).and_return(nil)
1534
- semantic_form_for(@new_post) do |builder|
1535
- concat(builder.input(:author, :as => :select, :prompt => "choose author"))
1536
- end
1537
- end
1538
-
1539
- it 'should have a select with prompt' do
1540
- output_buffer.should have_tag("form li select option[@value='']", /choose author/)
1541
- end
1542
-
1543
- it 'should not have a blank select option' do
1544
- output_buffer.should_not have_tag("form li select option[@value='']", "")
1545
- end
1546
- end
1547
-
1548
- describe 'when no object is given' do
1549
- before(:each) do
1550
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
1551
- concat(builder.input(:author, :as => :select, :collection => Author.find(:all)))
1552
- end
1553
- end
1554
-
1555
- it 'should generate label' do
1556
- output_buffer.should have_tag('form li label', /Author/)
1557
- output_buffer.should have_tag("form li label[@for='project_author']")
1558
- end
1559
-
1560
- it 'should generate select inputs' do
1561
- output_buffer.should have_tag('form li select#project_author')
1562
- output_buffer.should have_tag('form li select option', :count => Author.find(:all).size + 1)
1563
- end
1564
-
1565
- it 'should generate an option to each item' do
1566
- Author.find(:all).each do |author|
1567
- output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
1568
- end
1569
- end
1570
- end
1571
- end
1572
-
1573
- describe ':as => :check_boxes' do
1574
-
1575
- describe 'for a has_many association' do
1576
- before do
1577
- semantic_form_for(@fred) do |builder|
1578
- concat(builder.input(:posts, :as => :check_boxes, :value_as_class => true))
1579
- end
1580
- end
1581
-
1582
- it 'should have a check_boxes class on the wrapper' do
1583
- output_buffer.should have_tag('form li.check_boxes')
1584
- end
1585
-
1586
- it 'should have a author_posts_input id on the wrapper' do
1587
- output_buffer.should have_tag('form li#author_posts_input')
1588
- end
1589
-
1590
- it 'should generate a fieldset and legend containing label text for the input' do
1591
- output_buffer.should have_tag('form li fieldset')
1592
- output_buffer.should have_tag('form li fieldset legend')
1593
- output_buffer.should have_tag('form li fieldset legend', /Posts/)
1594
- end
1595
-
1596
- it 'should generate an ordered list with a list item for each choice' do
1597
- output_buffer.should have_tag('form li fieldset ol')
1598
- output_buffer.should have_tag('form li fieldset ol li', :count => Post.find(:all).size)
1599
- end
1600
-
1601
- it 'should have one option with a "checked" attribute' do
1602
- output_buffer.should have_tag('form li input[@checked]', :count => 1)
1603
- end
1604
-
1605
- it 'should generate hidden inputs with default value blank' do
1606
- output_buffer.should have_tag("form li fieldset ol li label input[@type='hidden'][@value='']", :count => Post.find(:all).size)
1607
- end
1608
-
1609
- describe "each choice" do
1610
-
1611
- it 'should contain a label for the radio input with a nested input and label text' do
1612
- Post.find(:all).each do |post|
1613
- output_buffer.should have_tag('form li fieldset ol li label', /#{post.to_label}/)
1614
- output_buffer.should have_tag("form li fieldset ol li label[@for='author_post_ids_#{post.id}']")
1615
- end
1616
- end
1617
-
1618
- it 'should use values as li.class when value_as_class is true' do
1619
- Post.find(:all).each do |post|
1620
- output_buffer.should have_tag("form li fieldset ol li.#{post.id} label")
1621
- end
1622
- end
1623
-
1624
- it 'should have a checkbox input for each post' do
1625
- Post.find(:all).each do |post|
1626
- output_buffer.should have_tag("form li fieldset ol li label input#author_post_ids_#{post.id}")
1627
- output_buffer.should have_tag("form li fieldset ol li label input[@name='author[post_ids][]']", :count => 2)
1628
- end
1629
- end
1630
-
1631
- it "should mark input as checked if it's the the existing choice" do
1632
- Post.find(:all).include?(@fred.posts.first).should be_true
1633
- output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
1634
- end
1635
- end
1636
-
1637
- describe 'and no object is given' do
1638
- before(:each) do
1639
- output_buffer.replace ''
1640
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
1641
- concat(builder.input(:author_id, :as => :check_boxes, :collection => Author.find(:all)))
1642
- end
1643
- end
1644
-
1645
- it 'should generate a fieldset with legend' do
1646
- output_buffer.should have_tag('form li fieldset legend', /Author/)
1647
- end
1648
-
1649
- it 'shold generate an li tag for each item in the collection' do
1650
- output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
1651
- end
1652
-
1653
- it 'should generate labels for each item' do
1654
- Author.find(:all).each do |author|
1655
- output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
1656
- output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
1657
- end
1658
- end
1659
-
1660
- it 'should generate inputs for each item' do
1661
- Author.find(:all).each do |author|
1662
- output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
1663
- output_buffer.should have_tag("form li fieldset ol li label input[@type='checkbox']")
1664
- output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
1665
- output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id][]']")
1666
- end
1667
- end
1668
- end
1669
- end
1670
- end
1671
-
1672
- describe 'for collections' do
1673
-
1674
- before do
1675
- @new_post.stub!(:author).and_return(@bob)
1676
- @new_post.stub!(:author_id).and_return(@bob.id)
1677
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
1678
- end
1679
-
1680
- { :select => :option, :radio => :input, :check_boxes => :'input[@type="checkbox"]' }.each do |type, countable|
1681
-
1682
- describe ":as => #{type.inspect}" do
1683
- describe 'when the :collection option is not provided' do
1684
- it 'should perform a basic find on the association class' do
1685
- Author.should_receive(:find)
1686
-
1687
- semantic_form_for(@new_post) do |builder|
1688
- concat(builder.input(:author, :as => type))
1689
- end
1690
- end
1691
-
1692
- it 'should show a deprecation warning if user gives the association using _id' do
1693
- # Check for deprecation message
1694
- ::ActiveSupport::Deprecation.should_receive(:warn).with(/association/, anything())
1695
-
1696
- Author.should_receive(:find)
1697
- semantic_form_for(@new_post) do |builder|
1698
- concat(builder.input(:author_id, :as => type))
1699
- end
1700
- end
1701
- end
1702
-
1703
- describe 'when the :collection option is provided' do
1704
-
1705
- before do
1706
- @authors = Author.find(:all) * 2
1707
- output_buffer.replace '' # clears the output_buffer from the before block, hax!
1708
- end
1709
-
1710
- it 'should not call find() on the parent class' do
1711
- Author.should_not_receive(:find)
1712
- semantic_form_for(@new_post) do |builder|
1713
- concat(builder.input(:author, :as => type, :collection => @authors))
1714
- end
1715
- end
1716
-
1717
- it 'should use the provided collection' do
1718
- semantic_form_for(@new_post) do |builder|
1719
- concat(builder.input(:author, :as => type, :collection => @authors))
1720
- end
1721
- output_buffer.should have_tag("form li.#{type} #{countable}", :count => @authors.size + (type == :select ? 1 : 0))
1722
- end
1723
-
1724
- describe 'and the :collection is an array of strings' do
1725
- before do
1726
- @new_post.stub!(:category_name).and_return('')
1727
- @categories = [ 'General', 'Design', 'Development' ]
1728
- end
1729
-
1730
- it "should use the string as the label text and value for each #{countable}" do
1731
- semantic_form_for(@new_post) do |builder|
1732
- concat(builder.input(:category_name, :as => type, :collection => @categories))
1733
- end
1734
-
1735
- @categories.each do |value|
1736
- output_buffer.should have_tag("form li.#{type}", /#{value}/)
1737
- output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value}']")
1738
- end
1739
- end
1740
-
1741
- if type == :radio
1742
- it 'should generate a sanitized label for attribute' do
1743
- @bob.stub!(:category_name).and_return(@categories)
1744
- semantic_form_for(@new_post) do |builder|
1745
- builder.semantic_fields_for(@bob) do |bob_builder|
1746
- concat(bob_builder.input(:category_name, :as => type, :collection => @categories))
1747
- end
1748
- end
1749
-
1750
- @categories.each do |item|
1751
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_category_name_#{item.downcase}']")
1752
- end
1753
- end
1754
- end
1755
- end
1756
-
1757
- describe 'and the :collection is a hash of strings' do
1758
- before do
1759
- @new_post.stub!(:category_name).and_return('')
1760
- @categories = { 'General' => 'gen', 'Design' => 'des','Development' => 'dev' }
1761
- end
1762
-
1763
- it "should use the key as the label text and the hash value as the value attribute for each #{countable}" do
1764
- semantic_form_for(@new_post) do |builder|
1765
- concat(builder.input(:category_name, :as => type, :collection => @categories))
1766
- end
1767
-
1768
- @categories.each do |label, value|
1769
- output_buffer.should have_tag("form li.#{type}", /#{label}/)
1770
- output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value}']")
1771
- end
1772
- end
1773
- end
1774
-
1775
- describe 'and the :collection is an array of arrays' do
1776
- before do
1777
- @new_post.stub!(:category_name).and_return('')
1778
- @categories = { 'General' => 'gen', 'Design' => 'des','Development' => 'dev' }.to_a
1779
- end
1780
-
1781
- it "should use the first value as the label text and the last value as the value attribute for #{countable}" do
1782
- semantic_form_for(@new_post) do |builder|
1783
- concat(builder.input(:category_name, :as => type, :collection => @categories))
1784
- end
1785
-
1786
- @categories.each do |text, value|
1787
- label = type == :select ? :option : :label
1788
- output_buffer.should have_tag("form li.#{type} #{label}", /#{text}/i)
1789
- output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value.to_s}']")
1790
- end
1791
- end
1792
- end
1793
-
1794
- describe 'and the :collection is an array of symbols' do
1795
- before do
1796
- @new_post.stub!(:category_name).and_return('')
1797
- @categories = [ :General, :Design, :Development ]
1798
- end
1799
-
1800
- it "should use the symbol as the label text and value for each #{countable}" do
1801
- semantic_form_for(@new_post) do |builder|
1802
- concat(builder.input(:category_name, :as => type, :collection => @categories))
1803
- end
1804
-
1805
- @categories.each do |value|
1806
- label = type == :select ? :option : :label
1807
- output_buffer.should have_tag("form li.#{type} #{label}", /#{value}/i)
1808
- output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value.to_s}']")
1809
- end
1810
- end
1811
- end
1812
-
1813
- describe 'when the :label_method option is provided' do
1814
- before do
1815
- semantic_form_for(@new_post) do |builder|
1816
- concat(builder.input(:author, :as => type, :label_method => :login))
1817
- end
1818
- end
1819
-
1820
- it 'should have options with text content from the specified method' do
1821
- Author.find(:all).each do |author|
1822
- output_buffer.should have_tag("form li.#{type}", /#{author.login}/)
1823
- end
1824
- end
1825
- end
1826
-
1827
- describe 'when the :label_method option is not provided' do
1828
- Formtastic::SemanticFormBuilder.collection_label_methods.each do |label_method|
1829
-
1830
- describe "when the collection objects respond to #{label_method}" do
1831
- before do
1832
- @fred.stub!(:respond_to?).and_return { |m| m.to_s == label_method }
1833
- Author.find(:all).each { |a| a.stub!(label_method).and_return('The Label Text') }
1834
-
1835
- semantic_form_for(@new_post) do |builder|
1836
- concat(builder.input(:author, :as => type))
1837
- end
1838
- end
1839
-
1840
- it "should render the options with #{label_method} as the label" do
1841
- Author.find(:all).each do |author|
1842
- output_buffer.should have_tag("form li.#{type}", /The Label Text/)
1843
- end
1844
- end
1845
- end
1846
-
1847
- end
1848
- end
1849
-
1850
- describe 'when the :value_method option is provided' do
1851
- before do
1852
- semantic_form_for(@new_post) do |builder|
1853
- concat(builder.input(:author, :as => type, :value_method => :login))
1854
- end
1855
- end
1856
-
1857
- it 'should have options with values from specified method' do
1858
- Author.find(:all).each do |author|
1859
- output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{author.login}']")
1860
- end
1861
- end
1862
- end
1863
-
1864
- end
1865
- end
1866
- end
1867
-
1868
- describe 'for boolean attributes' do
1869
-
1870
- { :select => :option, :radio => :input }.each do |type, countable|
1871
- checked_or_selected = { :select => :selected, :radio => :checked }[type]
1872
-
1873
- describe ":as => #{type.inspect}" do
1874
-
1875
- before do
1876
- @new_post.stub!(:allow_comments)
1877
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
1878
-
1879
- semantic_form_for(@new_post) do |builder|
1880
- concat(builder.input(:allow_comments, :as => type))
1881
- end
1882
- end
1883
-
1884
- it "should have a #{type} class on the wrapper" do
1885
- output_buffer.should have_tag("form li.#{type}")
1886
- end
1887
-
1888
- it 'should have a post_allow_comments_input id on the wrapper' do
1889
- output_buffer.should have_tag('form li#post_allow_comments_input')
1890
- end
1891
-
1892
- it 'should generate a fieldset containing a legend' do
1893
- output_buffer.should have_tag("form li.#{type}", /Allow comments/)
1894
- end
1895
-
1896
- it "should generate two #{countable}" do
1897
- output_buffer.should have_tag("form li.#{type} #{countable}", :count => (type == :select ? 3 : 2))
1898
- output_buffer.should have_tag(%{form li.#{type} #{countable}[@value="true"]})
1899
- output_buffer.should have_tag(%{form li.#{type} #{countable}[@value="false"]})
1900
- end
1901
-
1902
- describe 'when the locale sets the label text' do
1903
- before do
1904
- I18n.backend.store_translations 'en', :formtastic => {:yes => 'Absolutely!', :no => 'Never!'}
1905
-
1906
- semantic_form_for(@new_post) do |builder|
1907
- concat(builder.input(:allow_comments, :as => type))
1908
- end
1909
- end
1910
-
1911
- after do
1912
- I18n.backend.store_translations 'en', :formtastic => {:yes => nil, :no => nil}
1913
- end
1914
-
1915
- it 'should allow translation of the labels' do
1916
- output_buffer.should have_tag("form li.#{type}", /Absolutely\!/)
1917
- output_buffer.should have_tag("form li.#{type}", /Never\!/)
1918
- end
1919
- end
1920
-
1921
- describe 'when the value is nil' do
1922
- before do
1923
- @new_post.stub!(:allow_comments).and_return(nil)
1924
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
1925
-
1926
- semantic_form_for(@new_post) do |builder|
1927
- concat(builder.input(:allow_comments, :as => type))
1928
- end
1929
- end
1930
-
1931
- it "should not mark either #{countable} as #{checked_or_selected}" do
1932
- output_buffer.should_not have_tag(%{form li.#{type} input[@#{checked_or_selected}="#{checked_or_selected}"]})
1933
- end
1934
- end
1935
-
1936
- describe 'when the value is true' do
1937
- before do
1938
- @new_post.stub!(:allow_comments).and_return(true)
1939
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
1940
- semantic_form_for(@new_post) do |builder|
1941
- concat(builder.input(:allow_comments, :as => type))
1942
- end
1943
- end
1944
-
1945
- it "should mark the true #{countable} as #{checked_or_selected}" do
1946
- output_buffer.should have_tag(%{form li.#{type} #{countable}[@value="true"][@#{checked_or_selected}="#{checked_or_selected}"]}, :count => 1)
1947
- end
1948
-
1949
- it "should not mark the false #{countable} as #{checked_or_selected}" do
1950
- output_buffer.should_not have_tag(%{form li.#{type} #{countable}[@value="false"][@#{checked_or_selected}="#{checked_or_selected}"]})
1951
- end
1952
- end
1953
-
1954
- describe 'when the value is false' do
1955
- before do
1956
- @new_post.stub!(:allow_comments).and_return(false)
1957
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
1958
- semantic_form_for(@new_post) do |builder|
1959
- concat(builder.input(:allow_comments, :as => type))
1960
- end
1961
- end
1962
-
1963
- it "should not mark the true #{countable} as #{checked_or_selected}" do
1964
- output_buffer.should_not have_tag(%{form li.#{type} #{countable}[@value="true"][@#{checked_or_selected}="#{checked_or_selected}"]})
1965
- end
1966
-
1967
- it "should mark the false #{countable} as #{checked_or_selected}" do
1968
- output_buffer.should have_tag(%{form li.#{type} #{countable}[@value="false"][@#{checked_or_selected}="#{checked_or_selected}"]}, :count => 1)
1969
- end
1970
- end
1971
-
1972
- describe 'when :true and :false options are provided' do
1973
- before do
1974
- @new_post.stub!(:allow_comments)
1975
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
1976
- semantic_form_for(@new_post) do |builder|
1977
- concat(builder.input(:allow_comments, :as => type, :true => "Absolutely", :false => "No Way"))
1978
- end
1979
- end
1980
-
1981
- it 'should use them as labels' do
1982
- output_buffer.should have_tag("form li.#{type}", /Absolutely/)
1983
- output_buffer.should have_tag("form li.#{type}", /No Way/)
1984
- end
1985
- end
1986
- end
1987
-
1988
- end
1989
- end
1990
- end
1991
-
1992
- describe ':as => :date' do
1993
-
1994
- before do
1995
- @new_post.stub!(:publish_at)
1996
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :date))
1997
-
1998
- semantic_form_for(@new_post) do |@builder|
1999
- concat(@builder.input(:publish_at, :as => :date))
2000
- end
2001
- end
2002
-
2003
- it 'should have a date class on the wrapper li' do
2004
- output_buffer.should have_tag('form li.date')
2005
- end
2006
-
2007
- it 'should have a fieldset inside the li wrapper' do
2008
- output_buffer.should have_tag('form li.date fieldset')
2009
- end
2010
-
2011
- it 'should have a legend containing the label text inside the fieldset' do
2012
- output_buffer.should have_tag('form li.date fieldset legend', /Publish at/)
2013
- end
2014
-
2015
- it 'should have an ordered list of three items inside the fieldset' do
2016
- output_buffer.should have_tag('form li.date fieldset ol')
2017
- output_buffer.should have_tag('form li.date fieldset ol li', :count => 3)
2018
- end
2019
-
2020
- it 'should have three labels for year, month and day' do
2021
- output_buffer.should have_tag('form li.date fieldset ol li label', :count => 3)
2022
- output_buffer.should have_tag('form li.date fieldset ol li label', /year/i)
2023
- output_buffer.should have_tag('form li.date fieldset ol li label', /month/i)
2024
- output_buffer.should have_tag('form li.date fieldset ol li label', /day/i)
2025
- end
2026
-
2027
- it 'should have three selects for year, month and day' do
2028
- output_buffer.should have_tag('form li.date fieldset ol li select', :count => 3)
2029
- end
2030
- end
2031
-
2032
- describe ':as => :datetime' do
2033
-
2034
- before do
2035
- @new_post.stub!(:publish_at)
2036
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :datetime))
2037
-
2038
- semantic_form_for(@new_post) do |builder|
2039
- concat(builder.input(:publish_at, :as => :datetime))
2040
- end
2041
- end
2042
-
2043
- it 'should have a datetime class on the wrapper li' do
2044
- output_buffer.should have_tag('form li.datetime')
2045
- end
2046
-
2047
- it 'should have a fieldset inside the li wrapper' do
2048
- output_buffer.should have_tag('form li.datetime fieldset')
2049
- end
2050
-
2051
- it 'should have a legend containing the label text inside the fieldset' do
2052
- output_buffer.should have_tag('form li.datetime fieldset legend', /Publish at/)
2053
- end
2054
-
2055
- it 'should have an ordered list of five items inside the fieldset' do
2056
- output_buffer.should have_tag('form li.datetime fieldset ol')
2057
- output_buffer.should have_tag('form li.datetime fieldset ol li', :count => 5)
2058
- end
2059
-
2060
- it 'should have five labels for year, month, day, hour and minute' do
2061
- output_buffer.should have_tag('form li.datetime fieldset ol li label', :count => 5)
2062
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /year/i)
2063
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /month/i)
2064
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /day/i)
2065
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /hour/i)
2066
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /minute/i)
2067
- end
2068
-
2069
- it 'should have five selects for year, month, day, hour and minute' do
2070
- output_buffer.should have_tag('form li.datetime fieldset ol li select', :count => 5)
2071
- end
2072
-
2073
- it 'should generate a sanitized label and matching ids for attribute' do
2074
- @bob.stub!(:publish_at)
2075
- @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :datetime))
2076
-
2077
- semantic_form_for(@new_post) do |builder|
2078
- builder.semantic_fields_for(@bob, :index => 10) do |bob_builder|
2079
- concat(bob_builder.input(:publish_at, :as => :datetime))
2080
- end
2081
- end
2082
-
2083
- 1.upto(5) do |i|
2084
- output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_10_publish_at_#{i}i']")
2085
- output_buffer.should have_tag("form li fieldset ol li #post_author_10_publish_at_#{i}i")
2086
- end
2087
- end
2088
-
2089
- describe 'when :discard_input => true is set' do
2090
- it 'should use default hidden value equals to 1 when attribute returns nil' do
2091
- semantic_form_for(@new_post) do |builder|
2092
- concat(builder.input(:publish_at, :as => :datetime, :discard_day => true))
2093
- end
2094
-
2095
- output_buffer.should have_tag("form li input[@type='hidden'][@value='1']")
2096
- end
2097
-
2098
- it 'should use default attribute value when it is not nil' do
2099
- @new_post.stub!(:publish_at).and_return(Date.new(2007,12,27))
2100
- semantic_form_for(@new_post) do |builder|
2101
- concat(builder.input(:publish_at, :as => :datetime, :discard_day => true))
2102
- end
2103
-
2104
- output_buffer.should have_tag("form li input[@type='hidden'][@value='27']")
2105
- end
2106
- end
2107
-
2108
- describe 'when :include_blank => true is set' do
2109
- before do
2110
- semantic_form_for(@new_post) do |builder|
2111
- concat(builder.input(:publish_at, :as => :datetime, :include_blank => true))
2112
- end
2113
- end
2114
-
2115
- it 'should have a blank select option' do
2116
- output_buffer.should have_tag("option[@value='']", "")
2117
- end
2118
- end
2119
-
2120
- describe 'inputs order' do
2121
- it 'should have a default' do
2122
- semantic_form_for(@new_post) do |builder|
2123
- self.should_receive(:select_year).once.ordered.and_return('')
2124
- self.should_receive(:select_month).once.ordered.and_return('')
2125
- self.should_receive(:select_day).once.ordered.and_return('')
2126
- builder.input(:publish_at, :as => :datetime)
2127
- end
2128
- end
2129
-
2130
- it 'should be specified with :order option' do
2131
- I18n.backend.store_translations 'en', :date => { :order => [:month, :year, :day] }
2132
- semantic_form_for(@new_post) do |builder|
2133
- self.should_receive(:select_month).once.ordered.and_return('')
2134
- self.should_receive(:select_year).once.ordered.and_return('')
2135
- self.should_receive(:select_day).once.ordered.and_return('')
2136
- builder.input(:publish_at, :as => :datetime)
2137
- end
2138
- end
2139
-
2140
- it 'should be changed through I18n' do
2141
- semantic_form_for(@new_post) do |builder|
2142
- self.should_receive(:select_day).once.ordered.and_return('')
2143
- self.should_receive(:select_month).once.ordered.and_return('')
2144
- self.should_receive(:select_year).once.ordered.and_return('')
2145
- builder.input(:publish_at, :as => :datetime, :order => [:day, :month, :year])
2146
- end
2147
- end
2148
- end
2149
-
2150
- describe 'when the locale changes the label text' do
2151
- before do
2152
- I18n.backend.store_translations 'en', :datetime => {:prompts => {
2153
- :year => 'The Year', :month => 'The Month', :day => 'The Day',
2154
- :hour => 'The Hour', :minute => 'The Minute'
2155
- }}
2156
- semantic_form_for(@new_post) do |builder|
2157
- concat(builder.input(:publish_at, :as => :datetime))
2158
- end
2159
- end
2160
-
2161
- after do
2162
- I18n.backend.store_translations 'en', :formtastic => {
2163
- :year => nil, :month => nil, :day => nil,
2164
- :hour => nil, :minute => nil
2165
- }
2166
- end
2167
-
2168
- it 'should have translated labels for year, month, day, hour and minute' do
2169
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Year/)
2170
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Month/)
2171
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Day/)
2172
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Hour/)
2173
- output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Minute/)
2174
- end
2175
- end
2176
-
2177
- describe 'when no object is given' do
2178
- before(:each) do
2179
- output_buffer.replace ''
2180
- semantic_form_for(:project, :url => 'http://test.host') do |@builder|
2181
- concat(@builder.input(:publish_at, :as => :datetime))
2182
- end
2183
- end
2184
-
2185
- it 'should have fieldset with legend' do
2186
- output_buffer.should have_tag('form li.datetime fieldset legend', /Publish at/)
2187
- end
2188
-
2189
- it 'should have labels for each input' do
2190
- output_buffer.should have_tag('form li.datetime fieldset ol li label', :count => 5)
2191
- end
2192
-
2193
- it 'should have selects for each inputs' do
2194
- output_buffer.should have_tag('form li.datetime fieldset ol li select', :count => 5)
2195
- end
2196
- end
2197
- end
2198
-
2199
- describe ':as => :time' do
2200
- before do
2201
- @new_post.stub!(:publish_at)
2202
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :time))
2203
-
2204
- semantic_form_for(@new_post) do |builder|
2205
- concat(builder.input(:publish_at, :as => :time))
2206
- end
2207
- end
2208
-
2209
- it 'should have a time class on the wrapper li' do
2210
- output_buffer.should have_tag('form li.time')
2211
- end
2212
-
2213
- it 'should have a fieldset inside the li wrapper' do
2214
- output_buffer.should have_tag('form li.time fieldset')
2215
- end
2216
-
2217
- it 'should have a legend containing the label text inside the fieldset' do
2218
- output_buffer.should have_tag('form li.time fieldset legend', /Publish at/)
2219
- end
2220
-
2221
- it 'should have an ordered list of two items inside the fieldset' do
2222
- output_buffer.should have_tag('form li.time fieldset ol')
2223
- output_buffer.should have_tag('form li.time fieldset ol li', :count => 2)
2224
- end
2225
-
2226
- it 'should have five labels for hour and minute' do
2227
- output_buffer.should have_tag('form li.time fieldset ol li label', :count => 2)
2228
- output_buffer.should have_tag('form li.time fieldset ol li label', /hour/i)
2229
- output_buffer.should have_tag('form li.time fieldset ol li label', /minute/i)
2230
- end
2231
-
2232
- it 'should have two selects for hour and minute' do
2233
- #output_buffer.should have_tag('form li.time fieldset ol li select', :count => 2)
2234
- output_buffer.should have_tag('form li.time fieldset ol li', :count => 2)
2235
- end
2236
- end
2237
-
2238
- [:boolean_select, :boolean_radio].each do |type|
2239
- describe ":as => #{type.inspect}" do
2240
- it 'should show a deprecation warning' do
2241
- @new_post.stub!(:allow_comments)
2242
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
2243
-
2244
- ::ActiveSupport::Deprecation.should_receive(:warn).with(/select|radio/, anything())
2245
-
2246
- semantic_form_for(@new_post) do |builder|
2247
- concat(builder.input(:allow_comments, :as => type))
2248
- end
2249
- end
2250
- end
2251
- end
2252
-
2253
- describe ':as => :boolean' do
2254
-
2255
- before do
2256
- @new_post.stub!(:allow_comments)
2257
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
2258
-
2259
- semantic_form_for(@new_post) do |builder|
2260
- concat(builder.input(:allow_comments, :as => :boolean))
2261
- end
2262
- end
2263
-
2264
- it 'should have a boolean class on the wrapper' do
2265
- output_buffer.should have_tag('form li.boolean')
2266
- end
2267
-
2268
- it 'should have a post_allow_comments_input id on the wrapper' do
2269
- output_buffer.should have_tag('form li#post_allow_comments_input')
2270
- end
2271
-
2272
- it 'should generate a label containing the input' do
2273
- output_buffer.should have_tag('form li label')
2274
- output_buffer.should have_tag('form li label[@for="post_allow_comments"')
2275
- output_buffer.should have_tag('form li label', /Allow comments/)
2276
- output_buffer.should have_tag('form li label input[@type="checkbox"]')
2277
- end
2278
-
2279
- it 'should generate a checkbox input' do
2280
- output_buffer.should have_tag('form li label input')
2281
- output_buffer.should have_tag('form li label input#post_allow_comments')
2282
- output_buffer.should have_tag('form li label input[@type="checkbox"]')
2283
- output_buffer.should have_tag('form li label input[@name="post[allow_comments]"]')
2284
- output_buffer.should have_tag('form li label input[@type="checkbox"][@value="1"]')
2285
- end
2286
-
2287
- it 'should allow checked and unchecked values to be sent' do
2288
- semantic_form_for(@new_post) do |builder|
2289
- concat(builder.input(:allow_comments, :as => :boolean, :checked_value => 'checked', :unchecked_value => 'unchecked'))
2290
- end
2291
-
2292
- output_buffer.should have_tag('form li label input[@type="checkbox"][@value="checked"]')
2293
- output_buffer.should have_tag('form li label input[@type="hidden"][@value="unchecked"]')
2294
- end
2295
-
2296
- it 'should generate a label and a checkbox even if no object is given' do
2297
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
2298
- concat(builder.input(:allow_comments, :as => :boolean))
2299
- end
2300
-
2301
- output_buffer.should have_tag('form li label[@for="project_allow_comments"')
2302
- output_buffer.should have_tag('form li label', /Allow comments/)
2303
- output_buffer.should have_tag('form li label input[@type="checkbox"]')
2304
-
2305
- output_buffer.should have_tag('form li label input#project_allow_comments')
2306
- output_buffer.should have_tag('form li label input[@type="checkbox"]')
2307
- output_buffer.should have_tag('form li label input[@name="project[allow_comments]"]')
2308
- end
2309
-
2310
- end
2311
- end
2312
-
2313
- describe '#inputs' do
2314
-
2315
- describe 'with a block' do
2316
-
2317
- describe 'when no options are provided' do
2318
- before do
2319
- output_buffer.replace 'before_builder' # clear the output buffer and sets before_builder
2320
- semantic_form_for(@new_post) do |builder|
2321
- @inputs_output = builder.inputs do
2322
- concat('hello')
2323
- end
2324
- end
2325
- end
2326
-
2327
- it 'should output just the content wrapped in inputs, not the whole template' do
2328
- output_buffer.should =~ /before_builder/
2329
- @inputs_output.should_not =~ /before_builder/
2330
- end
2331
-
2332
- it 'should render a fieldset inside the form, with a class of "inputs"' do
2333
- output_buffer.should have_tag("form fieldset.inputs")
2334
- end
2335
-
2336
- it 'should render an ol inside the fieldset' do
2337
- output_buffer.should have_tag("form fieldset.inputs ol")
2338
- end
2339
-
2340
- it 'should render the contents of the block inside the ol' do
2341
- output_buffer.should have_tag("form fieldset.inputs ol", /hello/)
2342
- end
2343
-
2344
- it 'should not render a legend inside the fieldset' do
2345
- output_buffer.should_not have_tag("form fieldset.inputs legend")
2346
- end
2347
-
2348
- it 'should render a fieldset even if no object is given' do
2349
- semantic_form_for(:project, :url => 'http://test.host/') do |builder|
2350
- @inputs_output = builder.inputs do
2351
- concat('bye')
2352
- end
2353
- end
2354
-
2355
- output_buffer.should have_tag("form fieldset.inputs ol", /bye/)
2356
- end
2357
- end
2358
-
2359
- describe 'when a :for option is provided' do
2360
- it 'should render nested inputs' do
2361
- @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
2362
-
2363
- semantic_form_for(@new_post) do |builder|
2364
- builder.inputs :for => [:author, @bob] do |bob_builder|
2365
- concat(bob_builder.input(:login))
2366
- end
2367
- end
2368
-
2369
- output_buffer.should have_tag("form fieldset.inputs #post_author_login")
2370
- output_buffer.should_not have_tag("form fieldset.inputs #author_login")
2371
- end
2372
-
2373
- it 'should raise an error if :for and block with no argument is given' do
2374
- semantic_form_for(@new_post) do |builder|
2375
- proc {
2376
- builder.inputs(:for => [:author, @bob]) do
2377
- #
2378
- end
2379
- }.should raise_error(ArgumentError, 'You gave :for option with a block to inputs method, ' <<
2380
- 'but the block does not accept any argument.')
2381
- end
2382
- end
2383
-
2384
- it 'should pass options down to semantic_fields_for' do
2385
- @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
2386
-
2387
- semantic_form_for(@new_post) do |builder|
2388
- builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
2389
- concat(bob_builder.input(:login))
2390
- end
2391
- end
2392
-
2393
- output_buffer.should have_tag('form fieldset ol li #post_author_10_login')
2394
- end
2395
-
2396
- it 'should not add builder as a fieldset attribute tag' do
2397
- semantic_form_for(@new_post) do |builder|
2398
- builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
2399
- concat('input')
2400
- end
2401
- end
2402
-
2403
- output_buffer.should_not have_tag('fieldset[@builder="Formtastic::SemanticFormHelper"]')
2404
- end
2405
-
2406
- it 'should send parent_builder as an option to allow child index interpolation' do
2407
- semantic_form_for(@new_post) do |builder|
2408
- builder.instance_variable_set('@nested_child_index', 0)
2409
- builder.inputs :for => [:author, @bob], :name => 'Author #%i' do |bob_builder|
2410
- concat('input')
2411
- end
2412
- end
2413
-
2414
- output_buffer.should have_tag('fieldset legend', 'Author #1')
2415
- end
2416
-
2417
- it 'should also provide child index interpolation when nested child index is a hash' do
2418
- semantic_form_for(@new_post) do |builder|
2419
- builder.instance_variable_set('@nested_child_index', :author => 10)
2420
- builder.inputs :for => [:author, @bob], :name => 'Author #%i' do |bob_builder|
2421
- concat('input')
2422
- end
2423
- end
2424
-
2425
- output_buffer.should have_tag('fieldset legend', 'Author #11')
2426
- end
2427
- end
2428
-
2429
- describe 'when a :name option is provided' do
2430
- before do
2431
- @legend_text = "Advanced options"
2432
-
2433
- semantic_form_for(@new_post) do |builder|
2434
- builder.inputs :name => @legend_text do
2435
- end
2436
- end
2437
- end
2438
-
2439
- it 'should render a fieldset inside the form' do
2440
- output_buffer.should have_tag("form fieldset legend", /#{@legend_text}/)
2441
- end
2442
- end
2443
-
2444
- describe 'when other options are provided' do
2445
- before do
2446
- @id_option = 'advanced'
2447
- @class_option = 'wide'
2448
-
2449
- semantic_form_for(@new_post) do |builder|
2450
- builder.inputs :id => @id_option, :class => @class_option do
2451
- end
2452
- end
2453
- end
2454
-
2455
- it 'should pass the options into the fieldset tag as attributes' do
2456
- output_buffer.should have_tag("form fieldset##{@id_option}")
2457
- output_buffer.should have_tag("form fieldset.#{@class_option}")
2458
- end
2459
- end
2460
-
2461
- end
2462
-
2463
- describe 'without a block' do
2464
-
2465
- before do
2466
- Post.stub!(:reflections).and_return({:author => mock('reflection', :macro => :belongs_to),
2467
- :comments => mock('reflection', :macro => :has_many) })
2468
- Post.stub!(:content_columns).and_return([mock('column', :name => 'title'), mock('column', :name => 'body'), mock('column', :name => 'created_at')])
2469
- Author.stub!(:find).and_return([@fred, @bob])
2470
-
2471
- @new_post.stub!(:title)
2472
- @new_post.stub!(:body)
2473
- @new_post.stub!(:author_id)
2474
-
2475
- @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :string, :limit => 255))
2476
- @new_post.stub!(:column_for_attribute).with(:body).and_return(mock('column', :type => :text))
2477
- @new_post.stub!(:column_for_attribute).with(:created_at).and_return(mock('column', :type => :datetime))
2478
- @new_post.stub!(:column_for_attribute).with(:author).and_return(nil)
2479
- end
2480
-
2481
- describe 'with no args' do
2482
- before do
2483
- semantic_form_for(@new_post) do |builder|
2484
- concat(builder.inputs)
2485
- end
2486
- end
2487
-
2488
- it 'should render a form' do
2489
- output_buffer.should have_tag('form')
2490
- end
2491
-
2492
- it 'should render a fieldset inside the form' do
2493
- output_buffer.should have_tag('form > fieldset.inputs')
2494
- end
2495
-
2496
- it 'should not render a legend in the fieldset' do
2497
- output_buffer.should_not have_tag('form > fieldset.inputs > legend')
2498
- end
2499
-
2500
- it 'should render an ol in the fieldset' do
2501
- output_buffer.should have_tag('form > fieldset.inputs > ol')
2502
- end
2503
-
2504
- it 'should render a list item in the ol for each column and reflection' do
2505
- # Remove the :has_many macro and :created_at column
2506
- count = Post.content_columns.size + Post.reflections.size - 2
2507
- output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => count)
2508
- end
2509
-
2510
- it 'should render a string list item for title' do
2511
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
2512
- end
2513
-
2514
- it 'should render a text list item for body' do
2515
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
2516
- end
2517
-
2518
- it 'should render a select list item for author_id' do
2519
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.select', :count => 1)
2520
- end
2521
-
2522
- it 'should not render timestamps inputs by default' do
2523
- output_buffer.should_not have_tag('form > fieldset.inputs > ol > li.datetime')
2524
- end
2525
- end
2526
-
2527
- describe 'with column names as args' do
2528
- describe 'and an object is given' do
2529
- it 'should render a form with a fieldset containing two list items' do
2530
- semantic_form_for(@new_post) do |builder|
2531
- concat(builder.inputs(:title, :body))
2532
- end
2533
-
2534
- output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 2)
2535
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
2536
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
2537
- end
2538
- end
2539
-
2540
- describe 'and no object is given' do
2541
- it 'should render a form with a fieldset containing two list items' do
2542
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
2543
- concat(builder.inputs(:title, :body))
2544
- end
2545
-
2546
- output_buffer.should have_tag('form > fieldset.inputs > ol > li.string', :count => 2)
2547
- end
2548
- end
2549
- end
2550
-
2551
- describe 'when a :for option is provided' do
2552
- describe 'and an object is given' do
2553
- it 'should render nested inputs' do
2554
- @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
2555
-
2556
- semantic_form_for(@new_post) do |builder|
2557
- concat(builder.inputs(:login, :for => @bob))
2558
- end
2559
-
2560
- output_buffer.should have_tag("form fieldset.inputs #post_author_login")
2561
- output_buffer.should_not have_tag("form fieldset.inputs #author_login")
2562
- end
2563
- end
2564
-
2565
- describe 'and no object is given' do
2566
- it 'should render nested inputs' do
2567
- semantic_form_for(:project, :url => 'http://test.host/') do |builder|
2568
- concat(builder.inputs(:login, :for => @bob))
2569
- end
2570
-
2571
- output_buffer.should have_tag("form fieldset.inputs #project_author_login")
2572
- output_buffer.should_not have_tag("form fieldset.inputs #project_login")
2573
- end
2574
- end
2575
- end
2576
-
2577
- describe 'with column names and an options hash as args' do
2578
- before do
2579
- semantic_form_for(@new_post) do |builder|
2580
- concat(builder.inputs(:title, :body, :name => "Legendary Legend Text", :id => "my-id"))
2581
- end
2582
- end
2583
-
2584
- it 'should render a form with a fieldset containing two list items' do
2585
- output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 2)
2586
- end
2587
-
2588
- it 'should pass the options down to the fieldset' do
2589
- output_buffer.should have_tag('form > fieldset#my-id.inputs')
2590
- end
2591
-
2592
- it 'should use the special :name option as a text for the legend tag' do
2593
- output_buffer.should have_tag('form > fieldset#my-id.inputs > legend', /Legendary Legend Text/)
2594
- end
2595
- end
2596
-
2597
- end
2598
-
2599
- end
2600
-
2601
- describe '#buttons' do
2602
-
2603
- describe 'with a block' do
2604
- describe 'when no options are provided' do
2605
- before do
2606
- semantic_form_for(@new_post) do |builder|
2607
- builder.buttons do
2608
- concat('hello')
2609
- end
2610
- end
2611
- end
2612
-
2613
- it 'should render a fieldset inside the form, with a class of "inputs"' do
2614
- output_buffer.should have_tag("form fieldset.buttons")
2615
- end
2616
-
2617
- it 'should render an ol inside the fieldset' do
2618
- output_buffer.should have_tag("form fieldset.buttons ol")
2619
- end
2620
-
2621
- it 'should render the contents of the block inside the ol' do
2622
- output_buffer.should have_tag("form fieldset.buttons ol", /hello/)
2623
- end
2624
-
2625
- it 'should not render a legend inside the fieldset' do
2626
- output_buffer.should_not have_tag("form fieldset.buttons legend")
2627
- end
2628
- end
2629
-
2630
- describe 'when a :name option is provided' do
2631
- before do
2632
- @legend_text = "Advanced options"
2633
-
2634
- semantic_form_for(@new_post) do |builder|
2635
- builder.buttons :name => @legend_text do
2636
- end
2637
- end
2638
- end
2639
- it 'should render a fieldset inside the form' do
2640
- output_buffer.should have_tag("form fieldset legend", /#{@legend_text}/)
2641
- end
2642
- end
2643
-
2644
- describe 'when other options are provided' do
2645
- before do
2646
- @id_option = 'advanced'
2647
- @class_option = 'wide'
2648
-
2649
- semantic_form_for(@new_post) do |builder|
2650
- builder.buttons :id => @id_option, :class => @class_option do
2651
- end
2652
- end
2653
- end
2654
- it 'should pass the options into the fieldset tag as attributes' do
2655
- output_buffer.should have_tag("form fieldset##{@id_option}")
2656
- output_buffer.should have_tag("form fieldset.#{@class_option}")
2657
- end
2658
- end
2659
-
2660
- end
2661
-
2662
- describe 'without a block' do
2663
-
2664
- describe 'with no args (default buttons)' do
2665
-
2666
- before do
2667
- semantic_form_for(@new_post) do |builder|
2668
- concat(builder.buttons)
2669
- end
2670
- end
2671
-
2672
- it 'should render a form' do
2673
- output_buffer.should have_tag('form')
2674
- end
2675
-
2676
- it 'should render a buttons fieldset inside the form' do
2677
- output_buffer.should have_tag('form fieldset.buttons')
2678
- end
2679
-
2680
- it 'should not render a legend in the fieldset' do
2681
- output_buffer.should_not have_tag('form fieldset.buttons legend')
2682
- end
2683
-
2684
- it 'should render an ol in the fieldset' do
2685
- output_buffer.should have_tag('form fieldset.buttons ol')
2686
- end
2687
-
2688
- it 'should render a list item in the ol for each default button' do
2689
- output_buffer.should have_tag('form fieldset.buttons ol li', :count => 1)
2690
- end
2691
-
2692
- it 'should render a commit list item for the commit button' do
2693
- output_buffer.should have_tag('form fieldset.buttons ol li.commit')
2694
- end
2695
-
2696
- end
2697
-
2698
- describe 'with button names as args' do
2699
-
2700
- before do
2701
- semantic_form_for(@new_post) do |builder|
2702
- concat(builder.buttons(:commit))
2703
- end
2704
- end
2705
-
2706
- it 'should render a form with a fieldset containing a list item for each button arg' do
2707
- output_buffer.should have_tag('form > fieldset.buttons > ol > li', :count => 1)
2708
- output_buffer.should have_tag('form > fieldset.buttons > ol > li.commit')
2709
- end
2710
-
2711
- end
2712
-
2713
- describe 'with button names as args and an options hash' do
2714
-
2715
- before do
2716
- semantic_form_for(@new_post) do |builder|
2717
- concat(builder.buttons(:commit, :name => "Now click a button", :id => "my-id"))
2718
- end
2719
- end
2720
-
2721
- it 'should render a form with a fieldset containing a list item for each button arg' do
2722
- output_buffer.should have_tag('form > fieldset.buttons > ol > li', :count => 1)
2723
- output_buffer.should have_tag('form > fieldset.buttons > ol > li.commit', :count => 1)
2724
- end
2725
-
2726
- it 'should pass the options down to the fieldset' do
2727
- output_buffer.should have_tag('form > fieldset#my-id.buttons')
2728
- end
2729
-
2730
- it 'should use the special :name option as a text for the legend tag' do
2731
- output_buffer.should have_tag('form > fieldset#my-id.buttons > legend', /Now click a button/)
2732
- end
2733
-
2734
- end
2735
-
2736
- end
2737
-
2738
- end
2739
-
2740
- describe '#commit_button' do
2741
-
2742
- describe 'when used on any record' do
2743
-
2744
- before do
2745
- @new_post.stub!(:new_record?).and_return(false)
2746
- semantic_form_for(@new_post) do |builder|
2747
- concat(builder.commit_button)
2748
- end
2749
- end
2750
-
2751
- it 'should render a commit li' do
2752
- output_buffer.should have_tag('li.commit')
2753
- end
2754
-
2755
- it 'should render an input with a type attribute of "submit"' do
2756
- output_buffer.should have_tag('li.commit input[@type="submit"]')
2757
- end
2758
-
2759
- it 'should render an input with a name attribute of "commit"' do
2760
- output_buffer.should have_tag('li.commit input[@name="commit"]')
2761
- end
2762
-
2763
- it 'should pass options given in :button_html to the button' do
2764
- @new_post.stub!(:new_record?).and_return(false)
2765
- semantic_form_for(@new_post) do |builder|
2766
- concat(builder.commit_button('text', :button_html => {:class => 'my_class', :id => 'my_id'}))
2767
- end
2768
-
2769
- output_buffer.should have_tag('li.commit input#my_id')
2770
- output_buffer.should have_tag('li.commit input.my_class')
2771
- end
2772
-
2773
- end
2774
-
2775
- describe 'when the first option is a string and the second is a hash' do
2776
-
2777
- before do
2778
- @new_post.stub!(:new_record?).and_return(false)
2779
- semantic_form_for(@new_post) do |builder|
2780
- concat(builder.commit_button("a string", :button_html => { :class => "pretty"}))
2781
- end
2782
- end
2783
-
2784
- it "should render the string as the value of the button" do
2785
- output_buffer.should have_tag('li input[@value="a string"]')
2786
- end
2787
-
2788
- it "should deal with the options hash" do
2789
- output_buffer.should have_tag('li input.pretty')
2790
- end
2791
-
2792
- end
2793
-
2794
- describe 'when the first option is a hash' do
2795
-
2796
- before do
2797
- @new_post.stub!(:new_record?).and_return(false)
2798
- semantic_form_for(@new_post) do |builder|
2799
- concat(builder.commit_button(:button_html => { :class => "pretty"}))
2800
- end
2801
- end
2802
-
2803
- it "should deal with the options hash" do
2804
- output_buffer.should have_tag('li input.pretty')
2805
- end
2806
-
2807
- end
2808
-
2809
- describe 'when used on an existing record' do
2810
-
2811
- it 'should render an input with a value attribute of "Save Post"' do
2812
- @new_post.stub!(:new_record?).and_return(false)
2813
- semantic_form_for(@new_post) do |builder|
2814
- concat(builder.commit_button)
2815
- end
2816
- output_buffer.should have_tag('li.commit input[@value="Save Post"]')
2817
- end
2818
-
2819
- describe 'when the locale sets the label text' do
2820
- before do
2821
- I18n.backend.store_translations 'en', :formtastic => {:save => 'Save Changes To' }
2822
- @new_post.stub!(:new_record?).and_return(false)
2823
- semantic_form_for(@new_post) do |builder|
2824
- concat(builder.commit_button)
2825
- end
2826
- end
2827
-
2828
- after do
2829
- I18n.backend.store_translations 'en', :formtastic => {:save => nil}
2830
- end
2831
-
2832
- it 'should allow translation of the labels' do
2833
- output_buffer.should have_tag('li.commit input[@value="Save Changes To Post"]')
2834
- end
2835
- end
2836
- end
2837
-
2838
- describe 'when used on a new record' do
2839
-
2840
- it 'should render an input with a value attribute of "Create Post"' do
2841
- @new_post.stub!(:new_record?).and_return(true)
2842
- semantic_form_for(@new_post) do |builder|
2843
- concat(builder.commit_button)
2844
- end
2845
- output_buffer.should have_tag('li.commit input[@value="Create Post"]')
2846
- end
2847
-
2848
- describe 'when the locale sets the label text' do
2849
- before do
2850
- I18n.backend.store_translations 'en', :formtastic => {:create => 'Make' }
2851
- semantic_form_for(@new_post) do |builder|
2852
- concat(builder.commit_button)
2853
- end
2854
- end
2855
-
2856
- after do
2857
- I18n.backend.store_translations 'en', :formtastic => {:create => nil}
2858
- end
2859
-
2860
- it 'should allow translation of the labels' do
2861
- output_buffer.should have_tag('li.commit input[@value="Make Post"]')
2862
- end
2863
- end
2864
-
2865
- end
2866
-
2867
- describe 'when used without object' do
2868
-
2869
- it 'should render an input with a value attribute of "Submit"' do
2870
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
2871
- concat(builder.commit_button)
2872
- end
2873
-
2874
- output_buffer.should have_tag('li.commit input[@value="Submit Project"]')
2875
- end
2876
-
2877
- describe 'when the locale sets the label text' do
2878
- before do
2879
- I18n.backend.store_translations 'en', :formtastic => { :submit => 'Send' }
2880
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
2881
- concat(builder.commit_button)
2882
- end
2883
- end
2884
-
2885
- after do
2886
- I18n.backend.store_translations 'en', :formtastic => {:submit => nil}
2887
- end
2888
-
2889
- it 'should allow translation of the labels' do
2890
- output_buffer.should have_tag('li.commit input[@value="Send Project"]')
2891
- end
2892
- end
2893
-
2894
- end
2895
-
2896
- end
2897
-
2898
- end
2899
-
2900
- end