rapuncel 0.0.1.alpha

Sign up to get free protection for your applications and to get access to all the features.
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