rapuncel 0.0.5.RC1 → 0.0.5.RC2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +30 -0
- data/README.md +44 -22
- data/lib/rapuncel/base_64_string.rb +17 -12
- data/lib/rapuncel/client.rb +29 -4
- data/lib/rapuncel/connection.rb +2 -1
- data/lib/rapuncel/proxy.rb +10 -3
- data/lib/rapuncel/request.rb +0 -2
- data/lib/rapuncel/response.rb +5 -6
- data/lib/rapuncel/xml_rpc/deserializer.rb +113 -0
- data/lib/rapuncel/xml_rpc/serializer.rb +153 -0
- data/rapuncel-0.0.5.RC1.gem +0 -0
- data/rapuncel.gemspec +1 -1
- data/spec/unit/array_spec.rb +2 -2
- data/spec/unit/base64_spec.rb +2 -2
- data/spec/unit/boolean_spec.rb +5 -5
- data/spec/unit/custom_serialization_spec.rb +23 -0
- data/spec/unit/float_spec.rb +5 -5
- data/spec/unit/hash_spec.rb +2 -2
- data/spec/unit/int_spec.rb +3 -3
- data/spec/unit/nil_spec.rb +1 -1
- data/spec/unit/object_spec.rb +23 -2
- data/spec/unit/request_spec.rb +1 -1
- data/spec/unit/response_spec.rb +3 -3
- data/spec/unit/string_spec.rb +5 -5
- data/spec/unit/time_spec.rb +2 -2
- metadata +92 -51
- data/lib/rapuncel/xml_rpc_deserializer.rb +0 -110
- data/lib/rapuncel/xml_rpc_serializer.rb +0 -148
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
module Rapuncel
|
5
|
+
module XmlRpc
|
6
|
+
class Serializer
|
7
|
+
XML_ENCODING = 'UTF-8'
|
8
|
+
|
9
|
+
attr_reader :builder
|
10
|
+
|
11
|
+
def initialize object
|
12
|
+
@builder = Nokogiri::XML::Builder.new :encoding => XML_ENCODING
|
13
|
+
|
14
|
+
serialize object
|
15
|
+
end
|
16
|
+
|
17
|
+
def serialize object
|
18
|
+
case object
|
19
|
+
when Base64String
|
20
|
+
serialize_base64 object
|
21
|
+
when Array
|
22
|
+
serialize_array object
|
23
|
+
when String, Symbol
|
24
|
+
serialize_string object.to_s
|
25
|
+
when TrueClass
|
26
|
+
serialize_true
|
27
|
+
when FalseClass
|
28
|
+
serialize_false
|
29
|
+
when Float
|
30
|
+
serialize_float object
|
31
|
+
when BigDecimal
|
32
|
+
serialize_big_decimal object
|
33
|
+
when Hash
|
34
|
+
serialize_hash object
|
35
|
+
when Integer
|
36
|
+
serialize_integer object
|
37
|
+
when NilClass
|
38
|
+
serialize_nil
|
39
|
+
when Time
|
40
|
+
serialize_time object
|
41
|
+
when Request
|
42
|
+
serialize_request object
|
43
|
+
else
|
44
|
+
if object.respond_to?(:acts_like?) && object.acts_like?(:time)
|
45
|
+
serialize_time object
|
46
|
+
elsif object.respond_to?(:to_xmlrpc)
|
47
|
+
object.to_xmlrpc self
|
48
|
+
else
|
49
|
+
serialize_hash instance_variable_hash(object)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
def serialize_base64 string
|
57
|
+
builder.base64 string.base64_encoded
|
58
|
+
end
|
59
|
+
|
60
|
+
def serialize_array array
|
61
|
+
builder.array do |builder|
|
62
|
+
builder.data do |builder|
|
63
|
+
array.each do |element|
|
64
|
+
builder.value do |_|
|
65
|
+
serialize element
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def serialize_string string
|
73
|
+
builder.string string
|
74
|
+
end
|
75
|
+
|
76
|
+
def serialize_true
|
77
|
+
builder.boolean "1"
|
78
|
+
end
|
79
|
+
|
80
|
+
def serialize_false
|
81
|
+
builder.boolean "0"
|
82
|
+
end
|
83
|
+
alias_method :serialize_nil, :serialize_false
|
84
|
+
|
85
|
+
def serialize_float float
|
86
|
+
builder.double float.to_s
|
87
|
+
end
|
88
|
+
|
89
|
+
def serialize_big_decimal big_decimal
|
90
|
+
builder.double big_decimal.to_s("F")
|
91
|
+
end
|
92
|
+
|
93
|
+
def serialize_hash hash
|
94
|
+
builder.struct do |builder|
|
95
|
+
hash.each_pair do |key, value|
|
96
|
+
builder.member do |builder|
|
97
|
+
# Get a better string representation of BigDecimals
|
98
|
+
key = key.to_s("F") if BigDecimal === key
|
99
|
+
builder.name key.to_s
|
100
|
+
|
101
|
+
builder.value do |builder|
|
102
|
+
serialize value
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def serialize_integer int
|
110
|
+
builder.int int.to_s
|
111
|
+
end
|
112
|
+
|
113
|
+
def serialize_time time
|
114
|
+
builder.send "dateTime.iso8601", time.iso8601
|
115
|
+
end
|
116
|
+
|
117
|
+
def serialize_request request
|
118
|
+
builder.methodCall do |builder|
|
119
|
+
builder.methodName request.method_name
|
120
|
+
builder.params do |builder|
|
121
|
+
request.arguments.each do |argument|
|
122
|
+
builder.param do |builder|
|
123
|
+
builder.value do |builder|
|
124
|
+
serialize argument
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def to_xml
|
133
|
+
@builder.to_xml
|
134
|
+
end
|
135
|
+
|
136
|
+
protected
|
137
|
+
def instance_variable_hash object
|
138
|
+
{}.tap do |hash|
|
139
|
+
object.instance_variables.each do |ivar|
|
140
|
+
hash[ivar[1..-1]] = object.instance_variable_get ivar
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
class << self
|
146
|
+
def serialize object
|
147
|
+
new(object).to_xml
|
148
|
+
end
|
149
|
+
alias_method :[], :serialize
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
Binary file
|
data/rapuncel.gemspec
CHANGED
data/spec/unit/array_spec.rb
CHANGED
@@ -5,7 +5,7 @@ describe Array do
|
|
5
5
|
before do
|
6
6
|
@array = (1..10).to_a.map &:to_s
|
7
7
|
|
8
|
-
@xml = Rapuncel::
|
8
|
+
@xml = Rapuncel::XmlRpc::Serializer[@array]
|
9
9
|
end
|
10
10
|
|
11
11
|
it "yields a value tag for each array element" do
|
@@ -27,7 +27,7 @@ describe Array do
|
|
27
27
|
<value><string>3</string></value>
|
28
28
|
</data></array>
|
29
29
|
XML
|
30
|
-
@array = Rapuncel::
|
30
|
+
@array = Rapuncel::XmlRpc::Deserializer[@xml]
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'has correct number of elements' do
|
data/spec/unit/base64_spec.rb
CHANGED
@@ -14,7 +14,7 @@ describe "Base64" do
|
|
14
14
|
string = "abcdefghABCDEFGH1234567890".as_base64
|
15
15
|
string.should be_a Rapuncel::Base64String
|
16
16
|
|
17
|
-
xml = Rapuncel::
|
17
|
+
xml = Rapuncel::XmlRpc::Serializer[string]
|
18
18
|
xml.should have_xpath('/base64', :content => to_base64(string))
|
19
19
|
end
|
20
20
|
|
@@ -23,7 +23,7 @@ describe "Base64" do
|
|
23
23
|
<base64>YWJjZGVmZ2hBQkNERUZHSDEyMzQ1Njc4OTA=</base64>
|
24
24
|
XML
|
25
25
|
|
26
|
-
string = Rapuncel::
|
26
|
+
string = Rapuncel::XmlRpc::Deserializer[xml]
|
27
27
|
string.should be_a Rapuncel::Base64String
|
28
28
|
string.should == "abcdefghABCDEFGH1234567890"
|
29
29
|
end
|
data/spec/unit/boolean_spec.rb
CHANGED
@@ -3,11 +3,11 @@ require 'spec_helper'
|
|
3
3
|
describe TrueClass, FalseClass do
|
4
4
|
describe "Serialization" do
|
5
5
|
it 'represents true as 1' do
|
6
|
-
Rapuncel::
|
6
|
+
Rapuncel::XmlRpc::Serializer[true].should have_xpath('/boolean', :content => '1')
|
7
7
|
end
|
8
8
|
|
9
9
|
it 'represents false as 0' do
|
10
|
-
Rapuncel::
|
10
|
+
Rapuncel::XmlRpc::Serializer[false].should have_xpath('/boolean', :content => '0')
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -17,7 +17,7 @@ describe TrueClass, FalseClass do
|
|
17
17
|
<boolean>1</boolean>
|
18
18
|
XML
|
19
19
|
|
20
|
-
Rapuncel::
|
20
|
+
Rapuncel::XmlRpc::Deserializer[xml].should be_a TrueClass
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'reads 0 as false' do
|
@@ -25,7 +25,7 @@ describe TrueClass, FalseClass do
|
|
25
25
|
<boolean>0</boolean>
|
26
26
|
XML
|
27
27
|
|
28
|
-
Rapuncel::
|
28
|
+
Rapuncel::XmlRpc::Deserializer[xml].should be_a FalseClass
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'reads anything else as false' do
|
@@ -33,7 +33,7 @@ describe TrueClass, FalseClass do
|
|
33
33
|
<boolean>abcd</boolean>
|
34
34
|
XML
|
35
35
|
|
36
|
-
Rapuncel::
|
36
|
+
Rapuncel::XmlRpc::Deserializer[xml].should be_a FalseClass
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Custom serialization" do
|
4
|
+
module CustomSerialization
|
5
|
+
class Serializer < Rapuncel::XmlRpc::Serializer
|
6
|
+
end
|
7
|
+
|
8
|
+
class Deserializer < Rapuncel::XmlRpc::Deserializer
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'client selects custom (de)serializer, if provided by Symbol' do
|
13
|
+
client = Rapuncel::Client.new :serialization => :CustomSerialization
|
14
|
+
|
15
|
+
client.send(:serializer).should == CustomSerialization::Serializer
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'client selects custom (de)serializer, if provided by Class' do
|
19
|
+
client = Rapuncel::Client.new :serialization => CustomSerialization
|
20
|
+
|
21
|
+
client.send(:serializer).should == CustomSerialization::Serializer
|
22
|
+
end
|
23
|
+
end
|
data/spec/unit/float_spec.rb
CHANGED
@@ -4,12 +4,12 @@ describe Float do
|
|
4
4
|
describe "Serialization" do
|
5
5
|
it "can serialize Floats" do
|
6
6
|
number = 1.23456
|
7
|
-
Rapuncel::
|
7
|
+
Rapuncel::XmlRpc::Serializer[number].should have_xpath('/double', :content => "1.23456")
|
8
8
|
end
|
9
9
|
|
10
10
|
it "can serialize BigDecimal" do
|
11
11
|
number = BigDecimal.new '1.23456'
|
12
|
-
Rapuncel::
|
12
|
+
Rapuncel::XmlRpc::Serializer[number].should have_xpath('/double', :content => "1.23456")
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -18,18 +18,18 @@ describe Float do
|
|
18
18
|
xml = <<-XML
|
19
19
|
<double>1.23456</double>
|
20
20
|
XML
|
21
|
-
number = Rapuncel::
|
21
|
+
number = Rapuncel::XmlRpc::Deserializer[xml]
|
22
22
|
number.should be_a Float
|
23
23
|
number.should == 1.23456
|
24
24
|
end
|
25
25
|
|
26
26
|
it "can optionally deserialize all double to BigDecimal" do
|
27
|
-
Rapuncel::
|
27
|
+
Rapuncel::XmlRpc::Deserializer.double_as_bigdecimal = true
|
28
28
|
|
29
29
|
xml = <<-XML
|
30
30
|
<double>1.23456</double>
|
31
31
|
XML
|
32
|
-
number = Rapuncel::
|
32
|
+
number = Rapuncel::XmlRpc::Deserializer[xml]
|
33
33
|
|
34
34
|
number.should be_a BigDecimal
|
35
35
|
number.to_s("F").should == "1.23456"
|
data/spec/unit/hash_spec.rb
CHANGED
@@ -10,7 +10,7 @@ describe Hash do
|
|
10
10
|
BigDecimal.new('1.23') => "abcd"
|
11
11
|
}
|
12
12
|
|
13
|
-
@xml = Rapuncel::
|
13
|
+
@xml = Rapuncel::XmlRpc::Serializer[@hash]
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'preserves number of key-value pairs' do
|
@@ -35,7 +35,7 @@ describe Hash do
|
|
35
35
|
</struct>
|
36
36
|
XML
|
37
37
|
|
38
|
-
@hash = Rapuncel::
|
38
|
+
@hash = Rapuncel::XmlRpc::Deserializer[@xml]
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'preserves number of key-value pairs' do
|
data/spec/unit/int_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Integer do
|
4
4
|
it "serialization" do
|
5
|
-
Rapuncel::
|
5
|
+
Rapuncel::XmlRpc::Serializer[123].should have_xpath('/int', :content => "123")
|
6
6
|
end
|
7
7
|
|
8
8
|
it "deserialization of int" do
|
@@ -10,7 +10,7 @@ describe Integer do
|
|
10
10
|
<int>123</int>
|
11
11
|
XML
|
12
12
|
|
13
|
-
Rapuncel::
|
13
|
+
Rapuncel::XmlRpc::Deserializer[xml].should == 123
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'deserialization of i4' do
|
@@ -18,6 +18,6 @@ describe Integer do
|
|
18
18
|
<i4>123</i4>
|
19
19
|
XML
|
20
20
|
|
21
|
-
Rapuncel::
|
21
|
+
Rapuncel::XmlRpc::Deserializer[xml].should == 123
|
22
22
|
end
|
23
23
|
end
|
data/spec/unit/nil_spec.rb
CHANGED
data/spec/unit/object_spec.rb
CHANGED
@@ -5,20 +5,41 @@ describe Object do
|
|
5
5
|
attr_accessor :a, :b, :c
|
6
6
|
end
|
7
7
|
|
8
|
+
class TestObjectWithOwnBehavior < TestObject
|
9
|
+
def to_xmlrpc serializer
|
10
|
+
serializer.builder.string "custom thing"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
8
14
|
describe "Serialization of an arbitrary Object" do
|
9
15
|
it "serializes all instance variables like a hash" do
|
10
16
|
obj = TestObject.new
|
11
17
|
obj.a = "one"
|
12
18
|
obj.b = "two"
|
13
19
|
|
14
|
-
xml = Rapuncel::
|
20
|
+
xml = Rapuncel::XmlRpc::Serializer[obj]
|
15
21
|
xml.should have_xpath('/struct/member', :count => 2)
|
16
22
|
|
17
|
-
reparsed_object = Rapuncel::
|
23
|
+
reparsed_object = Rapuncel::XmlRpc::Deserializer[xml]
|
18
24
|
reparsed_object.should == {
|
19
25
|
:a => 'one',
|
20
26
|
:b => 'two'
|
21
27
|
}
|
22
28
|
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "Serialization of an Object with #to_xmlrpc" do
|
33
|
+
it "uses this method to serialize" do
|
34
|
+
obj = TestObjectWithOwnBehavior.new
|
35
|
+
|
36
|
+
obj.a = 'one'
|
37
|
+
|
38
|
+
xml = Rapuncel::XmlRpc::Serializer[obj]
|
39
|
+
xml.should have_xpath('/string')
|
40
|
+
|
41
|
+
reparsed_object = Rapuncel::XmlRpc::Deserializer[xml]
|
42
|
+
reparsed_object.should == "custom thing"
|
43
|
+
end
|
23
44
|
end
|
24
45
|
end
|
data/spec/unit/request_spec.rb
CHANGED
@@ -5,7 +5,7 @@ describe Rapuncel::Request do
|
|
5
5
|
describe "Serialization" do
|
6
6
|
before do
|
7
7
|
@request = Rapuncel::Request.new 'test_method', "one argument", "another"
|
8
|
-
@xml = Rapuncel::
|
8
|
+
@xml = Rapuncel::XmlRpc::Serializer[@request]
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'should be in xml version=1.0' do
|
data/spec/unit/response_spec.rb
CHANGED
@@ -27,7 +27,7 @@ describe Rapuncel::Response do
|
|
27
27
|
</methodResponse>
|
28
28
|
XML
|
29
29
|
|
30
|
-
response = Rapuncel::Response.new successful_response
|
30
|
+
response = Rapuncel::Response.new successful_response, Rapuncel::XmlRpc::Deserializer
|
31
31
|
response.should be_success
|
32
32
|
|
33
33
|
response.result.should == "foo foo foo"
|
@@ -66,7 +66,7 @@ describe Rapuncel::Response do
|
|
66
66
|
</methodResponse>
|
67
67
|
XML
|
68
68
|
|
69
|
-
response = Rapuncel::Response.new fault_response
|
69
|
+
response = Rapuncel::Response.new fault_response, Rapuncel::XmlRpc::Deserializer
|
70
70
|
response.should be_fault
|
71
71
|
|
72
72
|
response.to_ruby.should be_a Hash
|
@@ -76,7 +76,7 @@ describe Rapuncel::Response do
|
|
76
76
|
it 'should handle errors' do
|
77
77
|
error_response = HttpResponse.new "Not Found", false, 404
|
78
78
|
|
79
|
-
response = Rapuncel::Response.new error_response
|
79
|
+
response = Rapuncel::Response.new error_response, Rapuncel::XmlRpc::Deserializer
|
80
80
|
response.should be_error
|
81
81
|
|
82
82
|
response.to_ruby.should be_a Hash
|
data/spec/unit/string_spec.rb
CHANGED
@@ -3,19 +3,19 @@ require 'spec_helper'
|
|
3
3
|
describe String, Symbol do
|
4
4
|
it 'serialization of a String' do
|
5
5
|
string = "foobar"
|
6
|
-
xml = Rapuncel::
|
6
|
+
xml = Rapuncel::XmlRpc::Serializer[string]
|
7
7
|
xml.should have_xpath('/string', :content => "foobar")
|
8
8
|
end
|
9
9
|
|
10
10
|
it 'serialization of a Symbol' do
|
11
11
|
symbol = :foobar
|
12
|
-
xml = Rapuncel::
|
12
|
+
xml = Rapuncel::XmlRpc::Serializer[symbol]
|
13
13
|
xml.should have_xpath('/string', :content => "foobar")
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'preservation of trailing an leading whitespaces' do
|
17
17
|
string = "\n\t abcd\n \t"
|
18
|
-
xml = Rapuncel::
|
18
|
+
xml = Rapuncel::XmlRpc::Serializer[string]
|
19
19
|
xml.should have_xpath('/string', :content => "\n\t abcd\n \t")
|
20
20
|
end
|
21
21
|
|
@@ -23,13 +23,13 @@ describe String, Symbol do
|
|
23
23
|
xml = <<-XML
|
24
24
|
<string>abcd\nefgh \n\t</string>
|
25
25
|
XML
|
26
|
-
string = Rapuncel::
|
26
|
+
string = Rapuncel::XmlRpc::Deserializer[xml]
|
27
27
|
string.should == "abcd\nefgh \n\t"
|
28
28
|
end
|
29
29
|
|
30
30
|
it 'normalization of linebreaks' do
|
31
31
|
string = "one\r\ntwo\rthree\nfour"
|
32
|
-
string2 = Rapuncel::
|
32
|
+
string2 = Rapuncel::XmlRpc::Deserializer[Rapuncel::XmlRpc::Serializer[string]]
|
33
33
|
string2.should == "one\ntwo\nthree\nfour"
|
34
34
|
end
|
35
35
|
end
|