require "spec_helper"
[NestedForm::Builder, NestedForm::SimpleBuilder, defined?(NestedForm::FormtasticBuilder) ? NestedForm::FormtasticBuilder : nil].compact.each do |builder|
describe builder do
let(:project) do
Project.new
end
let(:template) do
template = ActionView::Base.new
template.output_buffer = ""
template
end
context "with no options" do
subject do
builder.new(:item, project, template, {}, proc {})
end
describe '#link_to_add' do
it "behaves similar to a Rails link_to" do
subject.link_to_add("Add", :tasks).should == 'Add'
subject.link_to_add("Add", :tasks, :class => "foo", :href => "url").should == 'Add'
subject.link_to_add(:tasks) { "Add" }.should == 'Add'
end
context 'when missing association is provided' do
it 'raises Argument error' do
expect{ subject.link_to_add('Add', :bugs) }.to raise_error(ArgumentError,
'Failed to find Project association by name "bugs"')
end
end
end
describe '#link_to_remove' do
it "behaves similar to a Rails link_to" do
subject.link_to_remove("Remove").should == 'Remove'
subject.link_to_remove("Remove", :class => "foo", :href => "url").should == 'Remove'
subject.link_to_remove { "Remove" }.should == 'Remove'
end
it 'has data-association attribute' do
project.tasks.build
subject.fields_for(:tasks, :builder => builder) do |tf|
tf.link_to_remove 'Remove'
end.should match 'Remove'
end
context 'when association is declared in a model by the class_name' do
it 'properly detects association name' do
project.assignments.build
subject.fields_for(:assignments, :builder => builder) do |tf|
tf.link_to_remove 'Remove'
end.should match 'Remove'
end
end
context 'when there is more than one nested level' do
it 'properly detects association name' do
task = project.tasks.build
task.milestones.build
subject.fields_for(:tasks, :builder => builder) do |tf|
tf.fields_for(:milestones, :builder => builder) do |mf|
mf.link_to_remove 'Remove'
end
end.should match 'Remove'
end
end
end
describe '#fields_for' do
it "wraps nested fields each in a div with class" do
2.times { project.tasks.build }
subject.fields_for(:tasks) do
"Task"
end.should == '
Task
Task
'
end
end
it "wraps nested fields marked for destruction with an additional class" do
task = project.tasks.build
task.mark_for_destruction
fields = subject.fields_for(:tasks) { 'Task' }
fields.should eq('
Task
')
end
it "puts blueprint into data-blueprint attribute" do
task = project.tasks.build
task.mark_for_destruction
subject.fields_for(:tasks) { 'Task' }
subject.link_to_add('Add', :tasks)
output = template.send(:after_nested_form_callbacks)
expected = ERB::Util.html_escape '
Task
'
output.should match(/div.+data-blueprint="#{expected}"/)
end
it "adds parent association name to the blueprint div id" do
task = project.tasks.build
task.milestones.build
subject.fields_for(:tasks, :builder => builder) do |tf|
tf.fields_for(:milestones, :builder => builder) { 'Milestone' }
tf.link_to_add('Add', :milestones)
end
output = template.send(:after_nested_form_callbacks)
output.should match(/div.+id="tasks_milestones_fields_blueprint"/)
end
it "doesn't render wrapper div" do
task = project.tasks.build
fields = subject.fields_for(:tasks, :wrapper => false) { 'Task' }
fields.should eq('Task')
subject.link_to_add 'Add', :tasks
output = template.send(:after_nested_form_callbacks)
output.should match(/div.+data-blueprint="Task"/)
end
end
context "with options" do
subject { builder.new(:item, project, template, {}, proc {}) }
context "when model_object given" do
it "should use it instead of new generated" do
subject.fields_for(:tasks) {|f| f.object.name }
subject.link_to_add("Add", :tasks, :model_object => Task.new(:name => 'for check'))
output = template.send(:after_nested_form_callbacks)
expected = ERB::Util.html_escape '
for check
'
output.should match(/div.+data-blueprint="#{expected}"/)
end
end
end
end
end