formtastic 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,7 +9,12 @@ module Formtastic
9
9
  :create => 'Create {{model}}',
10
10
  :update => 'Update {{model}}'
11
11
  }.freeze
12
-
12
+ SCOPES = [
13
+ '{{model}}.{{action}}.{{attribute}}',
14
+ '{{model}}.{{attribute}}',
15
+ '{{attribute}}'
16
+ ]
17
+
13
18
  class << self
14
19
 
15
20
  def translate(*args)
@@ -75,6 +75,7 @@ module CustomMacros
75
75
  def it_should_use_default_text_field_size_when_method_has_no_database_column(as)
76
76
  it 'should use default_text_field_size when method has no database column' do
77
77
  @new_post.stub!(:column_for_attribute).and_return(nil) # Return a nil column
78
+
78
79
  semantic_form_for(@new_post) do |builder|
79
80
  concat(builder.input(:title, :as => as))
80
81
  end
@@ -222,7 +223,108 @@ module CustomMacros
222
223
  end
223
224
  end
224
225
  end
225
-
226
+
227
+ def it_should_select_existing_datetime_else_current(*datetime_parts)
228
+ describe "default value" do
229
+ before do
230
+ @new_post.should_receive(:publish_at=).any_number_of_times
231
+ end
232
+
233
+ describe "when attribute value is present" do
234
+ before do
235
+ @output_buffer = ''
236
+ publish_at_value = 1.year.ago + 2.month + 3.day + 4.hours + 5.minutes # No comment =)
237
+ @new_post.stub!(:publish_at).and_return(publish_at_value)
238
+
239
+ semantic_form_for(@new_post) do |builder|
240
+ concat(builder.input(:publish_at, :as => :datetime))
241
+ end
242
+ end
243
+
244
+ it "should select the present value by default" do
245
+ # puts output_buffer
246
+ output_buffer.should have_tag("form li select#post_publish_at_1i option[@selected='selected'][@value='#{@new_post.publish_at.year}']") if datetime_parts.include?(:year)
247
+ output_buffer.should have_tag("form li select#post_publish_at_2i option[@selected='selected'][@value='#{@new_post.publish_at.month}']") if datetime_parts.include?(:month)
248
+ output_buffer.should have_tag("form li select#post_publish_at_3i option[@selected='selected'][@value='#{@new_post.publish_at.day}']") if datetime_parts.include?(:day)
249
+ output_buffer.should have_tag("form li select#post_publish_at_4i option[@selected='selected'][@value='#{@new_post.publish_at.strftime("%H")}']") if datetime_parts.include?(:hour)
250
+ output_buffer.should have_tag("form li select#post_publish_at_5i option[@selected='selected'][@value='#{@new_post.publish_at.strftime("%M")}']") if datetime_parts.include?(:minute)
251
+ #output_buffer.should have_tag("form li select#post_publish_at_6i option[@selected='selected'][@value='#{@new_post.publish_at.sec}']") if datetime_parts.include?(:second)
252
+ end
253
+ end
254
+
255
+ describe "when no attribute value is present" do
256
+ before do
257
+ @output_buffer = ''
258
+ @new_post.stub!(:publish_at).and_return(nil)
259
+ @current_time = ::Time.now
260
+
261
+ semantic_form_for(@new_post) do |builder|
262
+ concat(builder.input(:publish_at, :as => :datetime))
263
+ end
264
+ end
265
+
266
+ it "should select the current day/time by default" do
267
+ # puts output_buffer
268
+ output_buffer.should have_tag("form li select#post_publish_at_1i option[@selected='selected'][@value='#{@current_time.year}']") if datetime_parts.include?(:year)
269
+ output_buffer.should have_tag("form li select#post_publish_at_2i option[@selected='selected'][@value='#{@current_time.month}']") if datetime_parts.include?(:month)
270
+ output_buffer.should have_tag("form li select#post_publish_at_3i option[@selected='selected'][@value='#{@current_time.day}']") if datetime_parts.include?(:day)
271
+ output_buffer.should have_tag("form li select#post_publish_at_4i option[@selected='selected'][@value='#{@current_time.strftime("%H")}']") if datetime_parts.include?(:hour)
272
+ output_buffer.should have_tag("form li select#post_publish_at_5i option[@selected='selected'][@value='#{@current_time.strftime("%M")}']") if datetime_parts.include?(:minute)
273
+ #output_buffer.should have_tag("form li select#post_publish_at_6i option[@selected='selected'][@value='#{@custom_default_time.sec}']") if datetime_parts.include?(:second)
274
+ end
275
+
276
+ # TODO: Scenario when current time is not a possible choice (because of specified date/time ranges)?
277
+ end
278
+ end
279
+ end
280
+
281
+ def it_should_select_explicit_default_value_if_set(*datetime_parts)
282
+ describe 'when :selected is set' do
283
+ before do
284
+ @output_buffer = ''
285
+ end
286
+
287
+ # Note: Not possible to override default selected value for time_zone input
288
+ # without overriding Rails core helper. This Rails helper works "a bit different". =/
289
+ #
290
+ describe "no selected items" do
291
+ before do
292
+ @default_time = 2.days.ago
293
+ @new_post.stub!(:publish_at).and_return(@default_time)
294
+
295
+ semantic_form_for(@new_post) do |builder|
296
+ concat(builder.input(:publish_at, :as => :time_zone, :selected => nil))
297
+ end
298
+ end
299
+
300
+ it 'should not have any selected item(s)' do
301
+ output_buffer.should_not have_tag("form li select#post_publish_at_1i option[@selected='selected']")
302
+ end
303
+ end
304
+
305
+ describe "single selected item" do
306
+ before do
307
+ @custom_default_time = 5.days.ago
308
+ @new_post.stub!(:publish_at).and_return(2.days.ago)
309
+
310
+ semantic_form_for(@new_post) do |builder|
311
+ concat(builder.input(:publish_at, :as => :datetime, :selected => @custom_default_time))
312
+ end
313
+ end
314
+
315
+ it "should select the specified value" do
316
+ output_buffer.should have_tag("form li select#post_publish_at_1i option[@selected='selected'][@value='#{@custom_default_time.year}']") if datetime_parts.include?(:year)
317
+ output_buffer.should have_tag("form li select#post_publish_at_2i option[@selected='selected'][@value='#{@custom_default_time.month}']") if datetime_parts.include?(:month)
318
+ output_buffer.should have_tag("form li select#post_publish_at_3i option[@selected='selected'][@value='#{@custom_default_time.day}']") if datetime_parts.include?(:day)
319
+ output_buffer.should have_tag("form li select#post_publish_at_4i option[@selected='selected'][@value='#{@custom_default_time.strftime("%H")}']") if datetime_parts.include?(:hour)
320
+ output_buffer.should have_tag("form li select#post_publish_at_5i option[@selected='selected'][@value='#{@custom_default_time.strftime("%M")}']") if datetime_parts.include?(:minute)
321
+ #output_buffer.should have_tag("form li select#post_publish_at_6i option[@selected='selected'][@value='#{@custom_default_time.sec}']") if datetime_parts.include?(:second)
322
+ end
323
+ end
324
+
325
+ end
326
+ end
327
+
226
328
  def it_should_use_the_collection_when_provided(as, countable)
