remote_api 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt CHANGED
@@ -12,7 +12,9 @@ lib/remote_api/xml_response.rb
12
12
 
13
13
  lib/remote_api/version.rb
14
14
 
15
- test/test_helper.rb
16
- test/base_test.rb
17
- test/xml_test.rb
18
- test/xml_response_test.rb
15
+ test/spec_test.rb
16
+
17
+ spec/base_spec.rb
18
+ spec/spec_helper.rb
19
+ spec/xml_response_spec.rb
20
+ spec/xml_spec.rb
data/README.txt CHANGED
@@ -1,41 +1,112 @@
1
- Simple Readme for now.
1
+ = Remote API
2
2
 
3
3
  Rubyforge Project: http://rubyforge.org/projects/remote-api/
4
4
 
5
- === Installation
5
+ Installation: <tt>gem install remote_api</tt>
6
6
 
7
- gem install remote_api
7
+ == Overview
8
8
 
9
- === Example
9
+ +RemoteAPI+ is an abstraction from API classes. I noticed that there was very overlapping
10
+ functionality in the various API wrappers I had going. This gem will make it much easier to
11
+ write an API wrapper by taking care of the common stuff. All you have to do is write the
12
+ parts that are specific to the API you are talking to.
13
+
14
+ === Usage and Checklist
15
+
16
+ To use this gem you should follow this simple checklist of things that you must implement on
17
+ your own.
18
+
19
+ 1. Create a class that descends from RemoteAPI: <tt>class Foo < RemoteAPI; end</tt>
20
+ 2. Define the url to access with the url dsl_accessor <tt>url 'some url here'</tt>
21
+ 3. Add a +request+ method to your class. This should return the body of your request.
22
+ 4. Add a +assert_response+ method. This method should raise exceptions if the contents
23
+ of <tt>@response</tt> describe a fatal error.
24
+ 5. Add a +process+ method. This parses the API response. It should pull the relevant
25
+ data out of the <tt>@response</tt> object and put it in instance variables.
26
+ 6. Create <tt>attr_reader</tt>s for the instance variables from the +process+ method that
27
+ you want to expose as methods.
28
+
29
+ === Basic Walkthrough
30
+
31
+ I'm going to explain just what happens under the hood of a class that inherits from RemoteAPI.
32
+
33
+ So lets say that I am writing an API to ship a package. It requires address and weight, each
34
+ on their own line in a YAML like format. On success, it returns the tracking number of the
35
+ package. On failure it just says "There was an error!".
36
+
37
+ Here is an API class that can handle that:
10
38
 
11
- This is an example of how to access a little API that allows you to change the title of an object.
12
- The API would return the title, but in Title Case, and we want to capture that.
13
-
14
39
  require 'remote_api'
15
40
 
16
- class MyAPI < RemoteAPI
17
-
18
- attr_reader :title
19
-
20
- url 'http://test.com/posts/change_title'
41
+ class Shipment < RemoteAPI
42
+ attr_reader :tracking_number
43
+ url 'http://test.com/shipments'
21
44
 
22
45
  def request
23
- "title=#{@title}&post_id={@post_id}"
46
+ <<-EOF
47
+ address: #{@address}
48
+ weight: #{@weight}
49
+ EOF
24
50
  end
25
51
 
26
52
  def assert_success
27
- if @response =~ /&?error=(.+?)&?/
28
- raise ResponseFailure, $1
29
- end
53
+ raise ResponseFailure if @response =~ /error/
30
54
  end
31
55
 
32
56
  def process
33
- @title = @response.match(/&?title=(.+?)&?/)[1]
57
+ @tracking_number = @response
34
58
  end
35
59
 
36
60
  end
