activeresource 2.0.2 → 2.0.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activeresource might be problematic. Click here for more details.

data/CHANGELOG CHANGED
@@ -1,3 +1,18 @@
1
+ *2.0.4* (2nd September 2008)
2
+
3
+ * Fix small documentation typo. Closes #10670 [l.guidi]
4
+
5
+ * find_or_create_resource_for handles module nesting. #10646 [xavier]
6
+
7
+ * Allow setting ActiveResource::Base#format before #site. [rick]
8
+
9
+ * Support agnostic formats when calling custom methods. Closes #10635 [joerichsen]
10
+
11
+ * Document custom methods. #10589 [Cheah Chu Yeow]
12
+
13
+ * Ruby 1.9 compatibility. [Jeremy Kemper]
14
+
15
+
1
16
  *2.0.2* (December 16th, 2007)
2
17
 
3
18
  * Added more specific exceptions for 400, 401, and 403 (all descending from ClientError so existing rescues will work) #10326 [trek]
data/Rakefile CHANGED
@@ -4,6 +4,7 @@ require 'rake/testtask'
4
4
  require 'rake/rdoctask'
5
5
  require 'rake/packagetask'
6
6
  require 'rake/gempackagetask'
7
+ require 'rake/contrib/sshpublisher'
7
8
  require 'rake/contrib/rubyforgepublisher'
8
9
  require File.join(File.dirname(__FILE__), 'lib', 'active_resource', 'version')
9
10
 
@@ -63,7 +64,7 @@ spec = Gem::Specification.new do |s|
63
64
  s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
64
65
  end
65
66
 
66
- s.add_dependency('activesupport', '= 2.0.2' + PKG_BUILD)
67
+ s.add_dependency('activesupport', '= 2.0.4' + PKG_BUILD)
67
68
 
68
69
  s.require_path = 'lib'
69
70
  s.autorequire = 'active_resource'
@@ -113,8 +114,8 @@ end
113
114
 
114
115
  desc "Publish the beta gem"
115
116
  task :pgem => [:package] do