227
329
  describe 'when the :collection option is provided' do
228
330
 
@@ -456,6 +558,4 @@ module CustomMacros
456
558
  end
457
559
 
458
560
  end
459
-
460
-
461
561
  end
@@ -79,7 +79,17 @@ describe 'SemanticFormHelper' do
79
79
  builder.object_name.to_s.should == "post" # TODO: is this forced .to_s a bad assumption somewhere?
80
80
  end
81
81
  end
82
-
82
+
83
+ describe "with :builder option" do
84
+ it "yields an instance of the given builder" do
85
+ class MyAwesomeCustomBuilder < ::Formtastic::SemanticFormBuilder
86
+ end
87
+ semantic_form_for(:post, ::Post.new, :url => '/hello', :builder => MyAwesomeCustomBuilder) do |builder|
88
+ builder.class.should == MyAwesomeCustomBuilder
89
+ end
90
+ end
91
+ end
92
+
83
93
  end
84
94
 
85
95
  describe '#semantic_fields_for' do
@@ -80,4 +80,52 @@ describe 'Formtastic::I18n' do
80
80
 
81
81
  end
82
82
 
83
+ describe "I18n string lookups" do
84
+
85
+ include FormtasticSpecHelper
86
+
87
+ before do
88
+ @output_buffer = ''
89
+ mock_everything
90
+
91
+ ::I18n.backend.store_translations :en, :formtastic => {
92
+ :labels => {
93
+ :title => "Hello world!",
94
+ :post => {:title => "Hello post!"},
95
+ :project => {:title => "Hello project!"}
96
+ }
97
+ }
98
+ ::Formtastic::SemanticFormBuilder.i18n_lookups_by_default = true
99
+
100
+ @new_post.stub!(:title)
101
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :string, :limit => 255))
102
+ end
103
+
104
+ after do
105
+ ::I18n.backend.store_translations :en, :formtastic => nil
106
+ ::Formtastic::SemanticFormBuilder.i18n_lookups_by_default = false
107
+ end
108
+
109
+ it "lookup scopes should be defined" do
110
+ lambda { ::Formtastic::I18n::SCOPES }.should_not raise_error(::NameError)
111
+ end
112
+
113
+ it "should be able to translate with namespaced object" do
114
+ semantic_form_for(@new_post) do |builder|
115
+ concat(builder.input(:title))
116
+ end
117
+ output_buffer.should have_tag("form label", /Hello post!/)
118
+ end
119
+
120
+ it "should be able to translate without form-object" do
121
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
122
+ concat(builder.input(:title))
123
+ end
124
+ output_buffer.should have_tag("form label", /Hello project!/)
125
+ end
126
+
127
+ # TODO: Add spec for namespaced models?
128
+
129
+ end
130
+
83
131
  end
