spec/formtastic_spec.rb in nofxx-formtastic-0.1.8 vs spec/formtastic_spec.rb in nofxx-formtastic-0.1.9
- old
+ new
@@ -234,10 +234,14 @@
@new_post.stub!(:title)
@new_post.stub!(:body)
@new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
end
+ after do
+ Formtastic::SemanticFormHelper.builder = Formtastic::SemanticFormBuilder
+ end
+
it "can be overridden" do
class CustomFormBuilder < Formtastic::SemanticFormBuilder
def custom(arg1, arg2, options = {})
[arg1, arg2, options]
@@ -285,10 +289,107 @@
output_buffer.should have_tag('form fieldset.inputs #post_author_1_login_input')
output_buffer.should_not have_tag('form fieldset.inputs #post[author]_1_login_input')
end
end
+ describe '#label' do
+ it 'should humanize the given attribute' do
+ semantic_form_for(@new_post) do |builder|
+ builder.label(:login).should have_tag('label', :with => /Login/)
+ end
+ end
+
+ it 'should be printed as span' do
+ semantic_form_for(@new_post) do |builder|
+ builder.label(:login, nil, { :required => true, :as_span => true }).should have_tag('span.label abbr')
+ end
+ end
+
+ describe 'when required is given' do
+ it 'should append a required note' do
+ semantic_form_for(@new_post) do |builder|
+ builder.label(:login, nil, :required => true).should have_tag('label abbr')
+ end
+ end
+
+ it 'should allow require option to be given as second argument' do
+ semantic_form_for(@new_post) do |builder|
+ builder.label(:login, :required => true).should have_tag('label abbr')
+ end
+ end
+ end
+
+ describe 'when label is given' do
+ it 'should allow the text to be given as label option' do
+ semantic_form_for(@new_post) do |builder|
+ builder.label(:login, :required => true, :label => 'My label').should have_tag('label', :with => /My label/)
+ end
+ end
+
+ it 'should return nil if label is false' do
+ semantic_form_for(@new_post) do |builder|
+ builder.label(:login, :label => false).should be_nil
+ end
+ end
+ end
+ end
+
+ describe '#errors_on' do
+ before(:each) do
+ @title_errors = ['must not be blank', 'must be longer than 10 characters', 'must be awesome']
+ @errors = mock('errors')
+ @errors.stub!(:on).with('title').and_return(@title_errors)
+ @errors.stub!(:on).with('body').and_return(nil)
+ @new_post.stub!(:errors).and_return(@errors)
+ end
+
+ describe 'and the errors will be displayed as a sentence' do
+ it 'should render a paragraph with the errors joined into a sentence' do
+ Formtastic::SemanticFormBuilder.inline_errors = :sentence
+ semantic_form_for(@new_post) do |builder|
+ builder.errors_on(:title).should have_tag('p.inline-errors', @title_errors.to_sentence)
+ end
+ end
+ end
+
+ describe 'and the errors will be displayed as a list' do
+ it 'should render an unordered list with the class errors' do
+ Formtastic::SemanticFormBuilder.inline_errors = :list
+ semantic_form_for(@new_post) do |builder|
+ builder.errors_on(:title).should have_tag('ul.errors')
+ end
+ end
+
+ it 'should include a list element for each of the errors within the unordered list' do
+ Formtastic::SemanticFormBuilder.inline_errors = :list
+ semantic_form_for(@new_post) do |builder|
+ @title_errors.each do |error|
+ builder.errors_on(:title).should have_tag('ul.errors li', error)
+ end
+ end
+ end
+ end
+
+ describe 'but the errors will not be shown' do
+ it 'should return nil' do
+ Formtastic::SemanticFormBuilder.inline_errors = :none
+ semantic_form_for(@new_post) do |builder|
+ builder.errors_on(:title).should be_nil
+ end
+ end
+ end
+
+ describe 'and no error is found on the method' do
+ it 'should return nil' do
+ Formtastic::SemanticFormBuilder.inline_errors = :sentence
+ semantic_form_for(@new_post) do |builder|
+ builder.errors_on(:body).should be_nil
+ end
+ end
+ end
+ end
+
describe '#input' do
before do
@new_post.stub!(:title)
@new_post.stub!(:body)
@@ -538,10 +639,14 @@
default_input_type(:integer).should == :numeric
default_input_type(:float).should == :numeric
default_input_type(:decimal).should == :numeric
end
+ it 'should default to :country for :string columns named country' do
+ default_input_type(:string, :country).should == :country
+ end
+
describe 'defaulting to file column' do
Formtastic::SemanticFormBuilder.file_methods.each do |method|
it "should default to :file for attributes that respond to ##{method}" do
@new_post.stub!(:column_for_attribute).and_return(nil)
column = mock('column')
@@ -560,11 +665,11 @@
end
end
it 'should call the corresponding input method' do
- [:select, :time_zone, :radio, :date, :datetime, :time, :boolean].each do |input_style|
+ [:select, :time_zone, :radio, :date, :datetime, :time, :boolean, :check_boxes, :hidden].each do |input_style|
@new_post.stub!(:generic_column_name)
@new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
semantic_form_for(@new_post) do |builder|
builder.should_receive(:"#{input_style}_input").once.and_return("fake HTML output from #input")
concat(builder.input(:generic_column_name, :as => input_style))
@@ -647,10 +752,34 @@
end
end
end
+ describe ':size option' do
+ describe 'when provided' do
+ it 'should be passed down to the input tag' do
+ semantic_form_for(@new_post) do |builder|
+ concat(builder.input(:title, :size => 17))
+ end
+ output_buffer.should have_tag('form li input#post_title[@size=17]')
+ end
+ end
+
+ describe 'when not provided' do
+ it 'should default to the configured default text size' do
+ # Temporarily rewrite the value so that we know the output size isn't just a coincidence
+ old_value = Formtastic::SemanticFormBuilder.default_text_field_size
+ Formtastic::SemanticFormBuilder.default_text_field_size = 31
+ semantic_form_for(@new_post) do |builder|
+ concat(builder.input(:title))
+ end
+ Formtastic::SemanticFormBuilder.default_text_field_size = old_value
+ output_buffer.should have_tag('form li input#post_title[@size=31]')
+ end
+ end
+ end
+
describe ':wrapper_html option' do
describe 'when provided' do
it 'should be passed down to the li tag' do
semantic_form_for(@new_post) do |builder|
@@ -700,11 +829,10 @@
end
output_buffer.should have_tag('form li', :count => 2)
end
describe 'when there are errors on the object for this method' do
-
before do
@title_errors = ['must not be blank', 'must be longer than 10 characters', 'must be awesome']
@errors = mock('errors')
@errors.stub!(:on).with('title').and_return(@title_errors)
@new_post.stub!(:errors).and_return(@errors)
@@ -722,69 +850,28 @@
concat(builder.input(:title))
end
output_buffer.should_not have_tag('div.fieldWithErrors')
end
- describe 'and the errors will be displayed as a sentence' do
-
- before do
- Formtastic::SemanticFormBuilder.inline_errors = :sentence
- semantic_form_for(@new_post) do |builder|
- concat(builder.input(:title))
- end
+ it 'should render a paragraph for the errors' do
+ Formtastic::SemanticFormBuilder.inline_errors = :sentence
+ semantic_form_for(@new_post) do |builder|
+ concat(builder.input(:title))
end
-
- it 'should render a paragraph with the errors joined into a sentence' do
- output_buffer.should have_tag('form li.error p.inline-errors', @title_errors.to_sentence)
- end
-
+ output_buffer.should have_tag('form li.error p.inline-errors')
end
- describe 'and the errors will be displayed as a list' do
-
- before do
- Formtastic::SemanticFormBuilder.inline_errors = :list
- semantic_form_for(@new_post) do |builder|
- concat(builder.input(:title))
- end
+ it 'should not display an error list' do
+ Formtastic::SemanticFormBuilder.inline_errors = :list
+ semantic_form_for(@new_post) do |builder|
+ concat(builder.input(:title))
end
-
- it 'should render an unordered list with the class errors' do
- output_buffer.should have_tag('form li.error ul.errors')
- end
-
- it 'should include a list element for each of the errors within the unordered list' do
- @title_errors.each do |error|
- output_buffer.should have_tag('form li.error ul.errors li', error)
- end
- end
-
+ output_buffer.should have_tag('form li.error ul.errors')
end
-
- describe 'but the errors will not be shown' do
-
- before do
- Formtastic::SemanticFormBuilder.inline_errors = :none
- semantic_form_for(@new_post) do |builder|
- concat(builder.input(:title))
- end
- end
-
- it 'should not display an error sentence' do
- output_buffer.should_not have_tag('form li.error p.inline-errors')
- end
-
- it 'should not display an error list' do
- output_buffer.should_not have_tag('form li.error ul.errors')
- end
-
- end
-
end
describe 'when there are no errors on the object for this method' do
-
before do
semantic_form_for(@new_post) do |builder|
concat(builder.input(:title))
end
end
@@ -798,15 +885,13 @@
end
it 'should not display an error list' do
output_buffer.should_not have_tag('form li.error ul.errors')
end
-
end
describe 'when no object is provided' do
-
before do
semantic_form_for(:project, :url => 'http://test.host') do |builder|
concat(builder.input(:title))
end
end
@@ -820,11 +905,10 @@
end
it 'should not display an error list' do
output_buffer.should_not have_tag('form li.error ul.errors')
end
-
end
end
# Test string_mappings: :string, :password and :numeric
string_mappings = Formtastic::SemanticFormBuilder::INPUT_MAPPINGS.slice(*Formtastic::SemanticFormBuilder::STRING_MAPPINGS)
@@ -987,34 +1071,69 @@
output_buffer.should have_tag("form li #{input_type}.myclass")
end
end
- it 'should generate input and labels even if no object is given' do
- semantic_form_for(:project, :url => 'http://test.host/') do |builder|
- concat(builder.input(:title, :as => type))
+ describe 'when no object is given' do
+ before(:each) do
+ semantic_form_for(:project, :url => 'http://test.host/') do |builder|
+ concat(builder.input(:title, :as => type))
+ end
end
- output_buffer.should have_tag('form li label')
- output_buffer.should have_tag('form li label[@for="project_title"')
- output_buffer.should have_tag('form li label', /Title/)
+ it 'should generate input' do
+ if template_method.to_s =~ /_field$/ # password_field
+ output_buffer.should have_tag("form li input")
+ output_buffer.should have_tag("form li input#project_title")
+ output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
+ output_buffer.should have_tag("form li input[@name=\"project[title]\"]")
+ else
+ output_buffer.should have_tag("form li #{input_type}")
+ output_buffer.should have_tag("form li #{input_type}#project_title")
+ output_buffer.should have_tag("form li #{input_type}[@name=\"project[title]\"]")
+ end
+ end
- if template_method.to_s =~ /_field$/ # password_field
- output_buffer.should have_tag("form li input")
- output_buffer.should have_tag("form li input#project_title")
- output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
- output_buffer.should have_tag("form li input[@name=\"project[title]\"]")
- else
- output_buffer.should have_tag("form li #{input_type}")
- output_buffer.should have_tag("form li #{input_type}#project_title")
- output_buffer.should have_tag("form li #{input_type}[@name=\"project[title]\"]")
+ it 'should generate labels' do
+ output_buffer.should have_tag('form li label')
+ output_buffer.should have_tag('form li label[@for="project_title"')
+ output_buffer.should have_tag('form li label', /Title/)
end
end
end
end
+ describe ":as => :hidden" do
+ before do
+ @new_post.stub!(:hidden)
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string))
+
+ semantic_form_for(@new_post) do |builder|
+ concat(builder.input(:hidden, :as => :hidden))
+ end
+ end
+
+ it "should have a hidden class on the wrapper" do
+ output_buffer.should have_tag('form li.hidden')
+ end
+
+ it 'should have a post_hidden_input id on the wrapper' do
+ output_buffer.should have_tag('form li#post_hidden_input')
+ end
+
+ it 'should not generate a label for the input' do
+ output_buffer.should_not have_tag('form li label')
+ end
+
+ it "should generate a input field" do
+ output_buffer.should have_tag("form li input#post_hidden")
+ output_buffer.should have_tag("form li input[@type=\"hidden\"]")
+ output_buffer.should have_tag("form li input[@name=\"post[hidden]\"]")
+ end
+ end
+
describe ":as => :time_zone" do
before do
@new_post.stub!(:time_zone)
@new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string))
@@ -1048,31 +1167,114 @@
concat(builder.input(:time_zone, :input_html => { :class => 'myclass' }))
end
output_buffer.should have_tag("form li select.myclass")
end
- it 'should generate input and labels even if no object is given' do
- semantic_form_for(:project, :url => 'http://test.host/') do |builder|
- concat(builder.input(:time_zone, :as => :time_zone))
+ describe 'when no object is given' do
+ before(:each) do
+ semantic_form_for(:project, :url => 'http://test.host/') do |builder|
+ concat(builder.input(:time_zone, :as => :time_zone))
+ end
end
- output_buffer.should have_tag('form li label')
- output_buffer.should have_tag('form li label[@for="project_time_zone"')
- output_buffer.should have_tag('form li label', /Time zone/)
+ it 'should generate labels' do
+ output_buffer.should have_tag('form li label')
+ output_buffer.should have_tag('form li label[@for="project_time_zone"')
+ output_buffer.should have_tag('form li label', /Time zone/)
+ end
- output_buffer.should have_tag("form li select")
- output_buffer.should have_tag("form li select#project_time_zone")
- output_buffer.should have_tag("form li select[@name=\"project[time_zone]\"]")
+ it 'should generate select inputs' do
+ output_buffer.should have_tag("form li select")
+ output_buffer.should have_tag("form li select#project_time_zone")
+ output_buffer.should have_tag("form li select[@name=\"project[time_zone]\"]")
+ end
end
end
+ describe ":as => :country" do
+
+ before do
+ @new_post.stub!(:country)
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string))
+ end
+
+ describe "when country_select is not available as a helper from a plugin" do
+
+ it "should raise an error, sugesting the author installs a plugin" do
+ lambda {
+ semantic_form_for(@new_post) do |builder|
+ concat(builder.input(:country, :as => :country))
+ end
+ }.should raise_error
+ end
+
+ end
+
+ describe "when country_select is available as a helper (from a plugin)" do
+
+ before do
+ semantic_form_for(@new_post) do |builder|
+ builder.stub!(:country_select).and_return("<select><option>...</option></select>")
+ concat(builder.input(:country, :as => :country))
+ end
+ end
+
+ it "should have a time_zone class on the wrapper" do
+ output_buffer.should have_tag('form li.country')
+ end
+
+ it 'should have a post_title_input id on the wrapper' do
+ output_buffer.should have_tag('form li#post_country_input')
+ end
+
+ it 'should generate a label for the input' do
+ output_buffer.should have_tag('form li label')
+ output_buffer.should have_tag('form li label[@for="post_country"')
+ output_buffer.should have_tag('form li label', /Country/)
+ end
+
+ it "should generate a select" do
+ output_buffer.should have_tag("form li select")
+ end
+
+ end
+
+ describe ":priority_countries option" do
+
+ it "should be passed down to the country_select helper when provided" do
+ priority_countries = ["Foo", "Bah"]
+ semantic_form_for(@new_post) do |builder|
+ builder.stub!(:country_select).and_return("<select><option>...</option></select>")
+ builder.should_receive(:country_select).with(:country, priority_countries, {}, {}).and_return("<select><option>...</option></select>")
+
+ concat(builder.input(:country, :as => :country, :priority_countries => priority_countries))
+ end
+ end
+
+ it "should default to the @@priority_countries config when absent" do
+ priority_countries = Formtastic::SemanticFormBuilder.priority_countries
+ priority_countries.should_not be_empty
+ priority_countries.should_not be_nil
+
+ semantic_form_for(@new_post) do |builder|
+ builder.stub!(:country_select).and_return("<select><option>...</option></select>")
+ builder.should_receive(:country_select).with(:country, priority_countries, {}, {}).and_return("<select><option>...</option></select>")
+
+ concat(builder.input(:country, :as => :country))
+ end
+ end
+
+ end
+
+ end
+
describe ':as => :radio' do
before do
@new_post.stub!(:author).and_return(@bob)
@new_post.stub!(:author_id).and_return(@bob.id)
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
+ Post.stub!(:reflect_on_association).and_return { |column_name| mock('reflection', :klass => Author, :macro => :belongs_to) }
end
describe 'for belongs_to association' do
before do
semantic_form_for(@new_post) do |builder|
@@ -1082,11 +1284,11 @@
it 'should have a radio class on the wrapper' do
output_buffer.should have_tag('form li.radio')
end
- it 'should have a post_author_id_input id on the wrapper' do
+ it 'should have a post_author_input id on the wrapper' do
output_buffer.should have_tag('form li#post_author_input')
end
it 'should generate a fieldset and legend containing label text for the input' do
output_buffer.should have_tag('form li fieldset')
@@ -1097,22 +1299,20 @@
it 'should generate an ordered list with a list item for each choice' do
output_buffer.should have_tag('form li fieldset ol')
output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
end
- it 'should have one option with a "selected" attribute' do
+ it 'should have one option with a "checked" attribute' do
output_buffer.should have_tag('form li input[@checked]', :count => 1)
end
describe "each choice" do
it 'should contain a label for the radio input with a nested input and label text' do
Author.find(:all).each do |author|
- output_buffer.should have_tag('form li fieldset ol li label')
output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_id_#{author.id}']")
- output_buffer.should have_tag("form li fieldset ol li label input")
end
end
it 'should use values as li.class when value_as_class is true' do
Author.find(:all).each do |author|
@@ -1140,33 +1340,43 @@
output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
end
end
- it 'should generate a fieldset, legend, labels and inputs even if no object is given' do
- output_buffer.replace ''
+ describe 'and no object is given' do
+ before(:each) do
+ output_buffer.replace ''
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
+ concat(builder.input(:author_id, :as => :radio, :collection => Author.find(:all)))
+ end
+ end
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
- concat(builder.input(:author_id, :as => :radio, :collection => Author.find(:all)))
+ it 'should generate a fieldset with legend' do
+ output_buffer.should have_tag('form li fieldset legend', /Author/)
end
- output_buffer.should have_tag('form li fieldset legend', /Author/)
- output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
+ it 'shold generate an li tag for each item in the collection' do
+ output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
+ end
- Author.find(:all).each do |author|
- output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
- output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
+ it 'should generate labels for each item' do
+ Author.find(:all).each do |author|
+ output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
+ output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
+ end
+ end
- output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
- output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
- output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
- output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id]']")
+ it 'should generate inputs for each item' do
+ Author.find(:all).each do |author|
+ output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
+ output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
+ output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
+ output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id]']")
+ end
end
end
-
end
-
end
describe ':as => :select' do
before do
@@ -1320,36 +1530,143 @@
it 'should have a select with prompt' do
output_buffer.should have_tag("form li select option[@value='']", /choose author/)
end
end
- it 'should generate label, select and options even if object is not given' do
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
- concat(builder.input(:author, :as => :select, :collection => Author.find(:all)))
+ describe 'when no object is given' do
+ before(:each) do
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
+ concat(builder.input(:author, :as => :select, :collection => Author.find(:all)))
+ end
end
- output_buffer.should have_tag('form li label', /Author/)
- output_buffer.should have_tag("form li label[@for='project_author']")
+ it 'should generate label' do
+ output_buffer.should have_tag('form li label', /Author/)
+ output_buffer.should have_tag("form li label[@for='project_author']")
+ end
- output_buffer.should have_tag('form li select#project_author')
- output_buffer.should have_tag('form li select option', :count => Author.find(:all).size)
+ it 'should generate select inputs' do
+ output_buffer.should have_tag('form li select#project_author')
+ output_buffer.should have_tag('form li select option', :count => Author.find(:all).size)
+ end
- Author.find(:all).each do |author|
- output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
+ it 'should generate an option to each item' do
+ Author.find(:all).each do |author|
+ output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
+ end
end
end
end
+ describe ':as => :check_boxes' do
+
+ describe 'for a has_many association' do
+ before do
+ semantic_form_for(@fred) do |builder|
+ concat(builder.input(:posts, :as => :check_boxes, :value_as_class => true))
+ end
+ end
+
+ it 'should have a check_boxes class on the wrapper' do
+ output_buffer.should have_tag('form li.check_boxes')
+ end
+
+ it 'should have a author_posts_input id on the wrapper' do
+ output_buffer.should have_tag('form li#author_posts_input')
+ end
+
+ it 'should generate a fieldset and legend containing label text for the input' do
+ output_buffer.should have_tag('form li fieldset')
+ output_buffer.should have_tag('form li fieldset legend')
+ output_buffer.should have_tag('form li fieldset legend', /Posts/)
+ end
+
+ it 'should generate an ordered list with a list item for each choice' do
+ output_buffer.should have_tag('form li fieldset ol')
+ output_buffer.should have_tag('form li fieldset ol li', :count => Post.find(:all).size)
+ end
+
+ it 'should have one option with a "checked" attribute' do
+ output_buffer.should have_tag('form li input[@checked]', :count => 1)
+ end
+
+ it 'should generate hidden inputs with default value blank' do
+ output_buffer.should have_tag("form li fieldset ol li label input[@type='hidden'][@value='']", :count => Post.find(:all).size)
+ end
+
+ describe "each choice" do
+
+ it 'should contain a label for the radio input with a nested input and label text' do
+ Post.find(:all).each do |post|
+ output_buffer.should have_tag('form li fieldset ol li label', /#{post.to_label}/)
+ output_buffer.should have_tag("form li fieldset ol li label[@for='author_post_ids_#{post.id}']")
+ end
+ end
+
+ it 'should use values as li.class when value_as_class is true' do
+ Post.find(:all).each do |post|
+ output_buffer.should have_tag("form li fieldset ol li.#{post.id} label")
+ end
+ end
+
+ it 'should have a checkbox input for each post' do
+ Post.find(:all).each do |post|
+ output_buffer.should have_tag("form li fieldset ol li label input#author_post_ids_#{post.id}")
+ output_buffer.should have_tag("form li fieldset ol li label input[@name='author[post_ids][]']", :count => 2)
+ end
+ end
+
+ it "should mark input as checked if it's the the existing choice" do
+ Post.find(:all).include?(@fred.posts.first).should be_true
+ output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
+ end
+ end
+
+ describe 'and no object is given' do
+ before(:each) do
+ output_buffer.replace ''
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
+ concat(builder.input(:author_id, :as => :check_boxes, :collection => Author.find(:all)))
+ end
+ end
+
+ it 'should generate a fieldset with legend' do
+ output_buffer.should have_tag('form li fieldset legend', /Author/)
+ end
+
+ it 'shold generate an li tag for each item in the collection' do
+ output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
+ end
+
+ it 'should generate labels for each item' do
+ Author.find(:all).each do |author|
+ output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
+ output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
+ end
+ end
+
+ it 'should generate inputs for each item' do
+ Author.find(:all).each do |author|
+ output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
+ output_buffer.should have_tag("form li fieldset ol li label input[@type='checkbox']")
+ output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
+ output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id][]']")
+ end
+ end
+ end
+ end
+ end
+
describe 'for collections' do
before do
@new_post.stub!(:author).and_return(@bob)
@new_post.stub!(:author_id).and_return(@bob.id)
@new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
end
- { :select => :option, :radio => :input }.each do |type, countable|
+ { :select => :option, :radio => :input, :check_boxes => :'input[@type="checkbox"]' }.each do |type, countable|
describe ":as => #{type.inspect}" do
describe 'when the :collection option is not provided' do
it 'should perform a basic find on the association class' do
Author.should_receive(:find)
@@ -1400,13 +1717,13 @@
it "should use the string as the label text and value for each #{countable}" do
semantic_form_for(@new_post) do |builder|
concat(builder.input(:category_name, :as => type, :collection => @categories))
end
- @categories.each do |item|
- output_buffer.should have_tag("form li.#{type}", /#{item}/)
- output_buffer.should have_tag("form li.#{type} #{countable}[@value=#{item}]")
+ @categories.each do |value|
+ output_buffer.should have_tag("form li.#{type}", /#{value}/)
+ output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value}']")
end
end
if type == :radio
it 'should generate a sanitized label for attribute' do
@@ -1435,11 +1752,11 @@
concat(builder.input(:category_name, :as => type, :collection => @categories))
end
@categories.each do |label, value|
output_buffer.should have_tag("form li.#{type}", /#{label}/)
- output_buffer.should have_tag("form li.#{type} #{countable}[@value=#{value}]")
+ output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value}']")
end
end
end
describe 'and the :collection is an array of arrays' do
@@ -1448,16 +1765,17 @@
@categories = { 'General' => 'gen', 'Design' => 'des','Development' => 'dev' }.to_a
end
it "should use the first value as the label text and the last value as the value attribute for #{countable}" do
semantic_form_for(@new_post) do |builder|
- concat(builder.input(:category_name, :as => :radio, :collection => @categories))
+ concat(builder.input(:category_name, :as => type, :collection => @categories))
end
- @categories.each do |label, value|
- output_buffer.should have_tag('form li fieldset ol li label', /#{label}/i)
- output_buffer.should have_tag('form li fieldset ol li label input[@value='+value+']')
+ @categories.each do |text, value|
+ label = type == :select ? :option : :label
+ output_buffer.should have_tag("form li.#{type} #{label}", /#{text}/i)
+ output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value.to_s}']")
end
end
end
describe 'and the :collection is an array of symbols' do
@@ -1466,16 +1784,17 @@
@categories = [ :General, :Design, :Development ]
end
it "should use the symbol as the label text and value for each #{countable}" do
semantic_form_for(@new_post) do |builder|
- concat(builder.input(:category_name, :as => :radio, :collection => @categories))
+ concat(builder.input(:category_name, :as => type, :collection => @categories))
end
@categories.each do |value|
- output_buffer.should have_tag('form li fieldset ol li label', /#{value}/i)
- output_buffer.should have_tag('form li fieldset ol li label input[@value='+value.to_s+']')
+ label = type == :select ? :option : :label
+ output_buffer.should have_tag("form li.#{type} #{label}", /#{value}/i)
+ output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value.to_s}']")
end
end
end
describe 'when the :label_method option is provided' do
@@ -1528,13 +1847,20 @@
end
end
end
end
+ end
+ end
- describe 'when attribute is a boolean' do
+ describe 'for boolean attributes' do
+ { :select => :option, :radio => :input }.each do |type, countable|
+ checked_or_selected = { :select => :selected, :radio => :checked }[type]
+
+ describe ":as => #{type.inspect}" do
+
before do
@new_post.stub!(:allow_comments)
@new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
semantic_form_for(@new_post) do |builder|
@@ -1577,12 +1903,10 @@
output_buffer.should have_tag("form li.#{type}", /Absolutely\!/)
output_buffer.should have_tag("form li.#{type}", /Never\!/)
end
end
- checked_or_selected = { :select => :selected, :radio => :checked }[type]
-
describe 'when the value is nil' do
before do
@new_post.stub!(:allow_comments).and_return(nil)
@new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :boolean))
@@ -1645,10 +1969,11 @@
output_buffer.should have_tag("form li.#{type}", /Absolutely/)
output_buffer.should have_tag("form li.#{type}", /No Way/)
end
end
end
+
end
end
end
describe ':as => :date' do
@@ -1753,20 +2078,20 @@
it 'should use default hidden value equals to 1 when attribute returns nil' do
semantic_form_for(@new_post) do |builder|
concat(builder.input(:publish_at, :as => :datetime, :discard_day => true))
end
- output_buffer.should have_tag("form li fieldset input[@type='hidden'][@value='1']")
+ output_buffer.should have_tag("form li input[@type='hidden'][@value='1']")
end
it 'should use default attribute value when it is not nil' do
@new_post.stub!(:publish_at).and_return(Date.new(2007,12,27))
semantic_form_for(@new_post) do |builder|
concat(builder.input(:publish_at, :as => :datetime, :discard_day => true))
end
- output_buffer.should have_tag("form li fieldset input[@type='hidden'][@value='27']")
+ output_buffer.should have_tag("form li input[@type='hidden'][@value='27']")
end
end
describe 'when :include_blank => true is set' do
before do
@@ -1835,20 +2160,29 @@
output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Hour/)
output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Minute/)
end
end
- it 'should have fieldset, legend, label and selects even if object is not given' do
- output_buffer.replace ''
+ describe 'when no object is given' do
+ before(:each) do
+ output_buffer.replace ''
+ semantic_form_for(:project, :url => 'http://test.host') do |@builder|
+ concat(@builder.input(:publish_at, :as => :datetime))
+ end
+ end
- semantic_form_for(:project, :url => 'http://test.host') do |@builder|
- concat(@builder.input(:publish_at, :as => :datetime))
+ it 'should have fieldset with legend' do
+ output_buffer.should have_tag('form li.datetime fieldset legend', /Publish at/)
end
- output_buffer.should have_tag('form li.datetime fieldset legend', /Publish at/)
- output_buffer.should have_tag('form li.datetime fieldset ol li label', :count => 5)
- output_buffer.should have_tag('form li.datetime fieldset ol li select', :count => 5)
+ it 'should have labels for each input' do
+ output_buffer.should have_tag('form li.datetime fieldset ol li label', :count => 5)
+ end
+
+ it 'should have selects for each inputs' do
+ output_buffer.should have_tag('form li.datetime fieldset ol li select', :count => 5)
+ end
end
end
describe ':as => :time' do
before do
@@ -1881,12 +2215,13 @@
output_buffer.should have_tag('form li.time fieldset li label', :count => 2)
output_buffer.should have_tag('form li.time fieldset li label', /hour/i)
output_buffer.should have_tag('form li.time fieldset li label', /minute/i)
end
- it 'should have five selects for hour and minute' do
- output_buffer.should have_tag('form li.time fieldset li select', :count => 2)
+ it 'should have two selects for hour and minute' do
+ #output_buffer.should have_tag('form li.time fieldset ol li select', :count => 2)
+ output_buffer.should have_tag('form li.time fieldset ol li', :count => 2)
end
end
[:boolean_select, :boolean_radio].each do |type|
describe ":as => #{type.inspect}" do
@@ -1961,11 +2296,10 @@
end
end
end
-
describe '#inputs' do
describe 'with a block' do
describe 'when no options are provided' do
@@ -2517,44 +2851,50 @@
describe "Nested Js Helpers" do
it "should have a add method" do
@new_post.stub!(:authors).and_return(mock("Authors", :build => mock('Author')))
+ should_receive(:render).with(hash_including(:partial => "mock")).and_return('"attributes___idx___test__idxx__"')
semantic_form_for(@new_post) do |builder|
- builder.should_receive(:render).with(hash_including(:partial => "mock")).and_return('"attributes___idx___test__idxx__"')
builder.inputs :name => "Contacts", :id => "contacts" do
concat(builder.add_associated_link(:name, :authors))
end
end
output_buffer.should have_tag('form fieldset a[@href=#]')
output_buffer.should match(/\\"attributes___idx___test__idxx__\\"".replace/)
end
- it "should have a remove method" do
- semantic_form_for(@new_post) do |builder|
- builder.semantic_fields_for(:links) do |link_builder|
- concat(link_builder.remove_link("Remove"))
- end
- end
- output_buffer.should eql("<form action=\"/posts\" class=\"formtastic post\" id=\"new_post\" method=\"post\"><input id=\"post_links__delete\" name=\"post[links][_delete]\" type=\"hidden\" /><a href=\"#\" onclick=\"$(this).parents('.nil_class').hide(); $(this).prev(':input').val('1');; return false;\">Remove</a></form>")
- end
it "should have a show method" do
@new_post.stub!(:authors).and_return([mock("Author")])
+ should_receive(:render).with(hash_including(:partial => "mock")).and_return("fields")
semantic_form_for(@new_post) do |builder|
- builder.should_receive(:render).with(hash_including(:partial => "mock")).and_return("fields")
builder.inputs :name => "Contacts" do
concat(builder.render_associated_form @new_post.authors)
end
end
+ # output_buffer.shou
output_buffer.should eql("<form action=\"/posts\" class=\"formtastic post\" id=\"new_post\" method=\"post\"><fieldset class=\"inputs\"><legend><span>Contacts</span></legend><ol>fields</ol></fieldset></form>")
end
+
+ it "should have a remove method" do
+ semantic_form_for(@new_post) do |builder|
+ builder.semantic_fields_for(:links) do |link_builder|
+ concat(link_builder.remove_link("Remove"))
+ end
+ end
+
+ output_buffer.should have_tag("form input[@type=hidden]")
+ output_buffer.should have_tag("form a[@href=#]")
+ # output_buffer.should match(/$(this).parents('.nil_class').hide(); $(this).prev(':input').val('1');; return false;)
+ # output_buffer.should eql("<<input id=\"post_links__delete\" name=\"post[links][_delete]\" type=\"hidden\" /><a href=\"#\" onclick=\"$(this).parents('.nil_class').hide(); $(this).prev(':input').val('1');; return false;\">Remove</a></form>")
+ end
end
end
end