I recently created my first custom Rails builder. It was very easy to do.
First, create a class that inherits from ActionView::Helpers::FormBuilder and then you can either write your own methods or overwrite the built in text_field, check_box, radio_button, etc.
Then, when using a form you can specify the builder (or set your builder to be the default in your config file)
That's all great and well documented, but I had a hard time finding the best way to write automated tests for the builder. I was looking for a way to write unit tests directly against this class, rather than relying on a view and controller and using the heavier functional test framework. Here is how it is done:
The keys are:
1. Inherit your unit test from ActionView::TestCase
2. tests ActionView::Helpers::FormHelper is key to allow you to directly call helper methods that you normally would call from an ERB template file (such as form_for)
2b. I had to define protect_against_forgery? in order to call form_for
3. output_buffer is an accessor of ActionView::TestCase, which is an HTMLDocument object of the output
4. assert_dom_equal is handy to compare HTML output for equality (ignoring attribute order and single quotes versus double quotes)
First, create a class that inherits from ActionView::Helpers::FormBuilder and then you can either write your own methods or overwrite the built in text_field, check_box, radio_button, etc.
class MyFirstFormBuilder < ActionView::Helpers::FormBuilder
...
end
Then, when using a form you can specify the builder (or set your builder to be the default in your config file)
<% form_for @post, :builder => MyFirstFormBuilder do |f| %>
...
<% end %>
That's all great and well documented, but I had a hard time finding the best way to write automated tests for the builder. I was looking for a way to write unit tests directly against this class, rather than relying on a view and controller and using the heavier functional test framework. Here is how it is done:
require File.expand_path('../../test_helper', __FILE__)
class MyFirstFormBuilderTest < ActionView::TestCase
tests ActionView::Helpers::FormHelper
def protect_against_forgery?
false
end
test_error_messages_format_when_no_errors
assert @post.valid?
form_for(:advertiser, @post, :url => "/foo",
:builder => MyFirstFormBuilder) do |f|
concat f.error_messages
end
assert_dom_equal "<form action="/foo" method="post"></form>",
output_buffer
end
end
The keys are:
1. Inherit your unit test from ActionView::TestCase
2. tests ActionView::Helpers::FormHelper is key to allow you to directly call helper methods that you normally would call from an ERB template file (such as form_for)
2b. I had to define protect_against_forgery? in order to call form_for
3. output_buffer is an accessor of ActionView::TestCase, which is an HTMLDocument object of the output
4. assert_dom_equal is handy to compare HTML output for equality (ignoring attribute order and single quotes versus double quotes)