formtastic 0.9.4 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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