From: Tom Hughes Date: Fri, 3 Sep 2010 14:41:00 +0000 (+0100) Subject: Add the dynamic form plugin to get error_messages_for support back X-Git-Tag: live~6128 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/f50ef32743c6d81df489c30aa12d4b004bf7bc5c Add the dynamic form plugin to get error_messages_for support back --- diff --git a/vendor/plugins/dynamic_form/MIT-LICENSE b/vendor/plugins/dynamic_form/MIT-LICENSE new file mode 100644 index 000000000..700c59bf7 --- /dev/null +++ b/vendor/plugins/dynamic_form/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2010 David Heinemeier Hansson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/plugins/dynamic_form/README b/vendor/plugins/dynamic_form/README new file mode 100644 index 000000000..216c30987 --- /dev/null +++ b/vendor/plugins/dynamic_form/README @@ -0,0 +1,13 @@ +DynamicForm +=========== + +DynamicForm holds a few helpers method to help you deal with your models, they are: + +* input(record, method, options = {}) +* form(record, options = {}) +* error_message_on(object, method, options={}) +* error_messages_for(record, options={}) + +It also adds f.error_messages and f.error_messages_on to your form builders. + +Copyright (c) 2010 David Heinemeier Hansson, released under the MIT license diff --git a/vendor/plugins/dynamic_form/Rakefile b/vendor/plugins/dynamic_form/Rakefile new file mode 100644 index 000000000..e1df65df8 --- /dev/null +++ b/vendor/plugins/dynamic_form/Rakefile @@ -0,0 +1,10 @@ +require 'rake/testtask' + +desc 'Default: run unit tests.' +task :default => :test + +desc 'Test the active_model_helper plugin.' +Rake::TestTask.new(:test) do |t| + t.libs << 'test' + t.pattern = 'test/**/*_test.rb' +end diff --git a/vendor/plugins/dynamic_form/init.rb b/vendor/plugins/dynamic_form/init.rb new file mode 100644 index 000000000..c1d1a3a43 --- /dev/null +++ b/vendor/plugins/dynamic_form/init.rb @@ -0,0 +1,5 @@ +require 'action_view/helpers/dynamic_form' + +class ActionView::Base + include DynamicForm +end diff --git a/vendor/plugins/dynamic_form/lib/action_view/helpers/dynamic_form.rb b/vendor/plugins/dynamic_form/lib/action_view/helpers/dynamic_form.rb new file mode 100644 index 000000000..b34d4bcbe --- /dev/null +++ b/vendor/plugins/dynamic_form/lib/action_view/helpers/dynamic_form.rb @@ -0,0 +1,300 @@ +require 'action_view/helpers' +require 'active_support/i18n' +require 'active_support/core_ext/enumerable' +require 'active_support/core_ext/object/blank' + +module ActionView + module Helpers + # The Active Record Helper makes it easier to create forms for records kept in instance variables. The most far-reaching is the +form+ + # method that creates a complete form for all the basic content types of the record (not associations or aggregations, though). This + # is a great way of making the record quickly available for editing, but likely to prove lackluster for a complicated real-world form. + # In that case, it's better to use the +input+ method and the specialized +form+ methods in link:classes/ActionView/Helpers/FormHelper.html + module DynamicForm + # Returns a default input tag for the type of object returned by the method. For example, if @post + # has an attribute +title+ mapped to a +VARCHAR+ column that holds "Hello World": + # + # input("post", "title") + # # => + def input(record_name, method, options = {}) + InstanceTag.new(record_name, method, self).to_tag(options) + end + + # Returns an entire form with all needed input tags for a specified Active Record object. For example, if @post + # has attributes named +title+ of type +VARCHAR+ and +body+ of type +TEXT+ then + # + # form("post") + # + # would yield a form like the following (modulus formatting): + # + #
+ #

+ #
+ # + #

+ #

+ #
+ # + #

