pax_global_header00006660000000000000000000000064131451061460014513gustar00rootroot0000000000000052 comment=356edf4dfc38fb1fbfee90c87856e4fe5b73c5e1 activemodel-serializers-xml-1.0.2/000077500000000000000000000000001314510614600171375ustar00rootroot00000000000000activemodel-serializers-xml-1.0.2/.gitignore000066400000000000000000000001271314510614600211270ustar00rootroot00000000000000/.bundle/ /.yardoc /Gemfile.lock /_yardoc/ /coverage/ /doc/ /pkg/ /spec/reports/ /tmp/ activemodel-serializers-xml-1.0.2/.travis.yml000066400000000000000000000002051314510614600212450ustar00rootroot00000000000000language: ruby sudo: false rvm: - 2.2.4 - 2.3.0 - ruby-head matrix: allow_failures: - rvm: ruby-head fast_finish: true activemodel-serializers-xml-1.0.2/CONTRIBUTING.md000066400000000000000000000056111314510614600213730ustar00rootroot00000000000000Contributing to ActiveModel::Serializers::Xml ===================== [![Build Status](https://api.travis-ci.org/rails/activemodel-serializers-xml.svg)](https://travis-ci.org/rails/activemodel-serializers-xml) ActiveModel::Serializers::Xml is work of [many contributors](https://github.com/rails/activemodel-serializers-xml/graphs/contributors). You're encouraged to submit [pull requests](https://github.com/rails/activemodel-serializers-xml/pulls), [propose features and discuss issues](https://github.com/rails/activemodel-serializers-xml/issues). #### Fork the Project Fork the [project on Github](https://github.com/rails/activemodel-serializers-xml) and check out your copy. ``` git clone https://github.com/contributor/activemodel-serializers-xml.git cd activemodel-serializers-xml git remote add upstream https://github.com/rails/activemodel-serializers-xml.git ``` #### Create a Topic Branch Make sure your fork is up-to-date and create a topic branch for your feature or bug fix. ``` git checkout master git pull upstream master git checkout -b my-feature-branch ``` #### Bundle Install and Test Ensure that you can build the project and run tests. ``` bundle install bundle exec rake test ``` #### Write Tests Try to write a test that reproduces the problem you're trying to fix or describes a feature that you want to build. Add to [test](test). We definitely appreciate pull requests that highlight or reproduce a problem, even without a fix. #### Write Code Implement your feature or bug fix. Make sure that `bundle exec rake test` completes without errors. #### Write Documentation Document any external behavior in the [README](README.md). #### Commit Changes Make sure git knows your name and email address: ``` git config --global user.name "Your Name" git config --global user.email "contributor@example.com" ``` Writing good commit logs is important. A commit log should describe what changed and why. ``` git add ... git commit ``` #### Push ``` git push origin my-feature-branch ``` #### Make a Pull Request Go to https://github.com/contributor/activemodel-serializers-xml and select your feature branch. Click the 'Pull Request' button and fill out the form. Pull requests are usually reviewed within a few days. #### Rebase If you've been working on a change for a while, rebase with upstream/master. ``` git fetch upstream git rebase upstream/master git push origin my-feature-branch -f ``` #### Check on Your Pull Request Go back to your pull request after a few minutes and see whether it passed muster with Travis-CI. Everything should look green, otherwise fix issues and amend your commit as described above. #### Be Patient It's likely that your change will not be merged and that the nitpicky maintainers will ask you to do more, or fix seemingly benign problems. Hang on there! #### Thank You Please do know that we really appreciate and value your time and work. We love you, really. activemodel-serializers-xml-1.0.2/Gemfile000066400000000000000000000001601314510614600204270ustar00rootroot00000000000000source 'https://rubygems.org' # Specify your gem's dependencies in activemodel-serializers-xml.gemspec gemspec activemodel-serializers-xml-1.0.2/MIT-LICENSE000066400000000000000000000020701314510614600205720ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2015 Zachary Scott 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. activemodel-serializers-xml-1.0.2/README.md000066400000000000000000000037171314510614600204260ustar00rootroot00000000000000# ActiveModel::Serializers::Xml This gem provides XML serialization for your Active Model objects and Active Record models. ## Installation Add this line to your application's Gemfile: ```ruby gem 'activemodel-serializers-xml' ``` And then execute: $ bundle Or install it yourself as: $ gem install activemodel-serializers-xml ## Usage ### ActiveModel::Serializers::Xml To use the `ActiveModel::Serializers::Xml` you only need to change from `ActiveModel::Serialization` to `ActiveModel::Serializers::Xml`. ```ruby class Person include ActiveModel::Serializers::Xml attr_accessor :name def attributes {'name' => nil} end end ``` With the `to_xml` you have an XML representing the model. ```ruby person = Person.new person.to_xml # => "\n\n \n\n" person.name = "Bob" person.to_xml # => "\n\n Bob\n\n" ``` From an XML string you define the attributes of the model. You need to have the `attributes=` method defined on your class: ```ruby class Person include ActiveModel::Serializers::Xml attr_accessor :name def attributes=(hash) hash.each do |key, value| send("#{key}=", value) end end def attributes {'name' => nil} end end ``` Now it is possible to create an instance of person and set the attributes using `from_xml`. ```ruby xml = { name: 'Bob' }.to_xml person = Person.new person.from_xml(xml) # => # person.name # => "Bob" ``` ### ActiveRecord::XmlSerializer This gem also provides serialization to XML for Active Record. Please see ActiveRecord::Serialization#to_xml for more information. ## Contributing to ActiveModel::Serializers::Xml ActiveModel::Serializers::Xml is work of many contributors. You're encouraged to submit pull requests, propose features and discuss issues. See [CONTRIBUTING](CONTRIBUTING.md) activemodel-serializers-xml-1.0.2/Rakefile000066400000000000000000000003001314510614600205750ustar00rootroot00000000000000require "bundler/gem_tasks" require "rake/testtask" Rake::TestTask.new do |t| t.libs << "test" t.test_files = FileList['test/**/*_test.rb'] t.verbose = true end task :default => :test activemodel-serializers-xml-1.0.2/activemodel-serializers-xml.gemspec000066400000000000000000000020321314510614600261250ustar00rootroot00000000000000# coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'active_model/serializers/version' Gem::Specification.new do |spec| spec.name = "activemodel-serializers-xml" spec.version = ActiveModel::Serializers::VERSION spec.authors = ["Rails team"] spec.email = ["security@rubyonrails.com"] spec.summary = "XML serialization for your Active Model objects and Active Record models - extracted from Rails" spec.homepage = "http://github.com/rails/activemodel-serializers-xml" spec.license = "MIT" spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } spec.require_paths = ["lib"] spec.add_dependency "activesupport", "> 5.x" spec.add_dependency "activemodel", "> 5.x" spec.add_dependency "builder", "~> 3.1" spec.add_development_dependency "rake", "~> 10.0" spec.add_development_dependency "activerecord", "> 5.x" spec.add_development_dependency "sqlite3" end activemodel-serializers-xml-1.0.2/lib/000077500000000000000000000000001314510614600177055ustar00rootroot00000000000000activemodel-serializers-xml-1.0.2/lib/active_model/000077500000000000000000000000001314510614600223405ustar00rootroot00000000000000activemodel-serializers-xml-1.0.2/lib/active_model/serializers.rb000066400000000000000000000007011314510614600252170ustar00rootroot00000000000000require 'active_support' require 'active_support/lazy_load_hooks' require 'active_model' require "active_model/serializers/version" ActiveSupport.on_load(:active_record) do require "active_record/serializers/xml_serializer" end module ActiveModel module Serializers extend ActiveSupport::Autoload eager_autoload do autoload :Xml end end def self.eager_load! super ActiveModel::Serializers.eager_load! end end activemodel-serializers-xml-1.0.2/lib/active_model/serializers/000077500000000000000000000000001314510614600246745ustar00rootroot00000000000000activemodel-serializers-xml-1.0.2/lib/active_model/serializers/version.rb000066400000000000000000000001101314510614600266760ustar00rootroot00000000000000module ActiveModel module Serializers VERSION = "1.0.2" end end activemodel-serializers-xml-1.0.2/lib/active_model/serializers/xml.rb000066400000000000000000000167001314510614600260250ustar00rootroot00000000000000require 'active_support/deprecation' 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 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 # # # # 1 # David # 16 # 2011-01-30T22:29:23Z # # # The :only and :except 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 :methods. # # To include associations use :include. # # For further documentation, see ActiveRecord::Serialization#to_xml 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.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 activemodel-serializers-xml-1.0.2/lib/active_record/000077500000000000000000000000001314510614600225165ustar00rootroot00000000000000activemodel-serializers-xml-1.0.2/lib/active_record/serializers/000077500000000000000000000000001314510614600250525ustar00rootroot00000000000000activemodel-serializers-xml-1.0.2/lib/active_record/serializers/xml_serializer.rb000066400000000000000000000160741314510614600304400ustar00rootroot00000000000000require 'active_support/core_ext/hash/conversions' require 'active_model/serializers/xml' module ActiveRecord #:nodoc: module Serialization include ActiveModel::Serializers::Xml # Builds an XML document to represent the model. Some configuration is # available through +options+. However more complicated cases should # override ActiveRecord::Base#to_xml. # # By default the generated XML document will include the processing # instruction and all the object's attributes. For example: # # # # The First Topic # David # 1 # false # 0 # 2000-01-01T08:28:00+12:00 # 2003-07-16T09:28:00+1200 # Have a nice day # david@loudthinking.com # # 2004-04-15 # # # This behavior can be controlled with :only, :except, # :skip_instruct, :skip_types, :dasherize and :camelize . # The :only and :except options are the same as for the # +attributes+ method. The default is to dasherize all column names, but you # can disable this setting :dasherize to +false+. Setting :camelize # to +true+ will camelize all column names - this also overrides :dasherize. # To not have the column type included in the XML output set :skip_types to +true+. # # For instance: # # topic.to_xml(skip_instruct: true, except: [ :id, :bonus_time, :written_on, :replies_count ]) # # # The First Topic # David # false # Have a nice day # david@loudthinking.com # # 2004-04-15 # # # To include first level associations use :include: # # firm.to_xml include: [ :account, :clients ] # # # # 1 # 1 # 37signals # # # 1 # Summit # # # 1 # Microsoft # # # # 1 # 50 # # # # Additionally, the record being serialized will be passed to a Proc's second # parameter. This allows for ad hoc additions to the resultant document that # incorporate the context of the record being serialized. And by leveraging the # closure created by a Proc, to_xml can be used to add elements that normally fall # outside of the scope of the model -- for example, generating and appending URLs # associated with models. # # proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) } # firm.to_xml procs: [ proc ] # # # # ... normal attributes as shown above ... # slangis73 # # # To include deeper levels of associations pass a hash like this: # # firm.to_xml include: {account: {}, clients: {include: :address}} # # # 1 # 1 # 37signals # # # 1 # Summit #
# ... #
#
# # 1 # Microsoft #
# ... #
#
#
# # 1 # 50 # #
# # To include any methods on the model being called use :methods: # # firm.to_xml methods: [ :calculated_earnings, :real_earnings ] # # # # ... normal attributes as shown above ... # 100000000000000000 # 5 # # # To call any additional Procs use :procs. The Procs are passed a # modified version of the options hash that was given to +to_xml+: # # proc = Proc.new { |options| options[:builder].tag!('abc', 'def') } # firm.to_xml procs: [ proc ] # # # # ... normal attributes as shown above ... # def # # # Alternatively, you can yield the builder object as part of the +to_xml+ call: # # firm.to_xml do |xml| # xml.creator do # xml.first_name "David" # xml.last_name "Heinemeier Hansson" # end # end # # # # ... normal attributes as shown above ... # # David # Heinemeier Hansson # # # # As noted above, you may override +to_xml+ in your ActiveRecord::Base # subclasses to have complete control about what's generated. The general # form of doing this is: # # class IHaveMyOwnXML < ActiveRecord::Base # def to_xml(options = {}) # require 'builder' # options[:indent] ||= 2 # xml = options[:builder] ||= ::Builder::XmlMarkup.new(indent: options[:indent]) # xml.instruct! unless options[:skip_instruct] # xml.level_one do # xml.tag!(:second_level, 'content') # end # end # end def to_xml(options = {}, &block) XmlSerializer.new(self, options).serialize(&block) end end class XmlSerializer < ActiveModel::Serializers::Xml::Serializer #:nodoc: class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute #:nodoc: def compute_type klass = @serializable.class cast_type = klass.type_for_attribute(name) type = ActiveSupport::XmlMini::TYPE_NAMES[value.class.name] || cast_type.type { :text => :string, :time => :datetime }[type] || type end protected :compute_type end end end activemodel-serializers-xml-1.0.2/lib/activemodel-serializers-xml.rb000066400000000000000000000000431314510614600256530ustar00rootroot00000000000000require 'active_model/serializers' activemodel-serializers-xml-1.0.2/test/000077500000000000000000000000001314510614600201165ustar00rootroot00000000000000activemodel-serializers-xml-1.0.2/test/active_model/000077500000000000000000000000001314510614600225515ustar00rootroot00000000000000activemodel-serializers-xml-1.0.2/test/active_model/xml_serialization_test.rb000066400000000000000000000200661314510614600276760ustar00rootroot00000000000000require '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 AMXmlSerializationTest < ActiveSupport::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{^}, xml assert_match %r{$}, xml end test "should serialize namespaced root" do xml = Admin::Contact.new(@contact.attributes).to_xml assert_match %r{^}, xml assert_match %r{$}, xml end test "should serialize default root with namespace" do xml = @contact.to_xml namespace: "http://xml.rubyonrails.org/contact" assert_match %r{^}, xml assert_match %r{$}, xml end test "should serialize custom root" do xml = @contact.to_xml root: 'xml_contact' assert_match %r{^}, xml assert_match %r{$}, xml end test "should allow undasherized tags" do xml = @contact.to_xml root: 'xml_contact', dasherize: false assert_match %r{^}, xml assert_match %r{$}, xml assert_match %r{}, xml assert_match %r{$}, xml assert_match %r{}, xml assert_match %r{$}, xml assert_match %r{aaron stack}, xml assert_match %r{25}, xml assert_no_match %r{}, xml end test "should allow skipped types" do xml = @contact.to_xml skip_types: true assert_match %r{25}, xml end test "should include yielded additions" do xml_output = @contact.to_xml do |xml| xml.creator "David" end assert_match %r{David}, xml_output end test "should serialize string" do assert_match %r{aaron stack}, @contact.to_xml end test "should serialize nil" do assert_match %r{}, @contact.to_xml(methods: :pseudonyms) end test "should serialize integer" do assert_match %r{25}, @contact.to_xml end test "should serialize datetime" do assert_match %r{2006-08-01T00:00:00Z}, @contact.to_xml end test "should serialize boolean" do assert_match %r{false}, @contact.to_xml end test "should serialize array" do assert_match %r{\s*twitter\s*github\s*}, @contact.to_xml(methods: :social) end test "should serialize hash" do assert_match %r{\s*github\s*}, @contact.to_xml(methods: :network) end test "should serialize yaml" do assert_match %r{--- !ruby/struct:Customer(\s*)\nname: John\n}, @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{unknown}, 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{kcats noraa}, xml end test "should serialize string correctly when type passed" do xml = @contact.to_xml type: 'Contact' assert_match %r{}, xml assert_match %r{aaron stack}, 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{}, xml assert_match %r{}, 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{}, xml assert_match %r{}, 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{}, xml assert_match %r{}, xml end test "include with options" do xml = @contact.to_xml indent: 0, skip_instruct: true, include: { address: { only: :city } } assert xml.include?(%(>
Springfield
)) end test "propagates skip_types option to included associations" do xml = @contact.to_xml include: :friends, indent: 0, skip_types: true assert_match %r{}, xml assert_match %r{}, 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{
}, xml assert_match %r{}, 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{
}, xml assert_match %r{}, 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{}, 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{
}, xml assert_match %r{}, 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{
}, xml assert_match %r{}, 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{
}, xml assert_match %r{}, xml end test "association with sti" do xml = @contact.to_xml(include: :contact) assert xml.include?(%()) end end activemodel-serializers-xml-1.0.2/test/active_record/000077500000000000000000000000001314510614600227275ustar00rootroot00000000000000activemodel-serializers-xml-1.0.2/test/active_record/xml_serialization_test.rb000066400000000000000000000401121314510614600300460ustar00rootroot00000000000000require "helper" require "rexml/document" require 'models/arcontact' require 'models/post' require 'models/author' require 'models/comment' require 'models/company_in_module' require 'models/toy' require 'models/topic' require 'models/reply' require 'models/company' class ARXmlSerializationTest < ActiveRecord::TestCase def test_should_serialize_default_root @xml = ARContact.new.to_xml assert_match %r{^}, @xml assert_match %r{$}, @xml end def test_should_serialize_default_root_with_namespace @xml = ARContact.new.to_xml :namespace=>"http://xml.rubyonrails.org/ar-contact" assert_match %r{^}, @xml assert_match %r{$}, @xml end def test_should_serialize_custom_root @xml = ARContact.new.to_xml :root => 'xml_contact' assert_match %r{^}, @xml assert_match %r{$}, @xml end def test_should_allow_undasherized_tags @xml = ARContact.new.to_xml :root => 'xml_contact', :dasherize => false assert_match %r{^}, @xml assert_match %r{$}, @xml assert_match %r{ 'xml_contact', :camelize => true assert_match %r{^}, @xml assert_match %r{$}, @xml assert_match %r{ 25).to_xml :skip_types => true assert %r{25}.match(@xml) end def test_should_include_yielded_additions @xml = ARContact.new.to_xml do |xml| xml.creator "David" end assert_match %r{David}, @xml end def test_to_xml_with_block value = "Rockin' the block" xml = ARContact.new.to_xml(:skip_instruct => true) do |_xml| _xml.tag! "arbitrary-element", value end assert_equal "", xml.first(12) assert xml.include?(%(#{value})) end def test_should_skip_instruct_for_included_records @contact = ARContact.new @contact.alternative = ARContact.new(:name => 'Copa Cabana') @xml = @contact.to_xml(:include => [ :alternative ]) assert_equal @xml.index(' 'aaron stack', :age => 25, :avatar => 'binarydata', :created_at => Time.utc(2006, 8, 1), :awesome => false, :preferences => { :gem => 'ruby' } ) end def test_should_serialize_string assert_match %r{aaron stack}, @contact.to_xml end def test_should_serialize_integer assert_match %r{25}, @contact.to_xml end def test_should_serialize_binary xml = @contact.to_xml assert_match %r{YmluYXJ5ZGF0YQ==\n}, xml assert_match %r{2006-08-01T00:00:00Z}, @contact.to_xml end def test_should_serialize_boolean assert_match %r{false}, @contact.to_xml end def test_should_serialize_hash assert_match %r{\s*ruby\s*}m, @contact.to_xml end def test_uses_serializable_hash_with_only_option def @contact.serializable_hash(options=nil) super(only: %w(name)) end xml = @contact.to_xml assert_match %r{aaron stack}, xml assert_no_match %r{age}, xml assert_no_match %r{awesome}, xml end def test_uses_serializable_hash_with_except_option def @contact.serializable_hash(options=nil) super(except: %w(age)) end xml = @contact.to_xml assert_match %r{aaron stack}, xml assert_match %r{false}, xml assert_no_match %r{age}, xml end def test_does_not_include_inheritance_column_from_sti @contact = ContactSti.new(@contact.attributes) assert_equal 'ContactSti', @contact.type xml = @contact.to_xml assert_match %r{aaron stack}, xml assert_no_match %r{aaron stack}, xml assert_no_match %r{age}, xml assert_no_match %r{ 'Mickey', :updated_at => Time.utc(2006, 8, 1)) assert_match %r{2006-07-31T17:00:00-07:00}, toy.to_xml end end def test_should_serialize_datetime_with_timezone_reloaded with_timezone_config zone: "Pacific Time (US & Canada)" do contact = ARContact.create(:name => 'Minnie', :updated_at => Time.utc(2006, 8, 1)).reload assert_match %r{2006-07-31T17:00:00-07:00}, contact.to_xml end end end class NilXmlSerializationTest < ActiveRecord::TestCase def setup @xml = ARContact.new.to_xml(:root => 'xml_contact') end def test_should_serialize_string assert_match %r{}, @xml end def test_should_serialize_integer assert %r{}.match(@xml) attributes = $1 assert_match %r{nil="true"}, attributes assert_match %r{type="integer"}, attributes end def test_should_serialize_binary assert %r{}.match(@xml) attributes = $1 assert_match %r{type="binary"}, attributes assert_match %r{encoding="base64"}, attributes assert_match %r{nil="true"}, attributes end def test_should_serialize_datetime assert %r{}.match(@xml) attributes = $1 assert_match %r{nil="true"}, attributes assert_match %r{type="dateTime"}, attributes end def test_should_serialize_boolean assert %r{}.match(@xml) attributes = $1 assert_match %r{type="boolean"}, attributes assert_match %r{nil="true"}, attributes end def test_should_serialize_yaml assert_match %r{}, @xml end end class DatabaseConnectedXmlSerializationTest < ActiveRecord::TestCase fixtures :topics, :companies, :accounts, :authors, :posts, :projects def test_to_xml xml = REXML::Document.new(topics(:first).to_xml(:indent => 0)) bonus_time_in_current_timezone = topics(:first).bonus_time.xmlschema written_on_in_current_timezone = topics(:first).written_on.xmlschema assert_equal "topic", xml.root.name assert_equal "The First Topic" , xml.elements["//title"].text assert_equal "David" , xml.elements["//author-name"].text assert_match "Have a nice day", xml.elements["//content"].text assert_equal "1", xml.elements["//id"].text assert_equal "integer" , xml.elements["//id"].attributes['type'] assert_equal "1", xml.elements["//replies-count"].text assert_equal "integer" , xml.elements["//replies-count"].attributes['type'] assert_equal written_on_in_current_timezone, xml.elements["//written-on"].text assert_equal "dateTime" , xml.elements["//written-on"].attributes['type'] assert_equal "david@loudthinking.com", xml.elements["//author-email-address"].text assert_equal nil, xml.elements["//parent-id"].text assert_equal "integer", xml.elements["//parent-id"].attributes['type'] assert_equal "true", xml.elements["//parent-id"].attributes['nil'] # Oracle enhanced adapter allows to define Date attributes in model class (see topic.rb) assert_equal "2004-04-15", xml.elements["//last-read"].text assert_equal "date" , xml.elements["//last-read"].attributes['type'] assert_equal "false", xml.elements["//approved"].text assert_equal "boolean" , xml.elements["//approved"].attributes['type'] assert_equal bonus_time_in_current_timezone, xml.elements["//bonus-time"].text assert_equal "dateTime" , xml.elements["//bonus-time"].attributes['type'] end def test_except_option xml = topics(:first).to_xml(:indent => 0, :skip_instruct => true, :except => [:title, :replies_count]) assert_equal "", xml.first(7) assert !xml.include?(%(The First Topic)) assert xml.include?(%(David)) xml = topics(:first).to_xml(:indent => 0, :skip_instruct => true, :except => [:title, :author_name, :replies_count]) assert !xml.include?(%(The First Topic)) assert !xml.include?(%(David)) end # to_xml used to mess with the hash the user provided which # caused the builder to be reused. This meant the document kept # getting appended to. def test_modules projects = MyApplication::Business::Project.all xml = projects.to_xml root = projects.first.class.to_s.underscore.pluralize.tr('/','_').dasherize assert_match "<#{root} type=\"array\">", xml assert_match "", xml end def test_passing_hash_shouldnt_reuse_builder options = {:include=>:posts} david = authors(:david) first_xml_size = david.to_xml(options).size second_xml_size = david.to_xml(options).size assert_equal first_xml_size, second_xml_size end def test_include_uses_association_name xml = authors(:david).to_xml :include=>:hello_posts, :indent => 0 assert_match %r{}, xml assert_match %r{}, xml assert_match %r{}, xml end def test_included_associations_should_skip_types xml = authors(:david).to_xml :include=>:hello_posts, :indent => 0, :skip_types => true assert_match %r{}, xml assert_match %r{}, xml assert_match %r{}, xml end def test_including_has_many_association xml = topics(:first).to_xml(:indent => 0, :skip_instruct => true, :include => :replies, :except => :replies_count) assert_equal "", xml.first(7) assert xml.include?(%()) assert xml.include?(%(The Second Topic of the day)) end def test_including_belongs_to_association xml = companies(:first_client).to_xml(:indent => 0, :skip_instruct => true, :include => :firm) assert !xml.include?("") xml = companies(:second_client).to_xml(:indent => 0, :skip_instruct => true, :include => :firm) assert xml.include?("") end def test_including_multiple_associations xml = companies(:first_firm).to_xml(:indent => 0, :skip_instruct => true, :include => [ :clients, :account ]) assert_equal "", xml.first(6) assert xml.include?(%()) assert xml.include?(%()) end def test_including_association_with_options xml = companies(:first_firm).to_xml( :indent => 0, :skip_instruct => true, :include => { :clients => { :only => :name } } ) assert_equal "", xml.first(6) assert xml.include?(%(Summit)) assert xml.include?(%()) end def test_methods_are_called_on_object xml = authors(:david).to_xml :methods => :label, :indent => 0 assert_match %r{}, xml end def test_should_not_call_methods_on_associations_that_dont_respond xml = authors(:david).to_xml :include=>:hello_posts, :methods => :label, :indent => 2 assert !authors(:david).hello_posts.first.respond_to?(:label) assert_match %r{^ }, xml assert_no_match %r{^