rapuncel 0.0.1.alpha → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/README.md +33 -36
  2. data/{Rakefile → Rakefile.rb} +1 -1
  3. data/lib/rapuncel.rb +1 -2
  4. data/lib/rapuncel/adapters/net_http_adapter.rb +6 -6
  5. data/lib/rapuncel/adapters/typhoeus_adapter.rb +33 -0
  6. data/lib/rapuncel/base.rb +2 -2
  7. data/lib/rapuncel/client.rb +13 -21
  8. data/lib/rapuncel/connection.rb +2 -2
  9. data/lib/rapuncel/core_ext/array.rb +16 -9
  10. data/lib/rapuncel/core_ext/big_decimal.rb +0 -7
  11. data/lib/rapuncel/core_ext/boolean.rb +13 -10
  12. data/lib/rapuncel/core_ext/float.rb +7 -4
  13. data/lib/rapuncel/core_ext/hash.rb +27 -17
  14. data/lib/rapuncel/core_ext/integer.rb +10 -2
  15. data/lib/rapuncel/core_ext/object.rb +6 -6
  16. data/lib/rapuncel/core_ext/string.rb +7 -5
  17. data/lib/rapuncel/core_ext/symbol.rb +3 -2
  18. data/lib/rapuncel/core_ext/time.rb +8 -5
  19. data/lib/rapuncel/fault.rb +10 -0
  20. data/lib/rapuncel/proxy.rb +14 -39
  21. data/lib/rapuncel/request.rb +6 -7
  22. data/lib/rapuncel/response.rb +31 -69
  23. data/rapuncel.gemspec +4 -3
  24. data/test/coverage/-Users-mariantheisen-Projects-Kayoom-rapuncel-lib-rapuncel-adapters-typhoeus_adapter_rb.html +231 -0
  25. data/test/coverage/-Users-mariantheisen-Projects-Kayoom-rapuncel-lib-rapuncel-base_rb.html +105 -0
  26. data/test/coverage/-Users-mariantheisen-Projects-Kayoom-rapuncel-lib-rapuncel-client_rb.html +321 -0
  27. data/test/coverage/-Users-mariantheisen-Projects-Kayoom-rapuncel-lib-rapuncel-connection_rb.html +513 -0
  28. data/test/coverage/-Users-mariantheisen-Projects-Kayoom-rapuncel-lib-rapuncel-core_ext-array_rb.html +303 -0
  29. data/test/coverage/-Users-mariantheisen-Projects-Kayoom-rapuncel-lib-rapuncel-core_ext-boolean_rb.html +255 -0
  30. data/test/coverage/-Users-mariantheisen-Projects-Kayoom-rapuncel-lib-rapuncel-core_ext-float_rb.html +177 -0
  31. data/test/coverage/-Users-mariantheisen-Projects-Kayoom-rapuncel-lib-rapuncel-core_ext-hash_rb.html +297 -0
  32. data/test/coverage/-Users-mariantheisen-Projects-Kayoom-rapuncel-lib-rapuncel-core_ext-integer_rb.html +177 -0
  33. data/test/coverage/-Users-mariantheisen-Projects-Kayoom-rapuncel-lib-rapuncel-core_ext-object_rb.html +297 -0
  34. data/test/coverage/-Users-mariantheisen-Projects-Kayoom-rapuncel-lib-rapuncel-core_ext-string_rb.html +159 -0
  35. data/test/coverage/-Users-mariantheisen-Projects-Kayoom-rapuncel-lib-rapuncel-core_ext-time_rb.html +165 -0
  36. data/test/coverage/-Users-mariantheisen-Projects-Kayoom-rapuncel-lib-rapuncel-fault_rb.html +93 -0
  37. data/test/coverage/-Users-mariantheisen-Projects-Kayoom-rapuncel-lib-rapuncel-proxy_rb.html +393 -0
  38. data/test/coverage/-Users-mariantheisen-Projects-Kayoom-rapuncel-lib-rapuncel-request_rb.html +351 -0
  39. data/test/coverage/-Users-mariantheisen-Projects-Kayoom-rapuncel-lib-rapuncel-response_rb.html +399 -0
  40. data/test/coverage/-Users-mariantheisen-Projects-Kayoom-rapuncel-lib-rapuncel_rb.html +201 -0
  41. data/test/coverage/functional_test_helper_rb.html +141 -0
  42. data/test/coverage/index.html +410 -0
  43. data/test/coverage/jquery-1.3.2.min.js +19 -0
  44. data/test/coverage/jquery.tablesorter.min.js +15 -0
  45. data/test/coverage/print.css +12 -0
  46. data/test/coverage/rcov.js +42 -0
  47. data/test/coverage/screen.css +270 -0
  48. data/test/coverage/test_helper_rb.html +291 -0
  49. data/test/coverage/test_server_rb.html +231 -0
  50. data/test/functional/client_test.rb +7 -38
  51. data/test/functional_test_helper.rb +2 -2
  52. data/test/test_server.rb +29 -3
  53. data/test/unit/array_test.rb +14 -14
  54. data/test/unit/boolean_test.rb +6 -6
  55. data/test/unit/float_test.rb +7 -7
  56. data/test/unit/hash_test.rb +16 -16
  57. data/test/unit/object_test.rb +29 -29
  58. data/test/unit/proxy_test.rb +9 -9
  59. data/test/unit/response_test.rb +5 -69
  60. data/test/unit/string_test.rb +7 -15
  61. metadata +56 -20
  62. data/lib/rapuncel/core_ext/nil.rb +0 -7
  63. data/rapuncel-0.0.1.preview.gem +0 -0
  64. data/test/unit/nil_test.rb +0 -16
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Rapuncel - Simple XML-RPC Client
2
2
 