+ # + #
+ # + # It's possible to specialize the form builder by using a different action name and by supplying another + # block renderer. For example, if @entry has an attribute +message+ of type +VARCHAR+ then + # + # form("entry", + # :action => "sign", + # :input_block => Proc.new { |record, column| + # "#{column.human_name}: #{input(record, column.name)}
" + # }) + # + # would yield a form like the following (modulus formatting): + # + #
+ # Message: + #
+ # + #
+ # + # It's also possible to add additional content to the form by giving it a block, such as: + # + # form("entry", :action => "sign") do |form| + # form << content_tag("b", "Department") + # form << collection_select("department", "id", @departments, "id", "name") + # end + # + # The following options are available: + # + # * :action - The action used when submitting the form (default: +create+ if a new record, otherwise +update+). + # * :input_block - Specialize the output using a different block, see above. + # * :method - The method used when submitting the form (default: +post+). + # * :multipart - Whether to change the enctype of the form to "multipart/form-data", used when uploading a file (default: +false+). + # * :submit_value - The text of the submit button (default: "Create" if a new record, otherwise "Update"). + def form(record_name, options = {}) + record = instance_variable_get("@#{record_name}") + record = convert_to_model(record) + + options = options.symbolize_keys + options[:action] ||= record.persisted? ? "update" : "create" + action = url_for(:action => options[:action], :id => record) + + submit_value = options[:submit_value] || options[:action].gsub(/[^\w]/, '').capitalize + + contents = form_tag({:action => action}, :method =>(options[:method] || 'post'), :enctype => options[:multipart] ? 'multipart/form-data': nil) + contents.safe_concat hidden_field(record_name, :id) if record.persisted? + contents.safe_concat all_input_tags(record, record_name, options) + yield contents if block_given? + contents.safe_concat submit_tag(submit_value) + contents.safe_concat('') + end + + # Returns a string containing the error message attached to the +method+ on the +object+ if one exists. + # This error message is wrapped in a DIV tag by default or with :html_tag if specified, + # which can be extended to include a :prepend_text and/or :append_text (to properly explain + # the error), and a :css_class to style it accordingly. +object+ should either be the name of an + # instance variable or the actual object. The method can be passed in either as a string or a symbol. + # As an example, let's say you have a model @post that has an error message on the +title+ attribute: + # + # <%= error_message_on "post", "title" %> + # # =>
can't be empty
+ # + # <%= error_message_on @post, :title %> + # # =>
can't be empty
+ # + # <%= error_message_on "post", "title", + # :prepend_text => "Title simply ", + # :append_text => " (or it won't work).", + # :html_tag => "span", + # :css_class => "inputError" %> + # # => Title simply can't be empty (or it won't work). + def error_message_on(object, method, *args) + options = args.extract_options! + unless args.empty? + ActiveSupport::Deprecation.warn('error_message_on takes an option hash instead of separate ' + + 'prepend_text, append_text, html_tag, and css_class arguments', caller) + + options[:prepend_text] = args[0] || '' + options[:append_text] = args[1] || '' + options[:html_tag] = args[2] || 'div' + options[:css_class] = args[3] || 'formError' + end + options.reverse_merge!(:prepend_text => '', :append_text => '', :html_tag => 'div', :css_class => 'formError') + + object = convert_to_model(object) + + if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) && + (errors = obj.errors[method]).presence + content_tag(options[:html_tag], + (options[:prepend_text].html_safe << errors.first).safe_concat(options[:append_text]), + :class => options[:css_class] + ) + else + '' + end + end + + # Returns a string with a DIV containing all of the error messages for the objects located as instance variables by the names + # given. If more than one object is specified, the errors for the objects are displayed in the order that the object names are + # provided. + # + # This DIV can be tailored by the following options: + # + # * :header_tag - Used for the header of the error div (default: "h2"). + # * :id - The id of the error div (default: "errorExplanation"). + # * :class - The class of the error div (default: "errorExplanation"). + # * :object - The object (or array of objects) for which to display errors, + # if you need to escape the instance variable convention. + # * :object_name - The object name to use in the header, or any text that you prefer. + # If :object_name is not set, the name of the first object will be used. + # * :header_message - The message in the header of the error div. Pass +nil+ + # or an empty string to avoid the header message altogether. (Default: "X errors + # prohibited this object from being saved"). + # * :message - The explanation message after the header message and before + # the error list. Pass +nil+ or an empty string to avoid the explanation message + # altogether. (Default: "There were problems with the following fields:"). + # + # To specify the display for one object, you simply provide its name as a parameter. + # For example, for the @user model: + # + # error_messages_for 'user' + # + # You can also supply an object: + # + # error_messages_for @user + # + # This will use the last part of the model name in the presentation. For instance, if + # this is a MyKlass::User object, this will use "user" as the name in the String. This + # is taken from MyKlass::User.model_name.human, which can be overridden. + # + # To specify more than one object, you simply list them; optionally, you can add an extra :object_name parameter, which + # will be the name used in the header message: + # + # error_messages_for 'user_common', 'user', :object_name => 'user' + # + # You can also use a number of objects, which will have the same naming semantics + # as a single object. + # + # error_messages_for @user, @post + # + # If the objects cannot be located as instance variables, you can add an extra :object parameter which gives the actual + # object (or array of objects to use): + # + # error_messages_for 'user', :object => @question.user + # + # NOTE: This is a pre-packaged presentation of the errors with embedded strings and a certain HTML structure. If what + # you need is significantly different from the default presentation, it makes plenty of sense to access the object.errors + # instance yourself and set it up. View the source of this method to see how easy it is. + def error_messages_for(*params) + options = params.extract_options!.symbolize_keys + + objects = Array.wrap(options.delete(:object) || params).map do |object| + object = instance_variable_get("@#{object}") unless object.respond_to?(:to_model) + object = convert_to_model(object) + + if object.class.respond_to?(:model_name) + options[:object_name] ||= object.class.model_name.human.downcase + end + + object + end + + objects.compact! + count = objects.inject(0) {|sum, object| sum + object.errors.count } + + unless count.zero? + html = {} + [:id, :class].each do |key| + if options.include?(key) + value = options[key] + html[key] = value unless value.blank? + else + html[key] = 'errorExplanation' + end + end + options[:object_name] ||= params.first + + I18n.with_options :locale => options[:locale], :scope => [:errors, :template] do |locale| + header_message = if options.include?(:header_message) + options[:header_message] + else + locale.t :header, :count => count, :model => options[:object_name].to_s.gsub('_', ' ') + end + + message = options.include?(:message) ? options[:message] : locale.t(:body) + + error_messages = objects.sum do |object| + object.errors.full_messages.map do |msg| + content_tag(:li, msg) + end + end.join.html_safe + + contents = '' + contents << content_tag(options[:header_tag] || :h2, header_message) unless header_message.blank? + contents << content_tag(:p, message) unless message.blank? + contents << content_tag(:ul, error_messages) + + content_tag(:div, contents.html_safe, html) + end + else + '' + end + end + + private + + def all_input_tags(record, record_name, options) + input_block = options[:input_block] || default_input_block + record.class.content_columns.collect{ |column| input_block.call(record_name, column) }.join("\n") + end + + def default_input_block + Proc.new { |record, column| %(