116
- Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
117
- `ssh davidhh@wrath.rubyonrails.org './gemupdate.sh'`
117
+ Rake::SshFilePublisher.new("david@greed.loudthinking.com", "/u/sites/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
118
+ `ssh david@greed.loudthinking.com '/u/sites/gems/gemupdate.sh'`
118
119
  end
119
120
 
120
121
  desc "Publish the API documentation"
@@ -27,7 +27,7 @@ $:.unshift(File.dirname(__FILE__)) unless
27
27
  unless defined?(ActiveSupport)
28
28
  begin
29
29
  $:.unshift(File.dirname(__FILE__) + "/../../activesupport/lib")
30
- require 'active_support'
30
+ require 'active_support'
31
31
  rescue LoadError
32
32
  require 'rubygems'
33
33
  gem 'activesupport'
@@ -5,7 +5,7 @@ require 'set'
5
5
  module ActiveResource
6
6
  # ActiveResource::Base is the main class for mapping RESTful resources as models in a Rails application.
7
7
  #
8
- # For an outline of what Active Resource is capable of, see link:files/README.html.
8
+ # For an outline of what Active Resource is capable of, see link:files/vendor/rails/activeresource/README.html.
9
9
  #
10
10
  # == Automated mapping
11
11
  #
@@ -33,7 +33,7 @@ module ActiveResource
33
33
  # ryan.exists? #=> true
34
34
  #
35
35
  # ryan = Person.find(1)
36
- # # => Resource holding our newly create Person object
36
+ # # => Resource holding our newly created Person object
37
37
  #
38
38
  # ryan.first = 'Rizzle'
39
39
  # ryan.save #=> true
@@ -46,15 +46,26 @@ module ActiveResource
46
46
  # === Custom REST methods
47
47
  #
48
48
  # Since simple CRUD/lifecycle methods can't accomplish every task, Active Resource also supports
49
- # defining your own custom REST methods.
50
- #
51
- # Person.new(:name => 'Ryan).post(:register)
49
+ # defining your own custom REST methods. To invoke them, Active Resource provides the <tt>get</tt>,
50
+ # <tt>post</tt>, <tt>put</tt> and <tt>delete</tt> methods where you can specify a custom REST method
51
+ # name to invoke.
52
+ #
53
+ # # POST to the custom 'register' REST method, i.e. POST /people/new/register.xml.
54
+ # Person.new(:name => 'Ryan').post(:register)
52
55
  # # => { :id => 1, :name => 'Ryan', :position => 'Clerk' }
53
56
  #
57
+ # # PUT an update by invoking the 'promote' REST method, i.e. PUT /people/1/promote.xml?position=Manager.
54
58
  # Person.find(1).put(:promote, :position => 'Manager')
55
59
  # # => { :id => 1, :name => 'Ryan', :position => 'Manager' }
60
+ #
61
+ # # GET all the positions available, i.e. GET /people/positions.xml.
62
+ # Person.get(:positions)
63
+ # # => [{:name => 'Manager'}, {:name => 'Clerk'}]
64
+ #
65
+ # # DELETE to 'fire' a person, i.e. DELETE /people/1/fire.xml.
66
+ # Person.find(1).delete(:fire)
56
67
  #
57
- # For more information on creating and using custom REST methods, see the
68
+ # For more information on using custom REST methods, see the
58
69
  # ActiveResource::CustomMethods documentation.
59
70
  #
60
71
  # == Validations
@@ -87,12 +98,12 @@ module ActiveResource
87
98
  # == Errors & Validation
88
99
  #
89
100
  # Error handling and validation is handled in much the same manner as you're used to seeing in
90
- # Active Record. Both the response code in the Http response and the body of the response are used to
101
+ # Active Record. Both the response code in the HTTP response and the body of the response are used to
91
102
  # indicate that an error occurred.
92
103
  #
93
104
  # === Resource errors
94
105
  #
95
- # When a get is requested for a resource that does not exist, the HTTP +404+ (Resource Not Found)
106
+ # When a GET is requested for a resource that does not exist, the HTTP <tt>404</tt> (Resource Not Found)
96
107
  # response code will be returned from the server which will raise an ActiveResource::ResourceNotFound
97
108
  # exception.
98
109
  #
@@ -100,7 +111,7 @@ module ActiveResource
100
111
  # ryan = Person.find(999) # => Raises ActiveResource::ResourceNotFound
101
112
  # # => Response = 404
102
113
  #
103
- # +404+ is just one of the HTTP error response codes that ActiveResource will handle with its own exception. The
114
+ # <tt>404</tt> is just one of the HTTP error response codes that ActiveResource will handle with its own exception. The
104
115
  # following HTTP response codes will also result in these exceptions:
105
116
  #
106
117
  # 200 - 399:: Valid response, no exception
@@ -125,8 +136,8 @@ module ActiveResource
125
136
  #
126
137
  # Active Resource supports validations on resources and will return errors if any these validations fail
127
138
  # (e.g., "First name can not be blank" and so on). These types of errors are denoted in the response by
128
- # a response code of +422+ and an XML representation of the validation errors. The save operation will
129
- # then fail (with a +false+ return value) and the validation errors can be accessed on the resource in question.
139
+ # a response code of <tt>422</tt> and an XML representation of the validation errors. The save operation will
140
+ # then fail (with a <tt>false</tt> return value) and the validation errors can be accessed on the resource in question.
130
141
  #
131
142
  # ryan = Person.find(1)
132
143
  # ryan.first #=> ''
@@ -181,7 +192,7 @@ module ActiveResource
181
192
  ActiveResource::Formats[mime_type_reference_or_format] : mime_type_reference_or_format
182
193
 
183
194
  write_inheritable_attribute("format", format)
184
- connection.format = format
195
+ connection.format = format if site
185
196
  end
186
197
 
187
198
  # Returns the current format, default is ActiveResource::Formats::XmlFormat
@@ -191,7 +202,7 @@ module ActiveResource
191
202
 
192
203
  # An instance of ActiveResource::Connection that is the base connection to the remote service.
193
204
  # The +refresh+ parameter toggles whether or not the connection is refreshed at every request
194
- # or not (defaults to +false+).
205
+ # or not (defaults to <tt>false</tt>).
195
206
  def connection(refresh = false)
196
207
  if defined?(@connection) || superclass == Object
197
208
  @connection = Connection.new(site, format) if refresh || @connection.nil?
@@ -372,6 +383,9 @@ module ActiveResource
372
383
  # Person.find(:one, :from => :leader)
373
384
  # # => GET /people/leader.xml
374
385
  #
386
+ # Person.find(:all, :from => :developers, :params => { :language => 'ruby' })
387
+ # # => GET /people/developers.xml?language=ruby
388
+ #
375
389
  # Person.find(:one, :from => "/companies/1/manager.xml")
376
390
  # # => GET /companies/1/manager.xml
377
391
  #
@@ -687,9 +701,9 @@ module ActiveResource
687
701
  #
688
702
  # indent:: Set the indent level for the XML output (default is +2+).
689
703
  # dasherize:: Boolean option to determine whether or not element names should
690
- # replace underscores with dashes (default is +false+).
704
+ # replace underscores with dashes (default is <tt>false</tt>).
691
705
  # skip_instruct:: Toggle skipping the +instruct!+ call on the XML builder
692
- # that generates the XML declaration (default is +false+).
706
+ # that generates the XML declaration (default is <tt>false</tt>).
693
707
  #
694
708
  # ==== Examples
695
709
  # my_group = SubsidiaryGroup.find(:first)
@@ -769,8 +783,8 @@ module ActiveResource
769
783
  alias_method :respond_to_without_attributes?, :respond_to?
770
784
 
771
785
  # A method to determine if an object responds to a message (e.g., a method call). In Active Resource, a +Person+ object with a
772
- # +name+ attribute can answer +true+ to +my_person.respond_to?("name")+, +my_person.respond_to?("name=")+, and
773
- # +my_person.respond_to?("name?")+.
786
+ # +name+ attribute can answer <tt>true</tt> to <tt>my_person.respond_to?("name")</tt>, <tt>my_person.respond_to?("name=")</tt>, and
787
+ # <tt>my_person.respond_to?("name?")</tt>.
774
788
  def respond_to?(method, include_priv = false)
775
789
  method_name = method.to_s
776
790
  if attributes.nil?
@@ -831,17 +845,26 @@ module ActiveResource
831
845
  find_or_create_resource_for(name.to_s.singularize)
832
846
  end
833
847
 
848
+ # Tries to find a resource in a non empty list of nested modules
849
+ # Raises a NameError if it was not found in any of the given nested modules
850
+ def find_resource_in_modules(resource_name, module_names)
851
+ receiver = Object
852
+ namespaces = module_names[0, module_names.size-1].map do |module_name|
853
+ receiver = receiver.const_get(module_name)
854
+ end
855
+ if namespace = namespaces.reverse.detect { |ns| ns.const_defined?(resource_name) }
856
+ return namespace.const_get(resource_name)
857
+ else
858
+ raise NameError
859
+ end
860
+ end
861
+
834
862
  # Tries to find a resource for a given name; if it fails, then the resource is created
835
863
  def find_or_create_resource_for(name)
836
864
  resource_name = name.to_s.camelize
837
-
838
- # FIXME: Make it generic enough to support any depth of module nesting
839
- if (ancestors = self.class.name.split("::")).size > 1
840
- begin
841
- ancestors.first.constantize.const_get(resource_name)
842
- rescue NameError
843
- self.class.const_get(resource_name)
844
- end
865
+ ancestors = self.class.name.split("::")
866
+ if ancestors.size > 1
867
+ find_resource_in_modules(resource_name, ancestors)
845
868
  else
846
869
  self.class.const_get(resource_name)
847
870
  end
@@ -1,59 +1,73 @@
1
- # A module to support custom REST methods and sub-resources, allowing you to break out
2
- # of the "default" REST methods with your own custom resource requests. For example,
3
- # say you use Rails to expose a REST service and configure your routes with:
4
- #
5
- # map.resources :people, :new => { :register => :post },
6
- # :element => { :promote => :put, :deactivate => :delete }
7
- # :collection => { :active => :get }
8
- #
9
- # This route set creates routes for the following http requests:
10
- #
11
- # POST /people/new/register.xml #=> PeopleController.register
12
- # PUT /people/1/promote.xml #=> PeopleController.promote with :id => 1
13
- # DELETE /people/1/deactivate.xml #=> PeopleController.deactivate with :id => 1
14
- # GET /people/active.xml #=> PeopleController.active
15
- #
16
- # Using this module, Active Resource can use these custom REST methods just like the
17
- # standard methods.
18
- #
19
- # class Person < ActiveResource::Base
20
- # self.site = "http://37s.sunrise.i:3000"
21
- # end
22
- #
23
- # Person.new(:name => 'Ryan).post(:register) # POST /people/new/register.xml
24
- # # => { :id => 1, :name => 'Ryan' }
25
- #
26
- # Person.find(1).put(:promote, :position => 'Manager') # PUT /people/1/promote.xml
27
- # Person.find(1).delete(:deactivate) # DELETE /people/1/deactivate.xml
28
- #
29
- # Person.get(:active) # GET /people/active.xml
30
- # # => [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}]
31
- #
32
1
  module ActiveResource
2
+ # A module to support custom REST methods and sub-resources, allowing you to break out
3
+ # of the "default" REST methods with your own custom resource requests. For example,
4
+ # say you use Rails to expose a REST service and configure your routes with:
5
+ #
6
+ # map.resources :people, :new => { :register => :post },
7
+ # :member => { :promote => :put, :deactivate => :delete }
8
+ # :collection => { :active => :get }
9
+ #
10
+ # This route set creates routes for the following http requests:
11
+ #
12
+ # POST /people/new/register.xml #=> PeopleController.register
13
+ # PUT /people/1/promote.xml #=> PeopleController.promote with :id => 1
14
+ # DELETE /people/1/deactivate.xml #=> PeopleController.deactivate with :id => 1
15
+ # GET /people/active.xml #=> PeopleController.active
16
+ #
17
+ # Using this module, Active Resource can use these custom REST methods just like the
18
+ # standard methods.
19
+ #
20
+ # class Person < ActiveResource::Base
21
+ # self.site = "http://37s.sunrise.i:3000"
22
+ # end
23
+ #
24
+ # Person.new(:name => 'Ryan).post(:register) # POST /people/new/register.xml
25
+ # # => { :id => 1, :name => 'Ryan' }
26
+ #
27
+ # Person.find(1).put(:promote, :position => 'Manager') # PUT /people/1/promote.xml
28
+ # Person.find(1).delete(:deactivate) # DELETE /people/1/deactivate.xml
29
+ #
30
+ # Person.get(:active) # GET /people/active.xml
31
+ # # => [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}]
32
+ #
33
33
  module CustomMethods
34
- def self.included(within)
35
- within.class_eval do
34
+ def self.included(base)
35
+ base.class_eval do
36
36
  extend ActiveResource::CustomMethods::ClassMethods
37
37
  include ActiveResource::CustomMethods::InstanceMethods
38
38
 
39
39
  class << self
40
40
  alias :orig_delete :delete
41
41
 
42
- def get(method_name, options = {})
43
- connection.get(custom_method_collection_url(method_name, options), headers)
42
+ # Invokes a GET to a given custom REST method. For example:
43
+ #
44
+ # Person.get(:active) # GET /people/active.xml
45
+ # # => [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}]
46
+ #
47
+ # Person.get(:active, :awesome => true) # GET /people/active.xml?awesome=true
48
+ # # => [{:id => 1, :name => 'Ryan'}]
49
+ #
50
+ # Note: the objects returned from this method are not automatically converted
51
+ # into ActiveResource instances - they are ordinary Hashes. If you are expecting
52
+ # ActiveResource instances, use the <tt>find</tt> class method with the
53
+ # <tt>:from</tt> option. For example:
54
+ #
55
+ # Person.find(:all, :from => :active)
56
+ def get(custom_method_name, options = {})
57
+ connection.get(custom_method_collection_url(custom_method_name, options), headers)
44
58
  end
45
59
 
46
- def post(method_name, options = {}, body = '')
47
- connection.post(custom_method_collection_url(method_name, options), body, headers)
60
+ def post(custom_method_name, options = {}, body = '')
61
+ connection.post(custom_method_collection_url(custom_method_name, options), body, headers)
48
62
  end
49
63
 
50
- def put(method_name, options = {}, body = '')
51
- connection.put(custom_method_collection_url(method_name, options), body, headers)
64
+ def put(custom_method_name, options = {}, body = '')
65
+ connection.put(custom_method_collection_url(custom_method_name, options), body, headers)
52
66
  end
53
67
 
54
- # Need to jump through some hoops to retain the original class 'delete' method
55
68
  def delete(custom_method_name, options = {})
56
- if (custom_method_name.is_a?(Symbol))
69
+ # Need to jump through some hoops to retain the original class 'delete' method
70
+ if custom_method_name.is_a?(Symbol)
57
71
  connection.delete(custom_method_collection_url(custom_method_name, options), headers)
58
72
  else
59
73
  orig_delete(custom_method_name, options)
@@ -66,7 +80,7 @@ module ActiveResource
66
80
  module ClassMethods
67
81
  def custom_method_collection_url(method_name, options = {})
68
82
  prefix_options, query_options = split_options(options)
69
- "#{prefix(prefix_options)}#{collection_name}/#{method_name}.xml#{query_string(query_options)}"
83
+ "#{prefix(prefix_options)}#{collection_name}/#{method_name}.#{format.extension}#{query_string(query_options)}"
70
84
  end
71
85
  end
72
86
 
@@ -94,11 +108,11 @@ module ActiveResource
94
108
 
95
109
  private
96
110
  def custom_method_element_url(method_name, options = {})
97
- "#{self.class.prefix(prefix_options)}#{self.class.collection_name}/#{id}/#{method_name}.xml#{self.class.send!(:query_string, options)}"
111
+ "#{self.class.prefix(prefix_options)}#{self.class.collection_name}/#{id}/#{method_name}.#{self.class.format.extension}#{self.class.send!(:query_string, options)}"
98
112
  end
99
113
 
100
114
  def custom_method_new_element_url(method_name, options = {})
101
- "#{self.class.prefix(prefix_options)}#{self.class.collection_name}/new/#{method_name}.xml#{self.class.send!(:query_string, options)}"
115
+ "#{self.class.prefix(prefix_options)}#{self.class.collection_name}/new/#{method_name}.#{self.class.format.extension}#{self.class.send!(:query_string, options)}"
102
116
  end
103
117
  end
104
118
  end
@@ -10,7 +10,7 @@ module ActiveResource
10
10
  end
11
11
 
12
12
  for method in [ :post, :put, :get, :delete ]
13
- module_eval <<-EOE
13
+ module_eval <<-EOE, __FILE__, __LINE__
14
14
  def #{method}(path, request_headers = {}, body = nil, status = 200, response_headers = {})
15
15
  @responses[Request.new(:#{method}, path, nil, request_headers)] = Response.new(body || "", status, response_headers)
16
16
  end
@@ -47,21 +47,21 @@ module ActiveResource
47
47
  end
48
48
 
49
49
  for method in [ :post, :put ]
50
- module_eval <<-EOE
50
+ module_eval <<-EOE, __FILE__, __LINE__
51
51
  def #{method}(path, body, headers)
52
52
  request = ActiveResource::Request.new(:#{method}, path, body, headers)
53
53
  self.class.requests << request
54
- self.class.responses[request] || raise(InvalidRequestError.new("No response recorded for: \#{request.inspect}"))
54
+ self.class.responses[request] || raise(InvalidRequestError.new("No response recorded for \#{request}"))
55
55
  end
56
56
  EOE
57
57
  end
58
58
 
59
59
  for method in [ :get, :delete ]
60
- module_eval <<-EOE
60
+ module_eval <<-EOE, __FILE__, __LINE__
61
61
  def #{method}(path, headers)
62
62
  request = ActiveResource::Request.new(:#{method}, path, nil, headers)
63
63
  self.class.requests << request
64
- self.class.responses[request] || raise(InvalidRequestError.new("No response recorded for: \#{request.inspect}"))
64
+ self.class.responses[request] || raise(InvalidRequestError.new("No response recorded for \#{request}"))
65
65
  end
66
66
  EOE
67
67
  end
@@ -75,8 +75,7 @@ module ActiveResource
75
75
  attr_accessor :path, :method, :body, :headers
76
76
 
77
77
  def initialize(method, path, body = nil, headers = {})
78
- @method, @path, @body, @headers = method, path, body, headers.dup
79
- @headers.update('Content-Type' => 'application/xml')
78
+ @method, @path, @body, @headers = method, path, body, headers.reverse_merge('Content-Type' => 'application/xml')
80
79
  end
81
80
 
82
81
  def ==(other_request)
@@ -2,7 +2,7 @@ module ActiveResource
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 2
4
4
  MINOR = 0
5
- TINY = 2
5
+ TINY = 4
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -1,5 +1,4 @@
1
1
  require "#{File.dirname(__FILE__)}/abstract_unit"
2
- require 'base64'
3
2
 
4
3
  class AuthorizationTest < Test::Unit::TestCase
5
4
  Response = Struct.new(:code)
@@ -25,7 +24,7 @@ class AuthorizationTest < Test::Unit::TestCase
25
24
  authorization = authorization_header["Authorization"].to_s.split
26
25
 
27
26
  assert_equal "Basic", authorization[0]
28
- assert_equal ["david", "test123"], Base64.decode64(authorization[1]).split(":")[0..1]
27
+ assert_equal ["david", "test123"], ActiveSupport::Base64.decode64(authorization[1]).split(":")[0..1]
29
28
  end
30
29
 
31
30
  def test_authorization_header_with_username_but_no_password
@@ -34,7 +33,7 @@ class AuthorizationTest < Test::Unit::TestCase
34
33
  authorization = authorization_header["Authorization"].to_s.split
35
34
 
36
35
  assert_equal "Basic", authorization[0]
37
- assert_equal ["david"], Base64.decode64(authorization[1]).split(":")[0..1]
36
+ assert_equal ["david"], ActiveSupport::Base64.decode64(authorization[1]).split(":")[0..1]
38
37
  end
39
38
 
40
39
  def test_authorization_header_with_password_but_no_username
@@ -43,7 +42,7 @@ class AuthorizationTest < Test::Unit::TestCase
43
42
  authorization = authorization_header["Authorization"].to_s.split
44
43
 
45
44
  assert_equal "Basic", authorization[0]
46
- assert_equal ["", "test123"], Base64.decode64(authorization[1]).split(":")[0..1]
45
+ assert_equal ["", "test123"], ActiveSupport::Base64.decode64(authorization[1]).split(":")[0..1]
47
46
  end
48
47
 
49
48
  def test_get
@@ -10,6 +10,29 @@ module Highrise
10
10
  class Comment < ActiveResource::Base
11
11
  self.site = "http://37s.sunrise.i:3000"
12
12
  end
13
+
14
+ module Deeply
15
+ module Nested
16
+
17
+ class Note < ActiveResource::Base
18
+ self.site = "http://37s.sunrise.i:3000"
19
+ end
20
+
21
+ class Comment < ActiveResource::Base
22
+ self.site = "http://37s.sunrise.i:3000"
23
+ end
24
+
25
+ module TestDifferentLevels
26
+
27
+ class Note < ActiveResource::Base
28
+ self.site = "http://37s.sunrise.i:3000"
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
35
+
13
36
  end
14
37
 
15
38
 
@@ -108,4 +131,16 @@ class BaseLoadTest < Test::Unit::TestCase
108
131
  n = Highrise::Note.new(:comments => [{ :name => "1" }])
109
132
  assert_kind_of Highrise::Comment, n.comments.first
110
133
  end
134
+
135
+ def test_nested_collections_within_deeply_nested_namespace
136
+ n = Highrise::Deeply::Nested::Note.new(:comments => [{ :name => "1" }])
137
+ assert_kind_of Highrise::Deeply::Nested::Comment, n.comments.first
138
+ end
139
+
140
+ def test_nested_collections_in_different_levels_of_namespaces
141
+ n = Highrise::Deeply::Nested::TestDifferentLevels::Note.new(:comments => [{ :name => "1" }])
142
+ assert_kind_of Highrise::Deeply::Nested::Comment, n.comments.first
143
+ end
144
+
145
+
111
146
  end
@@ -1,5 +1,4 @@
1
1
  require "#{File.dirname(__FILE__)}/abstract_unit"
2
- require 'base64'
3
2
 
4
3
  class ConnectionTest < Test::Unit::TestCase
5
4
  ResponseCodeStub = Struct.new(:code)
data/test/format_test.rb CHANGED
@@ -29,6 +29,47 @@ class FormatTest < Test::Unit::TestCase
29
29
  end
30
30
  end
31
31
 
32
+ def test_formats_on_custom_collection_method
33
+ for format in [ :json, :xml ]
34
+ using_format(Person, format) do
35
+ ActiveResource::HttpMock.respond_to.get "/people/retrieve.#{format}?name=David", {}, ActiveResource::Formats[format].encode([@david])
36
+ remote_programmers = Person.get(:retrieve, :name => 'David')
37
+ assert_equal 1, remote_programmers.size
38
+ assert_equal @david[:id], remote_programmers[0]['id']
39
+ assert_equal @david[:name], remote_programmers[0]['name']
40
+ end
41
+ end
42
+ end
43
+
44
+ def test_formats_on_custom_element_method
45
+ for format in [ :json, :xml ]
46
+ using_format(Person, format) do
47
+ ActiveResource::HttpMock.respond_to do |mock|
48
+ mock.get "/people/2.#{format}", {}, ActiveResource::Formats[format].encode(@david)
49
+ mock.get "/people/2/shallow.#{format}", {}, ActiveResource::Formats[format].encode(@david)
50
+ end
51
+ remote_programmer = Person.find(2).get(:shallow)
52
+ assert_equal @david[:id], remote_programmer['id']
53
+ assert_equal @david[:name], remote_programmer['name']
54
+ end
55
+ end
56
+
57
+ for format in [ :json, :xml ]
58
+ ryan = ActiveResource::Formats[format].encode({ :name => 'Ryan' })
59
+ using_format(Person, format) do
60
+ ActiveResource::HttpMock.respond_to.post "/people/new/register.#{format}", {}, ryan, 201, 'Location' => "/people/5.#{format}"
61
+ remote_ryan = Person.new(:name => 'Ryan')
62
+ assert_equal ActiveResource::Response.new(ryan, 201, {'Location' => "/people/5.#{format}"}), remote_ryan.post(:register)
63
+ end
64
+ end
65
+ end
66
+
67
+ def test_setting_format_before_site
68
+ resource = Class.new(ActiveResource::Base)
69
+ resource.format = :json
70
+ resource.site = 'http://37s.sunrise.i:3000'
71
+ assert_equal ActiveResource::Formats[:json], resource.connection.format
72
+ end
32
73
 
33
74
  private
34
75
  def using_format(klass, mime_type_reference)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeresource
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
@@ -9,17 +9,18 @@ autorequire: active_resource
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2007-12-20 00:00:00 -06:00
12
+ date: 2008-09-03 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
17
+ type: :runtime
17
18
  version_requirement:
18
19
  version_requirements: !ruby/object:Gem::Requirement
19
20
  requirements:
20
21
  - - "="
21
22
  - !ruby/object:Gem::Version
22
- version: 2.0.2
23
+ version: 2.0.4
23
24
  version:
24
25
  description: Wraps web resources in model classes that can be manipulated through XML over REST.
25
26
  email: david@loudthinking.com
@@ -84,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
85
  requirements: []
85
86
 
86
87
  rubyforge_project: activeresource
87
- rubygems_version: 1.0.0
88
+ rubygems_version: 1.2.0
88
89
  signing_key:
89
90
  specification_version: 2
90
91
  summary: Think Active Record for web resources.