61
+
62
+ All the magic happens on instantiation. The request is built and sent, and the response is
63
+ processed. It all starts with:
64
+
65
+ Shipment.new(:address => '123 Fake St', :weight => 12)
66
+
67
+ ==== Instantiation
68
+
69
+ The hash passed to +new+ is converted to instance variables. In this case the Shipment instance
70
+ now has <tt>@address</tt> and <tt>@weight</tt> instance variables in it.
71
+
72
+ ==== Building the request
73
+
74
+ The next step is the +request+ method is called. This should return a string, something that can
75
+ be converted to a sttring. This string will be sent out as the request body to the remote server.
76
+
77
+ ==== Sending the request
78
+
79
+ Now that we have built the request, the connection is made to the remote server at the url defined
80
+ by the dsl_accessor +url+. The request is sent with the result of the +request+ method as the body.
81
+ What the server returns is stored in the <tt>@response</tt> variable. This all happens automatically.
82
+
83
+ ==== Assertion of Success
84
+
85
+ Most API's have some sort of error reporting. The <tt>assert_success</tt> method is for raising
86
+ exceptions if the API reports any errors. The ResponseFailure exception is built into RemoteAPI.
87
+ Parse the response to see if it reports errors.
88
+
89
+ ==== Processing the response
90
+
91
+ You must deinfe a +process+ method. This method will parse the response and stuff any needed data into
92
+ instance varibales. In this case, we are simply getting the entire response since that will be the
93
+ only tracking number that we are expecting.
94
+
95
+ ==== Using the result
96
+
97
+ Define a <tt>attr_reader</tt> for each instance variable from the +process+ you want exposed. Then use
98
+ your new object as you would any other object
99
+
100
+ pkg = Shipment.new(:address => '123 Fake St', :weight => 12)
101
+ puts "Sucess! Your tracking number is #{pkg.tracking_number}"
37
102
 
38
- result = MyAPI.new(:post_id => 123, :title => 'hello world')
39
- # API call happens here
103
+ ==== Using the result with Exception handling
104
+
105
+ You probably don't want your whole app to crash if there is an API error. This is why ruby has exception
106
+ handling
40
107
 
41
- result.title #=> 'Hello World'
108
+ begin
109
+ pkg = Shipment.new(:address => '123 Fake St', :weight => 'foo')
110
+ rescue RemoteAPI::ResponseFailure
111
+ puts "Unable to ship that package. The API really didn't like it."
112
+ end
data/Rakefile CHANGED
@@ -46,4 +46,21 @@ hoe = Hoe.new(GEM_NAME, VERS) do |p|
46
46
  #p.changes - A description of the release's latest changes.
47
47
  p.extra_deps = [['activesupport'], ['dsl_accessor']]
48
48
  #p.spec_extras - A hash of extra values to set in the gemspec.
49
+ end
50
+
51
+ require 'spec/rake/spectask'
52
+ desc "Run all specifications"
53
+ Spec::Rake::SpecTask.new('spec') do |t|
54
+ t.spec_files = FileList['spec/**/*.rb']
55
+ end
56
+
57
+ desc "Run all specification with spec output"
58
+ Spec::Rake::SpecTask.new('spec_print') do |t|
59
+ t.spec_files = FileList['spec/**/*.rb']
60
+ t.spec_opts = ["-f", "s"]
61
+ end
62
+
63
+ desc "Tell you to run specs instead of tests"
64
+ task :test do
65
+ puts "This gem has specs, not tests. Run 'rake spec' or 'rake spec_print' instead"
49
66
  end
@@ -1,42 +1,71 @@
1
1
  class RemoteAPI
2
2
  class ResponseFailure < RuntimeError; end
3
3
 
4
- dsl_accessor :debug
4
+ dsl_accessor :debug
5
5
  dsl_accessor :log_file
6
6
  dsl_accessor :url
7
7
  dsl_accessor :content_type
8
-
9
- class ResponseFailure < RuntimeError; end
10
8
 
