diff options
Diffstat (limited to 'activemodel')
-rw-r--r-- | activemodel/CHANGELOG.md | 14 | ||||
-rw-r--r-- | activemodel/README.rdoc | 9 | ||||
-rw-r--r-- | activemodel/lib/active_model.rb | 1 | ||||
-rw-r--r-- | activemodel/lib/active_model/attribute_methods.rb | 10 | ||||
-rw-r--r-- | activemodel/lib/active_model/naming.rb | 2 | ||||
-rw-r--r-- | activemodel/lib/active_model/serialization.rb | 12 | ||||
-rw-r--r-- | activemodel/lib/active_model/serializers/xml.rb | 238 | ||||
-rw-r--r-- | activemodel/lib/active_model/validations/confirmation.rb | 20 | ||||
-rw-r--r-- | activemodel/lib/active_model/validations/validates.rb | 2 | ||||
-rw-r--r-- | activemodel/test/cases/helper.rb | 3 | ||||
-rw-r--r-- | activemodel/test/cases/serializers/xml_serialization_test.rb | 251 | ||||
-rw-r--r-- | activemodel/test/cases/validations/confirmation_validation_test.rb | 14 | ||||
-rw-r--r-- | activemodel/test/cases/validations/i18n_validation_test.rb | 2 | ||||
-rw-r--r-- | activemodel/test/config.rb | 3 | ||||
-rw-r--r-- | activemodel/test/models/contact.rb | 1 |
15 files changed, 54 insertions, 528 deletions
diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md index 625dfa404b..769c0d6291 100644 --- a/activemodel/CHANGELOG.md +++ b/activemodel/CHANGELOG.md @@ -1,26 +1,34 @@ * Validate multiple contexts on `valid?` and `invalid?` at once. Example: - + class Person include ActiveModel::Validations - + attr_reader :name, :title validates_presence_of :name, on: :create validates_presence_of :title, on: :update end - + person = Person.new person.valid?([:create, :update]) # => true person.errors.messages # => {:name=>["can't be blank"], :title=>["can't be blank"]} *Dmitry Polushkin* +* Add case_sensitive option for confirmation validator in models. + + *Akshat Sharma* + * Ensure `method_missing` is called for methods passed to `ActiveModel::Serialization#serializable_hash` that don't exist. *Jay Elaraj* +* Remove `ActiveModel::Serializers::Xml` from core. + + *Zachary Scott* + * Add `ActiveModel::Dirty#[attr_name]_previously_changed?` and `ActiveModel::Dirty#[attr_name]_previous_change` to improve access to recorded changes after the model has been saved. diff --git a/activemodel/README.rdoc b/activemodel/README.rdoc index d954467387..20414c1d61 100644 --- a/activemodel/README.rdoc +++ b/activemodel/README.rdoc @@ -155,7 +155,7 @@ behavior out of the box: * Making objects serializable <tt>ActiveModel::Serialization</tt> provides a standard interface for your object - to provide +to_json+ or +to_xml+ serialization. + to provide +to_json+ serialization. class SerialPerson include ActiveModel::Serialization @@ -177,13 +177,6 @@ behavior out of the box: s = SerialPerson.new s.to_json # => "{\"name\":null}" - class SerialPerson - include ActiveModel::Serializers::Xml - end - - s = SerialPerson.new - s.to_xml # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<serial-person... - {Learn more}[link:classes/ActiveModel/Serialization.html] * Internationalization (i18n) support diff --git a/activemodel/lib/active_model.rb b/activemodel/lib/active_model.rb index 8aa1b6f664..4e1b3f7495 100644 --- a/activemodel/lib/active_model.rb +++ b/activemodel/lib/active_model.rb @@ -58,7 +58,6 @@ module ActiveModel eager_autoload do autoload :JSON - autoload :Xml end end diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb index 286cd6c206..77e4ce3afe 100644 --- a/activemodel/lib/active_model/attribute_methods.rb +++ b/activemodel/lib/active_model/attribute_methods.rb @@ -342,7 +342,7 @@ module ActiveModel private # The methods +method_missing+ and +respond_to?+ of this module are # invoked often in a typical rails, both of which invoke the method - # +match_attribute_method?+. The latter method iterates through an + # +matched_attribute_method+. The latter method iterates through an # array doing regular expression matches, which results in a lot of # object creations. Most of the time it returns a +nil+ match. As the # match result is always the same given a +method_name+, this cache is @@ -372,7 +372,7 @@ module ActiveModel "define_method(:'#{name}') do |*args|" end - extra = (extra.map!(&:inspect) << "*args").join(", ") + extra = (extra.map!(&:inspect) << "*args").join(", ".freeze) target = if send =~ CALL_COMPILABLE_REGEXP "#{"self." unless include_private}#{send}(#{extra})" @@ -429,7 +429,7 @@ module ActiveModel if respond_to_without_attributes?(method, true) super else - match = match_attribute_method?(method.to_s) + match = matched_attribute_method(method.to_s) match ? attribute_missing(match, *args, &block) : super end end @@ -454,7 +454,7 @@ module ActiveModel # but found among all methods. Which means that the given method is private. false else - !match_attribute_method?(method.to_s).nil? + !matched_attribute_method(method.to_s).nil? end end @@ -466,7 +466,7 @@ module ActiveModel private # Returns a struct representing the matching attribute method. # The struct's attributes are prefix, base and suffix. - def match_attribute_method?(method_name) + def matched_attribute_method(method_name) matches = self.class.send(:attribute_method_matchers_matching, method_name) matches.detect { |match| attribute_method?(match.attr_name) } end diff --git a/activemodel/lib/active_model/naming.rb b/activemodel/lib/active_model/naming.rb index 1f1749af4e..213f2d5b6a 100644 --- a/activemodel/lib/active_model/naming.rb +++ b/activemodel/lib/active_model/naming.rb @@ -192,7 +192,7 @@ module ActiveModel private def _singularize(string) - ActiveSupport::Inflector.underscore(string).tr('/', '_') + ActiveSupport::Inflector.underscore(string).tr('/'.freeze, '_'.freeze) end end diff --git a/activemodel/lib/active_model/serialization.rb b/activemodel/lib/active_model/serialization.rb index f95849eb84..341651d00d 100644 --- a/activemodel/lib/active_model/serialization.rb +++ b/activemodel/lib/active_model/serialization.rb @@ -31,16 +31,14 @@ module ActiveModel # of the attributes hash's keys. In order to override this behavior, take a look # at the private method +read_attribute_for_serialization+. # - # Most of the time though, either the JSON or XML serializations are needed. - # Both of these modules automatically include the - # <tt>ActiveModel::Serialization</tt> module, so there is no need to - # explicitly include it. + # The JSON serialization is provided by default when you include the + # <tt>ActiveModel::Serialization</tt> module, so there is no need to explicitly + # include it. # - # A minimal implementation including XML and JSON would be: + # A minimal implementation including JSON would be: # # class Person # include ActiveModel::Serializers::JSON - # include ActiveModel::Serializers::Xml # # attr_accessor :name # @@ -55,13 +53,11 @@ module ActiveModel # person.serializable_hash # => {"name"=>nil} # person.as_json # => {"name"=>nil} # person.to_json # => "{\"name\":null}" - # person.to_xml # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<serial-person... # # person.name = "Bob" # person.serializable_hash # => {"name"=>"Bob"} # person.as_json # => {"name"=>"Bob"} # person.to_json # => "{\"name\":\"Bob\"}" - # person.to_xml # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<serial-person... # # Valid options are <tt>:only</tt>, <tt>:except</tt>, <tt>:methods</tt> and # <tt>:include</tt>. The following are all valid examples: diff --git a/activemodel/lib/active_model/serializers/xml.rb b/activemodel/lib/active_model/serializers/xml.rb deleted file mode 100644 index e33c766627..0000000000 --- a/activemodel/lib/active_model/serializers/xml.rb +++ /dev/null @@ -1,238 +0,0 @@ -require 'active_support/core_ext/module/attribute_accessors' -require 'active_support/core_ext/array/conversions' -require 'active_support/core_ext/hash/conversions' -require 'active_support/core_ext/hash/slice' -require 'active_support/core_ext/time/acts_like' - -module ActiveModel - module Serializers - # == \Active \Model XML Serializer - module Xml - extend ActiveSupport::Concern - include ActiveModel::Serialization - - included do - extend ActiveModel::Naming - end - - class Serializer #:nodoc: - class Attribute #:nodoc: - attr_reader :name, :value, :type - - def initialize(name, serializable, value) - @name, @serializable = name, serializable - - if value.acts_like?(:time) && value.respond_to?(:in_time_zone) - value = value.in_time_zone - end - - @value = value - @type = compute_type - end - - def decorations - decorations = {} - decorations[:encoding] = 'base64' if type == :binary - decorations[:type] = (type == :string) ? nil : type - decorations[:nil] = true if value.nil? - decorations - end - - protected - - def compute_type - return if value.nil? - type = ActiveSupport::XmlMini::TYPE_NAMES[value.class.name] - type ||= :string if value.respond_to?(:to_str) - type ||= :yaml - type - end - end - - class MethodAttribute < Attribute #:nodoc: - end - - attr_reader :options - - def initialize(serializable, options = nil) - @serializable = serializable - @options = options ? options.dup : {} - end - - def serializable_hash - @serializable.serializable_hash(@options.except(:include)) - end - - def serializable_collection - methods = Array(options[:methods]).map(&:to_s) - serializable_hash.map do |name, value| - name = name.to_s - if methods.include?(name) - self.class::MethodAttribute.new(name, @serializable, value) - else - self.class::Attribute.new(name, @serializable, value) - end - end - end - - def serialize - require 'builder' unless defined? ::Builder - - options[:indent] ||= 2 - options[:builder] ||= ::Builder::XmlMarkup.new(indent: options[:indent]) - - @builder = options[:builder] - @builder.instruct! unless options[:skip_instruct] - - root = (options[:root] || @serializable.model_name.element).to_s - root = ActiveSupport::XmlMini.rename_key(root, options) - - args = [root] - args << { xmlns: options[:namespace] } if options[:namespace] - args << { type: options[:type] } if options[:type] && !options[:skip_types] - - @builder.tag!(*args) do - add_attributes_and_methods - add_includes - add_extra_behavior - add_procs - yield @builder if block_given? - end - end - - private - - def add_extra_behavior - end - - def add_attributes_and_methods - serializable_collection.each do |attribute| - key = ActiveSupport::XmlMini.rename_key(attribute.name, options) - ActiveSupport::XmlMini.to_tag(key, attribute.value, - options.merge(attribute.decorations)) - end - end - - def add_includes - @serializable.send(:serializable_add_includes, options) do |association, records, opts| - add_associations(association, records, opts) - end - end - - # TODO: This can likely be cleaned up to simple use ActiveSupport::XmlMini.to_tag as well. - def add_associations(association, records, opts) - merged_options = opts.merge(options.slice(:builder, :indent)) - merged_options[:skip_instruct] = true - - [:skip_types, :dasherize, :camelize].each do |key| - merged_options[key] = options[key] if merged_options[key].nil? && !options[key].nil? - end - - if records.respond_to?(:to_ary) - records = records.to_ary - - tag = ActiveSupport::XmlMini.rename_key(association.to_s, options) - type = options[:skip_types] ? { } : { type: "array" } - association_name = association.to_s.singularize - merged_options[:root] = association_name - - if records.empty? - @builder.tag!(tag, type) - else - @builder.tag!(tag, type) do - records.each do |record| - if options[:skip_types] - record_type = {} - else - record_class = (record.class.to_s.underscore == association_name) ? nil : record.class.name - record_type = { type: record_class } - end - - record.to_xml merged_options.merge(record_type) - end - end - end - else - merged_options[:root] = association.to_s - - unless records.class.to_s.underscore == association.to_s - merged_options[:type] = records.class.name - end - - records.to_xml merged_options - end - end - - def add_procs - if procs = options.delete(:procs) - Array(procs).each do |proc| - if proc.arity == 1 - proc.call(options) - else - proc.call(options, @serializable) - end - end - end - end - end - - # Returns XML representing the model. Configuration can be - # passed through +options+. - # - # Without any +options+, the returned XML string will include all the - # model's attributes. - # - # user = User.find(1) - # user.to_xml - # - # <?xml version="1.0" encoding="UTF-8"?> - # <user> - # <id type="integer">1</id> - # <name>David</name> - # <age type="integer">16</age> - # <created-at type="dateTime">2011-01-30T22:29:23Z</created-at> - # </user> - # - # The <tt>:only</tt> and <tt>:except</tt> options can be used to limit the - # attributes included, and work similar to the +attributes+ method. - # - # To include the result of some method calls on the model use <tt>:methods</tt>. - # - # To include associations use <tt>:include</tt>. - # - # For further documentation, see <tt>ActiveRecord::Serialization#to_xml</tt> - def to_xml(options = {}, &block) - Serializer.new(self, options).serialize(&block) - end - - # Sets the model +attributes+ from an XML string. Returns +self+. - # - # class Person - # include ActiveModel::Serializers::Xml - # - # attr_accessor :name, :age, :awesome - # - # def attributes=(hash) - # hash.each do |key, value| - # instance_variable_set("@#{key}", value) - # end - # end - # - # def attributes - # instance_values - # end - # end - # - # xml = { name: 'bob', age: 22, awesome:true }.to_xml - # person = Person.new - # person.from_xml(xml) # => #<Person:0x007fec5e3b3c40 @age=22, @awesome=true, @name="bob"> - # person.name # => "bob" - # person.age # => 22 - # person.awesome # => true - def from_xml(xml) - self.attributes = Hash.from_xml(xml).values.first - self - end - end - end -end diff --git a/activemodel/lib/active_model/validations/confirmation.rb b/activemodel/lib/active_model/validations/confirmation.rb index 1b11c28087..bb2f0bd064 100644 --- a/activemodel/lib/active_model/validations/confirmation.rb +++ b/activemodel/lib/active_model/validations/confirmation.rb @@ -3,14 +3,16 @@ module ActiveModel module Validations class ConfirmationValidator < EachValidator # :nodoc: def initialize(options) - super + super({ case_sensitive: true }.merge!(options)) setup!(options[:class]) end def validate_each(record, attribute, value) - if (confirmed = record.send("#{attribute}_confirmation")) && (value != confirmed) - human_attribute_name = record.class.human_attribute_name(attribute) - record.errors.add(:"#{attribute}_confirmation", :confirmation, options.merge(attribute: human_attribute_name)) + if (confirmed = record.send("#{attribute}_confirmation")) + unless confimation_value_equal?(record, attribute, value, confirmed) + human_attribute_name = record.class.human_attribute_name(attribute) + record.errors.add(:"#{attribute}_confirmation", :confirmation, options.except(:case_sensitive).merge!(attribute: human_attribute_name)) + end end end @@ -24,6 +26,14 @@ module ActiveModel :"#{attribute}_confirmation" unless klass.method_defined?(:"#{attribute}_confirmation=") end.compact) end + + def confimation_value_equal?(record, attribute, value, confirmed) + if !options[:case_sensitive] && value.is_a?(String) + value.casecmp(confirmed) == 0 + else + value == confirmed + end + end end module HelperMethods @@ -55,6 +65,8 @@ module ActiveModel # Configuration options: # * <tt>:message</tt> - A custom error message (default is: "doesn't match # <tt>%{translated_attribute_name}</tt>"). + # * <tt>:case_sensitive</tt> - Looks for an exact match. Ignored by + # non-text columns (+true+ by default). # # There is also a list of default options supported by every validator: # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+. diff --git a/activemodel/lib/active_model/validations/validates.rb b/activemodel/lib/active_model/validations/validates.rb index bda436d8d0..1da4df21e7 100644 --- a/activemodel/lib/active_model/validations/validates.rb +++ b/activemodel/lib/active_model/validations/validates.rb @@ -115,7 +115,7 @@ module ActiveModel key = "#{key.to_s.camelize}Validator" begin - validator = key.include?('::') ? key.constantize : const_get(key) + validator = key.include?('::'.freeze) ? key.constantize : const_get(key) rescue NameError raise ArgumentError, "Unknown validator: '#{key}'" end diff --git a/activemodel/test/cases/helper.rb b/activemodel/test/cases/helper.rb index c100646837..27fdbc739c 100644 --- a/activemodel/test/cases/helper.rb +++ b/activemodel/test/cases/helper.rb @@ -1,6 +1,5 @@ require File.expand_path('../../../../load_paths', __FILE__) -require 'config' require 'active_model' require 'active_support/core_ext/string/access' @@ -13,8 +12,6 @@ I18n.enforce_available_locales = false require 'active_support/testing/autorun' require 'active_support/testing/method_call_assertions' -require 'minitest/mock' - # Skips the current run on Rubinius using Minitest::Assertions#skip def rubinius_skip(message = '') skip message if RUBY_ENGINE == 'rbx' diff --git a/activemodel/test/cases/serializers/xml_serialization_test.rb b/activemodel/test/cases/serializers/xml_serialization_test.rb deleted file mode 100644 index 37faf6cef8..0000000000 --- a/activemodel/test/cases/serializers/xml_serialization_test.rb +++ /dev/null @@ -1,251 +0,0 @@ -require 'cases/helper' -require 'models/contact' -require 'active_support/core_ext/object/instance_variables' -require 'ostruct' -require 'yaml' - -module Admin - class Contact < ::Contact - end -end - -class Customer < Struct.new(:name) -end - -class Address - include ActiveModel::Serializers::Xml - - attr_accessor :street, :city, :state, :zip, :apt_number - - def attributes - instance_values - end -end - -class SerializableContact < Contact - def serializable_hash(options={}) - super(options.merge(only: [:name, :age])) - end -end - -class XmlSerializationTest < ActiveModel::TestCase - def setup - @contact = Contact.new - @contact.name = 'aaron stack' - @contact.age = 25 - @contact.created_at = Time.utc(2006, 8, 1) - @contact.awesome = false - customer = Customer.new - customer.name = "John" - @contact.preferences = customer - @contact.address = Address.new - @contact.address.city = "Springfield" - @contact.address.apt_number = 35 - @contact.friends = [Contact.new, Contact.new] - @contact.contact = SerializableContact.new - end - - test "should serialize default root" do - xml = @contact.to_xml - assert_match %r{^<contact>}, xml - assert_match %r{</contact>$}, xml - end - - test "should serialize namespaced root" do - xml = Admin::Contact.new(@contact.attributes).to_xml - assert_match %r{^<contact>}, xml - assert_match %r{</contact>$}, xml - end - - test "should serialize default root with namespace" do - xml = @contact.to_xml namespace: "http://xml.rubyonrails.org/contact" - assert_match %r{^<contact xmlns="http://xml.rubyonrails.org/contact">}, xml - assert_match %r{</contact>$}, xml - end - - test "should serialize custom root" do - xml = @contact.to_xml root: 'xml_contact' - assert_match %r{^<xml-contact>}, xml - assert_match %r{</xml-contact>$}, xml - end - - test "should allow undasherized tags" do - xml = @contact.to_xml root: 'xml_contact', dasherize: false - assert_match %r{^<xml_contact>}, xml - assert_match %r{</xml_contact>$}, xml - assert_match %r{<created_at}, xml - end - - test "should allow camelized tags" do - xml = @contact.to_xml root: 'xml_contact', camelize: true - assert_match %r{^<XmlContact>}, xml - assert_match %r{</XmlContact>$}, xml - assert_match %r{<CreatedAt}, xml - end - - test "should allow lower-camelized tags" do - xml = @contact.to_xml root: 'xml_contact', camelize: :lower - assert_match %r{^<xmlContact>}, xml - assert_match %r{</xmlContact>$}, xml - assert_match %r{<createdAt}, xml - end - - test "should use serializable hash" do - @contact = SerializableContact.new - @contact.name = 'aaron stack' - @contact.age = 25 - - xml = @contact.to_xml - assert_match %r{<name>aaron stack</name>}, xml - assert_match %r{<age type="integer">25</age>}, xml - assert_no_match %r{<awesome>}, xml - end - - test "should allow skipped types" do - xml = @contact.to_xml skip_types: true - assert_match %r{<age>25</age>}, xml - end - - test "should include yielded additions" do - xml_output = @contact.to_xml do |xml| - xml.creator "David" - end - assert_match %r{<creator>David</creator>}, xml_output - end - - test "should serialize string" do - assert_match %r{<name>aaron stack</name>}, @contact.to_xml - end - - test "should serialize nil" do - assert_match %r{<pseudonyms nil="true"/>}, @contact.to_xml(methods: :pseudonyms) - end - - test "should serialize integer" do - assert_match %r{<age type="integer">25</age>}, @contact.to_xml - end - - test "should serialize datetime" do - assert_match %r{<created-at type="dateTime">2006-08-01T00:00:00Z</created-at>}, @contact.to_xml - end - - test "should serialize boolean" do - assert_match %r{<awesome type="boolean">false</awesome>}, @contact.to_xml - end - - test "should serialize array" do - assert_match %r{<social type="array">\s*<social>twitter</social>\s*<social>github</social>\s*</social>}, @contact.to_xml(methods: :social) - end - - test "should serialize hash" do - assert_match %r{<network>\s*<git type="symbol">github</git>\s*</network>}, @contact.to_xml(methods: :network) - end - - test "should serialize yaml" do - assert_match %r{<preferences type="yaml">--- !ruby/struct:Customer(\s*)\nname: John\n</preferences>}, @contact.to_xml - end - - test "should call proc on object" do - proc = Proc.new { |options| options[:builder].tag!('nationality', 'unknown') } - xml = @contact.to_xml(procs: [ proc ]) - assert_match %r{<nationality>unknown</nationality>}, xml - end - - test "should supply serializable to second proc argument" do - proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) } - xml = @contact.to_xml(procs: [ proc ]) - assert_match %r{<name-reverse>kcats noraa</name-reverse>}, xml - end - - test "should serialize string correctly when type passed" do - xml = @contact.to_xml type: 'Contact' - assert_match %r{<contact type="Contact">}, xml - assert_match %r{<name>aaron stack</name>}, xml - end - - test "include option with singular association" do - xml = @contact.to_xml include: :address, indent: 0 - assert xml.include?(@contact.address.to_xml(indent: 0, skip_instruct: true)) - end - - test "include option with plural association" do - xml = @contact.to_xml include: :friends, indent: 0 - assert_match %r{<friends type="array">}, xml - assert_match %r{<friend type="Contact">}, xml - end - - class FriendList - def initialize(friends) - @friends = friends - end - - def to_ary - @friends - end - end - - test "include option with ary" do - @contact.friends = FriendList.new(@contact.friends) - xml = @contact.to_xml include: :friends, indent: 0 - assert_match %r{<friends type="array">}, xml - assert_match %r{<friend type="Contact">}, xml - end - - test "multiple includes" do - xml = @contact.to_xml indent: 0, skip_instruct: true, include: [ :address, :friends ] - assert xml.include?(@contact.address.to_xml(indent: 0, skip_instruct: true)) - assert_match %r{<friends type="array">}, xml - assert_match %r{<friend type="Contact">}, xml - end - - test "include with options" do - xml = @contact.to_xml indent: 0, skip_instruct: true, include: { address: { only: :city } } - assert xml.include?(%(><address><city>Springfield</city></address>)) - end - - test "propagates skip_types option to included associations" do - xml = @contact.to_xml include: :friends, indent: 0, skip_types: true - assert_match %r{<friends>}, xml - assert_match %r{<friend>}, xml - end - - test "propagates skip-types option to included associations and attributes" do - xml = @contact.to_xml skip_types: true, include: :address, indent: 0 - assert_match %r{<address>}, xml - assert_match %r{<apt-number>}, xml - end - - test "propagates camelize option to included associations and attributes" do - xml = @contact.to_xml camelize: true, include: :address, indent: 0 - assert_match %r{<Address>}, xml - assert_match %r{<AptNumber type="integer">}, xml - end - - test "propagates dasherize option to included associations and attributes" do - xml = @contact.to_xml dasherize: false, include: :address, indent: 0 - assert_match %r{<apt_number type="integer">}, xml - end - - test "don't propagate skip_types if skip_types is defined at the included association level" do - xml = @contact.to_xml skip_types: true, include: { address: { skip_types: false } }, indent: 0 - assert_match %r{<address>}, xml - assert_match %r{<apt-number type="integer">}, xml - end - - test "don't propagate camelize if camelize is defined at the included association level" do - xml = @contact.to_xml camelize: true, include: { address: { camelize: false } }, indent: 0 - assert_match %r{<address>}, xml - assert_match %r{<apt-number type="integer">}, xml - end - - test "don't propagate dasherize if dasherize is defined at the included association level" do - xml = @contact.to_xml dasherize: false, include: { address: { dasherize: true } }, indent: 0 - assert_match %r{<address>}, xml - assert_match %r{<apt-number type="integer">}, xml - end - - test "association with sti" do - xml = @contact.to_xml(include: :contact) - assert xml.include?(%(<contact type="SerializableContact">)) - end -end diff --git a/activemodel/test/cases/validations/confirmation_validation_test.rb b/activemodel/test/cases/validations/confirmation_validation_test.rb index c1431548f7..c56bf1c0ad 100644 --- a/activemodel/test/cases/validations/confirmation_validation_test.rb +++ b/activemodel/test/cases/validations/confirmation_validation_test.rb @@ -104,4 +104,18 @@ class ConfirmationValidationTest < ActiveModel::TestCase assert_equal "expected title", model.title_confirmation, "confirmation validation should not override the writer" end + + def test_title_confirmation_with_case_sensitive_option_true + Topic.validates_confirmation_of(:title, case_sensitive: true) + + t = Topic.new(title: "title", title_confirmation: "Title") + assert t.invalid? + end + + def test_title_confirmation_with_case_sensitive_option_false + Topic.validates_confirmation_of(:title, case_sensitive: false) + + t = Topic.new(title: "title", title_confirmation: "Title") + assert t.valid? + end end diff --git a/activemodel/test/cases/validations/i18n_validation_test.rb b/activemodel/test/cases/validations/i18n_validation_test.rb index ce9a782f73..09d7226b5a 100644 --- a/activemodel/test/cases/validations/i18n_validation_test.rb +++ b/activemodel/test/cases/validations/i18n_validation_test.rb @@ -101,7 +101,7 @@ class I18nValidationTest < ActiveModel::TestCase Person.validates_length_of :title, validation_options.merge(within: 3..5) @person.title = 'this title is too long' call = [:title, :too_long, generate_message_options.merge(count: 5)] - assert_called_with(@person.errors, :generate_message, ) do + assert_called_with(@person.errors, :generate_message, call) do @person.valid? end end diff --git a/activemodel/test/config.rb b/activemodel/test/config.rb deleted file mode 100644 index 0b577a9936..0000000000 --- a/activemodel/test/config.rb +++ /dev/null @@ -1,3 +0,0 @@ -TEST_ROOT = File.expand_path(File.dirname(__FILE__)) -FIXTURES_ROOT = TEST_ROOT + "/fixtures" -SCHEMA_FILE = TEST_ROOT + "/schema.rb" diff --git a/activemodel/test/models/contact.rb b/activemodel/test/models/contact.rb index bcfd267a34..113ab0bc1f 100644 --- a/activemodel/test/models/contact.rb +++ b/activemodel/test/models/contact.rb @@ -4,7 +4,6 @@ class Contact include ActiveModel::Validations include ActiveModel::Serializers::JSON - include ActiveModel::Serializers::Xml attr_accessor :id, :name, :age, :created_at, :awesome, :preferences attr_accessor :address, :friends, :contact |