rapuncel 0.0.1.alpha
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/MIT-LICENSE +20 -0
- data/README.md +171 -0
- data/Rakefile +24 -0
- data/lib/rapuncel.rb +25 -0
- data/lib/rapuncel/adapters/net_http_adapter.rb +34 -0
- data/lib/rapuncel/base.rb +7 -0
- data/lib/rapuncel/client.rb +54 -0
- data/lib/rapuncel/connection.rb +75 -0
- data/lib/rapuncel/core_ext/array.rb +23 -0
- data/lib/rapuncel/core_ext/big_decimal.rb +7 -0
- data/lib/rapuncel/core_ext/boolean.rb +29 -0
- data/lib/rapuncel/core_ext/float.rb +11 -0
- data/lib/rapuncel/core_ext/hash.rb +32 -0
- data/lib/rapuncel/core_ext/integer.rb +11 -0
- data/lib/rapuncel/core_ext/nil.rb +7 -0
- data/lib/rapuncel/core_ext/object.rb +49 -0
- data/lib/rapuncel/core_ext/string.rb +12 -0
- data/lib/rapuncel/core_ext/symbol.rb +7 -0
- data/lib/rapuncel/core_ext/time.rb +14 -0
- data/lib/rapuncel/proxy.rb +82 -0
- data/lib/rapuncel/request.rb +49 -0
- data/lib/rapuncel/response.rb +92 -0
- data/rapuncel-0.0.1.preview.gem +0 -0
- data/rapuncel.gemspec +22 -0
- data/test/functional/client_test.rb +54 -0
- data/test/functional_test_helper.rb +13 -0
- data/test/test_helper.rb +38 -0
- data/test/test_server.rb +28 -0
- data/test/unit/array_test.rb +96 -0
- data/test/unit/boolean_test.rb +34 -0
- data/test/unit/connection_test.rb +17 -0
- data/test/unit/float_test.rb +23 -0
- data/test/unit/hash_test.rb +54 -0
- data/test/unit/int_test.rb +27 -0
- data/test/unit/nil_test.rb +16 -0
- data/test/unit/object_test.rb +83 -0
- data/test/unit/proxy_test.rb +52 -0
- data/test/unit/request_test.rb +34 -0
- data/test/unit/response_test.rb +100 -0
- data/test/unit/string_test.rb +40 -0
- data/test/unit/time_test.rb +23 -0
- metadata +154 -0
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'functional_test_helper'
|
2
|
+
|
3
|
+
class FunctionalClientTest < FunctionalTest
|
4
|
+
test "Simple XMLRPC call" do
|
5
|
+
client = Rapuncel::Client.new :port => 8080, :raise_on => :both
|
6
|
+
proxy = client.proxy_for 'num'
|
7
|
+
|
8
|
+
result = proxy.add 40, 2
|
9
|
+
|
10
|
+
assert_equal 42, result
|
11
|
+
end
|
12
|
+
|
13
|
+
test "Fault rpc call without raise" do
|
14
|
+
client = Rapuncel::Client.new :port => 8080
|
15
|
+
proxy = client.proxy_for 'num'
|
16
|
+
|
17
|
+
assert_nothing_raised Rapuncel::Response::Exception do
|
18
|
+
proxy.add 20, 20, 2
|
19
|
+
end
|
20
|
+
|
21
|
+
assert_kind_of Rapuncel::Response::Fault, proxy.add(20, 20, 2)
|
22
|
+
end
|
23
|
+
|
24
|
+
test "Fault rpc call" do
|
25
|
+
client = Rapuncel::Client.new :port => 8080, :raise_on => :both
|
26
|
+
proxy = client.proxy_for 'num'
|
27
|
+
|
28
|
+
assert_raise Rapuncel::Response::Fault do
|
29
|
+
proxy.add 20, 20, 2
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
test "Error rpc connection" do
|
34
|
+
client = Rapuncel::Client.new :host => 'www.cice-online.net', :port => 80, :path => '/hullahoobahubbahooo', :raise_on => :both
|
35
|
+
proxy = client.proxy
|
36
|
+
|
37
|
+
assert_raise Rapuncel::Response::Error do
|
38
|
+
proxy.foo :bar, :baz
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
test "Error rpc connection without raise" do
|
43
|
+
client = Rapuncel::Client.new :host => 'www.google.de', :port => 80, :path => '/hullahoobahubbahooo'
|
44
|
+
proxy = client.proxy
|
45
|
+
|
46
|
+
assert_nothing_raised Rapuncel::Response::Error do
|
47
|
+
proxy.foo :bar, :baz
|
48
|
+
end
|
49
|
+
|
50
|
+
err = proxy.foo(:bar, :baz)
|
51
|
+
assert_kind_of Rapuncel::Response::Error, err
|
52
|
+
assert_equal 404, err.code
|
53
|
+
end
|
54
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
lib_dir = File.join File.dirname(__FILE__), '..', 'lib'
|
2
|
+
$:.unshift lib_dir
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'active_support'
|
6
|
+
require 'test/unit'
|
7
|
+
require 'mocha'
|
8
|
+
require 'rapuncel'
|
9
|
+
require 'nokogiri'
|
10
|
+
require 'ruby-debug'
|
11
|
+
|
12
|
+
class ActiveSupport::TestCase
|
13
|
+
def assert_select xml, xpath, eq, count = nil
|
14
|
+
doc = Nokogiri::XML.parse xml, nil, nil, Nokogiri::XML::ParseOptions::STRICT
|
15
|
+
res = doc.xpath xpath
|
16
|
+
|
17
|
+
eq.nil? && assert(res.blank?) && return
|
18
|
+
|
19
|
+
case eq
|
20
|
+
when Integer
|
21
|
+
assert_equal eq, res.size
|
22
|
+
when String
|
23
|
+
eq = eq.strip
|
24
|
+
|
25
|
+
if count
|
26
|
+
assert_equal count, res.to_a.select{ |node|
|
27
|
+
node.text.strip == eq
|
28
|
+
}.size
|
29
|
+
else
|
30
|
+
assert res.to_a.all?{ |node|
|
31
|
+
node.text.strip == eq
|
32
|
+
}
|
33
|
+
end
|
34
|
+
else
|
35
|
+
raise "Third argument should be String or Integer"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/test/test_server.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require "xmlrpc/server"
|
2
|
+
|
3
|
+
class Num
|
4
|
+
INTERFACE = XMLRPC::interface("num") {
|
5
|
+
meth 'int add(int, int)', 'Add two numbers', 'add'
|
6
|
+
meth 'int div(int, int)', 'Divide two numbers'
|
7
|
+
}
|
8
|
+
|
9
|
+
def add(a, b) a + b end
|
10
|
+
def div(a, b) a / b end
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
class TestServer
|
15
|
+
def initialize
|
16
|
+
@server = XMLRPC::Server.new(8080, '127.0.0.1', 4, File.open('/dev/null','w')).tap do |s|
|
17
|
+
s.add_handler(Num::INTERFACE, Num.new)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def start
|
22
|
+
Thread.new { @server.serve }
|
23
|
+
end
|
24
|
+
|
25
|
+
def stop
|
26
|
+
@server.shutdown
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ArrayTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
test "an array of 10 entries should have 10x /array/data/value" do
|
6
|
+
arr = (1..10).to_a.map &:to_s
|
7
|
+
xml = arr.to_xml_rpc
|
8
|
+
|
9
|
+
assert_select xml, '/array/data/value', 10
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_array arr
|
13
|
+
xml = arr.to_xml_rpc
|
14
|
+
|
15
|
+
xml_node = Nokogiri::XML(xml).children.first
|
16
|
+
|
17
|
+
reparsed = Array.from_xml_rpc xml_node
|
18
|
+
|
19
|
+
reparsed
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
test "An array, converted to xml and parsed back should be itself" do
|
24
|
+
arr1 = (1..10).to_a
|
25
|
+
arr2 = arr1.map &:to_s
|
26
|
+
|
27
|
+
arr3 = [arr1, arr2]
|
28
|
+
|
29
|
+
arr4 = ["hello", arr3]
|
30
|
+
|
31
|
+
reparsed1 = test_array arr1
|
32
|
+
reparsed2 = test_array arr2
|
33
|
+
reparsed3 = test_array arr3
|
34
|
+
reparsed4 = test_array arr4
|
35
|
+
|
36
|
+
[reparsed1, reparsed2, reparsed3, reparsed4].zip([arr1, arr2, arr3, arr4]).each do |b|
|
37
|
+
assert_equal *b
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
test "real world repsonse" do
|
43
|
+
response_body = <<-XML
|
44
|
+
<array><data>
|
45
|
+
<value><struct>
|
46
|
+
<member>
|
47
|
+
<name>state</name>
|
48
|
+
<value><string>uninstalled</string></value>
|
49
|
+
</member>
|
50
|
+
<member>
|
51
|
+
<name>name</name>
|
52
|
+
<value><string>account_cancel</string></value>
|
53
|
+
</member>
|
54
|
+
<member>
|
55
|
+
<name>id</name>
|
56
|
+
<value><int>1</int></value>
|
57
|
+
</member>
|
58
|
+
</struct></value>
|
59
|
+
<value><struct>
|
60
|
+
<member>
|
61
|
+
<name>state</name>
|
62
|
+
<value><string>uninstalled</string></value>
|
63
|
+
</member>
|
64
|
+
<member>
|
65
|
+
<name>name</name>
|
66
|
+
<value><string>document_ftp</string></value>
|
67
|
+
</member>
|
68
|
+
<member>
|
69
|
+
<name>id</name>
|
70
|
+
<value><int>3</int></value>
|
71
|
+
</member>
|
72
|
+
</struct></value>
|
73
|
+
<value><struct>
|
74
|
+
<member>
|
75
|
+
<name>state</name>
|
76
|
+
<value><string>uninstalled</string></value>
|
77
|
+
</member>
|
78
|
+
<member>
|
79
|
+
<name>name</name>
|
80
|
+
<value><string>mrp_repair</string></value>
|
81
|
+
</member>
|
82
|
+
<member>
|
83
|
+
<name>id</name>
|
84
|
+
<value><int>2</int></value>
|
85
|
+
</member>
|
86
|
+
</struct></value>
|
87
|
+
</data></array>
|
88
|
+
XML
|
89
|
+
|
90
|
+
arr = Object.from_xml_rpc response_body
|
91
|
+
|
92
|
+
assert_kind_of Array, arr
|
93
|
+
assert_equal 3, arr.size
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class BooleanTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
test "true must evaluate to 1" do
|
6
|
+
assert_select true.to_xml_rpc, '/boolean', 1
|
7
|
+
assert_select true.to_xml_rpc, '/boolean', '1'
|
8
|
+
end
|
9
|
+
|
10
|
+
test "false must evaluate to 0" do
|
11
|
+
assert_select false.to_xml_rpc, '/boolean', 1
|
12
|
+
assert_select false.to_xml_rpc, '/boolean', '0'
|
13
|
+
end
|
14
|
+
|
15
|
+
test "true.to_xml_rpc reparsed must be true" do
|
16
|
+
xml=true.to_xml_rpc
|
17
|
+
xml_node = Nokogiri::XML(xml).children.first
|
18
|
+
|
19
|
+
assert Rapuncel::Boolean.from_xml_rpc(xml_node) #I assume assert takes a boolean?
|
20
|
+
assert Rapuncel::Boolean.from_xml_rpc(xml_node) == true #is this different? just in case the other function gives back something non nil/false which is not necessarily true
|
21
|
+
end
|
22
|
+
|
23
|
+
test "false.to_xml_rpc reparsed must be false" do
|
24
|
+
xml=false.to_xml_rpc
|
25
|
+
xml_node = Nokogiri::XML(xml).children.first
|
26
|
+
|
27
|
+
assert !Rapuncel::Boolean.from_xml_rpc(xml_node)
|
28
|
+
end
|
29
|
+
|
30
|
+
test "anything else should evaluate to what now?" do
|
31
|
+
assert true
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ConnectionTest < ActiveSupport::TestCase
|
4
|
+
test "Connection.new should return an AuthConnection if user, password or auth_method is set" do
|
5
|
+
assert_kind_of Rapuncel::AuthConnection, Rapuncel::Connection.build(:auth_method => 'basic')
|
6
|
+
assert_kind_of Rapuncel::AuthConnection, Rapuncel::Connection.build(:user => '')
|
7
|
+
assert_kind_of Rapuncel::AuthConnection, Rapuncel::Connection.build(:password => '')
|
8
|
+
end
|
9
|
+
|
10
|
+
test "Connection.new should return an ApiKeyAuthConnection if api_key is set" do
|
11
|
+
assert_kind_of Rapuncel::ApiKeyAuthConnection, Rapuncel::Connection.build(:api_key => 'xyz')
|
12
|
+
end
|
13
|
+
|
14
|
+
test "ApiKeyAuthConnection should contain api key in headers" do
|
15
|
+
assert_equal 'xyz', Rapuncel::Connection.build(:api_key => 'xyz').headers['X-ApiKey']
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class FloatTest < ActiveSupport::TestCase
|
4
|
+
test "A float should be a number between 'double' tags" do
|
5
|
+
num=1.123456
|
6
|
+
xml=num.to_xml_rpc
|
7
|
+
|
8
|
+
assert_select xml, '/double', 1
|
9
|
+
assert_select xml, '/double', num.to_s
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
test "A float converted to xml and back should be the same number!" do
|
14
|
+
num=1.123456
|
15
|
+
xml=num.to_xml_rpc
|
16
|
+
|
17
|
+
xml_node=Nokogiri::XML(xml).children.first #make a nokogiri xml_node containing the float
|
18
|
+
|
19
|
+
assert_equal num, Float.from_xml_rpc(xml_node)
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'active_support/core_ext/hash/keys'
|
3
|
+
|
4
|
+
class TestHelper < ActiveSupport::TestCase
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
def to_and_from_xml_rpc hash
|
10
|
+
xml = hash.to_xml_rpc
|
11
|
+
|
12
|
+
xml_node = Nokogiri::XML(xml).children.first
|
13
|
+
|
14
|
+
Hash.from_xml_rpc xml_node
|
15
|
+
end
|
16
|
+
|
17
|
+
test 'Hash#to_xml_rpc' do
|
18
|
+
xml = {
|
19
|
+
:abc => 'one and two',
|
20
|
+
40 => %w(foo bar bee)
|
21
|
+
}.to_xml_rpc
|
22
|
+
|
23
|
+
assert_select xml, '/struct', 1
|
24
|
+
assert_select xml, '/struct/member', 2
|
25
|
+
assert_select xml, '/struct/member/name', 'abc', 1
|
26
|
+
assert_select xml, '/struct/member/value/string', 'one and two', 1
|
27
|
+
assert_select xml, '/struct/member/name', '40', 1
|
28
|
+
assert_select xml, '/struct/member/value/array/data/value', 3
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
test "A hash to xml and back should be itself" do
|
33
|
+
hash1 = {:a => "b", :c => "d", :A => "B"}
|
34
|
+
arr1 = (1..10).to_a
|
35
|
+
hash2 = {:arr => arr1, :text => "sheeee"}
|
36
|
+
hash3 = hash1.merge({:jooooo => hash2})
|
37
|
+
|
38
|
+
hash4 = Hash[*(1..10).to_a] #separate, non symbol keys
|
39
|
+
|
40
|
+
hashes = [hash1, hash2, hash3]
|
41
|
+
|
42
|
+
results = hashes.map do |h|
|
43
|
+
to_and_from_xml_rpc h
|
44
|
+
end
|
45
|
+
|
46
|
+
result4 = to_and_from_xml_rpc hash4 #separate, non symbol keys
|
47
|
+
|
48
|
+
hashes.zip(results).each do |hr|
|
49
|
+
assert_equal *hr
|
50
|
+
end
|
51
|
+
|
52
|
+
assert_equal hash4.stringify_keys.symbolize_keys, result4
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class IntTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
def test_number num = 1
|
6
|
+
assert_select num.to_xml_rpc, '/int', 1
|
7
|
+
assert_select num.to_xml_rpc, '/int', num.to_s
|
8
|
+
end
|
9
|
+
|
10
|
+
test "should convert the number 1234567 to the string '<int>1234567</int>'" do
|
11
|
+
num = 1234567
|
12
|
+
|
13
|
+
test_number num
|
14
|
+
end
|
15
|
+
|
16
|
+
test "should warn if numbers go out of 4 byte signed integer range [#{(-2**31).to_s}, #{(2**31-1)}], e.g #{(2**31).to_s},
|
17
|
+
but should still give the right result as long as ruby can handle the number" do
|
18
|
+
num = 2**31
|
19
|
+
|
20
|
+
test_number num
|
21
|
+
end
|
22
|
+
|
23
|
+
test "An int converted to xml and back should be the same number!" do
|
24
|
+
num = 234132
|
25
|
+
assert_equal num, Integer.from_xml_rpc(Nokogiri::XML(num.to_xml_rpc).children.first)
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class NilTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
test "nil should have the same response as false" do
|
6
|
+
assert_equal false.to_xml_rpc, nil.to_xml_rpc
|
7
|
+
end
|
8
|
+
|
9
|
+
test "nil must evaluate to /boolean/0, as does false" do
|
10
|
+
assert_select nil.to_xml_rpc, '/boolean', 1
|
11
|
+
assert_select nil.to_xml_rpc, '/boolean', '0'
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ObjectTest < ActiveSupport::TestCase
|
4
|
+
class TestObject
|
5
|
+
attr_accessor :a, :b, :c
|
6
|
+
end
|
7
|
+
|
8
|
+
test 'Object#to_xml_rpc should collect instance_variables in a Hash and return Hash#to_xml_rpc' do
|
9
|
+
obj = TestObject.new
|
10
|
+
obj.a = "one"
|
11
|
+
obj.b = "two"
|
12
|
+
|
13
|
+
assert_equal({'a' => 'one', 'b' => 'two'}, obj.send(:_collect_ivars_in_hash))
|
14
|
+
|
15
|
+
obj.a.expects :to_xml_rpc
|
16
|
+
obj.b.expects :to_xml_rpc
|
17
|
+
|
18
|
+
obj.to_xml_rpc
|
19
|
+
end
|
20
|
+
|
21
|
+
test "Object.from_xml_rpc should accept nodes as strings" do
|
22
|
+
xml = "<int>42</int>"
|
23
|
+
|
24
|
+
Integer.expects :from_xml_rpc
|
25
|
+
Object.from_xml_rpc xml
|
26
|
+
end
|
27
|
+
|
28
|
+
test "Object.from_xml_rpc should accept Nokogiri nodes" do
|
29
|
+
xml = Nokogiri::XML.parse("<int>42</int>").root
|
30
|
+
|
31
|
+
Integer.expects :from_xml_rpc
|
32
|
+
Object.from_xml_rpc xml
|
33
|
+
end
|
34
|
+
|
35
|
+
test "Object.from_xml_rpc should delegate int nodes" do
|
36
|
+
xml = "<int>42</int>"
|
37
|
+
|
38
|
+
Integer.expects :from_xml_rpc
|
39
|
+
Object.from_xml_rpc xml
|
40
|
+
end
|
41
|
+
|
42
|
+
test "Object.from_xml_rpc should delegate string nodes" do
|
43
|
+
xml = "<string>foo<string>"
|
44
|
+
|
45
|
+
String.expects :from_xml_rpc
|
46
|
+
Object.from_xml_rpc xml
|
47
|
+
end
|
48
|
+
|
49
|
+
test "Object.from_xml_rpc should delegate array nodes" do
|
50
|
+
xml = "<array>42</array>"
|
51
|
+
|
52
|
+
Array.expects :from_xml_rpc
|
53
|
+
Object.from_xml_rpc xml
|
54
|
+
end
|
55
|
+
|
56
|
+
test "Object.from_xml_rpc should delegate hash nodes" do
|
57
|
+
xml = "<struct>42</struct>"
|
58
|
+
|
59
|
+
Hash.expects :from_xml_rpc
|
60
|
+
Object.from_xml_rpc xml
|
61
|
+
end
|
62
|
+
|
63
|
+
test "Object.from_xml_rpc should delegate boolean nodes" do
|
64
|
+
xml = "<boolean>1</boolean>"
|
65
|
+
|
66
|
+
Rapuncel::Boolean.expects :from_xml_rpc
|
67
|
+
Object.from_xml_rpc xml
|
68
|
+
end
|
69
|
+
|
70
|
+
test "Object.from_xml_rpc should delegate double nodes" do
|
71
|
+
xml = "<double>42.23</double>"
|
72
|
+
|
73
|
+
Float.expects :from_xml_rpc
|
74
|
+
Object.from_xml_rpc xml
|
75
|
+
end
|
76
|
+
|
77
|
+
test "Object.from_xml_rpc should delegate Time nodes" do
|
78
|
+
xml = "<dateTime.iso8601>2010-11-25T11:44:46+01:00</dateTime.iso8601>"
|
79
|
+
|
80
|
+
Time.expects :from_xml_rpc
|
81
|
+
Object.from_xml_rpc xml
|
82
|
+
end
|
83
|
+
end
|