sj-plist 3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +21 -0
- data/README +40 -0
- data/Rakefile +135 -0
- data/docs/USAGE +104 -0
- data/lib/plist.rb +22 -0
- data/lib/plist/ascii.rb +251 -0
- data/lib/plist/binary.rb +510 -0
- data/lib/plist/generator.rb +240 -0
- data/lib/plist/parser.rb +224 -0
- data/test/assets/AlbumData.xml +203 -0
- data/test/assets/Cookies.plist +104 -0
- data/test/assets/commented.plist +9 -0
- data/test/assets/example_data.bin +0 -0
- data/test/assets/example_data.jpg +0 -0
- data/test/assets/example_data.plist +259 -0
- data/test/assets/example_data_ascii.plist +51 -0
- data/test/assets/ruby.plist +1696 -0
- data/test/assets/test_data_elements.plist +24 -0
- data/test/assets/test_empty_key.plist +13 -0
- data/test/test_ascii.rb +143 -0
- data/test/test_binary.rb +116 -0
- data/test/test_data_elements.rb +115 -0
- data/test/test_generator.rb +59 -0
- data/test/test_generator_basic_types.rb +58 -0
- data/test/test_generator_collections.rb +82 -0
- data/test/test_parser.rb +100 -0
- metadata +80 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
3
|
+
<plist version="1.0">
|
4
|
+
<dict>
|
5
|
+
<key>stringio</key>
|
6
|
+
<data>dGhpcyBpcyBhIHN0cmluZ2lvIG9iamVjdA==
|
7
|
+
</data>
|
8
|
+
<key>file</key>
|
9
|
+
<data>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
10
|
+
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
11
|
+
AAAAAAAAAAAAAA==
|
12
|
+
</data>
|
13
|
+
<key>io</key>
|
14
|
+
<data>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
15
|
+
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
16
|
+
AAAAAAAAAAAAAA==
|
17
|
+
</data>
|
18
|
+
<key>marshal</key>
|
19
|
+
<!-- The <data> element below contains a Ruby object which has been serialized with Marshal.dump. -->
|
20
|
+
<data>BAhvOhZNYXJzaGFsYWJsZU9iamVjdAY6CUBmb28iHnRoaXMgb2JqZWN0IHdh
|
21
|
+
cyBtYXJzaGFsZWQ=
|
22
|
+
</data>
|
23
|
+
</dict>
|
24
|
+
</plist>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
3
|
+
<plist version="1.0">
|
4
|
+
<dict>
|
5
|
+
<key>key</key>
|
6
|
+
<dict>
|
7
|
+
<key></key>
|
8
|
+
<string>1</string>
|
9
|
+
<key>subkey</key>
|
10
|
+
<string>2</string>
|
11
|
+
</dict>
|
12
|
+
</dict>
|
13
|
+
</plist>
|
data/test/test_ascii.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "test/unit"
|
4
|
+
require "date"
|
5
|
+
require "plist/ascii"
|
6
|
+
|
7
|
+
class TestAscii < Test::Unit::TestCase
|
8
|
+
def test_should_parse_a_simple_dictionary
|
9
|
+
assert_equal({'a' => 'b'}, parse("{ a = b; }"))
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_should_parse_a_simple_array
|
13
|
+
assert_equal(%w[1 2 3], parse("(1, 2, 3)"))
|
14
|
+
assert_equal(%w[foo], parse("(foo, )"))
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_should_assume_dictionary_keys_are_strings_when_they_start_with_a_number
|
18
|
+
assert_equal({ '1' => 'foo' }, parse("{ 1 = foo; }"))
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_should_correctly_parse_escaped_unicode_points
|
22
|
+
assert_equal({'foo' => "æ"}, parse('{ foo = "\u00e6"; }'))
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_should_always_return_string_keys
|
26
|
+
assert_equal({'1234' => 'boo'}, parse_with_numbers('{ 1234 = boo; }'))
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_should_correctly_parse_control_chars
|
30
|
+
assert_equal({'foo' => "\a\v\r\t\n\b\f"}, parse('{ foo = "\a\v\r\t\n\b\f"; }'))
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_should_correctly_parse_octal_escapes
|
34
|
+
expected = "\303\246"
|
35
|
+
expected.force_encoding("BINARY") if expected.respond_to?(:force_encoding)
|
36
|
+
assert_equal({'foo' => expected}, parse('{ foo = "\303\246"; }'))
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_should_correctly_parse_escaped_strings
|
40
|
+
assert_equal({'foo' => '"hello world"'}, parse('{ foo = "\"hello world\""; }'))
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_should_correctly_parse_NSDate_strings
|
44
|
+
assert_equal({'time' => DateTime.parse("2008-11-22 14:17:04 +0100")}, parse('{ time = 2008-11-22 14:17:04 +0100;}'))
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_should_parse_floats
|
48
|
+
assert_equal({ 'hello' => 1.2 }, parse_with_numbers("{ hello = 1.2; }"))
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_should_parse_ints
|
52
|
+
assert_equal([1,2,3], parse_with_numbers("(1, 2, 3)"))
|
53
|
+
assert_equal({ 'hello' => "12abc" }, parse_with_numbers('{ hello = 12abc; }'))
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_should_parse_booleans
|
57
|
+
assert_equal({'foo' => true}, parse_with_bools("{foo = true;}"))
|
58
|
+
assert_equal({'foo' => "1"}, parse("{foo = true;}"))
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_should_parse_data
|
62
|
+
assert_equal({'data' => "foo\n"}, parse("{data = <666f6f0a>;}"))
|
63
|
+
assert_equal(asset("example_data.jpg"), parse(asset("example_data_ascii.plist"))['image'])
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# errors
|
68
|
+
#
|
69
|
+
|
70
|
+
def test_should_raise_error_if_given_a_non_string_key
|
71
|
+
assert_raises Plist::AsciiParser::ParseError do
|
72
|
+
parse_with_numbers "{ 1.2 = foo; }"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_should_raise_error_on_missing_semicolons
|
77
|
+
assert_raises Plist::AsciiParser::ParseError do
|
78
|
+
parse "{ foo = bar }"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_should_raise_error_on_missing_closing_parenthesis
|
83
|
+
assert_raises Plist::AsciiParser::ParseError do
|
84
|
+
parse "( foo, bar "
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_should_raise_error_on_missing_end_quote
|
89
|
+
assert_raises Plist::AsciiParser::ParseError do
|
90
|
+
parse '{ foo = "bar; }'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_wshould_raise_error_on_empty_string
|
95
|
+
assert_raises Plist::AsciiParser::ParseError do
|
96
|
+
parse ''
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
101
|
+
# other
|
102
|
+
#
|
103
|
+
|
104
|
+
def test_should_parse_textmate_ruby_grammar_without_errors
|
105
|
+
assert_nothing_raised do
|
106
|
+
parse asset("ruby.plist")
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_should_handle_a_stringio_as_input
|
111
|
+
io = StringIO.new("(a,b,c)")
|
112
|
+
assert_equal(%w[a b c], parse(io))
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_should_handle_an_io_as_input
|
116
|
+
File.open(path = "test.txt", "w") { |file| file << "{baz=(1,2,3);}" }
|
117
|
+
io = File.open(path, "r")
|
118
|
+
assert_equal({'baz' => [1,2,3] }, parse_with_numbers(io))
|
119
|
+
ensure
|
120
|
+
io.close
|
121
|
+
File.delete(io.path)
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
# helpers
|
126
|
+
#
|
127
|
+
|
128
|
+
def parse(str)
|
129
|
+
Plist.parse_ascii(str)
|
130
|
+
end
|
131
|
+
|
132
|
+
def parse_with_numbers(str)
|
133
|
+
Plist.parse_ascii(str, :parse_numbers => true)
|
134
|
+
end
|
135
|
+
|
136
|
+
def parse_with_bools(str)
|
137
|
+
Plist.parse_ascii(str, :parse_booleans => true)
|
138
|
+
end
|
139
|
+
|
140
|
+
def asset(filename)
|
141
|
+
File.read("#{File.dirname(__FILE__)}/assets/#{filename}")
|
142
|
+
end
|
143
|
+
end
|
data/test/test_binary.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
require "test/unit"
|
3
|
+
require "plist"
|
4
|
+
|
5
|
+
class TestBinary < Test::Unit::TestCase
|
6
|
+
def test_binary_min_byte_size
|
7
|
+
# 1-, 2-, and 4-byte integers are unsigned.
|
8
|
+
assert_equal(1, Plist::Binary.send(:min_byte_size, 0))
|
9
|
+
assert_equal(1, Plist::Binary.send(:min_byte_size, 0xff))
|
10
|
+
assert_equal(2, Plist::Binary.send(:min_byte_size, 0x100))
|
11
|
+
assert_equal(2, Plist::Binary.send(:min_byte_size, 0xffff))
|
12
|
+
assert_equal(4, Plist::Binary.send(:min_byte_size, 0x10000))
|
13
|
+
assert_equal(4, Plist::Binary.send(:min_byte_size, 0xffffffff))
|
14
|
+
# 8- and 16-byte integers are signed.
|
15
|
+
assert_equal(8, Plist::Binary.send(:min_byte_size, 0x100000000))
|
16
|
+
assert_equal(8, Plist::Binary.send(:min_byte_size, 0x7fffffffffffffff))
|
17
|
+
assert_equal(16, Plist::Binary.send(:min_byte_size, 0x8000000000000000))
|
18
|
+
assert_equal(16, Plist::Binary.send(:min_byte_size, 0x7fffffffffffffffffffffffffffffff))
|
19
|
+
assert_raises(RangeError) { Plist::Binary.send(:min_byte_size, 0x80000000000000000000000000000000) }
|
20
|
+
assert_equal(8, Plist::Binary.send(:min_byte_size, -1))
|
21
|
+
assert_equal(8, Plist::Binary.send(:min_byte_size, -0x8000000000000000))
|
22
|
+
assert_equal(16, Plist::Binary.send(:min_byte_size, -0x8000000000000001))
|
23
|
+
assert_equal(16, Plist::Binary.send(:min_byte_size, -0x80000000000000000000000000000000))
|
24
|
+
assert_raises(RangeError) { Plist::Binary.send(:min_byte_size, -0x80000000000000000000000000000001) }
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_binary_pack_int
|
28
|
+
assert_equal("\x0", Plist::Binary.send(:pack_int, 0, 1))
|
29
|
+
assert_equal("\x0\x34", Plist::Binary.send(:pack_int, 0x34, 2))
|
30
|
+
assert_equal("\x0\xde\xdb\xef", Plist::Binary.send(:pack_int, 0xdedbef, 4))
|
31
|
+
assert_equal("\x0\xca\xfe\x0\x0\xde\xdb\xef", Plist::Binary.send(:pack_int, 0xcafe0000dedbef, 8))
|
32
|
+
assert_equal("\x0\x7f\xf7\x0\x0\x12\x34\x0\x0\xca\xfe\x0\x0\xde\xdb\xef", Plist::Binary.send(:pack_int, 0x7ff7000012340000cafe0000dedbef, 16))
|
33
|
+
assert_raises(ArgumentError) { Plist::Binary.send(:pack_int, -1, 1) }
|
34
|
+
assert_raises(ArgumentError) { Plist::Binary.send(:pack_int, -1, 2) }
|
35
|
+
assert_raises(ArgumentError) { Plist::Binary.send(:pack_int, -1, 4) }
|
36
|
+
assert_equal("\xff\xff\xff\xff\xff\xff\xff\xff", Plist::Binary.send(:pack_int, -1, 8))
|
37
|
+
assert_equal("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", Plist::Binary.send(:pack_int, -1, 16))
|
38
|
+
[-2,0,3,5,6,7,9,10,11,12,13,14,15,17,18,19,20,32].each do |i|
|
39
|
+
assert_raises(ArgumentError) { Plist::Binary.send(:pack_int, 0, i) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_binary_plist_data
|
44
|
+
assert_equal("\x4ahelloworld",
|
45
|
+
Plist::Binary.send(:binary_plist_data, "helloworld"))
|
46
|
+
data = "x" * 32000
|
47
|
+
assert_equal("\x4f\x11\x7d\x00#{data}",
|
48
|
+
Plist::Binary.send(:binary_plist_data, data))
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_flatten_collection
|
52
|
+
assert_equal([[1, 2, 3], :a, :b, :c],
|
53
|
+
Plist::Binary.send(:flatten_collection, [:a, :b, :c]))
|
54
|
+
assert_equal([[1, 2, 3, 4], :a, :b, :c, [1, 1]],
|
55
|
+
Plist::Binary.send(:flatten_collection, [:a, :b, :c, [:a, :a]]))
|
56
|
+
assert_equal(["booger"],
|
57
|
+
Plist::Binary.send(:flatten_collection, "booger"))
|
58
|
+
assert_equal([[1, 2], "hello", { 3 => 4 }, "key", [5, 6, 7], 1, 2, 3],
|
59
|
+
Plist::Binary.send(:flatten_collection, ["hello", { :key => [1, 2, 3] }]))
|
60
|
+
ary = [:a, :b, :c]
|
61
|
+
assert_equal([[1, 5], [2, 3, 4], :a, :b, :c, { 1 => 6 }, "whee"],
|
62
|
+
Plist::Binary.send(:flatten_collection, [ary, { ary => "whee" }]))
|
63
|
+
hsh = { :a => :b }
|
64
|
+
assert_equal([[1, 4], { 2 => 3 }, "a", :b, [5, 6, 1], 1, 2],
|
65
|
+
Plist::Binary.send(:flatten_collection, [hsh, [1, 2, hsh]]))
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_binary_plist_obj
|
69
|
+
assert_equal("\x5bHello World",
|
70
|
+
Plist::Binary.send(:binary_plist_obj, "Hello World"))
|
71
|
+
assert_equal("\x5f\x10\x1bDomo-kun's Angry Smash Fest",
|
72
|
+
Plist::Binary.send(:binary_plist_obj, "Domo-kun's Angry Smash Fest"))
|
73
|
+
assert_equal("\x63\x59\x7d\x30\x4d\x30\x60",
|
74
|
+
Plist::Binary.send(:binary_plist_obj, "好きだ"))
|
75
|
+
assert_raises(ArgumentError) { Plist::Binary.send(:binary_plist_obj, "𝄢") }
|
76
|
+
assert_equal("\x63\x59\x7d\x30\x4d\x30\x60",
|
77
|
+
Plist::Binary.send(:binary_plist_obj, "好きだ"))
|
78
|
+
assert_equal("\x66\000s\000e\0\361\000o\000r\000a",
|
79
|
+
Plist::Binary.send(:binary_plist_obj, "señora"))
|
80
|
+
assert_equal("\x23#{[3.14159].pack('G')}",
|
81
|
+
Plist::Binary.send(:binary_plist_obj, 3.14159))
|
82
|
+
assert_equal("\x9", Plist::Binary.send(:binary_plist_obj, true))
|
83
|
+
assert_equal("\x8", Plist::Binary.send(:binary_plist_obj, false))
|
84
|
+
assert_equal("\x33\xc1\xcd\x27\xe4\x2\x80\x0\x0",
|
85
|
+
Plist::Binary.send(:binary_plist_obj, Time.at(123)))
|
86
|
+
sio = StringIO.new("Hello World")
|
87
|
+
assert_equal("\x4bHello World", Plist::Binary.send(:binary_plist_obj, sio))
|
88
|
+
assert_equal("\xa3\x1\x2\x3",
|
89
|
+
Plist::Binary.send(:binary_plist_obj, [1, 2, 3], 1))
|
90
|
+
assert_equal("\xaf\x10\x10\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10",
|
91
|
+
Plist::Binary.send(:binary_plist_obj, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], 1))
|
92
|
+
assert_equal("\xa3\x0\x1\x0\x2\x0\x3",
|
93
|
+
Plist::Binary.send(:binary_plist_obj, [1, 2, 3], 2))
|
94
|
+
assert_equal("\xd2\x1\x3\x2\x4",
|
95
|
+
Plist::Binary.send(:binary_plist_obj, {1=>2, 3=>4}, 1))
|
96
|
+
assert_equal("\xdf\x10\x10\x5\x0\xb\x6\x1\xc\x7\x2\xd\x8\x3\xe\x9\x4\xf\xa\x15\x10\x1b\x16\x11\x1c\x17\x12\x1d\x18\x13\x1e\x19\x14\x1f\x1a",
|
97
|
+
Plist::Binary.send(:binary_plist_obj, {5=>21, 11=>27, 0=>16, 6=>22, 12=>28, 1=>17, 7=>23, 13=>29, 2=>18, 8=>24, 14=>30, 3=>19, 9=>25, 15=>31, 4=>20, 10=>26}, 1))
|
98
|
+
assert_equal("\xd2\x0\x1\x0\x3\x0\x2\x0\x4",
|
99
|
+
Plist::Binary.send(:binary_plist_obj, {1=>2, 3=>4}, 2))
|
100
|
+
assert_equal("\xc3\x1\x2\x3",
|
101
|
+
Plist::Binary.send(:binary_plist_obj, Set.new([1, 2, 3]), 1))
|
102
|
+
assert_equal("\xcf\x10\x10\x10\x5\xb\x6\xc\x1\x7\xd\x2\x8\xe\x3\x9\xf\x4\xa",
|
103
|
+
Plist::Binary.send(:binary_plist_obj, Set.new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]), 1))
|
104
|
+
assert_equal("\xc3\x0\x1\x0\x2\x0\x3",
|
105
|
+
Plist::Binary.send(:binary_plist_obj, Set.new([1, 2, 3]), 2))
|
106
|
+
assert_equal("\x49\x4\x8/\x9narf\0",
|
107
|
+
Plist::Binary.send(:binary_plist_obj, /narf/))
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_binary_plist
|
111
|
+
assert_equal("bplist00\x55hello\x8\x0\x0\x0\x0\x0\x0\x1\x1\x0\x0\x0\x0\x0\x0\x0\x1\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\xe",
|
112
|
+
Plist::Binary.binary_plist("hello"))
|
113
|
+
assert_equal("bplist00\xa4\x1\x2\x3\x6\x45\x4\x8\x3a\x6\x61\x45\x4\x8\x3a\x6\x62\xd1\x4\x5\x55\x73\x74\x75\x66\x66\x58\x77\x68\x61\x74\x65\x76\x65\x72\x10\x7b\x8\xd\x13\x19\x1c\x22\x2b\x0\x0\x0\x0\x0\x0\x1\x1\x0\x0\x0\x0\x0\x0\x0\x7\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x2d",
|
114
|
+
Plist::Binary.binary_plist([:a, :b, { :stuff => "whatever" }, 123]))
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
##############################################################
|
2
|
+
# Copyright 2006, Ben Bleything <ben@bleything.net> and #
|
3
|
+
# Patrick May <patrick@hexane.org> #
|
4
|
+
# #
|
5
|
+
# Distributed under the MIT license. #
|
6
|
+
##############################################################
|
7
|
+
|
8
|
+
require 'test/unit'
|
9
|
+
require 'plist'
|
10
|
+
require 'stringio'
|
11
|
+
|
12
|
+
class MarshalableObject
|
13
|
+
attr_accessor :foo
|
14
|
+
|
15
|
+
def initialize(str)
|
16
|
+
@foo = str
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class TestDataElements < Test::Unit::TestCase
|
21
|
+
@@result = Plist::parse_xml('test/assets/test_data_elements.plist')
|
22
|
+
|
23
|
+
def test_marshal
|
24
|
+
expected = <<END
|
25
|
+
<!-- The <data> element below contains a Ruby object which has been serialized with Marshal.dump. -->
|
26
|
+
<data>
|
27
|
+
BAhvOhZNYXJzaGFsYWJsZU9iamVjdAY6CUBmb28iHnRoaXMgb2JqZWN0IHdhcyBtYXJz
|
28
|
+
aGFsZWQ=
|
29
|
+
</data>
|
30
|
+
END
|
31
|
+
|
32
|
+
mo = MarshalableObject.new('this object was marshaled')
|
33
|
+
|
34
|
+
assert_equal expected.chomp, Plist::Emit.dump(mo, false).chomp
|
35
|
+
|
36
|
+
assert_instance_of MarshalableObject, @@result['marshal']
|
37
|
+
|
38
|
+
assert_equal mo.foo, @@result['marshal'].foo
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_generator_io_and_file
|
42
|
+
expected = <<END
|
43
|
+
<data>
|
44
|
+
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
45
|
+
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
46
|
+
</data>
|
47
|
+
END
|
48
|
+
|
49
|
+
expected.chomp!
|
50
|
+
|
51
|
+
fd = IO.sysopen('test/assets/example_data.bin')
|
52
|
+
io = IO.open(fd, 'r')
|
53
|
+
|
54
|
+
# File is a subclass of IO, so catching IO in the dispatcher should work for File as well...
|
55
|
+
f = File.open('test/assets/example_data.bin')
|
56
|
+
|
57
|
+
assert_equal expected, Plist::Emit.dump(io, false).chomp
|
58
|
+
assert_equal expected, Plist::Emit.dump(f, false).chomp
|
59
|
+
|
60
|
+
assert_instance_of StringIO, @@result['io']
|
61
|
+
assert_instance_of StringIO, @@result['file']
|
62
|
+
|
63
|
+
io.rewind
|
64
|
+
f.rewind
|
65
|
+
|
66
|
+
assert_equal io.read, @@result['io'].read
|
67
|
+
assert_equal f.read, @@result['file'].read
|
68
|
+
|
69
|
+
io.close
|
70
|
+
f.close
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_generator_string_io
|
74
|
+
expected = <<END
|
75
|
+
<data>
|
76
|
+
dGhpcyBpcyBhIHN0cmluZ2lvIG9iamVjdA==
|
77
|
+
</data>
|
78
|
+
END
|
79
|
+
|
80
|
+
sio = StringIO.new('this is a stringio object')
|
81
|
+
|
82
|
+
assert_equal expected.chomp, Plist::Emit.dump(sio, false).chomp
|
83
|
+
|
84
|
+
assert_instance_of StringIO, @@result['stringio']
|
85
|
+
|
86
|
+
sio.rewind
|
87
|
+
assert_equal sio.read, @@result['stringio'].read
|
88
|
+
end
|
89
|
+
|
90
|
+
# this functionality is credited to Mat Schaffer,
|
91
|
+
# who discovered the plist with the data tag
|
92
|
+
# supplied the test data, and provided the parsing code.
|
93
|
+
def test_data
|
94
|
+
# test reading plist <data> elements
|
95
|
+
data = Plist::parse_xml("test/assets/example_data.plist");
|
96
|
+
assert_equal( File.open("test/assets/example_data.jpg"){|f| f.read }, data['image'].read )
|
97
|
+
|
98
|
+
# test writing data elements
|
99
|
+
expected = File.read("test/assets/example_data.plist")
|
100
|
+
result = data.to_plist
|
101
|
+
#File.open('result.plist', 'w') {|f|f.write(result)} # debug
|
102
|
+
assert_equal( expected, result )
|
103
|
+
|
104
|
+
# Test changing the <data> object in the plist to a StringIO and writing.
|
105
|
+
# This appears extraneous given that plist currently returns a StringIO,
|
106
|
+
# so the above writing test also flexes StringIO#to_plist_node.
|
107
|
+
# However, the interface promise is to return an IO, not a particular class.
|
108
|
+
# plist used to return Tempfiles, which was changed solely for performance reasons.
|
109
|
+
data['image'] = StringIO.new( File.read("test/assets/example_data.jpg"))
|
110
|
+
|
111
|
+
assert_equal(expected, data.to_plist )
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
##############################################################
|
2
|
+
# Copyright 2006, Ben Bleything <ben@bleything.net> and #
|
3
|
+
# Patrick May <patrick@hexane.org> #
|
4
|
+
# #
|
5
|
+
# Distributed under the MIT license. #
|
6
|
+
##############################################################
|
7
|
+
|
8
|
+
require 'test/unit'
|
9
|
+
require 'plist'
|
10
|
+
|
11
|
+
class SerializableObject
|
12
|
+
attr_accessor :foo
|
13
|
+
|
14
|
+
def initialize(str)
|
15
|
+
@foo = str
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_plist_node
|
19
|
+
return "<string>#{CGI::escapeHTML @foo}</string>"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class TestGenerator < Test::Unit::TestCase
|
24
|
+
def test_to_plist_vs_plist_emit_dump_no_envelope
|
25
|
+
source = [1, :b, true]
|
26
|
+
|
27
|
+
to_plist = source.to_plist(false)
|
28
|
+
plist_emit_dump = Plist::Emit.dump(source, false)
|
29
|
+
|
30
|
+
assert_equal to_plist, plist_emit_dump
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_to_plist_vs_plist_emit_dump_with_envelope
|
34
|
+
source = [1, :b, true]
|
35
|
+
|
36
|
+
to_plist = source.to_plist
|
37
|
+
plist_emit_dump = Plist::Emit.dump(source)
|
38
|
+
|
39
|
+
assert_equal to_plist, plist_emit_dump
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_dumping_serializable_object
|
43
|
+
str = 'this object implements #to_plist_node'
|
44
|
+
so = SerializableObject.new(str)
|
45
|
+
|
46
|
+
assert_equal "<string>#{str}</string>", Plist::Emit.dump(so, false)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_write_plist
|
50
|
+
data = [1, :two, {:c => 'dee'}]
|
51
|
+
|
52
|
+
data.save_plist('test.plist')
|
53
|
+
file = File.open('test.plist') {|f| f.read}
|
54
|
+
|
55
|
+
assert_equal file, data.to_plist
|
56
|
+
|
57
|
+
File.unlink('test.plist')
|
58
|
+
end
|
59
|
+
end
|