11
- # Eeverything happens on instantiation. Pass in a hash, and each key in the hash will
12
- # become an instance variable for use in the rest of the instance methods.
9
+ class ResponseFailure < RuntimeError; end
10
+
11
+ # Prepare a new API object. This will not make the actual remote
12
+ # call until the +call+ method is used. To execute the API call
13
+ # immediately, use the +call+ class method.
14
+ #
15
+ # Any options you pass in as a hash will be created as instance
16
+ # variables. So the below example will have an instance variable
17
+ # <tt>@foo</tt> in the generated API object.
18
+ #
19
+ # api = MyApi.new(:foo => 'bar')
20
+ # api.call
21
+ # api.some_result #=> "You said bar!"
13
22
  #
14
- # Then we send the request, assert that is the response is successful, and process the
15
- # response.
16
23
  def initialize(params = {})
17
24
  params.each do |k, v|
18
25
  instance_variable_set "@#{k}", v
19
26
  end
20
-
21
- send_request
22
- assert_success
23
- process
27
+ end
28
+
29
+ # Instatiate and call the API in one step.
30
+ #
31
+ # api = MyApi.call(:foo => 'bar')
32
+ # api.some_result #=> "You said bar!"
33
+ #
34
+ def self.call(params = {})
35
+ returning new(params) do |api|
36
+ api.call
37
+ end
38
+ end
39
+
40
+ # Execute an instance of an API object that has not been sent to the
41
+ # remote server yet.
42
+ #
43
+ # api = MyApi.new(:foo => 'bar')
44
+ # api.call
45
+ # api.some_result #=> "You said bar!"
46
+ #
47
+ def call
48
+ returning self do
49
+ send_request
50
+ assert_success
51
+ process
52
+ end
24
53
  end
25
54
 
26
55
  private
27
56
 
28
- # Send the request to the UPS servers
57
+ # Send the request to the remote servers
29
58
  def send_request(request_body = nil)
30
59
  request_body ||= request
31
60
  debug_request(request_body)
32
61
 
33
62
  # Setup HTTP objects
34
- url = URI.parse(server_url)
35
- http = Net::HTTP.new(url.host, url.port)
63
+ url = URI.parse(server_url)
64
+ http = Net::HTTP.new(url.host, url.port)
36
65
 
37
66
  if url.is_a?(URI::HTTPS)
38
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
39
- http.use_ssl = true
67
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
68
+ http.use_ssl = true
40
69
  end
41
70
 
42
71
  # Setup request options
@@ -49,28 +78,30 @@ class RemoteAPI
49
78
 
50
79
  # Convert response to proper format
51
80
  @response = prepare_response(response)
52
-
53
- # Code hook to raise execption if error conditions are met
81
+
82
+ # Code hook to raise execption if error conditions are met
54
83
  assert_success
55
84
  end
56
85
 
57
- def assert_success
58
- true
59
- end
86
+ # override this method and raises exception on failure
87
+ def assert_success; end
60
88
 
89
+ # override this method to parse your response
61
90
  def process
62
- raise 'You must define a "process" method! This should should parse the @response and' +
63
- 'extract relevant data.'
64
- end
65
-
66
- def request
67
- raise 'You must define a "request" method! This should create the body of your API request'
91
+ raise 'You must define a "process" method! This should should parse the @response and extract relevant data.'
92
+ end
93
+
94
+ # override this method to define your request body
95
+ def request
96
+ raise 'You must define a "request" method! This should create the body of your API request'
68
97
  end
69
98
 
99
+ # Convert response to proper format
70
100
  def prepare_response(response)
71
101
  response.body
72
102
  end
73
103
 
104
+ # Get the full path to the remote server
74
105
  def server_url
75
106
  url = self.class.url
76
107
 
@@ -78,7 +109,11 @@ class RemoteAPI
78
109
  when 'String'
79
110
  url
80
111
  when 'Hash'
81
- url.symbolize_keys[ENV['RAILS_ENV'].to_sym]
112
+ if env = ENV['RAILS_ENV']
113
+ url.symbolize_keys[ENV['RAILS_ENV'].to_sym]
114
+ else
115
+ raise 'Cannot use a hash for server url outside of a rails environment'
116
+ end
82
117
  when 'Proc'
83
118
  url.call
84
119
  else
@@ -86,16 +121,17 @@ class RemoteAPI
86
121
  end
