Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

specs for support of polymorphic association checking on top of Mongo…

…Mapper
  • Loading branch information...
commit c6c6d2bcb91831e1e6cf6f7fb6abbeaf3ecbf3b4 1 parent a452caf
@ijonas ijonas authored
Showing with 124 additions and 74 deletions.
  1. +85 −73 spec/helpers/inputs_helper_spec.rb
  2. +39 −1 spec/spec_helper.rb
View
158 spec/helpers/inputs_helper_spec.rb
@@ -11,7 +11,7 @@
end
describe 'with a block (block forms syntax)' do
-
+
describe 'when no options are provided' do
before do
output_buffer.replace 'before_builder' # clear the output buffer and sets before_builder
@@ -21,28 +21,28 @@
end
end)
end
-
+
it 'should output just the content wrapped in inputs, not the whole template' do
output_buffer.should =~ /before_builder/
@inputs_output.should_not =~ /before_builder/
end
-
+
it 'should render a fieldset inside the form, with a class of "inputs"' do
output_buffer.should have_tag("form fieldset.inputs")
end
-
+
it 'should render an ol inside the fieldset' do
output_buffer.should have_tag("form fieldset.inputs ol")
end
-
+
it 'should render the contents of the block inside the ol' do
output_buffer.should have_tag("form fieldset.inputs ol", /hello/)
end
-
+
it 'should not render a legend inside the fieldset' do
output_buffer.should_not have_tag("form fieldset.inputs legend")
end
-
+
it 'should render a fieldset even if no object is given' do
concat(semantic_form_for(:project, :url => 'http://test.host/') do |builder|
@inputs_output = builder.inputs do
@@ -52,17 +52,17 @@
output_buffer.should have_tag("form fieldset.inputs ol", /bye/)
end
end
-
+
describe 'when a :for option is provided' do
-
+
before do
@new_post.stub!(:respond_to?).and_return(true, true)
@new_post.stub!(:author).and_return(@bob)
end
-
+
it 'should render nested inputs' do
@bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
-
+
concat(semantic_form_for(@new_post) do |builder|
inputs = builder.inputs :for => [:author, @bob] do |bob_builder|
concat(bob_builder.input(:login))
@@ -72,23 +72,23 @@
output_buffer.should have_tag("form fieldset.inputs #post_author_attributes_login")
output_buffer.should_not have_tag("form fieldset.inputs #author_login")
end
-
+
it 'should concat rendered nested inputs to the template' do
@bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
-
+
concat(semantic_form_for(@new_post) do |builder|
builder.inputs :for => [:author, @bob] do |bob_builder|
concat(bob_builder.input(:login))
end
end)
-
+
output_buffer.should have_tag("form fieldset.inputs #post_author_attributes_login")
output_buffer.should_not have_tag("form fieldset.inputs #author_login")
-
+
end
-
+
describe "as a symbol representing the association name" do
-
+
it 'should nest the inputs with an _attributes suffix on the association name' do
concat(semantic_form_for(@new_post) do |post|
inputs = post.inputs :for => :author do |author|
@@ -98,15 +98,15 @@
end)
output_buffer.should have_tag("form input[@name='post[author_attributes][login]']")
end
-
+
end
-
+
describe "as a symbol representing a has_many association name" do
before do
@new_post.stub!(:authors).and_return([@bob, @fred])
@new_post.stub!(:authors_attributes=)
end
-
+
it 'should nest the inputs with a fieldset, legend and :name input for each item' do
concat(semantic_form_for(@new_post) do |post|
post.inputs :for => :authors, :name => '%i' do |author|
@@ -123,9 +123,9 @@
output_buffer.should_not have_tag('form fieldset[@name]')
end
end
-
+
describe 'as an array containing the a symbole for the association name and the associated object' do
-
+
it 'should nest the inputs with an _attributes suffix on the association name' do
concat(semantic_form_for(@new_post) do |post|
inputs = post.inputs :for => [:author, @new_post.author] do |author|
@@ -135,11 +135,11 @@
end)
output_buffer.should have_tag("form input[@name='post[author_attributes][login]']")
end
-
+
end
-
+
describe 'as an associated object' do
-
+
it 'should not nest the inputs with an _attributes suffix' do
concat(semantic_form_for(@new_post) do |post|
inputs = post.inputs :for => @new_post.author do |author|
@@ -149,9 +149,9 @@
end)
output_buffer.should have_tag("form input[@name='post[author][login]']")
end
-
+
end
-
+
it 'should raise an error if :for and block with no argument is given' do
semantic_form_for(@new_post) do |builder|
proc {
@@ -162,20 +162,20 @@
'but the block does not accept any argument.')
end
end
-
+
it 'should pass options down to semantic_fields_for' do
@bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
-
+
concat(semantic_form_for(@new_post) do |builder|
inputs = builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
concat(bob_builder.input(:login))
end
concat(inputs)
end)
-
+
output_buffer.should have_tag('form fieldset ol li #post_author_attributes_10_login')
end
-
+
it 'should not add builder as a fieldset attribute tag' do
concat(semantic_form_for(@new_post) do |builder|
inputs = builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
@@ -183,10 +183,10 @@
end
concat(inputs)
end)
-
+
output_buffer.should_not have_tag('fieldset[@builder="Formtastic::Helpers::FormHelper"]')
end
-
+
it 'should send parent_builder as an option to allow child index interpolation' do
concat(semantic_form_for(@new_post) do |builder|
builder.instance_variable_set('@nested_child_index', 0)
@@ -195,10 +195,10 @@
end
concat(inputs)
end)
-
+
output_buffer.should have_tag('fieldset legend', 'Author #1')
end
-
+
it 'should also provide child index interpolation when nested child index is a hash' do
concat(semantic_form_for(@new_post) do |builder|
builder.instance_variable_set('@nested_child_index', :author => 10)
@@ -207,11 +207,11 @@
end
concat(inputs)
end)
-
+
output_buffer.should have_tag('fieldset legend', 'Author #11')
end
end
-
+
describe 'when a :name or :title option is provided' do
describe 'and is a string' do
before do
@@ -234,7 +234,7 @@
concat(inputs)
end)
end
-
+
it 'should render a fieldset with a legend inside the form' do
output_buffer.should have_tag("form fieldset legend", /^#{@legend_text}$/)
output_buffer.should have_tag("form fieldset legend", /^#{@legend_text_using_name}$/)
@@ -242,7 +242,7 @@
output_buffer.should have_tag("form fieldset legend", /^#{@nested_forms_legend_text}$/)
end
end
-
+
describe 'and is a symbol' do
before do
@localized_legend_text = "Localized advanced options"
@@ -274,7 +274,7 @@
concat(inputs)
end)
end
-
+
it 'should render a fieldset with a localized legend inside the form' do
output_buffer.should have_tag("form fieldset legend", /^#{@localized_legend_text}$/)
output_buffer.should have_tag("form fieldset legend", /^#{@localized_legend_text_using_name}$/)
@@ -283,84 +283,84 @@
end
end
end
-
+
describe 'when other options are provided' do
before do
@id_option = 'advanced'
@class_option = 'wide'
-
+
concat(semantic_form_for(@new_post) do |builder|
builder.inputs :id => @id_option, :class => @class_option do
end
end)
end
-
+
it 'should pass the options into the fieldset tag as attributes' do
output_buffer.should have_tag("form fieldset##{@id_option}")
output_buffer.should have_tag("form fieldset.#{@class_option}")
end
end
-
+
end
-
+
describe 'without a block' do
-
+
before do
::Post.stub!(:reflections).and_return({:author => mock('reflection', :options => {}, :macro => :belongs_to),
:comments => mock('reflection', :options => {}, :macro => :has_many) })
::Author.stub!(:find).and_return([@fred, @bob])
-
+
@new_post.stub!(:title)
@new_post.stub!(:body)
@new_post.stub!(:author_id)
-
+
@new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :string, :limit => 255))
@new_post.stub!(:column_for_attribute).with(:body).and_return(mock('column', :type => :text))
@new_post.stub!(:column_for_attribute).with(:created_at).and_return(mock('column', :type => :datetime))
@new_post.stub!(:column_for_attribute).with(:author).and_return(nil)
end
-
+
describe 'with no args (quick forms syntax)' do
before do
concat(semantic_form_for(@new_post) do |builder|
concat(builder.inputs)
end)
end
-
+
it 'should render a form' do
output_buffer.should have_tag('form')
end
-
+
it 'should render a fieldset inside the form' do
output_buffer.should have_tag('form > fieldset.inputs')
end
-
+
it 'should not render a legend in the fieldset' do
output_buffer.should_not have_tag('form > fieldset.inputs > legend')
end
-
+
it 'should render an ol in the fieldset' do
output_buffer.should have_tag('form > fieldset.inputs > ol')
end
-
+
it 'should render a list item in the ol for each column and reflection' do
# Remove the :has_many macro and :created_at column
count = ::Post.content_columns.size + ::Post.reflections.size - 2
output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => count)
end
-
+
it 'should render a string list item for title' do
output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
end
-
+
it 'should render a text list item for body' do
output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
end
-
+
it 'should render a select list item for author_id' do
output_buffer.should have_tag('form > fieldset.inputs > ol > li.select', :count => 1)
end
-
+
it 'should not render timestamps inputs by default' do
output_buffer.should_not have_tag('form > fieldset.inputs > ol > li.datetime')
end
@@ -386,26 +386,26 @@
end
end
-
+
describe 'with column names as args (short hand forms syntax)' do
describe 'and an object is given' do
it 'should render a form with a fieldset containing two list items' do
concat(semantic_form_for(@new_post) do |builder|
concat(builder.inputs(:title, :body))
end)
-
+
output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 2)
output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
end
end
-
+
describe 'and no object is given' do
it 'should render a form with a fieldset containing two list items' do
concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
concat(builder.inputs(:title, :body))
end)
-
+
output_buffer.should have_tag('form > fieldset.inputs > ol > li.string', :count => 2)
end
end
@@ -434,7 +434,7 @@
end
end
-
+
describe 'when a :for option is provided' do
describe 'and an object is given' do
it 'should render nested inputs' do
@@ -442,12 +442,12 @@
concat(semantic_form_for(@new_post) do |builder|
concat(builder.inputs(:login, :for => @bob))
end)
-
+
output_buffer.should have_tag("form fieldset.inputs #post_author_login")
output_buffer.should_not have_tag("form fieldset.inputs #author_login")
end
end
-
+
describe 'and no object is given' do
it 'should render nested inputs' do
concat(semantic_form_for(:project, :url => 'http://test.host/') do |builder|
@@ -458,7 +458,7 @@
end
end
end
-
+
describe 'with column names and an options hash as args' do
before do
concat(semantic_form_for(@new_post) do |builder|
@@ -468,23 +468,23 @@
concat(builder.inputs(@legend_text_using_arg, :title, :body, :id => "my-id-2"))
end)
end
-
+
it 'should render a form with a fieldset containing two list items' do
output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 4)
end
-
+
it 'should pass the options down to the fieldset' do
output_buffer.should have_tag('form > fieldset#my-id.inputs')
end
-
+
it 'should use the special :name option as a text for the legend tag' do
output_buffer.should have_tag('form > fieldset#my-id.inputs > legend', /^#{@legend_text_using_option}$/)
output_buffer.should have_tag('form > fieldset#my-id-2.inputs > legend', /^#{@legend_text_using_arg}$/)
end
end
-
+
end
-
+
describe 'nesting' do
context "when not nested" do
@@ -531,7 +531,7 @@
output_buffer.should have_tag('form > fieldset.inputs > ol > li > fieldset.inputs > ol')
end
end
-
+
context "when nested (without block, with :for)" do
it "should wrap the nested inputs in an li block to maintain HTML validity" do
concat(semantic_form_for(@new_post) do |builder|
@@ -542,7 +542,7 @@
output_buffer.should have_tag('form > fieldset.inputs > ol > li > fieldset.inputs > ol')
end
end
-
+
context "when double nested" do
it "should wrap the nested inputs in an li block to maintain HTML validity" do
concat(semantic_form_for(@new_post) do |builder|
@@ -559,4 +559,16 @@
end
+ describe 'when using MongoMapper associations ' do
+ def generate_form
+ semantic_form_for(@new_mm_post) do |builder|
+ builder.inputs :title, :sub_posts
+ end
+ end
+ it "should throw PolymorphicInputWithoutCollectionError on sub_posts" do
+ ::MongoPost.should_receive(:associations).exactly(3).times
+ expect { generate_form }.to raise_error(Formtastic::PolymorphicInputWithoutCollectionError)
+ end
+ end
+
end
View
40 spec/spec_helper.rb
@@ -72,6 +72,17 @@ def active_model_numericality_validator(attributes, options = {})
active_model_validator(:numericality, attributes, options)
end
+ class ::MongoPost
+ include MongoMapper::Document if defined?(MongoMapper::Document)
+
+ def id
+ end
+
+ def persisted?
+ end
+ end
+
+
class ::Post
extend ActiveModel::Naming if defined?(ActiveModel::Naming)
include ActiveModel::Conversion if defined?(ActiveModel::Conversion)
@@ -256,7 +267,6 @@ def new_author_path; "/authors/new"; end
when :mongoid_reviewer
mock('reflection', :options => nil, :klass => ::Author, :macro => :referenced_in, :foreign_key => "reviewer_id") # custom id
end
-
end
::Post.stub!(:find).and_return([@freds_post])
::Post.stub!(:all).and_return([@freds_post])
@@ -266,6 +276,34 @@ def new_author_path; "/authors/new"; end
::Post.stub!(:persisted?).and_return(nil)
::Post.stub!(:to_ary)
+
+ ::MongoPost.stub!(:human_attribute_name).and_return { |column_name| column_name.humanize }
+ ::MongoPost.stub!(:human_name).and_return('MongoPost')
+ ::MongoPost.stub!(:associations).and_return do |column_name|
+ case column_name
+ when :sub_posts
+ mock('reflection', :options => {:polymorphic => true}, :klass => ::MongoPost, :macro => :has_many)
+ end
+ end
+ ::MongoPost.stub!(:find).and_return([@freds_post])
+ ::MongoPost.stub!(:all).and_return([@freds_post])
+ ::MongoPost.stub!(:where).and_return([@freds_post])
+ ::MongoPost.stub!(:to_key).and_return(nil)
+ ::MongoPost.stub!(:persisted?).and_return(nil)
+ ::MongoPost.stub!(:to_ary)
+ ::MongoPost.stub!(:model_name).and_return( mock(:model_name_mock, :singular => "post", :plural => "posts") )
+
+ @new_mm_post = mock('mm_post')
+ @new_mm_post.stub!(:class).and_return(::MongoPost)
+ @new_mm_post.stub!(:id).and_return(nil)
+ @new_mm_post.stub!(:new_record?).and_return(true)
+ @new_mm_post.stub!(:errors).and_return(mock('errors', :[] => nil))
+ @new_mm_post.stub!(:title).and_return("Hello World")
+ @new_mm_post.stub!(:sub_posts).and_return([]) #TODO should be a mock with methods for adding sub posts
+ @new_mm_post.stub!(:to_key).and_return(nil)
+ @new_mm_post.stub!(:to_model).and_return(@new_mm_post)
+ @new_mm_post.stub!(:persisted?).and_return(nil)
+
@mock_file = mock('file')
Formtastic::FormBuilder.file_methods.each do |method|
@mock_file.stub!(method).and_return(true)
Please sign in to comment.
Something went wrong with that request. Please try again.