diff options
author | Ben Bleything <ben@bleything.net> | 2006-09-11 03:40:56 +0000 |
---|---|---|
committer | Ben Bleything <ben@bleything.net> | 2006-09-11 03:40:56 +0000 |
commit | b51db1c0d1e477f458fd821a7e0fea8f9bc5063a (patch) | |
tree | 2813ccf132c8569bc39f5f1815a9a5283bf96c4d | |
parent | 406e11a004ec11ac39947d6aef2c5403fc1e1f09 (diff) | |
download | plist-b51db1c0d1e477f458fd821a7e0fea8f9bc5063a.tar.gz |
source:branches/generator-injection-removal/test/test_generator_data.rb
* new test file for <data> elements
source:branches/generator-injection-removal/test/test_generator.rb
* add test for custom element serialization (see below)
source:branches/generator-injection-removal/lib/plist/generator.rb
* add support for custom serialization in the form of #to_plist_node. If the object being dumped responds to #to_plist_node, whatever that method returns will be injected into the output stream instead of going through the normal dispatch.
* add Plist::Emit.comment, a helper method for emitting comments
* if we don't recognize the object, emit a comment and Marshal.dump the object, base64-encoding the resultant dump
source:branches/generator-injection-removal/lib/plist.rb
* require base64
-rw-r--r-- | lib/plist.rb | 1 | ||||
-rw-r--r-- | lib/plist/generator.rb | 62 | ||||
-rw-r--r-- | test/test_generator.rb | 19 | ||||
-rw-r--r-- | test/test_generator_data.rb | 33 |
4 files changed, 89 insertions, 26 deletions
diff --git a/lib/plist.rb b/lib/plist.rb index ecada01..3a74097 100644 --- a/lib/plist.rb +++ b/lib/plist.rb @@ -10,6 +10,7 @@ # # This is the main file for plist. Everything interesting happens in Plist and Plist::Emit. +require 'base64' require 'cgi' require 'stringio' diff --git a/lib/plist/generator.rb b/lib/plist/generator.rb index 06c2a5e..f5f1c00 100644 --- a/lib/plist/generator.rb +++ b/lib/plist/generator.rb @@ -67,36 +67,46 @@ module Plist private def self.plist_node(element) output = '' - case element - when Array - output << tag('array') { - element.collect {|e| plist_node(e)}.join - } - when Hash - inner_tags = [] - - element.each do |k,v| - inner_tags << tag('key', CGI::escapeHTML(k.to_s)) - inner_tags << plist_node(v) - end - - output << tag('dict') { - inner_tags.join - } - when true, false - output << "<#{element}/>" - when Time - output << tag('date', element.utc.strftime('%Y-%m-%dT%H:%M:%SZ')) - when Date # also catches DateTime - output << tag('date', element.strftime('%Y-%m-%dT%H:%M:%SZ')) - when String, Symbol, Fixnum, Bignum, Integer, Float - output << tag(element_type(element), CGI::escapeHTML(element.to_s)) + + if element.respond_to? :to_plist_node + output << element.to_plist_node else - output << tag('data', Marshal.dump(element)) + case element + when Array + output << tag('array') { + element.collect {|e| plist_node(e)}.join + } + when Hash + inner_tags = [] + + element.each do |k,v| + inner_tags << tag('key', CGI::escapeHTML(k.to_s)) + inner_tags << plist_node(v) + end + + output << tag('dict') { + inner_tags.join + } + when true, false + output << "<#{element}/>" + when Time + output << tag('date', element.utc.strftime('%Y-%m-%dT%H:%M:%SZ')) + when Date # also catches DateTime + output << tag('date', element.strftime('%Y-%m-%dT%H:%M:%SZ')) + when String, Symbol, Fixnum, Bignum, Integer, Float + output << tag(element_type(element), CGI::escapeHTML(element.to_s)) + else + output << comment( 'The <data> element below contains a Ruby object which has been serialized with Marshal.dump.' ) + output << tag('data', Base64.encode64(Marshal.dump(element))) + end end return output end + + def self.comment(content) + return "<!-- #{content} -->" + end def self.tag(type, contents = '', &block) contents << block.call if block_given? @@ -139,4 +149,4 @@ end class Hash include Plist::Emit -end +end
\ No newline at end of file diff --git a/test/test_generator.rb b/test/test_generator.rb index 5869eff..3413336 100644 --- a/test/test_generator.rb +++ b/test/test_generator.rb @@ -8,6 +8,18 @@ require 'test/unit' require 'plist' +class SerializableObject + attr_accessor :foo + + def initialize(str) + @foo = str + end + + def to_plist_node + return "<string>#{CGI::escapeHTML @foo}</string>" + end +end + class TestGenerator < Test::Unit::TestCase def test_to_plist_vs_plist_emit_dump_no_envelope source = [1, :b, true] @@ -26,4 +38,11 @@ class TestGenerator < Test::Unit::TestCase assert_equal to_plist, plist_emit_dump end + + def test_dumping_serializable_object + str = 'this object implements #to_plist_node' + so = SerializableObject.new(str) + + assert_equal "<string>#{str}</string>", Plist::Emit.dump(so, false) + end end
\ No newline at end of file diff --git a/test/test_generator_data.rb b/test/test_generator_data.rb new file mode 100644 index 0000000..133ed7c --- /dev/null +++ b/test/test_generator_data.rb @@ -0,0 +1,33 @@ +############################################################## +# Copyright 2006, Ben Bleything <ben@bleything.net> and # +# Patrick May <patrick@hexane.org> # +# # +# Distributed under the MIT license. # +############################################################## + +require 'test/unit' +require 'plist' + +class MarshableObject + attr_accessor :foo + + def initialize(str) + @foo = str + end +end + +class TestGeneratorData < Test::Unit::TestCase + def test_marshaling_object + mo = MarshableObject.new('this object was marshaled') + + expected = <<-END +<!-- The <data> element below contains a Ruby object which has been serialized with Marshal.dump. --><data>BAhvOhRNYXJzaGFibGVPYmplY3QGOglAZm9vIh50aGlzIG9iamVjdCB3YXMg +bWFyc2hhbGVk +</data> +END + + # must #chomp because heredocs won't let you not have a trailing newline. + # this won't be a problem once nice indent code goes into this branch. + assert_equal expected.chomp, Plist::Emit.dump(mo, false) + end +end
\ No newline at end of file |