87
122
  end
88
123
 
124
+ # Convert reponse to proper format
89
125
  def format_response(response)
90
126
  response
91
127
  end
92
-
93
- def log(data)
94
- data = "\n\n\n\n\n*** #{Time.now}\n\n" + data
95
- if file = self.class.log_file
96
- File.open(file, 'a') { |f| f.write data }
97
- end
98
- end
128
+
129
+ def log(data)
130
+ data = "\n\n\n\n\n*** #{Time.now}\n\n" + data
131
+ if file = self.class.log_file
132
+ File.open(file, 'a') { |f| f.write data }
133
+ end
134
+ end
99
135
 
100
136
  def debug_request(request_body)
101
137
  return unless self.class.debug || self.class.log_file
@@ -106,8 +142,8 @@ class RemoteAPI
106
142
  -----------
107
143
 
108
144
  #{request_body}
109
- DEBUG
110
- puts text if self.class.debug
145
+ DEBUG
146
+ puts text if self.class.debug
111
147
  log(text) if self.class.log_file
112
148
  end
113
149
 
@@ -125,9 +161,9 @@ DEBUG
125
161
 
126
162
  #{text}
127
163
 
128
- DEBUG
129
-
130
- puts text if self.class.debug
164
+ DEBUG
165
+
166
+ puts text if self.class.debug
131
167
  log(text) if self.class.log_file
132
168
  end
133
169
  end
@@ -1,8 +1,8 @@
1
1
  class RemoteAPI #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 1
5
- TINY = 2
4
+ MINOR = 2
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
data/lib/remote_api.rb CHANGED
@@ -8,6 +8,6 @@ require 'active_support'
8
8
  require 'dsl_accessor'
9
9
 
10
10
  # remote_api
11
- require 'remote_api/base'
12
- require 'remote_api/xml'
13
- require 'remote_api/xml_response'
11
+ %w( base xml xml_response ).each do |file|
12
+ require File.dirname(__FILE__) + '/remote_api/' + file
13
+ end
data/spec/base_spec.rb ADDED
@@ -0,0 +1,65 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ FakeWeb.register_uri(
4
+ 'http://test.com/base',
5
+ :string => '<server_response>The server recieved your message</server_response>'
6
+ )
7
+ FakeWeb.register_uri(
8
+ 'http://test.com/base/error',
9
+ :string => '<server_response>An error occurred!</server_response>'
10
+ )
11
+
12
+ context "A Generic API" do
13
+
14
+ setup do
15
+ BaseApi.url = 'http://test.com/base'
16
+ end
17
+
18
+ specify "'initialize'_should_set_hash_keys_as_instance_variables" do
19
+ api = BaseApi.new(:foo => 'bar', :baz => 'taz', :message => 'Hello')
20
+
21
+ api.instance_eval { @foo }.should_be == 'bar'
22
+ api.instance_eval { @baz }.should_be == 'taz'
23
+ api.instance_eval { @message }.should_be == 'Hello'
24
+ end
25
+
26
+ specify "instance method 'call' should perform API call" do
27
+ api = BaseApi.new(:message => 'Hello World!')
28
+ api.return_message.should_be_nil
29
+
30
+ api.call
31
+ api.return_message.should_be == 'The server recieved your message'
32
+ end
33
+
34
+ specify "class method 'call' should instantiate and call API" do
35
+ api = BaseApi.call(:message => 'Hello World!')
36
+ api.return_message.should_be == 'The server recieved your message'
37
+ end
38
+
39
+ specify "'assert_success' should raise and exception on an error" do
40
+ BaseApi.url = 'http://test.com/base/error'
41
+ proc { BaseApi.call(:message => 'foo') }.should_raise RemoteAPI::ResponseFailure
42
+ end
43
+
44
+ end
45
+
46
+
47
+ class BaseApi < RemoteAPI
48
+ attr_reader :return_message
49
+
50
+ def request
51
+ x = Builder::XmlMarkup.new
52
+ x.my_request @message
53
+ end
54
+
55
+ def assert_success
56
+ if @response =~ %r{<server_response>(.*error.*)</server_response>}
57
+ raise ResponseFailure, $1
58
+ end
59
+ end
60
+
61
+ def process
62
+ @return_message = @response.gsub(%r{</?server_response>}, '')
63
+ end
64
+
65
+ end
@@ -1,5 +1,3 @@
1
- require 'test/unit'
2
-
3
1
  require 'rubygems'
