Ticket #10162: to_xml_more_specific_procs.diff
| File to_xml_more_specific_procs.diff, 7.7 kB (added by chuyeow, 8 months ago) |
|---|
-
activerecord/test/xml_serialization_test.rb
old new 11 11 assert_match %r{^<contact>}, @xml 12 12 assert_match %r{</contact>$}, @xml 13 13 end 14 14 15 15 def test_should_serialize_default_root_with_namespace 16 16 @xml = Contact.new.to_xml :namespace=>"http://xml.rubyonrails.org/contact" 17 17 assert_match %r{^<contact xmlns="http://xml.rubyonrails.org/contact">}, @xml 18 18 assert_match %r{</contact>$}, @xml 19 19 end 20 20 21 21 def test_should_serialize_custom_root 22 22 @xml = Contact.new.to_xml :root => 'xml_contact' 23 23 assert_match %r{^<xml-contact>}, @xml 24 24 assert_match %r{</xml-contact>$}, @xml 25 25 end 26 26 27 27 def test_should_allow_undasherized_tags 28 28 @xml = Contact.new.to_xml :root => 'xml_contact', :dasherize => false 29 29 assert_match %r{^<xml_contact>}, @xml … … 48 48 def test_should_serialize_string 49 49 assert_match %r{<name>aaron stack</name>}, @xml 50 50 end 51 51 52 52 def test_should_serialize_integer 53 53 assert_match %r{<age type="integer">25</age>}, @xml 54 54 end 55 55 56 56 def test_should_serialize_binary 57 57 assert_match %r{YmluYXJ5ZGF0YQ==\n</avatar>}, @xml 58 58 assert_match %r{<avatar(.*)(type="binary")}, @xml 59 59 assert_match %r{<avatar(.*)(encoding="base64")}, @xml 60 60 end 61 61 62 62 def test_should_serialize_datetime 63 63 assert_match %r{<created-at type=\"datetime\">2006-08-01T00:00:00Z</created-at>}, @xml 64 64 end 65 65 66 66 def test_should_serialize_boolean 67 67 assert_match %r{<awesome type=\"boolean\">false</awesome>}, @xml 68 68 end 69 69 70 70 def test_should_serialize_yaml 71 71 assert_match %r{<preferences type=\"yaml\">--- \n:gem: ruby\n</preferences>}, @xml 72 72 end … … 80 80 def test_should_serialize_string 81 81 assert_match %r{<name nil="true"></name>}, @xml 82 82 end 83 83 84 84 def test_should_serialize_integer 85 85 assert %r{<age (.*)></age>}.match(@xml) 86 86 attributes = $1 87 87 assert_match %r{nil="true"}, attributes 88 88 assert_match %r{type="integer"}, attributes 89 89 end 90 90 91 91 def test_should_serialize_binary 92 92 assert %r{<avatar (.*)></avatar>}.match(@xml) 93 93 attributes = $1 … … 95 95 assert_match %r{encoding="base64"}, attributes 96 96 assert_match %r{nil="true"}, attributes 97 97 end 98 98 99 99 def test_should_serialize_datetime 100 100 assert %r{<created-at (.*)></created-at>}.match(@xml) 101 101 attributes = $1 102 102 assert_match %r{nil="true"}, attributes 103 103 assert_match %r{type="datetime"}, attributes 104 104 end 105 105 106 106 def test_should_serialize_boolean 107 107 assert %r{<awesome (.*)></awesome>}.match(@xml) 108 108 attributes = $1 109 109 assert_match %r{type="boolean"}, attributes 110 110 assert_match %r{nil="true"}, attributes 111 111 end 112 112 113 113 def test_should_serialize_yaml 114 114 assert %r{<preferences(.*)></preferences>}.match(@xml) 115 115 attributes = $1 … … 137 137 assert_match %r{<hello-post type="Post">}, xml 138 138 assert_match %r{<hello-post type="StiPost">}, xml 139 139 end 140 140 141 141 def test_methods_are_called_on_object 142 142 xml = authors(:david).to_xml :methods => :label, :indent => 0 143 143 assert_match %r{<label>.*</label>}, xml 144 144 end 145 145 146 146 def test_should_not_call_methods_on_associations_that_dont_respond 147 147 xml = authors(:david).to_xml :include=>:hello_posts, :methods => :label, :indent => 2 148 148 assert !authors(:david).hello_posts.first.respond_to?(:label) 149 149 assert_match %r{^ <label>.*</label>}, xml 150 150 assert_no_match %r{^ <label>}, xml 151 151 end 152 152 153 def test_procs_are_called_on_object 154 proc = Proc.new { |options| options[:builder].tag!('nationality', 'Danish') } 155 xml = authors(:david).to_xml(:procs => [ proc ]) 156 assert_match %r{<nationality>Danish</nationality>}, xml 157 end 158 159 def test_top_level_procs_arent_applied_to_associations 160 author_proc = Proc.new { |options| options[:builder].tag!('nationality', 'Danish') } 161 xml = authors(:david).to_xml(:procs => [ author_proc ], :include => :posts, :indent => 2) 162 163 assert_match %r{^ <nationality>Danish</nationality>}, xml 164 assert_no_match %r{^ {6}<nationality>Danish</nationality>}, xml 165 end 166 167 def test_procs_on_included_associations_are_called 168 posts_proc = Proc.new { |options| options[:builder].tag!('copyright', 'DHH') } 169 xml = authors(:david).to_xml( 170 :indent => 2, 171 :include => { 172 :posts => { :procs => [ posts_proc ] } 173 } 174 ) 175 176 assert_no_match %r{^ <copyright>DHH</copyright>}, xml 177 assert_match %r{^ {6}<copyright>DHH</copyright>}, xml 178 end 179 153 180 def test_should_include_empty_has_many_as_empty_array 154 authors(:david).posts.delete_all 181 authors(:david).posts.delete_all 155 182 xml = authors(:david).to_xml :include=>:posts, :indent => 2 156 183 157 184 assert_equal [], Hash.from_xml(xml)['author']['posts'] 158 185 assert_match %r{^ <posts type="array"/>}, xml 159 186 end 160 187 161 188 def test_should_has_many_array_elements_should_include_type_when_different_from_guessed_value 162 189 xml = authors(:david).to_xml :include=>:posts_with_comments, :indent => 2 163 190 164 191 assert Hash.from_xml(xml) 165 192 assert_match %r{^ <posts-with-comments type="array">}, xml 166 193 assert_match %r{^ <posts-with-comment type="Post">}, xml … … 171 198 assert types.include?('Post') 172 199 assert types.include?('StiPost') 173 200 end 174 201 175 202 end -
activerecord/lib/active_record/serializers/xml_serializer.rb
old new 1 1 module ActiveRecord #:nodoc: 2 2 module Serialization 3 3 # Builds an XML document to represent the model. Some configuration is 4 # available through +options+, however more complicated cases should 4 # available through +options+, however more complicated cases should 5 5 # override ActiveRecord's to_xml. 6 6 # 7 # By default the generated XML document will include the processing 7 # By default the generated XML document will include the processing 8 8 # instruction and all object's attributes. For example: 9 # 9 # 10 10 # <?xml version="1.0" encoding="UTF-8"?> 11 11 # <topic> 12 12 # <title>The First Topic</title> … … 42 42 # <parent-id></parent-id> 43 43 # <last-read type="date">2004-04-15</last-read> 44 44 # </topic> 45 # 45 # 46 46 # To include first level associations use :include 47 47 # 48 48 # firm.to_xml :include => [ :account, :clients ] … … 189 189 190 190 def add_tag(attribute) 191 191 builder.tag!( 192 dasherize? ? attribute.name.dasherize : attribute.name, 193 attribute.value.to_s, 192 dasherize? ? attribute.name.dasherize : attribute.name, 193 attribute.value.to_s, 194 194 attribute.decorations(!options[:skip_types]) 195 195 ) 196 196 end … … 204 204 else 205 205 builder.tag!(tag, :type => :array) do 206 206 association_name = association.to_s.singularize 207 records.each do |record| 207 records.each do |record| 208 208 record.to_xml opts.merge( 209 :root => association_name, 209 :root => association_name, 210 210 :type => (record.class.to_s.underscore == association_name ? nil : record.class.name) 211 211 ) 212 212 end … … 231 231 232 232 builder.tag!(*args) do 233 233 add_attributes 234 procs = options.delete(:procs) 234 235 add_includes { |association, records, opts| add_associations(association, records, opts) } 236 options[:procs] = procs 235 237 add_procs 236 238 yield builder if block_given? 237 239 end