3
- Rapuncel ([wikipedia](http://en.wikipedia.org/wiki/Rapunzel)) is a simple and lightweight, but fast XML-RPC client library for ruby.
4
- It's based on Nokogiri for XML parsing and thus provides a major performance improvement for large XML responses.
3
+ Rapuncel ([wikipedia](http://en.wikipedia.org/wiki/Rapunzel)) is a simple and lightweight, but fast XML-RPC client library for ruby.
4
+ It's based on Nokogiri for XML parsing and thus provides a major performance improvement for large XML responses.
5
5
 
6
6
  ## Installation
7
7
 
@@ -9,18 +9,18 @@ It's based on Nokogiri for XML parsing and thus provides a major performance imp
9
9
  Add this to your Gemfile:
10
10
 
11
11
  gem 'rapuncel'
12
-
13
- Run
12
+
13
+ Run
14
14
 
15
15
  bundle install
16
-
17
- and you're good to go.
18
-
16
+
17
+ and you're good to go.
18
+
19
19
  ### Other Ruby / IRB
20
20
  Install it as gem:
21
21
 
22
22
  gem install rapuncel
23
-
23
+
24
24
  Require **rubygems** and **rapuncel**
25
25
 
26
26
  require 'rubygems'
@@ -34,50 +34,47 @@ object.
34
34
  First you have to create a client with the connection details, e.g.
35
35
 
36
36
  client = Rapuncel::Client.new :host => 'localhost', :port => 8080, :path => '/xmlrpc'
37
-
37
+
38
38
  Available options are:
39
39
 
40
40
  * **host**
41
- hostname or ip-address,
41
+ hostname or ip-address,
42
42
  _default_: localhost
43
43
  * **port**
44
- port where your XMLRPC service is listening,
44
+ port where your XMLRPC service is listening,
45
45
  _default_: 8080
46
46
  * **path**
47
- path to the service,
47
+ path to the service,
48
48
  _default_: /
49
49
  * **user**
50
- Username for HTTP Authentication
50
+ Username for HTTP Authentication
51
51
  _default_: _empty_
52
52
  * **password**
53
- Username for HTTP Authentication
53
+ Username for HTTP Authentication
54
54
  _default_: _empty_
55
55
  * **auth\_method**
56
- HTTP Auth method
56
+ HTTP Auth method
57
57
  _default_: basic **IF** user or password is set
58
58
  * **api\_key**
59
59
  If set, sends all request with a X-ApiKey: _api\_key_ header
60
60
  * **api\_key\_header**
61
- Allows you to modify the header key for API-Key auth
61
+ Allows you to modify the header key for API-Key auth
62
62
  _default_: X-ApiKey
63
- * **raise_on**
64
- Lets you define the behavior on errors or faults, if set to _:fault_, _:error_ or _:both_,
65
- an Exception will be raised if something goes wrong
66
63
 
67
- ### Get a proxy object and ...
64
+ ### Get a proxy object and ...
68
65
  A proxy object receives ruby method calls, redirects them to your XMLRPC service and returns the response as ruby objects!
69
-
66
+
70
67
  proxy = client.proxy
71
-
68
+
72
69
  # suppose your XMLRPC service has a method exposed 'concat_string(string1, string2)'
73
70
  proxy.concat_string "foo", "bar"
74
71
  -> "foobar"
75
-
72
+
76
73
  # if you need to access specific interfaces on your service, e.g. 'string.concat(string1, string2)'
77
74
  proxy = client.proxy_for 'string'
78
75
  proxy.concat 'foo', 'bar'
79
76
  -> 'foobar'
80
-
77
+
81
78
  ## Supported objects
82
79
  Rapuncel supports natively following object-types (and all their subclasses):
83
80
 
@@ -87,7 +84,6 @@ Rapuncel supports natively following object-types (and all their subclasses):
87
84
  * Hash
88
85
  * TrueClass, FalseClass
89
86
  * Float
90
- * BigDecimal (treated like Float)
91
87
  * Time, Time-like objects
92
88
 
93
89
  * Symbols are converted to Strings
@@ -111,33 +107,34 @@ Of course you don't have to delegate to #to\_s, you just can use the Builder obj
111
107
  You can use most methods via
112
108
 
113
109
  proxy.methodname *args
114
-
110
+
115
111
  However methods starting with \_\_, or ending with a bang \! or a question mark ? are not supported. To call those methods you can always
116
112
  use
117
113
 
118
114
  proxy.call! 'methodname', *args
119
-
115
+
120
116
  or via
121
117
 
122
118
  client.call_to_ruby 'methodname', *args
119
+
120
+ note
123
121
 
124
- note
125
-
126
- client.call 'methodname', *args
127
-
122
+ client.call 'methodname', *args
123
+
128
124
  will return a Rapuncel::Response object, use _call\_to\_ruby_ to get standard ruby objects
129
125
 
130
126
  ## Todo ?
131
127
 
132
- * RDoc
133
- * Extensive functional tests
134
- * Async requests
135
128
  * Base64 support (or rather a consistent concept for Base64)
136
129
  * XMLRPC Extensions (pluggable support)
130
+ * RDoc
131
+ * Extensive functional tests
137
132
 
138
133
  ## What happens if something goes wrong?
139
- ### HTTP Errors / XMLRPC Faults
140
- See Usage -> configuration -> raise\_on switch
134
+ ### HTTP Errors
135
+ Any HTTP response but 200 OK will raise an error, containing the returned status code and response body.
136
+ ### XMLRPC Faults
137
+ If the XMLRPC response is 'fault', a Rapuncel::Fault object will be returned, having a _code_ and a _string_ attribute
141
138
  ### Malformed XML/XMLRPC
142
139
  Rapuncel will most likely fail hard.
143
140
 
@@ -19,6 +19,6 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
19
19
  rdoc.rdoc_dir = 'rdoc'
20
20
  rdoc.title = 'Rapuncel'
21
21
  rdoc.options << '--line-numbers' << '--inline-source'
22
- rdoc.rdoc_files.include('README.md')
22
+ rdoc.rdoc_files.include('README')
23
23
  rdoc.rdoc_files.include('lib/**/*.rb')
24
24
  end
data/lib/rapuncel.rb CHANGED
@@ -1,4 +1,4 @@
1
-
1
+ require 'builder'
2
2
 
3
3
  require 'active_support/core_ext/hash/keys'
4
4
 
@@ -20,6 +20,5 @@ require 'rapuncel/core_ext/float'
20
20
  require 'rapuncel/core_ext/hash'
21
21
  require 'rapuncel/core_ext/array'
22
22
  require 'rapuncel/core_ext/boolean'
23
- require 'rapuncel/core_ext/nil'
24
23
 
25
24
  require 'rapuncel/core_ext/time'
@@ -5,28 +5,28 @@ module Rapuncel
5
5
  module Adapters
6
6
  module NetHttpAdapter
7
7
  extend ActiveSupport::Memoizable
8
-
8
+
9
9
  class HttpResponse
10
10
  def initialize response
11
11
  @response = response
12
12
  end
13
-
13
+
14
14
  def success?
15
15
  @response.is_a? Net::HTTPOK
16
16
  end
17
-
17
+
18
18
  def body
19
19
  @response.body
20
20
  end
21
-
21
+
22
22
  def code
23
23
  @response.code
24
24
  end
25
25
  end
26
-
26
+
27
27
  def send_method_call str
28
28
  req = Net::HTTP.new connection.host, connection.port
29
-
29
+
30
30
  HttpResponse.new req.post(connection.path, str, connection.headers.stringify_keys)
31
31
  end
32
32
  end
@@ -0,0 +1,33 @@
1
+ require 'typhoeus'
2
+ require 'active_support/memoizable'
3
+
4
+ module Rapuncel
5
+ module Adapters
6
+ module TyphoeusAdapter
7
+ extend ActiveSupport::Memoizable
8
+
9
+
10
+ def send_method_call str
11
+ Typhoeus::Request.post connection.url, typhoeus_params.merge(:body => str)
12
+ end
13
+
14
+ protected
15
+ def typhoeus_params
16
+ {
17
+ :headers => connection.headers
18
+ }.merge auth_params
19
+ end
20
+ memoize :typhoeus_params
21
+
22
+ def auth_params
23
+ return {} unless connection.http_auth?
24
+
25
+ {
26
+ :user => connection.user,
27
+ :password => connection.password,
28
+ :auth_method => connection.auth_method
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
data/lib/rapuncel/base.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Rapuncel
2
- BUILDER_OPTIONS = {:encoding => 'UTF-8'}
2
+ BUILDER_OPTIONS = {}
3
3
 
4
4
  def self.get_builder options = {}
5
- Nokogiri::XML::Builder.new options
5
+ Builder::XmlMarkup.new BUILDER_OPTIONS.merge(options)
6
6
  end
7
7
  end
@@ -1,34 +1,28 @@
1
+ # require 'rapuncel/adapters/typhoeus_adapter'
1
2
  require 'rapuncel/adapters/net_http_adapter'
2
3
  require 'rapuncel/connection'
3
- require 'active_support/core_ext/hash/except'
4
+
4
5
 
5
6
  module Rapuncel
6
7
  class Client
7
- attr_accessor :connection, :raise_on_fault, :raise_on_error
8
+ attr_accessor :connection
8
9
 
9
10
  include Adapters::NetHttpAdapter
10
11
 
11
12
  def proxy_for interface
12
13
  Proxy.new self, interface
13
14
  end
14
-
15
+
15
16
  def proxy
16
17
  proxy_for nil
17
18
  end
18
19
 
19
20
  def initialize configuration = {}
20
- @connection = Connection.build configuration.except(:raise_on)
21
+ @connection = init_connection(configuration)
22
+ end
21
23
 
22
- @raise_on_fault, @raise_on_error = case configuration[:raise_on]
23
- when :fault
24
- [true, false]
25
- when :error
26
- [false, true]
27
- when :both
28
- [true, true]
29
- else
30
- [false, false]
31
- end
24
+ def init_connection configuration = {}
25
+ Connection.build configuration
32
26
  end
33
27
 
34
28
  def call name, *args
@@ -36,18 +30,16 @@ module Rapuncel
36
30
  end
37
31
 
38
32
  def call_to_ruby name, *args
39
- response = call name, *args
40
-
41
- raise_on_fault && response.fault? && raise(response.fault)
42
- raise_on_error && response.error? && raise(response.error)
33
+ call(name, *args).to_ruby
34
+ end
43
35
 
44
- response.to_ruby
36
+ def execute_to_ruby request
37
+ execute(request).to_ruby
45
38
  end
46
39
 
47
- protected
48
40
  def execute request
49
41
  xml = request.to_xml_rpc
50
-
42
+
51
43
  Response.new send_method_call(xml)
52
44
  end
53
45
  end
@@ -17,7 +17,7 @@ module Rapuncel
17
17
  alias_method :ssl?, :ssl
18
18
 
19
19
  def initialize configuration = {}
20
-
20
+
21
21
  @host = configuration[:host] || 'localhost'
22
22
  @port = configuration[:port] || '8080'
23
23
  @path = configuration[:path] || '/'
@@ -33,7 +33,7 @@ module Rapuncel
33
33
  def url
34
34
  "http://#{host}:#{port}#{path}"
35
35
  end
36
-
36
+
37
37
  def headers
38
38
  @headers.merge :Accept => 'text/xml', :'content-type' => 'text/xml'
39
39
  end
@@ -1,23 +1,30 @@
1
+ require 'builder'
2
+ require 'nokogiri'
3
+
1
4
  class Array
5
+
2
6
  def to_xml_rpc b = Rapuncel.get_builder
3
- b.array do |b|
4
- b.data do |b|
7
+
8
+ b.array do
9
+ b.data do
5
10
  each do |array_entry|
6
- b.value do |b|
11
+ b.value do
7
12
  array_entry.to_xml_rpc b
8
13
  end
9
14
  end
10
15
  end
11
16
  end
12
-
13
- b.to_xml
14
17
  end
15
-
18
+
19
+
16
20
  def self.from_xml_rpc xml_node
17
- values = xml_node.first_element_child.element_children
18
-
21
+ #warn "Warning: This is not an array-node (It is a(n) #{xml_node.name}.). Parsing may go wrong. Continuing at your risk" unless ['array'].include? xml_node.name.downcase
22
+
23
+
24
+ values = xml_node.first_element_child.element_children #xpath('./data/value/*')
25
+
19
26
  values.map do |value|
20
27
  Object.from_xml_rpc value.first_element_child
21
- end
28
+ end
22
29
  end
23
30
  end
@@ -1,7 +0,0 @@
1
- class BigDecimal
2
- def to_xml_rpc b = Rapuncel.get_builder
3
- b.double self.to_s
4
-
5
- b.to_xml
6
- end
7
- end
@@ -1,29 +1,32 @@
1
+ require 'builder'
2
+ require 'nokogiri'
3
+
1
4
  class TrueClass
5
+
2
6
  def to_xml_rpc b = Rapuncel.get_builder
3
7
  b.boolean "1"
4
-
5
- b.to_xml
6
8
  end
7
9
  end
8
10
 
11
+
9
12
  class FalseClass
13
+
10
14
  def to_xml_rpc b = Rapuncel.get_builder
11
15
  b.boolean "0"
12
-
13
- b.to_xml
14
16
  end
15
17
  end
16
18
 
17
- # this is to catch the from_xml_rpc call from Object
18
- class Rapuncel::Boolean
19
- def self.from_xml_rpc xml_node
20
19
 
21
- # DISCUSS: need convention here:
20
+ class Rapuncel::Boolean #this is to catch the from_xml_rpc call from Object
21
+ def self.from_xml_rpc xml_node
22
+ #warn "This node is not boolean (it is #{xml_node.name}), but will be treated as one at your request. keep in mind that 1 means true and all the rest will be false" unless ['boolean'].include? xml_node.name.downcase
23
+
24
+ #need convention here:
22
25
  case xml_node.text.downcase
23
26
  when '1'
24
27
  true
25
28
  else
26
29
  false
27
- end
28
- end
30
+ end
31
+ end
29
32
  end
@@ -1,11 +1,14 @@
1
+ require 'builder'
2
+ require 'nokogiri'
3
+
1
4
  class Float
2
5
  def self.from_xml_rpc xml_node
3
- xml_node.text.strip.to_f #calling to_float on the text between the (hopefully correct) tags
6
+ #warn "Node given (name of #{xml_node.name}) is not a 'double' node, name should be 'double'. Will still parse, at your risk." unless ['double'].include? xml_node.name.downcase
7
+
8
+ xml_node.text.to_f #calling to_float on the text between the (hopefully correct) tags
4
9
  end
5
-
10
+
6
11
  def to_xml_rpc b = Rapuncel.get_builder
7
12
  b.double to_s
8
-
9
- b.to_xml
10
13
  end
11
14
  end