summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Bleything <ben@bleything.net>2006-09-11 03:40:56 +0000
committerBen Bleything <ben@bleything.net>2006-09-11 03:40:56 +0000
commitb51db1c0d1e477f458fd821a7e0fea8f9bc5063a (patch)
tree2813ccf132c8569bc39f5f1815a9a5283bf96c4d
parent406e11a004ec11ac39947d6aef2c5403fc1e1f09 (diff)
downloadplist-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.rb1
-rw-r--r--lib/plist/generator.rb62
-rw-r--r--test/test_generator.rb19
-rw-r--r--test/test_generator_data.rb33
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