@@ -400,9 +400,8 @@ describe 'SemanticFormBuilder#input' do
400
400
 
401
401
  describe 'when not provided' do
402
402
  describe 'when localized label is NOT provided' do
403
- describe 'and object is not given' do
403
+ describe 'and label_str_method is not provided' do
404
404
  it 'should default the humanized method name, passing it down to the label tag' do
405
- ::Formtastic::SemanticFormBuilder.label_str_method = :humanize
406
405
 
407
406
  semantic_form_for(:project, :url => 'http://test.host') do |builder|
408
407
  concat(builder.input(:meta_description))
@@ -412,16 +411,17 @@ describe 'SemanticFormBuilder#input' do
412
411
  end
413
412
  end
414
413
 
415
- describe 'and object is given' do
416
- it 'should delegate the label logic to class human attribute name and pass it down to the label tag' do
417
- @new_post.stub!(:meta_description) # a two word method name
418
- @new_post.class.should_receive(:human_attribute_name).with('meta_description').and_return('meta_description'.humanize)
414
+ describe 'and label_str_method is :capitalize' do
415
+ it 'should capitalize method name, passing it down to the label tag' do
416
+ old_value = ::Formtastic::SemanticFormBuilder.label_str_method
417
+ ::Formtastic::SemanticFormBuilder.label_str_method = :capitalize
419
418
 
420
- semantic_form_for(@new_post) do |builder|
419
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
421
420
  concat(builder.input(:meta_description))
422
421
  end
423
422
 