#{input(record, column.name)}

) } + end + + module InstanceTagMethods + def to_tag(options = {}) + case column_type + when :string + field_type = @method_name.include?("password") ? "password" : "text" + to_input_field_tag(field_type, options) + when :text + to_text_area_tag(options) + when :integer, :float, :decimal + to_input_field_tag("text", options) + when :date + to_date_select_tag(options) + when :datetime, :timestamp + to_datetime_select_tag(options) + when :time + to_time_select_tag(options) + when :boolean + to_boolean_select_tag(options) + end + end + + def column_type + object.send(:column_for_attribute, @method_name).type + end + end + + module FormBuilderMethods + def error_message_on(method, *args) + @template.error_message_on(@object || @object_name, method, *args) + end + + def error_messages(options = {}) + @template.error_messages_for(@object_name, objectify_options(options)) + end + end + end + + class InstanceTag + include DynamicForm::InstanceTagMethods + end + + class FormBuilder + include DynamicForm::FormBuilderMethods + end + end +end + +I18n.load_path << File.expand_path("../../locale/en.yml", __FILE__) diff --git a/vendor/plugins/dynamic_form/lib/action_view/locale/en.yml b/vendor/plugins/dynamic_form/lib/action_view/locale/en.yml new file mode 100644 index 000000000..9e2af96fc --- /dev/null +++ b/vendor/plugins/dynamic_form/lib/action_view/locale/en.yml @@ -0,0 +1,8 @@ +en: + errors: + template: + header: + one: "1 error prohibited this %{model} from being saved" + other: "%{count} errors prohibited this %{model} from being saved" + # The variable :count is also available + body: "There were problems with the following fields:" diff --git a/vendor/plugins/dynamic_form/test/dynamic_form_i18n_test.rb b/vendor/plugins/dynamic_form/test/dynamic_form_i18n_test.rb new file mode 100644 index 000000000..82c52ca51 --- /dev/null +++ b/vendor/plugins/dynamic_form/test/dynamic_form_i18n_test.rb @@ -0,0 +1,42 @@ +require 'test_helper' + +class DynamicFormI18nTest < Test::Unit::TestCase + include ActionView::Context + include ActionView::Helpers::DynamicForm + + attr_reader :request + + def setup + @object = stub :errors => stub(:count => 1, :full_messages => ['full_messages']) + @object.stubs :to_model => @object + @object.stubs :class => stub(:model_name => stub(:human => "")) + + @object_name = 'book_seller' + @object_name_without_underscore = 'book seller' + + stubs(:content_tag).returns 'content_tag' + + I18n.stubs(:t).with(:'header', :locale => 'en', :scope => [:errors, :template], :count => 1, :model => '').returns "1 error prohibited this from being saved" + I18n.stubs(:t).with(:'body', :locale => 'en', :scope => [:errors, :template]).returns 'There were problems with the following fields:' + end + + def test_error_messages_for_given_a_header_option_it_does_not_translate_header_message + I18n.expects(:t).with(:'header', :locale => 'en', :scope => [:errors, :template], :count => 1, :model => '').never + error_messages_for(:object => @object, :header_message => 'header message', :locale => 'en') + end + + def test_error_messages_for_given_no_header_option_it_translates_header_message + I18n.expects(:t).with(:'header', :locale => 'en', :scope => [:errors, :template], :count => 1, :model => '').returns 'header message' + error_messages_for(:object => @object, :locale => 'en') + end + + def test_error_messages_for_given_a_message_option_it_does_not_translate_message + I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:errors, :template]).never + error_messages_for(:object => @object, :message => 'message', :locale => 'en') + end + + def test_error_messages_for_given_no_message_option_it_translates_message + I18n.expects(:t).with(:'body', :locale => 'en', :scope => [:errors, :template]).returns 'There were problems with the following fields:' + error_messages_for(:object => @object, :locale => 'en') + end +end \ No newline at end of file diff --git a/vendor/plugins/dynamic_form/test/dynamic_form_test.rb b/vendor/plugins/dynamic_form/test/dynamic_form_test.rb new file mode 100644 index 000000000..e616cba4e --- /dev/null +++ b/vendor/plugins/dynamic_form/test/dynamic_form_test.rb @@ -0,0 +1,370 @@ +require 'test_helper' +require 'action_view/template/handlers/erb' + +class DynamicFormTest < ActionView::TestCase + tests ActionView::Helpers::DynamicForm + + def form_for(*) + @output_buffer = super + end + + silence_warnings do + class Post < Struct.new(:title, :author_name, :body, :secret, :written_on) + extend ActiveModel::Naming + include ActiveModel::Conversion + end + + class User < Struct.new(:email) + extend ActiveModel::Naming + include ActiveModel::Conversion + end + + class Column < Struct.new(:type, :name, :human_name) + extend ActiveModel::Naming + include ActiveModel::Conversion + end + end + + class DirtyPost + class Errors + def empty? + false + end + + def count + 1 + end + + def full_messages + ["Author name can't be empty"] + end + + def [](field) + ["can't be empty"] + end + end + + def errors + Errors.new + end + end + + def setup_post + @post = Post.new + def @post.errors + Class.new { + def [](field) + case field.to_s + when "author_name" + ["can't be empty"] + when "body" + ['foo'] + else + [] + end + end + def empty?() false end + def count() 1 end + def full_messages() [ "Author name can't be empty" ] end + }.new + end + + def @post.persisted?() false end + def @post.to_param() nil end + + def @post.column_for_attribute(attr_name) + Post.content_columns.select { |column| column.name == attr_name }.first + end + + silence_warnings do + def Post.content_columns() [ Column.new(:string, "title", "Title"), Column.new(:text, "body", "Body") ] end + end + + @post.title = "Hello World" + @post.author_name = "" + @post.body = "Back to the hill and over it again!" + @post.secret = 1 + @post.written_on = Date.new(2004, 6, 15) + end + + def setup_user + @user = User.new + def @user.errors + Class.new { + def [](field) field == "email" ? ['nonempty'] : [] end + def empty?() false end + def count() 1 end + def full_messages() [ "User email can't be empty" ] end + }.new + end + + def @user.new_record?() true end + def @user.to_param() nil end + + def @user.column_for_attribute(attr_name) + User.content_columns.select { |column| column.name == attr_name }.first + end + + silence_warnings do + def User.content_columns() [ Column.new(:string, "email", "Email") ] end + end + + @user.email = "" + end + + def protect_against_forgery? + @protect_against_forgery ? true : false + end + attr_accessor :request_forgery_protection_token, :form_authenticity_token + + def setup + super + setup_post + setup_user + + @response = ActionController::TestResponse.new + end + + def url_for(options) + options = options.symbolize_keys + [options[:action], options[:id].to_param].compact.join('/') + end + + def test_generic_input_tag + assert_dom_equal( + %(), input("post", "title") + ) + end + + def test_text_area_with_errors + assert_dom_equal( + %(
), + text_area("post", "body") + ) + end + + def test_text_field_with_errors + assert_dom_equal( + %(
), + text_field("post", "author_name") + ) + end + + def test_field_error_proc + old_proc = ActionView::Base.field_error_proc + ActionView::Base.field_error_proc = Proc.new do |html_tag, instance| + %(
#{html_tag} #{[instance.error_message].join(', ')}
).html_safe + end + + assert_dom_equal( + %(
can't be empty
), + text_field("post", "author_name") + ) + ensure + ActionView::Base.field_error_proc = old_proc if old_proc + end + + def test_form_with_string + assert_dom_equal( + %(


\n


), + form("post") + ) + + silence_warnings do + class << @post + def persisted?() true end + def to_param() id end + def id() 1 end + end + end + + assert_dom_equal( + %(


\n


), + form("post") + ) + end + + def test_form_with_protect_against_forgery + @protect_against_forgery = true + @request_forgery_protection_token = 'authenticity_token' + @form_authenticity_token = '123' + assert_dom_equal( + %(


\n


), + form("post") + ) + end + + def test_form_with_method_option + assert_dom_equal( + %(


\n


), + form("post", :method=>'get') + ) + end + + def test_form_with_action_option + output_buffer << form("post", :action => "sign") + assert_select "form[action=sign]" do |form| + assert_select "input[type=submit][value=Sign]" + end + end + + def test_form_with_date + silence_warnings do + def Post.content_columns() [ Column.new(:date, "written_on", "Written on") ] end + end + + assert_dom_equal( + %(


\n\n\n

), + form("post") + ) + end + + def test_form_with_datetime + silence_warnings do + def Post.content_columns() [ Column.new(:datetime, "written_on", "Written on") ] end + end + @post.written_on = Time.gm(2004, 6, 15, 16, 30) + + assert_dom_equal( + %(


\n\n\n — \n : \n

), + form("post") + ) + end + + def test_error_for_block + assert_dom_equal %(

1 error prohibited this post from being saved

There were problems with the following fields:

), error_messages_for("post") + assert_equal %(

1 error prohibited this post from being saved

There were problems with the following fields:

), error_messages_for("post", :class => "errorDeathByClass", :id => "errorDeathById", :header_tag => "h1") + assert_equal %(

1 error prohibited this post from being saved

There were problems with the following fields:

), error_messages_for("post", :class => nil, :id => "errorDeathById", :header_tag => "h1") + assert_equal %(

1 error prohibited this post from being saved

There were problems with the following fields:

), error_messages_for("post", :class => "errorDeathByClass", :id => nil, :header_tag => "h1") + end + + def test_error_messages_for_escapes_html + @dirty_post = DirtyPost.new + assert_dom_equal %(

1 error prohibited this dirty post from being saved

There were problems with the following fields:

), error_messages_for("dirty_post") + end + + def test_error_messages_for_handles_nil + assert_equal "", error_messages_for("notthere") + end + + def test_error_message_on_escapes_html + @dirty_post = DirtyPost.new + assert_dom_equal "
can't be <em>empty</em>
", error_message_on(:dirty_post, :author_name) + end + + def test_error_message_on_handles_nil + assert_equal "", error_message_on("notthere", "notthere") + end + + def test_error_message_on + assert_dom_equal "
can't be empty
", error_message_on(:post, :author_name) + end + + def test_error_message_on_no_instance_variable + other_post = @post + assert_dom_equal "
can't be empty
", error_message_on(other_post, :author_name) + end + + def test_error_message_on_with_options_hash + assert_dom_equal "
beforecan't be emptyafter
", error_message_on(:post, :author_name, :css_class => 'differentError', :prepend_text => 'before', :append_text => 'after') + end + + def test_error_message_on_with_tag_option_in_options_hash + assert_dom_equal "beforecan't be emptyafter", error_message_on(:post, :author_name, :html_tag => "span", :css_class => 'differentError', :prepend_text => 'before', :append_text => 'after') + end + + def test_error_message_on_handles_empty_errors + assert_equal "", error_message_on(@post, :tag) + end + + def test_error_messages_for_many_objects + assert_dom_equal %(

