formtastic 2.3.1 → 3.0.0.rc
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.
- checksums.yaml +8 -8
- data/.travis.yml +0 -24
- data/Appraisals +0 -8
- data/CHANGELOG +0 -16
- data/README.textile +2 -2
- data/formtastic.gemspec +9 -8
- data/lib/formtastic.rb +1 -2
- data/lib/formtastic/actions/button_action.rb +1 -8
- data/lib/formtastic/helpers/input_helper.rb +2 -0
- data/lib/formtastic/inputs.rb +1 -0
- data/lib/formtastic/inputs/base.rb +1 -9
- data/lib/formtastic/inputs/base/collections.rb +5 -17
- data/lib/formtastic/inputs/base/errors.rb +3 -3
- data/lib/formtastic/inputs/base/hints.rb +1 -1
- data/lib/formtastic/inputs/base/options.rb +1 -1
- data/lib/formtastic/inputs/boolean_input.rb +1 -3
- data/lib/formtastic/inputs/color_input.rb +42 -0
- data/lib/formtastic/inputs/datetime_picker_input.rb +4 -1
- data/lib/formtastic/inputs/hidden_input.rb +2 -6
- data/lib/formtastic/inputs/select_input.rb +1 -25
- data/lib/formtastic/localizer.rb +2 -0
- data/lib/formtastic/util.rb +1 -1
- data/lib/formtastic/version.rb +1 -1
- data/lib/generators/formtastic/install/install_generator.rb +4 -19
- data/spec/actions/generic_action_spec.rb +38 -2
- data/spec/helpers/input_helper_spec.rb +6 -29
- data/spec/inputs/boolean_input_spec.rb +28 -42
- data/spec/inputs/color_input_spec.rb +97 -0
- data/spec/inputs/hidden_input_spec.rb +11 -28
- data/spec/inputs/select_input_spec.rb +6 -107
- data/spec/inputs/string_input_spec.rb +13 -1
- data/spec/localizer_spec.rb +23 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/support/custom_macros.rb +5 -2
- data/spec/util_spec.rb +15 -22
- metadata +32 -32
- data/gemfiles/rails_3.0.gemfile +0 -7
- data/gemfiles/rails_3.1.gemfile +0 -7
- data/lib/formtastic/inputs/base/grouped_collections.rb +0 -77
data/lib/formtastic/util.rb
CHANGED
data/lib/formtastic/version.rb
CHANGED
@@ -1,32 +1,17 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module Formtastic
|
4
|
-
# Copies
|
5
|
-
# to config/initializers/formtastic.rb (all Rails versions).
|
4
|
+
# Copies a config initializer to config/initializers/formtastic.rb
|
6
5
|
#
|
7
6
|
# @example
|
8
7
|
# $ rails generate formtastic:install
|
9
|
-
#
|
10
|
-
# @todo Test with Rails 3.0
|
11
8
|
class InstallGenerator < Rails::Generators::Base
|
12
9
|
source_root File.expand_path('../../../templates', __FILE__)
|
13
10
|
class_option :template_engine
|
14
11
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
def copy_files
|
19
|
-
copy_file 'formtastic.rb', 'config/initializers/formtastic.rb'
|
20
|
-
end
|
21
|
-
else
|
22
|
-
# Rails 3.0 doesn't have an asset pipeline, so we copy in CSS too
|
23
|
-
desc "Copies some CSS files to public/stylesheets/ and a config initializer to config/initializers/formtastic.rb"
|
24
|
-
def copy_files
|
25
|
-
template 'formtastic.rb', 'config/initializers/formtastic.rb'
|
26
|
-
template '../../../app/assets/stylesheets/formtastic.css', 'public/stylesheets/formtastic.css'
|
27
|
-
template '../../../app/assets/stylesheets/formtastic_ie6.css', 'public/stylesheets/formtastic_ie6.css'
|
28
|
-
template '../../../app/assets/stylesheets/formtastic_ie7.css', 'public/stylesheets/formtastic_ie7.css'
|
29
|
-
end
|
12
|
+
desc "Copies a config initializer to config/initializers/formtastic.rb"
|
13
|
+
def copy_files
|
14
|
+
copy_file 'formtastic.rb', 'config/initializers/formtastic.rb'
|
30
15
|
end
|
31
16
|
|
32
17
|
def copy_scaffold_template
|
@@ -164,7 +164,14 @@ describe 'InputAction::Base' do
|
|
164
164
|
::I18n.backend.store_translations :en, :formtastic => {
|
165
165
|
:submit => 'Submit %{model}',
|
166
166
|
:reset => 'Reset %{model}',
|
167
|
-
:cancel => 'Cancel %{model}'
|
167
|
+
:cancel => 'Cancel %{model}',
|
168
|
+
:actions => {
|
169
|
+
:message => {
|
170
|
+
:submit => 'Submit message',
|
171
|
+
:reset => 'Reset message',
|
172
|
+
:cancel => 'Cancel message'
|
173
|
+
}
|
174
|
+
}
|
168
175
|
}
|
169
176
|
end
|
170
177
|
|
@@ -182,6 +189,17 @@ describe 'InputAction::Base' do
|
|
182
189
|
output_buffer.should have_tag('li.generic_action input[@value="Cancel Post"]')
|
183
190
|
output_buffer.should have_tag('li.generic_action input[@value="Reset Post"]')
|
184
191
|
end
|
192
|
+
|
193
|
+
it 'should render an input with custom resource name localized label' do
|
194
|
+
concat(semantic_form_for(:post, :as => :message, :url => 'http://example.com') do |builder|
|
195
|
+
concat(builder.action(:submit, :as => :generic))
|
196
|
+
concat(builder.action(:reset, :as => :generic))
|
197
|
+
concat(builder.action(:cancel, :as => :generic))
|
198
|
+
end)
|
199
|
+
output_buffer.should have_tag('li.generic_action input[@value="Submit message"]')
|
200
|
+
output_buffer.should have_tag('li.generic_action input[@value="Cancel message"]')
|
201
|
+
output_buffer.should have_tag('li.generic_action input[@value="Reset message"]')
|
202
|
+
end
|
185
203
|
end
|
186
204
|
|
187
205
|
describe 'when I18n-localized label is provided' do
|
@@ -366,7 +384,14 @@ describe 'InputAction::Base' do
|
|
366
384
|
::I18n.backend.store_translations :en, :formtastic => {
|
367
385
|
:update => 'Save %{model}',
|
368
386
|
:reset => 'Reset %{model}',
|
369
|
-
:cancel => 'Cancel %{model}'
|
387
|
+
:cancel => 'Cancel %{model}',
|
388
|
+
:actions => {
|
389
|
+
:message => {
|
390
|
+
:submit => 'Submit message',
|
391
|
+
:reset => 'Reset message',
|
392
|
+
:cancel => 'Cancel message'
|
393
|
+
}
|
394
|
+
}
|
370
395
|
}
|
371
396
|
end
|
372
397
|
|
@@ -384,6 +409,17 @@ describe 'InputAction::Base' do
|
|
384
409
|
output_buffer.should have_tag('li.generic_action input[@value="Reset Post"]')
|
385
410
|
output_buffer.should have_tag('li.generic_action input[@value="Cancel Post"]')
|
386
411
|
end
|
412
|
+
|
413
|
+
it 'should render an input with custom resource name localized label' do
|
414
|
+
concat(semantic_form_for(:post, :as => :message, :url => 'http://example.com') do |builder|
|
415
|
+
concat(builder.action(:submit, :as => :generic))
|
416
|
+
concat(builder.action(:reset, :as => :generic))
|
417
|
+
concat(builder.action(:cancel, :as => :generic))
|
418
|
+
end)
|
419
|
+
output_buffer.should have_tag('li.generic_action input[@value="Submit message"]')
|
420
|
+
output_buffer.should have_tag('li.generic_action input[@value="Cancel message"]')
|
421
|
+
output_buffer.should have_tag('li.generic_action input[@value="Reset message"]')
|
422
|
+
end
|
387
423
|
end
|
388
424
|
|
389
425
|
describe 'when I18n-localized label is provided' do
|
@@ -470,6 +470,12 @@ describe 'Formtastic::FormBuilder#input' do
|
|
470
470
|
default_input_type(:string, :search).should == :search
|
471
471
|
end
|
472
472
|
|
473
|
+
it 'should default to :color for :string columns matching color' do
|
474
|
+
default_input_type(:string, :color).should == :color
|
475
|
+
default_input_type(:string, :user_color).should == :color
|
476
|
+
default_input_type(:string, :color_for_image).should == :color
|
477
|
+
end
|
478
|
+
|
473
479
|
describe 'defaulting to file column' do
|
474
480
|
Formtastic::FormBuilder.file_methods.each do |method|
|
475
481
|
it "should default to :file for attributes that respond to ##{method}" do
|
@@ -665,16 +671,6 @@ describe 'Formtastic::FormBuilder#input' do
|
|
665
671
|
output_buffer.should have_tag("form li p.inline-hints", hint_text)
|
666
672
|
end
|
667
673
|
|
668
|
-
it 'should have a custom hint class if I ask for one' do
|
669
|
-
with_deprecation_silenced do
|
670
|
-
hint_text = "this is the title of the post"
|
671
|
-
concat(semantic_form_for(@new_post) do |builder|
|
672
|
-
concat(builder.input(:title, :hint => hint_text, :hint_class => 'custom-hint-class'))
|
673
|
-
end)
|
674
|
-
output_buffer.should have_tag("form li p.custom-hint-class", hint_text)
|
675
|
-
end
|
676
|
-
end
|
677
|
-
|
678
674
|
it 'should have a custom hint class defaulted for all forms' do
|
679
675
|
hint_text = "this is the title of the post"
|
680
676
|
Formtastic::FormBuilder.default_hint_class = "custom-hint-class"
|
@@ -720,25 +716,6 @@ describe 'Formtastic::FormBuilder#input' do
|
|
720
716
|
end
|
721
717
|
end
|
722
718
|
|
723
|
-
it 'should render a hint paragraph containing a localized hint (I18n) with a custom hint class if i ask for one' do
|
724
|
-
with_config :i18n_lookups_by_default, false do
|
725
|
-
::I18n.backend.store_translations :en,
|
726
|
-
:formtastic => {
|
727
|
-
:hints => {
|
728
|
-
:post => {
|
729
|
-
:title => @localized_hint_text
|
730
|
-
}
|
731
|
-
}
|
732
|
-
}
|
733
|
-
with_deprecation_silenced do
|
734
|
-
concat(semantic_form_for(@new_post) do |builder|
|
735
|
-
concat(builder.input(:title, :hint => true, :hint_class => 'custom-hint-class'))
|
736
|
-
end)
|
737
|
-
end
|
738
|
-
output_buffer.should have_tag('form li p.custom-hint-class', @localized_hint_text)
|
739
|
-
end
|
740
|
-
end
|
741
|
-
|
742
719
|
it 'should render a hint paragraph containing an optional localized hint (I18n) if first is not set' do
|
743
720
|
with_config :i18n_lookups_by_default, false do
|
744
721
|
concat(semantic_form_for(@new_post) do |builder|
|
@@ -8,21 +8,18 @@ describe 'boolean input' do
|
|
8
8
|
before do
|
9
9
|
@output_buffer = ''
|
10
10
|
mock_everything
|
11
|
+
|
12
|
+
concat(semantic_form_for(@new_post) do |builder|
|
13
|
+
concat(builder.input(:allow_comments, :as => :boolean))
|
14
|
+
end)
|
11
15
|
end
|
12
16
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
it_should_have_input_wrapper_with_class("boolean")
|
21
|
-
it_should_have_input_wrapper_with_class(:input)
|
22
|
-
it_should_have_input_wrapper_with_id("post_allow_comments_input")
|
23
|
-
it_should_apply_error_logic_for_input_type(:boolean)
|
24
|
-
|
25
|
-
it 'should generate a label containing the input' do
|
17
|
+
it_should_have_input_wrapper_with_class("boolean")
|
18
|
+
it_should_have_input_wrapper_with_class(:input)
|
19
|
+
it_should_have_input_wrapper_with_id("post_allow_comments_input")
|
20
|
+
it_should_apply_error_logic_for_input_type(:boolean)
|
21
|
+
|
22
|
+
it 'should generate a label containing the input' do
|
26
23
|
output_buffer.should_not have_tag('label.label')
|
27
24
|
output_buffer.should have_tag('form li label', :count => 1)
|
28
25
|
output_buffer.should have_tag('form li label[@for="post_allow_comments"]')
|
@@ -30,25 +27,24 @@ describe 'boolean input' do
|
|
30
27
|
output_buffer.should have_tag('form li label input[@type="checkbox"]', :count => 1)
|
31
28
|
output_buffer.should have_tag('form li input[@type="hidden"]', :count => 1)
|
32
29
|
output_buffer.should_not have_tag('form li label input[@type="hidden"]', :count => 1) # invalid HTML5
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should not add a "name" attribute to the label' do
|
33
|
+
output_buffer.should_not have_tag('form li label[@name]')
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should generate a checkbox input' do
|
37
|
+
output_buffer.should have_tag('form li label input')
|
38
|
+
output_buffer.should have_tag('form li label input#post_allow_comments')
|
39
|
+
output_buffer.should have_tag('form li label input[@type="checkbox"]')
|
40
|
+
output_buffer.should have_tag('form li label input[@name="post[allow_comments]"]')
|
41
|
+
output_buffer.should have_tag('form li label input[@type="checkbox"][@value="1"]')
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should generate a checked input if object.method returns true' do
|
45
|
+
output_buffer.should have_tag('form li label input[@checked="checked"]')
|
46
|
+
output_buffer.should have_tag('form li input[@name="post[allow_comments]"]', :count => 2)
|
47
|
+
output_buffer.should have_tag('form li input#post_allow_comments', :count => 1)
|
52
48
|
end
|
53
49
|
|
54
50
|
it 'should generate a checked input if :input_html is passed :checked => checked' do
|
@@ -131,16 +127,6 @@ describe 'boolean input' do
|
|
131
127
|
output_buffer.should have_tag('form li label input[@type="checkbox"][@value="yes"][@checked="checked"]')
|
132
128
|
end
|
133
129
|
|
134
|
-
it 'should generate a checked input for boolean database values compared to string checked values' do
|
135
|
-
@new_post.stub(:foo).and_return(1)
|
136
|
-
|
137
|
-
concat(semantic_form_for(@new_post) do |builder|
|
138
|
-
concat(builder.input(:foo, :as => :boolean))
|
139
|
-
end)
|
140
|
-
|
141
|
-
output_buffer.should have_tag('form li label input[@type="checkbox"][@value="1"][@checked="checked"]')
|
142
|
-
end
|
143
|
-
|
144
130
|
it 'should generate a checked input if object.method returns checked value when inverted' do
|
145
131
|
@new_post.stub(:allow_comments).and_return(0)
|
146
132
|
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'color input' do
|
5
|
+
|
6
|
+
include FormtasticSpecHelper
|
7
|
+
|
8
|
+
before do
|
9
|
+
@output_buffer = ''
|
10
|
+
mock_everything
|
11
|
+
end
|
12
|
+
|
13
|
+
if Formtastic::Util.rails3?
|
14
|
+
describe "attempting to use color input with Rails 3" do
|
15
|
+
it "raises an error" do
|
16
|
+
expect {
|
17
|
+
concat(semantic_form_for(@new_post) do |builder|
|
18
|
+
concat(builder.input(:color))
|
19
|
+
end)
|
20
|
+
}.to raise_error "The :color input requires the color_field form helper, which is only available in Rails 4+"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
else
|
24
|
+
describe "when object is provided" do
|
25
|
+
before do
|
26
|
+
concat(semantic_form_for(@new_post) do |builder|
|
27
|
+
concat(builder.input(:color))
|
28
|
+
end)
|
29
|
+
end
|
30
|
+
|
31
|
+
it_should_have_input_wrapper_with_class(:color)
|
32
|
+
it_should_have_input_wrapper_with_class(:input)
|
33
|
+
it_should_have_input_wrapper_with_class(:stringish)
|
34
|
+
it_should_have_input_wrapper_with_id("post_color_input")
|
35
|
+
it_should_have_label_with_text(/Color/)
|
36
|
+
it_should_have_label_for("post_color")
|
37
|
+
it_should_have_input_with_id("post_color")
|
38
|
+
it_should_have_input_with_type(:color)
|
39
|
+
it_should_have_input_with_name("post[color]")
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "when namespace is provided" do
|
44
|
+
|
45
|
+
before do
|
46
|
+
concat(semantic_form_for(@new_post, :namespace => 'context2') do |builder|
|
47
|
+
concat(builder.input(:color))
|
48
|
+
end)
|
49
|
+
end
|
50
|
+
|
51
|
+
it_should_have_input_wrapper_with_id("context2_post_color_input")
|
52
|
+
it_should_have_label_and_input_with_id("context2_post_color")
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "when index is provided" do
|
57
|
+
|
58
|
+
before do
|
59
|
+
@output_buffer = ''
|
60
|
+
mock_everything
|
61
|
+
|
62
|
+
concat(semantic_form_for(@new_post) do |builder|
|
63
|
+
concat(builder.fields_for(:author, :index => 3) do |author|
|
64
|
+
concat(author.input(:name, :as => :color))
|
65
|
+
end)
|
66
|
+
end)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should index the id of the wrapper' do
|
70
|
+
output_buffer.should have_tag("li#post_author_attributes_3_name_input")
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should index the id of the select tag' do
|
74
|
+
output_buffer.should have_tag("input#post_author_attributes_3_name")
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should index the name of the select tag' do
|
78
|
+
output_buffer.should have_tag("input[@name='post[author_attributes][3][name]']")
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
describe "when required" do
|
85
|
+
it "should add the required attribute to the input's html options" do
|
86
|
+
with_config :use_required_attribute, true do
|
87
|
+
concat(semantic_form_for(@new_post) do |builder|
|
88
|
+
concat(builder.input(:title, :as => :color, :required => true))
|
89
|
+
end)
|
90
|
+
output_buffer.should have_tag("input[@required]")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
@@ -9,15 +9,11 @@ describe 'hidden input' do
|
|
9
9
|
@output_buffer = ''
|
10
10
|
mock_everything
|
11
11
|
|
12
|
-
|
13
|
-
concat(
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
concat(builder.input(:reviewer, :as => :hidden, :input_html => {:class => 'new_post_reviewer', :id => 'new_post_reviewer'}))
|
18
|
-
concat(builder.input(:author, :as => :hidden, :value => 'direct_value', :input_html => {:value => "formtastic_value"}))
|
19
|
-
end)
|
20
|
-
end
|
12
|
+
concat(semantic_form_for(@new_post) do |builder|
|
13
|
+
concat(builder.input(:secret, :as => :hidden))
|
14
|
+
concat(builder.input(:published, :as => :hidden, :input_html => {:value => true}))
|
15
|
+
concat(builder.input(:reviewer, :as => :hidden, :input_html => {:class => 'new_post_reviewer', :id => 'new_post_reviewer'}))
|
16
|
+
end)
|
21
17
|
end
|
22
18
|
|
23
19
|
it_should_have_input_wrapper_with_class("hidden")
|
@@ -35,11 +31,6 @@ describe 'hidden input' do
|
|
35
31
|
output_buffer.should have_tag("form li input#post_secret[@type=\"hidden\"][@value=\"1\"]")
|
36
32
|
end
|
37
33
|
|
38
|
-
it "should pass any explicitly specified value - using :value" do
|
39
|
-
output_buffer.should have_tag("form li input#post_author_id[@type=\"hidden\"][@value=\"99\"]")
|
40
|
-
end
|
41
|
-
|
42
|
-
# Handle Formtastic :input_html options for consistency.
|
43
34
|
it "should pass any explicitly specified value - using :input_html options" do
|
44
35
|
output_buffer.should have_tag("form li input#post_published[@type=\"hidden\"][@value=\"true\"]")
|
45
36
|
end
|
@@ -48,10 +39,6 @@ describe 'hidden input' do
|
|
48
39
|
output_buffer.should have_tag("form li input#new_post_reviewer[@type=\"hidden\"][@class=\"new_post_reviewer\"]")
|
49
40
|
end
|
50
41
|
|
51
|
-
it "should prefer :input_html over directly supplied options" do
|
52
|
-
output_buffer.should have_tag("form li input#post_author_id[@type=\"hidden\"][@value=\"formtastic_value\"]")
|
53
|
-
end
|
54
|
-
|
55
42
|
it "should not render inline errors" do
|
56
43
|
@errors = double('errors')
|
57
44
|
@errors.stub(:[]).with(errors_matcher(:secret)).and_return(["foo", "bah"])
|
@@ -80,18 +67,14 @@ describe 'hidden input' do
|
|
80
67
|
@output_buffer = ''
|
81
68
|
mock_everything
|
82
69
|
|
83
|
-
|
84
|
-
concat(
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
concat(builder.input(:reviewer, :as => :hidden, :input_html => {:class => 'new_post_reviewer', :id => 'new_post_reviewer'}))
|
89
|
-
concat(builder.input(:author, :as => :hidden, :value => 'direct_value', :input_html => {:value => "formtastic_value"}))
|
90
|
-
end)
|
91
|
-
end
|
70
|
+
concat(semantic_form_for(@new_post, :namespace => 'context2') do |builder|
|
71
|
+
concat(builder.input(:secret, :as => :hidden))
|
72
|
+
concat(builder.input(:published, :as => :hidden, :input_html => {:value => true}))
|
73
|
+
concat(builder.input(:reviewer, :as => :hidden, :input_html => {:class => 'new_post_reviewer', :id => 'new_post_reviewer'}))
|
74
|
+
end)
|
92
75
|
end
|
93
76
|
|
94
|
-
attributes_to_check = [:secret, :
|
77
|
+
attributes_to_check = [:secret, :published, :reviewer]
|
95
78
|
attributes_to_check.each do |a|
|
96
79
|
it_should_have_input_wrapper_with_id("context2_post_#{a}_input")
|
97
80
|
end
|
@@ -220,21 +220,6 @@ describe 'select input' do
|
|
220
220
|
end
|
221
221
|
end
|
222
222
|
|
223
|
-
describe "for a belongs_to association with :group_by => :author" do
|
224
|
-
it "should call author.posts" do
|
225
|
-
::Author.stub(:reflect_on_all_associations).and_return { |macro| macro == :has_many ? [double('reflection', :klass => Post, :name => :posts)] : []}
|
226
|
-
|
227
|
-
[@freds_post].each { |post| post.stub(:to_label).and_return("Post - #{post.id}") }
|
228
|
-
@fred.should_receive(:posts)
|
229
|
-
|
230
|
-
with_deprecation_silenced do
|
231
|
-
concat(semantic_form_for(@new_post) do |builder|
|
232
|
-
concat(builder.input(:main_post, :as => :select, :group_by => :author ) )
|
233
|
-
end)
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
223
|
describe "for a belongs_to association with :conditions" do
|
239
224
|
before do
|
240
225
|
::Post.stub(:reflect_on_association).with(:author).and_return do
|
@@ -244,11 +229,11 @@ describe 'select input' do
|
|
244
229
|
end
|
245
230
|
end
|
246
231
|
|
247
|
-
it "should call author.
|
232
|
+
it "should call author.(scoped|where) with association conditions" do
|
248
233
|
if Formtastic::Util.rails3?
|
249
234
|
::Author.should_receive(:scoped).with(:conditions => {:active => true})
|
250
235
|
else
|
251
|
-
::Author.should_receive(:where).with(
|
236
|
+
::Author.should_receive(:where).with({:active => true})
|
252
237
|
end
|
253
238
|
|
254
239
|
semantic_form_for(@new_post) do |builder|
|
@@ -256,100 +241,14 @@ describe 'select input' do
|
|
256
241
|
end
|
257
242
|
end
|
258
243
|
|
259
|
-
it "should call author.
|
244
|
+
it "should call author.(scoped|where) with association conditions" do
|
260
245
|
if Formtastic::Util.rails3?
|
261
246
|
::Author.should_receive(:scoped).with(:conditions => {:active => true})
|
262
|
-
::Author.should_receive(:where).with({:publisher => true})
|
263
247
|
else
|
264
|
-
|
265
|
-
::Author.should_receive(:where).with({:active => true}).and_return(proxy)
|
266
|
-
proxy.should_receive(:where).with({:publisher => true})
|
267
|
-
end
|
268
|
-
|
269
|
-
|
270
|
-
with_deprecation_silenced do
|
271
|
-
semantic_form_for(@new_post) do |builder|
|
272
|
-
concat(builder.input(:author, :as => :select, :find_options => {:conditions => {:publisher => true}}))
|
273
|
-
end
|
274
|
-
end
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
describe 'for a belongs_to association with :group_by => :continent' do
|
279
|
-
before do
|
280
|
-
@authors = [@bob, @fred, @fred, @fred]
|
281
|
-
::Author.stub(:find).and_return(@authors)
|
282
|
-
@continent_names = %w(Europe Africa)
|
283
|
-
@continents = (0..1).map { |i| c = ::Continent.new; c.stub(:id).and_return(100 - i);c }
|
284
|
-
@authors[0..1].each_with_index { |author, i| author.stub(:continent).and_return(@continents[i]) }
|
285
|
-
|
286
|
-
::Continent.stub(:reflect_on_all_associations).and_return { |macro| macro == :has_many ? [double('reflection', :klass => Author, :name => :authors)] : [] }
|
287
|
-
::Continent.stub(:reflect_on_association).and_return {|column_name| double('reflection', :klass => Author) if column_name == :authors}
|
288
|
-
::Author.stub(:reflect_on_association).and_return { |column_name| double('reflection', :options => {}, :klass => Continent, :macro => :belongs_to) if column_name == :continent }
|
289
|
-
|
290
|
-
|
291
|
-
@continents.each_with_index do |continent, i|
|
292
|
-
continent.stub(:to_label).and_return(@continent_names[i])
|
293
|
-
continent.stub(:authors).and_return([@authors[i]])
|
248
|
+
::Author.should_receive(:where).with({:active => true})
|
294
249
|
end
|
295
|
-
|
296
|
-
|
297
|
-
concat(semantic_form_for(@new_post) do |builder|
|
298
|
-
concat(builder.input(:author, :as => :select, :group_by => :continent ) )
|
299
|
-
concat(builder.input(:author, :as => :select, :group_by => :continent, :group_label => :id ) )
|
300
|
-
concat(builder.input(:author, :as => :select, :group_by => :continent, :member_label => :login ) )
|
301
|
-
concat(builder.input(:author, :as => :select, :group_by => :continent, :member_label => :login, :group_label => :id ) )
|
302
|
-
end)
|
303
|
-
end
|
304
|
-
end
|
305
|
-
|
306
|
-
it_should_have_input_wrapper_with_class("select")
|
307
|
-
it_should_have_input_wrapper_with_id("post_author_input")
|
308
|
-
it_should_have_label_with_text(/Author/)
|
309
|
-
it_should_have_label_for('post_author_id')
|
310
|
-
|
311
|
-
# TODO, need to find a way to repeat some of the specs and logic from the belongs_to specs without grouping
|
312
|
-
|
313
|
-
0.upto(1) do |i|
|
314
|
-
it 'should have all option groups and the right values' do
|
315
|
-
output_buffer.should have_tag("form li select optgroup[@label='#{@continent_names[i]}']", @authors[i].to_label)
|
316
|
-
end
|
317
|
-
|
318
|
-
it 'should have custom group labels' do
|
319
|
-
output_buffer.should have_tag("form li select optgroup[@label='#{@continents[i].id}']", @authors[i].to_label)
|
320
|
-
end
|
321
|
-
|
322
|
-
it 'should have custom author labels' do
|
323
|
-
output_buffer.should have_tag("form li select optgroup[@label='#{@continent_names[i]}']", @authors[i].login)
|
324
|
-
end
|
325
|
-
|
326
|
-
it 'should have custom author and group labels' do
|
327
|
-
output_buffer.should have_tag("form li select optgroup[@label='#{@continents[i].id}']", @authors[i].login)
|
328
|
-
end
|
329
|
-
end
|
330
|
-
|
331
|
-
it 'should have no duplicate groups' do
|
332
|
-
output_buffer.should have_tag('form li select optgroup', :count => 8)
|
333
|
-
end
|
334
|
-
|
335
|
-
it 'should sort the groups on the label method' do
|
336
|
-
output_buffer.should have_tag("form li select optgroup[@label='Africa']")
|
337
|
-
output_buffer.should have_tag("form li select optgroup[@label='99']")
|
338
|
-
end
|
339
|
-
|
340
|
-
it 'should call find with :include for more optimized queries' do
|
341
|
-
if Formtastic::Util.rails3?
|
342
|
-
Author.should_receive(:where).with(:include => :continent)
|
343
|
-
else
|
344
|
-
proxy = author_array_or_scope(@authors)
|
345
|
-
Author.should_receive(:where).and_return(proxy)
|
346
|
-
proxy.should_receive(:includes).with(:continent).and_call_original
|
347
|
-
end
|
348
|
-
|
349
|
-
with_deprecation_silenced do
|
350
|
-
semantic_form_for(@new_post) do |builder|
|
351
|
-
concat(builder.input(:author, :as => :select, :group_by => :continent ) )
|
352
|
-
end
|
250
|
+
semantic_form_for(@new_post) do |builder|
|
251
|
+
concat(builder.input(:author, :as => :select))
|
353
252
|
end
|
354
253
|
end
|
355
254
|
end
|