4
2
  require 'fake_web'
5
3
  require 'builder'
@@ -0,0 +1,77 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ context "An XML Response object" do
4
+
5
+ XML = <<XML
6
+ <response>
7
+ <title>Test Title</title>
8
+ <items>
9
+ <item>
10
+ <name>Bob</name>
11
+ <id>1</id>
12
+ </item>
13
+ <item>
14
+ <name>Joe</name>
15
+ <id>2</id>
16
+ </item>
17
+ <item>
18
+ <name>Walter</name>
19
+ <id>3</id>
20
+ </item>
21
+ </items>
22
+ </response>
23
+ XML
24
+
25
+ setup do
26
+ @xml = RemoteAPI::XML::Response.new(XML)
27
+ end
28
+
29
+ specify "[] should accept XPath" do
30
+ @xml['//title'].should_be == "Test Title"
31
+ end
32
+
33
+ specify "a bad XPath passed to [] should return nil" do
34
+ @xml['/foo/bar/baz'].should_be_nil
35
+ end
36
+
37
+ specify "'each' with a bad XPath should not run provided block" do
38
+ count = 0
39
+ @xml.each('/foo/bar/baz') { |node| count += 1 }
40
+ count.should_be_zero
41
+ end
42
+
43
+ specify "'each' should execute block for every matching XPath" do
44
+ expected_names = %w( Bob Joe Walter )
45
+ expected_ids = %w( 1 2 3 )
46
+ count = 0
47
+
48
+ @xml.each "//items/item" do |node|
49
+ count += 1
50
+ node['name'].should_be == expected_names.shift
51
+ node['id'].should_be == expected_ids.shift
52
+ end
53
+
54
+ count.should_be == 3
55
+ end
56
+
57
+ specify "calling 'each' without a block should raise an ArgumentError" do
58
+ proc {
59
+ @xml.each('//title')
60
+ }.should_raise ArgumentError
61
+ end
62
+
63
+ specify "'to_formatted_s' should make the xml pretty" do
64
+ input = '<a><b><c>foo</c></b></a>'
65
+ expected = <<XML
66
+ <a>
67
+ <b>
68
+ <c>foo</c>
69
+ </b>
70
+ </a>
71
+ XML
72
+ xml_response = RemoteAPI::XML::Response.new(input)
73
+
74
+ xml_response.to_formatted_s.should_be == expected.chomp
75
+ end
76
+
77
+ end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/test_helper.rb'
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
3
  FakeWeb.register_uri(
4
4
  'http://test.com/xml',
@@ -8,56 +8,54 @@ FakeWeb.register_uri(
8
8
  'http://test.com/xml/error',
9
9
  :string => '<server_response><error>Big fat error</error></server_response>'
10
10
  )
11
+
12
+ class XmlApi < RemoteAPI::XML
13
+ attr_reader :return_message
14
+
15
+ def request
16
+ x = Builder::XmlMarkup.new
17
+ x.my_request @message
18
+ end
19
+
20
+ def assert_success
21
+ if error = @response['/server_response/error']
22
+ raise ResponseFailure, error
23
+ end
24
+ end
25
+
26
+ def process
27
+ @return_message = @response['/foo/server_response']
28
+ end
29
+ end
30
+
11
31
 
12
- class RemoteApiXMLTest < Test::Unit::TestCase
32
+ context "An XML API" do
13
33
 
14
- def setup
34
+ setup do
15
35
  XmlApi.url = 'http://test.com/xml'
16
36
  end
17
37
 
18
- def test_response_should_be_xml
19
- result = XmlApi.new(:message => 'foo')
20
- assert_equal('The server recieved your message', result.return_message)
38
+ specify "response should be XML" do
39
+ result = XmlApi.call(:message => 'foo')
40
+ result.return_message.should_be == 'The server recieved your message'
21
41
  end
22
42
 
23
- def test_format_response_should_produce_pretty_xml
43
+ specify "'format_response' should produce pretty xml" do
24
44
  expected = <<XML
25
45
  <foo>
26
46
  <server_response>The server recieved your message</server_response>
27
47
  </foo>
28
48
  XML
29
49
 
30
- result = XmlApi.new(:message => 'foo')
31
- data = result.send(:format_response, '<foo><server_response>The server recieved your message</server_response></foo>')
32
- assert_equal(expected.chomp, data)
50
+ result = XmlApi.call(:message => 'foo')
51
+ data = result.send(:format_response, '<foo><server_response>The server recieved your message</server_response></foo>')
52
+
53
+ data.should_be == expected.chomp
33
54
  end
34
55
 
35
- def test_assert_success_should_raise_exceptions
56
+ specify "'assert_success' should raise an exception on failure" do
36
57
  XmlApi.url = 'http://test.com/xml/error'
37
- assert_raise RemoteAPI::ResponseFailure do
38
- XmlApi.new(:message => 'foo')
39
- end
58
+ proc { XmlApi.call(:message => 'foo') }.should_raise RemoteAPI::ResponseFailure
40
59
  end
41
60
 
42
- end
43
-
44
-
45
- class XmlApi < RemoteAPI::XML
46
- attr_reader :return_message
47
-
48
- def request
49
- x = Builder::XmlMarkup.new
50
- x.my_request @message
51
- end
52
-
53
- def assert_success
54
- if error = @response['/server_response/error']
55
- raise ResponseFailure, error
56
- end
57
- end
58
-
59
- def process
60
- @return_message = @response['/foo/server_response']
61
- end
62
-
63
61
  end
data/test/spec_test.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'test/unit'
2
+
3
+ class SpecTest < Test::Unit::TestCase
4
+ def test_true
5
+ assert true
6
+ end
7
+ end
8
+
9
+ puts <<SPEC
10
+
11
+ ----------------------------------------------
12
+ This gem has no tests. Please run 'rake spec'
13
+ or 'rake spec_print' instead.
14
+
15
+ The rspec gem must be installed to run specs.
16
+ gem install rspec
17
+ ----------------------------------------------
18
+
19
+ SPEC
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.1
3
3
  specification_version: 1
4
4
  name: remote_api
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.2
7
- date: 2007-01-17 00:00:00 -08:00
6
+ version: 0.2.0
7
+ date: 2007-04-19 00:00:00 -07:00
8
8
  summary: Provides a basic framework for easily creating classes that access remote APIs.
9
9
  require_paths:
10
10
  - lib
@@ -39,14 +39,13 @@ files:
39
39
  - lib/remote_api/xml.rb
40
40
  - lib/remote_api/xml_response.rb
41
41
  - lib/remote_api/version.rb
42
- - test/test_helper.rb
43
- - test/base_test.rb
44
- - test/xml_test.rb
45
- - test/xml_response_test.rb
42
+ - test/spec_test.rb
43
+ - spec/base_spec.rb
44
+ - spec/spec_helper.rb
45
+ - spec/xml_response_spec.rb
46
+ - spec/xml_spec.rb
46
47
  test_files:
47
- - test/base_test.rb
48
- - test/xml_response_test.rb
49
- - test/xml_test.rb
48
+ - test/spec_test.rb
50
49
  rdoc_options: []
51
50
 
52
51
  extra_rdoc_files: []
data/test/base_test.rb DELETED
@@ -1,58 +0,0 @@
1
- require File.dirname(__FILE__) + '/test_helper.rb'
2
-
3
- FakeWeb.register_uri(
4
- 'http://test.com/base',
5
- :string => '<server_response>The server recieved your message</server_response>'
6
- )
7
- FakeWeb.register_uri(
8
- 'http://test.com/base/error',
9
- :string => '<server_response>An error occurred!</server_response>'
10
- )
11
-
12
- class RemoteApiTest < Test::Unit::TestCase
13
-
14
- def setup
15
- BaseApi.url = 'http://test.com/base'
16
- end
17
-
18
- def test_initialize_should_set_hash_keys_as_instance_variables
19
- result = BaseApi.new(:foo => 'bar', :baz => 'taz', :message => 'Hello')
20
-
21
- assert_equal('bar', result.instance_eval { @foo })
22
- assert_equal('taz', result.instance_eval { @baz })
23
- assert_equal('Hello', result.instance_eval { @message })
24
- end
25
-
26
- def test_initialize_should_perform_api_call
27
- result = BaseApi.new(:message => 'Hello World!')
28
- assert_equal 'The server recieved your message', result.return_message
29
- end
30
-
31
- def test_assert_success_should_raise_exception
32
- BaseApi.url = 'http://test.com/base/error'
33
- assert_raise RemoteAPI::ResponseFailure do
34
- BaseApi.new(:message => 'foo')
35
- end
36
- end
37
- end
38
-
39
-
40
- class BaseApi < RemoteAPI
41
- attr_reader :return_message
42
-
43
- def request
44
- x = Builder::XmlMarkup.new
45
- x.my_request @message
46
- end
47
-
48
- def assert_success
49
- if @response =~ %r{<server_response>(.*error.*)</server_response>}
50
- raise ResponseFailure, $1
51
- end
52
- end
53
-
54
- def process
55
- @return_message = @response.gsub(%r{</?server_response>}, '')
56
- end
57
-
58
- end
@@ -1,77 +0,0 @@
1
- require File.dirname(__FILE__) + '/test_helper.rb'
2
-
3
- class XmlResponseTest < Test::Unit::TestCase
4
-
5
- XML = <<XML
6
- <response>
7
- <title>Test Title</title>
8
- <items>
9
- <item>
10
- <name>Bob</name>
11
- <id>1</id>
12
- </item>
13
- <item>
14
- <name>Joe</name>
15
- <id>2</id>
16
- </item>
17
- <item>
18
- <name>Walter</name>
19
- <id>3</id>
20
- </item>
21
- </items>
22
- </response>
23
- XML
24
-
25
- def setup
26
- @xml = RemoteAPI::XML::Response.new(XML)
27
- end
28
-
29
- def test_brace_accessor
30
- assert_equal('Test Title', @xml['//title'])
31
- end
32
-
33
- def test_bad_xpath_should_return_nil
34
- assert_nil @xml['/foo/bar/baz']
35
- end
36
-
37
- def test_each_on_bad_xpath_should_not_run_block
38
- count = 0
39
- @xml.each('/foo/bar/baz') { |node| count += 1 }
40
- assert_equal(0, count)
41
- end
42
-
43
- def test_each
44
- expected_names = %w( Bob Joe Walter )
45
- expected_ids = %w( 1 2 3 )
46
- count = 0
47
-
48
- @xml.each '//items/item' do |node|
49
- count += 1
50
- assert_equal(expected_names.shift, node['name'])
51
- assert_equal(expected_ids.shift, node['id'])
52
- end
53
-
54
- assert_equal(3, count)
55
- end
56
-
57
- def test_each_without_block_should_raise_exception
58
- assert_raise(ArgumentError) do
59
- @xml.each('//title')
60
- end
61
- end
62
-
63
- def test_to_formatted_s
64
- input = '<a><b><c>foo</c></b></a>'
65
- expected = <<XML
66
- <a>
67
- <b>
68
- <c>foo</c>
69
- </b>
70
- </a>
71
- XML
72
- xml_response = RemoteAPI::XML::Response.new(input)
73
-
74
- assert_equal(expected.chomp, xml_response.to_formatted_s)
75
- end
76
-
77
- end