2 errors prohibited this post from being saved

There were problems with the following fields:

), error_messages_for("post", "user") + + # reverse the order, error order changes and so does the title + assert_dom_equal %(

2 errors prohibited this user from being saved

There were problems with the following fields:

), error_messages_for("user", "post") + + # add the default to put post back in the title + assert_dom_equal %(

2 errors prohibited this post from being saved

There were problems with the following fields:

), error_messages_for("user", "post", :object_name => "post") + + # symbols work as well + assert_dom_equal %(

2 errors prohibited this post from being saved

There were problems with the following fields:

), error_messages_for(:user, :post, :object_name => :post) + + # any default works too + assert_dom_equal %(

2 errors prohibited this monkey from being saved

There were problems with the following fields:

), error_messages_for(:user, :post, :object_name => "monkey") + + # should space object name + assert_dom_equal %(

2 errors prohibited this chunky bacon from being saved

There were problems with the following fields:

), error_messages_for(:user, :post, :object_name => "chunky_bacon") + + # hide header and explanation messages with nil or empty string + assert_dom_equal %(
), error_messages_for(:user, :post, :header_message => nil, :message => "") + + # override header and explanation messages + header_message = "Yikes! Some errors" + message = "Please fix the following fields and resubmit:" + assert_dom_equal %(