424
- output_buffer.should have_tag("form li label", /#{'meta_description'.humanize}/)
423
+ output_buffer.should have_tag("form li label", /#{'meta_description'.capitalize}/)
424
+ ::Formtastic::SemanticFormBuilder.label_str_method = old_value
425
425
  end
426
426
  end
427
427
  end
@@ -56,5 +56,38 @@ describe 'boolean input' do
56
56
  output_buffer.should have_tag('form li label input[@name="project[allow_comments]"]')
57
57
  end
58
58
 
59
- end
59
+ describe 'when :selected is set' do
60
+ before do
61
+ @output_buffer = ''
62
+ end
63
+
64
+ describe "not selected" do
65
+ before do
66
+ @new_post.stub!(:allow_comments).and_return(true)
67
+
68
+ semantic_form_for(@new_post) do |builder|
69
+ concat(builder.input(:allow_comments, :as => :boolean, :selected => false))
70
+ end
71
+ end
72
+
73
+ it 'should not be selected' do
74
+ output_buffer.should_not have_tag("form li label input[@type='checkbox'][@checked='checked']")
75
+ end
76
+ end
60
77
 
78
+ describe "selected" do
79
+ before do
80
+ @new_post.stub!(:allow_comments).and_return(false)
81
+
82
+ semantic_form_for(@new_post) do |builder|
83
+ concat(builder.input(:allow_comments, :as => :boolean, :selected => true))
84
+ end
85
+ end
86
+
87
+ it 'should be selected' do
88
+ output_buffer.should have_tag("form li label input[@type='checkbox'][@checked='checked']")
89
+ end
90
+ end
91
+ end
92
+
93
+ end
@@ -51,7 +51,7 @@ describe 'check_boxes input' do
51
51
 
52
52
  it 'should use values as li.class when value_as_class is true' do
53
53
  ::Post.find(:all).each do |post|
54
- output_buffer.should have_tag("form li fieldset ol li.#{post.id} label")
54
+ output_buffer.should have_tag("form li fieldset ol li.post_#{post.id} label")
55
55
  end
56
56
  end
57
57
 
@@ -100,6 +100,62 @@ describe 'check_boxes input' do
100
100
  end
101
101
  end
102
102
  end
103
+
104
+ describe 'when :selected is set' do
105
+ before do
106
+ @output_buffer = ''
107
+ end
108
+
109
+ describe "no selected items" do
110
+ before do
111
+ @new_post.stub!(:author_ids).and_return(nil)
112
+
113
+ semantic_form_for(@new_post) do |builder|
114
+ concat(builder.input(:authors, :as => :check_boxes, :selected => nil))
115
+ end
116
+ end
117
+
118
+ it 'should not have any selected item(s)' do
119
+ output_buffer.should_not have_tag("form li fieldset ol li label input[@checked='checked']")
120
+ end
121
+ end
122
+
123
+ describe "single selected item" do
124
+ before do
125
+ @new_post.stub!(:author_ids).and_return(nil)
126
+
127
+ semantic_form_for(@new_post) do |builder|
128
+ concat(builder.input(:authors, :as => :check_boxes, :selected => @fred.id))
129
+ end
130
+ end
131
+
132
+ it "should have one item selected; the specified one" do
133
+ output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']", :count => 1)
134
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@fred.id}']", /fred/i)
135
+ output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked'][@value='#{@fred.id}']")
136
+ end
137
+ end
138
+
139
+ describe "multiple selected items" do
140
+ before do
141
+ @new_post.stub!(:author_ids).and_return(nil)
142
+
143
+ semantic_form_for(@new_post) do |builder|
144
+ concat(builder.input(:authors, :as => :check_boxes, :selected => [@bob.id, @fred.id]))
145
+ end
146
+ end
147
+
148
+ it "should have multiple items selected; the specified ones" do
149
+ output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']", :count => 2)
150
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@bob.id}']", /bob/i)
151
+ output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked'][@value='#{@bob.id}']")
152
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@fred.id}']", /fred/i)
153
+ output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked'][@value='#{@fred.id}']")
154
+ end
155
+ end
156
+
157
+ end
158
+
103
159
  end
104
160
 
105
161
  end
