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.
Files changed (42) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +171 -0
  3. data/Rakefile +24 -0
  4. data/lib/rapuncel.rb +25 -0
  5. data/lib/rapuncel/adapters/net_http_adapter.rb +34 -0
  6. data/lib/rapuncel/base.rb +7 -0
  7. data/lib/rapuncel/client.rb +54 -0
  8. data/lib/rapuncel/connection.rb +75 -0
  9. data/lib/rapuncel/core_ext/array.rb +23 -0
  10. data/lib/rapuncel/core_ext/big_decimal.rb +7 -0
  11. data/lib/rapuncel/core_ext/boolean.rb +29 -0
  12. data/lib/rapuncel/core_ext/float.rb +11 -0
  13. data/lib/rapuncel/core_ext/hash.rb +32 -0
  14. data/lib/rapuncel/core_ext/integer.rb +11 -0
  15. data/lib/rapuncel/core_ext/nil.rb +7 -0
  16. data/lib/rapuncel/core_ext/object.rb +49 -0
  17. data/lib/rapuncel/core_ext/string.rb +12 -0
  18. data/lib/rapuncel/core_ext/symbol.rb +7 -0
  19. data/lib/rapuncel/core_ext/time.rb +14 -0
  20. data/lib/rapuncel/proxy.rb +82 -0
  21. data/lib/rapuncel/request.rb +49 -0
  22. data/lib/rapuncel/response.rb +92 -0
  23. data/rapuncel-0.0.1.preview.gem +0 -0
  24. data/rapuncel.gemspec +22 -0
  25. data/test/functional/client_test.rb +54 -0
  26. data/test/functional_test_helper.rb +13 -0
  27. data/test/test_helper.rb +38 -0
  28. data/test/test_server.rb +28 -0
  29. data/test/unit/array_test.rb +96 -0
  30. data/test/unit/boolean_test.rb +34 -0
  31. data/test/unit/connection_test.rb +17 -0
  32. data/test/unit/float_test.rb +23 -0
  33. data/test/unit/hash_test.rb +54 -0
  34. data/test/unit/int_test.rb +27 -0
  35. data/test/unit/nil_test.rb +16 -0
  36. data/test/unit/object_test.rb +83 -0
  37. data/test/unit/proxy_test.rb +52 -0
  38. data/test/unit/request_test.rb +34 -0
  39. data/test/unit/response_test.rb +100 -0
  40. data/test/unit/string_test.rb +40 -0
  41. data/test/unit/time_test.rb +23 -0
  42. 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
@@ -0,0 +1,13 @@
1
+ require 'test_helper'
2
+ require 'test_server'
3
+
4
+ class FunctionalTest < ActiveSupport::TestCase
5
+ def setup
6
+ @test_server = TestServer.new
7
+ @test_server.start
8
+ end
9
+
10
+ def teardown
11
+ @test_server.stop
12
+ end
13
+ end
@@ -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
@@ -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