#{header_message}

#{message}

), error_messages_for(:user, :post, :header_message => header_message, :message => message) + end + + def test_error_messages_for_non_instance_variable + actual_user = @user + actual_post = @post + @user = nil + @post = nil + + #explicitly set object + assert_dom_equal %(

1 error prohibited this post from being saved

There were problems with the following fields:

), error_messages_for("post", :object => actual_post) + + #multiple objects + assert_dom_equal %(

2 errors prohibited this user from being saved

There were problems with the following fields:

), error_messages_for("user", "post", :object => [actual_user, actual_post]) + + #nil object + assert_equal '', error_messages_for('user', :object => nil) + end + + def test_error_messages_for_model_objects + error = error_messages_for(@post) + assert_dom_equal %(

1 error prohibited this post from being saved

There were problems with the following fields:

), + error + + error = error_messages_for(@user, @post) + assert_dom_equal %(

2 errors prohibited this user from being saved

There were problems with the following fields:

), + error + end + + def test_form_with_string_multipart + assert_dom_equal( + %(


\n


), + form("post", :multipart => true) + ) + end + + def test_default_form_builder_with_dynamic_form_helpers + form_for(@post, :as => :post, :url => {}) do |f| + concat f.error_message_on('author_name') + concat f.error_messages + end + + expected = %(
) + + %(
can't be empty
) + + %(

1 error prohibited this post from being saved

There were problems with the following fields:

  • Author name can't be empty
) + + %(
) + + assert_dom_equal expected, output_buffer + end + + def test_default_form_builder_no_instance_variable + post = @post + @post = nil + + form_for(post, :as => :post, :url => {}) do |f| + concat f.error_message_on('author_name') + concat f.error_messages + end + + expected = %(
) + + %(
can't be empty
) + + %(

1 error prohibited this post from being saved

There were problems with the following fields:

  • Author name can't be empty
) + + %(
) + + assert_dom_equal expected, output_buffer + end +end \ No newline at end of file diff --git a/vendor/plugins/dynamic_form/test/test_helper.rb b/vendor/plugins/dynamic_form/test/test_helper.rb new file mode 100644 index 000000000..f62a43cce --- /dev/null +++ b/vendor/plugins/dynamic_form/test/test_helper.rb @@ -0,0 +1,9 @@ +require 'rubygems' +require 'test/unit' +require 'active_support' +require 'active_support/core_ext' +require 'action_view' +require 'action_controller' +require 'action_controller/test_case' +require 'active_model' +require 'action_view/helpers/dynamic_form'