@@ -39,5 +39,7 @@ describe 'date input' do
39
39
  output_buffer.should have_tag('form li.date fieldset ol li select', :count => 3)
40
40
  end
41
41
 
42
- end
42
+ it_should_select_existing_datetime_else_current(:year, :month, :day)
43
+ it_should_select_explicit_default_value_if_set(:year, :month, :day)
43
44
 
45
+ end
@@ -9,6 +9,11 @@ describe 'datetime input' do
9
9
  @output_buffer = ''
10
10
  mock_everything
11
11
 
12
+ @new_post.should_receive(:publish_at=).any_number_of_times
13
+ @new_post.should_receive(:created_at=).any_number_of_times
14
+ @bob.should_receive(:created_at=).any_number_of_times
15
+ @new_post.should_receive(:title=).any_number_of_times # Macro stuff forces this.
16
+
12
17
  semantic_form_for(@new_post) do |builder|
13
18
  concat(builder.input(:publish_at, :as => :datetime))
14
19
  end
@@ -54,15 +59,10 @@ describe 'datetime input' do
54
59
  end
55
60
  end
56
61
 
57
- describe 'when :discard_input => true is set' do
58
- it 'should use default hidden value equals to 1 when attribute returns nil' do
59
- semantic_form_for(@new_post) do |builder|
60
- concat(builder.input(:publish_at, :as => :datetime, :discard_day => true))
61
- end
62
-
63
- output_buffer.should have_tag("form li input[@type='hidden'][@value='1']")
64
- end
62
+ it_should_select_existing_datetime_else_current(:year, :month, :day, :hour, :minute, :second)
63
+ it_should_select_explicit_default_value_if_set(:year, :month, :day, :hour, :minute, :second)
65
64
 
65
+ describe 'when :discard_input => true is set' do
66
66
  it 'should use default attribute value when it is not nil' do
67
67
  @new_post.stub!(:publish_at).and_return(Date.new(2007,12,27))
68
68
  semantic_form_for(@new_post) do |builder|
@@ -49,7 +49,7 @@ describe 'radio input' do
49
49
 
50
50
  it 'should use values as li.class when value_as_class is true' do
51
51
  ::Author.find(:all).each do |author|
52
- output_buffer.should have_tag("form li fieldset ol li.#{author.id} label")
52
+ output_buffer.should have_tag("form li fieldset ol li.author_#{author.id} label")
53
53
  end
54
54
  end
55
55
 
@@ -109,5 +109,41 @@ describe 'radio input' do
109
109
  end
110
110
  end
111
111
 
112
- end
112
+ describe 'when :selected is set' do
113
+ before do
114
+ @output_buffer = ''
115
+ end
116
+
117
+ describe "no selected items" do
118
+ before do
119
+ @new_post.stub!(:author_ids).and_return(nil)
120
+
121
+ semantic_form_for(@new_post) do |builder|
122
+ concat(builder.input(:authors, :as => :radio, :selected => nil))
123
+ end
124
+ end
125
+
126
+ it 'should not have any selected item(s)' do
127
+ output_buffer.should_not have_tag("form li fieldset ol li label input[@checked='checked']")
128
+ end
129
+ end
113
130
 
131
+ describe "single selected item" do
132
+ before do
133
+ @new_post.stub!(:author_ids).and_return(nil)
134
+
135
+ semantic_form_for(@new_post) do |builder|
136
+ concat(builder.input(:authors, :as => :radio, :selected => @fred.id))
137
+ end
138
+ end
139
+
140
+ it "should have one item selected; the specified one" do
141
+ output_buffer.should have_tag("form li fieldset ol li label input[@type='radio'][@checked='checked']", :count => 1)
142
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@fred.id}']", /fred/i)
143
+ output_buffer.should have_tag("form li fieldset ol li label input[@type='radio'][@checked='checked'][@value='#{@fred.id}']")
144
+ end
145
+ end
146
+
147
+ end
148
+
149
+ end