swivel 0.0.160 → 0.0.175

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/lib/swivel.rb +7 -7
  2. data/lib/swivel2.rb +3 -1
  3. data/lib/swivel2/connection.rb +15 -1
  4. data/lib/swivel2/swivelrc.default +1 -2
  5. data/vendor/{activeresource-2.0.2- → activeresource}/CHANGELOG +17 -0
  6. data/vendor/activeresource/MIT-LICENSE +20 -0
  7. data/vendor/{activeresource-2.0.2- → activeresource}/README +0 -0
  8. data/vendor/{activeresource-2.0.2- → activeresource}/Rakefile +1 -1
  9. data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource.rb +1 -1
  10. data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/base.rb +55 -26
  11. data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/connection.rb +7 -1
  12. data/vendor/activeresource/lib/active_resource/custom_methods.rb +119 -0
  13. data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/formats.rb +0 -0
  14. data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/formats/json_format.rb +0 -0
  15. data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/formats/xml_format.rb +0 -0
  16. data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/http_mock.rb +8 -9
  17. data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/validations.rb +0 -0
  18. data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/version.rb +0 -0
  19. data/vendor/{activeresource-2.0.2- → activeresource}/lib/activeresource.rb +0 -0
  20. data/vendor/{activeresource-2.0.2- → activeresource}/test/abstract_unit.rb +0 -0
  21. data/vendor/{activeresource-2.0.2- → activeresource}/test/authorization_test.rb +4 -5
  22. data/vendor/{activeresource-2.0.2- → activeresource}/test/base/custom_methods_test.rb +3 -3
  23. data/vendor/{activeresource-2.0.2- → activeresource}/test/base/equality_test.rb +1 -1
  24. data/vendor/{activeresource-2.0.2- → activeresource}/test/base/load_test.rb +36 -1
  25. data/vendor/{activeresource-2.0.2- → activeresource}/test/base_errors_test.rb +1 -1
  26. data/vendor/{activeresource-2.0.2- → activeresource}/test/base_test.rb +6 -1
  27. data/vendor/{activeresource-2.0.2- → activeresource}/test/connection_test.rb +16 -2
  28. data/vendor/{activeresource-2.0.2- → activeresource}/test/fixtures/beast.rb +0 -0
  29. data/vendor/{activeresource-2.0.2- → activeresource}/test/fixtures/person.rb +0 -0
  30. data/vendor/{activeresource-2.0.2- → activeresource}/test/fixtures/street_address.rb +0 -0
  31. data/vendor/activeresource/test/format_test.rb +83 -0
  32. data/vendor/{activeresource-2.0.2- → activeresource}/test/setter_trap.rb +1 -1
  33. metadata +37 -36
  34. data/vendor/activeresource-2.0.2-/lib/active_resource/custom_methods.rb +0 -105
  35. data/vendor/activeresource-2.0.2-/test/format_test.rb +0 -42
@@ -207,7 +207,7 @@ module Swivel
207
207
  elsif @hash_doc[list_name].is_a? Hash and
208
208
  @hash_doc[list_name]['@type'] == 'array'
209
209
  member_name = (@hash_doc[list_name].keys.find{|k| !/^@/.match(k) } || list_name.singularize)
210
- list = (@hash_doc[list_name][member_name] rescue [])
210
+ list = (@hash_doc[list_name][member_name] || [] rescue [])
211
211
  list = [list] unless list.is_a?(Array)
212
212
  # hack to get the gem to parse all array types correctly
213
213
  hack_list = list.map{|i| {member_name => i}}
@@ -483,9 +483,6 @@ module Swivel
483
483
  def self.resource
484
484
  'user'
485
485
  end
486
- def to_param
487
- name
488
- end
489
486
  end
490
487
 
491
488
  class Group < Response
@@ -624,7 +621,10 @@ module Swivel
624
621
  'error'
625
622
  end
626
623
  def raise
627
- super ApiError, message, backtrace ? backtrace.split("\n") : ''
624
+ trace = caller
625
+ trace = backtrace.split("\n") + trace if backtrace
626
+
627
+ super ApiError, message, trace
628
628
  end
629
629
  end
630
630
 
@@ -669,7 +669,7 @@ module Swivel
669
669
  FileUtils::mkdir_p dir unless File.exist? dir
670
670
  @config =
671
671
  unless File.exist? @filename
672
- DEFAULT_CONFIG
672
+ DEFAULT_CONFIG.clone
673
673
  else
674
674
  YAML::load_file @filename
675
675
  end
@@ -691,7 +691,7 @@ module Swivel
691
691
  # set in ~/.swivelrc.
692
692
 
693
693
  def initialize options = Hash.new
694
- @config = Config::DEFAULT_CONFIG
694
+ @config = Config::DEFAULT_CONFIG.clone
695
695
  @config.merge! options
696
696
  @headers = options[:headers] || Hash.new
697
697
  @headers.merge! 'Accept' => 'application/xml'
@@ -2,7 +2,9 @@ require 'rubygems'
2
2
  require 'active_support'
3
3
  require File.dirname(__FILE__) + '/../vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/attr_accessor_with_default'
4
4
  require File.dirname(__FILE__) + '/../vendor/activesupport-2.0.2-/lib/active_support/core_ext/object/misc'
5
- require File.dirname(__FILE__) + '/../vendor/activeresource-2.0.2-/lib/active_resource'
5
+ $: << File.dirname(__FILE__) + '/../vendor/activesupport-2.0.2-/lib/active_support/vendor/xml-simple-1.0.11'
6
+ require File.dirname(__FILE__) + '/../vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/conversions'
7
+ require File.dirname(__FILE__) + '/../vendor/activeresource/lib/active_resource'
6
8
 
7
9
  require File.dirname(__FILE__) + '/swivel2/config'
8
10
  require File.dirname(__FILE__) + '/swivel2/connection'
@@ -1,11 +1,25 @@
1
1
  module Swivel2
2
+ class Resource < ActiveResource::Connection
3
+ attr_accessor :read_timeout
4
+ private
5
+ def http
6
+ if read_timeout
7
+ returning super do |h|
8
+ h.read_timeout = read_timeout
9
+ end
10
+ else
11
+ super
12
+ end
13
+ end
14
+ end
2
15
 
3
16
  class Connection
4
17
  attr_reader :config, :resource, :format
5
18
 
6
19
  def initialize config = Config.default
7
20
  @config = config.is_a?(Hash) ? Config.new(config) : config
8
- @resource = ActiveResource::Connection.new @config.site
21
+ @resource = Resource.new @config.site
22
+ @resource.read_timeout = @config.timeout_read if @config.timeout_read
9
23
  @format = Swivel2::Formats::XmlFormat
10
24
  end
11
25
 
@@ -1,4 +1,3 @@
1
1
  --- !ruby/struct:Swivel2::Config
2
2
  site: https://api.swivel.com
3
- timeout_read: 500
4
- timeout_write: 1_000
3
+ timeout_read: 600
@@ -1,3 +1,20 @@
1
+ *SVN*
2
+
3
+ * Use HEAD instead of GET in exists? [bscofield]
4
+
5
+ * Fix small documentation typo. Closes #10670 [l.guidi]
6
+
7
+ * find_or_create_resource_for handles module nesting. #10646 [xavier]
8
+
9
+ * Allow setting ActiveResource::Base#format before #site. [rick]
10
+
11
+ * Support agnostic formats when calling custom methods. Closes #10635 [joerichsen]
12
+
13
+ * Document custom methods. #10589 [Cheah Chu Yeow]
14
+
15
+ * Ruby 1.9 compatibility. [Jeremy Kemper]
16
+
17
+
1
18
  *2.0.2* (December 16th, 2007)
2
19
 
3
20
  * Added more specific exceptions for 400, 401, and 403 (all descending from ClientError so existing rescues will work) #10326 [trek]
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006 David Heinemeier Hansson
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -4,7 +4,6 @@ require 'rake/testtask'
4
4
  require 'rake/rdoctask'
5
5
  require 'rake/packagetask'
6
6
  require 'rake/gempackagetask'
7
- require 'rake/contrib/rubyforgepublisher'
8
7
  require File.join(File.dirname(__FILE__), 'lib', 'active_resource', 'version')
9
8
 
10
9
  PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
@@ -52,6 +51,7 @@ Rake::RDocTask.new { |rdoc|
52
51
  dist_dirs = [ "lib", "test", "examples", "dev-utils" ]
53
52
 
54
53
  spec = Gem::Specification.new do |s|
54
+ s.platform = Gem::Platform::RUBY
55
55
  s.name = PKG_NAME
56
56
  s.version = PKG_VERSION
57
57
  s.summary = "Think Active Record for web resources."
@@ -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
  #
@@ -422,7 +436,13 @@ module ActiveResource
422
436
  # Note.exists(1349)
423
437
  # # => false
424
438
  def exists?(id, options = {})
425
- id && !find_single(id, options).nil?
439
+ if id
440
+ prefix_options, query_options = split_options(options[:params])
441
+ path = element_path(id, prefix_options, query_options)
442
+ response = connection.head(path, headers)
443
+ response.code == 200
444
+ end
445
+ # id && !find_single(id, options).nil?
426
446
  rescue ActiveResource::ResourceNotFound
427
447
  false
428
448
  end
@@ -687,9 +707,9 @@ module ActiveResource
687
707
  #
688
708
  # indent:: Set the indent level for the XML output (default is +2+).
689
709
  # dasherize:: Boolean option to determine whether or not element names should
690
- # replace underscores with dashes (default is +false+).
710
+ # replace underscores with dashes (default is <tt>false</tt>).
691
711
  # skip_instruct:: Toggle skipping the +instruct!+ call on the XML builder
692
- # that generates the XML declaration (default is +false+).
712
+ # that generates the XML declaration (default is <tt>false</tt>).
693
713
  #
694
714
  # ==== Examples
695
715
  # my_group = SubsidiaryGroup.find(:first)
@@ -769,8 +789,8 @@ module ActiveResource
769
789
  alias_method :respond_to_without_attributes?, :respond_to?
770
790
 
771
791
  # 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?")+.
792
+ # +name+ attribute can answer <tt>true</tt> to <tt>my_person.respond_to?("name")</tt>, <tt>my_person.respond_to?("name=")</tt>, and
793
+ # <tt>my_person.respond_to?("name?")</tt>.
774
794
  def respond_to?(method, include_priv = false)
775
795
  method_name = method.to_s
776
796
  if attributes.nil?
@@ -831,17 +851,26 @@ module ActiveResource
831
851
  find_or_create_resource_for(name.to_s.singularize)
832
852
  end
833
853
 
854
+ # Tries to find a resource in a non empty list of nested modules
855
+ # Raises a NameError if it was not found in any of the given nested modules
856
+ def find_resource_in_modules(resource_name, module_names)
857
+ receiver = Object
858
+ namespaces = module_names.map do |module_name|
859
+ receiver = receiver.const_get(module_name)
860
+ end
861
+ if namespace = namespaces.reverse.detect { |ns| ns.const_defined?(resource_name) }
862
+ return namespace.const_get(resource_name)
863
+ else
864
+ raise NameError
865
+ end
866
+ end
867
+
834
868
  # Tries to find a resource for a given name; if it fails, then the resource is created
835
869
  def find_or_create_resource_for(name)
836
870
  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
871
+ ancestors = self.class.name.split("::")
872
+ if ancestors.size > 1
873
+ find_resource_in_modules(resource_name, ancestors)
845
874
  else
846
875
  self.class.const_get(resource_name)
847
876
  end
@@ -101,6 +101,12 @@ module ActiveResource
101
101
  request(:post, path, body.to_s, build_request_headers(headers))
102
102
  end
103
103
 
104
+ # Execute a HEAD request.
105
+ # Used to ...
106
+ def head(path, headers= {})
107
+ request(:head, path, build_request_headers(headers))
108
+ end
109
+
104
110
 
105
111
  private
106
112
  # Makes request to remote service.
@@ -108,7 +114,7 @@ module ActiveResource
108
114
  logger.info "#{method.to_s.upcase} #{site.scheme}://#{site.host}:#{site.port}#{path}" if logger
109
115
  result = nil
110
116
  time = Benchmark.realtime { result = http.send(method, path, *arguments) }
111
- logger.info "--> #{result.code} #{result.message} (#{result.body ? result.body : 0}b %.2fs)" % time if logger
117
+ logger.info "--> #{result.code} #{result.message} (#{result.body ? result.body : 0}b " + ("%.2fs)" % time) if logger
112
118
  handle_response(result)
113
119
  end
114
120
 
@@ -0,0 +1,119 @@
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
+ module CustomMethods
34
+ def self.included(base)
35
+ base.class_eval do
36
+ extend ActiveResource::CustomMethods::ClassMethods
37
+ include ActiveResource::CustomMethods::InstanceMethods
38
+
39
+ class << self
40
+ alias :orig_delete :delete
41
+
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)
58
+ end
59
+
60
+ def post(custom_method_name, options = {}, body = '')
61
+ connection.post(custom_method_collection_url(custom_method_name, options), body, headers)
62
+ end
63
+
64
+ def put(custom_method_name, options = {}, body = '')
65
+ connection.put(custom_method_collection_url(custom_method_name, options), body, headers)
66
+ end
67
+
68
+ def delete(custom_method_name, options = {})
69
+ # Need to jump through some hoops to retain the original class 'delete' method
70
+ if custom_method_name.is_a?(Symbol)
71
+ connection.delete(custom_method_collection_url(custom_method_name, options), headers)
72
+ else
73
+ orig_delete(custom_method_name, options)
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ module ClassMethods
81
+ def custom_method_collection_url(method_name, options = {})
82
+ prefix_options, query_options = split_options(options)
83
+ "#{prefix(prefix_options)}#{collection_name}/#{method_name}.#{format.extension}#{query_string(query_options)}"
84
+ end
85
+ end
86
+
87
+ module InstanceMethods
88
+ def get(method_name, options = {})
89
+ connection.get(custom_method_element_url(method_name, options), self.class.headers)
90
+ end
91
+
92
+ def post(method_name, options = {}, body = '')
93
+ if new?
94
+ connection.post(custom_method_new_element_url(method_name, options), (body.nil? ? to_xml : body), self.class.headers)
95
+ else
96
+ connection.post(custom_method_element_url(method_name, options), body, self.class.headers)
97
+ end
98
+ end
99
+
100
+ def put(method_name, options = {}, body = '')
101
+ connection.put(custom_method_element_url(method_name, options), body, self.class.headers)
102
+ end
103
+
104
+ def delete(method_name, options = {})
105
+ connection.delete(custom_method_element_url(method_name, options), self.class.headers)
106
+ end
107
+
108
+
109
+ private
110
+ def custom_method_element_url(method_name, options = {})
111
+ "#{self.class.prefix(prefix_options)}#{self.class.collection_name}/#{id}/#{method_name}.#{self.class.format.extension}#{self.class.send!(:query_string, options)}"
112
+ end
113
+
114
+ def custom_method_new_element_url(method_name, options = {})
115
+ "#{self.class.prefix(prefix_options)}#{self.class.collection_name}/new/#{method_name}.#{self.class.format.extension}#{self.class.send!(:query_string, options)}"
116
+ end
117
+ end
118
+ end
119
+ end
@@ -9,8 +9,8 @@ module ActiveResource
9
9
  @responses = responses
10
10
  end
11
11
 
12
- for method in [ :post, :put, :get, :delete ]
13
- module_eval <<-EOE
12
+ for method in [ :post, :put, :get, :delete, :head ]
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
- for method in [ :get, :delete ]
60
- module_eval <<-EOE
59
+ for method in [ :get, :delete, :head ]
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)
@@ -1,5 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/abstract_unit"
2
- require 'base64'
1
+ require 'abstract_unit'
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
@@ -1,6 +1,6 @@
1
- require "#{File.dirname(__FILE__)}/../abstract_unit"
2
- require "#{File.dirname(__FILE__)}/../fixtures/person"
3
- require "#{File.dirname(__FILE__)}/../fixtures/street_address"
1
+ require 'abstract_unit'
2
+ require 'fixtures/person'
3
+ require 'fixtures/street_address'
4
4
 
5
5
  class CustomMethodsTest < Test::Unit::TestCase
6
6
  def setup
@@ -1,4 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/../abstract_unit"
1
+ require 'abstract_unit'
2
2
  require "fixtures/person"
3
3
  require "fixtures/street_address"
4
4
 
@@ -1,4 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/../abstract_unit"
1
+ require 'abstract_unit'
2
2
  require "fixtures/person"
3
3
  require "fixtures/street_address"
4
4
 
@@ -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,4 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/abstract_unit"
1
+ require 'abstract_unit'
2
2
  require "fixtures/person"
3
3
 
4
4
  class BaseErrorsTest < Test::Unit::TestCase
@@ -1,4 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/abstract_unit"
1
+ require 'abstract_unit'
2
2
  require "fixtures/person"
3
3
  require "fixtures/street_address"
4
4
  require "fixtures/beast"
@@ -36,6 +36,11 @@ class BaseTest < Test::Unit::TestCase
36
36
  mock.put "/people//addresses/1.xml", {}, nil, 404
37
37
  mock.delete "/people//addresses/1.xml", {}, nil, 404
38
38
  mock.post "/people//addresses.xml", {}, nil, 404
39
+ mock.head "/people/1.xml", {}, nil, 200
40
+ mock.head "/people/99.xml", {}, nil, 404
41
+ mock.head "/people/1/addresses/1.xml", {}, nil, 200
42
+ mock.head "/people/1/addresses/2.xml", {}, nil, 404
43
+ mock.head "/people/2/addresses/1.xml", {}, nil, 404
39
44
  end
40
45
  end
41
46
 
@@ -1,5 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/abstract_unit"
2
- require 'base64'
1
+ require 'abstract_unit'
3
2
 
4
3
  class ConnectionTest < Test::Unit::TestCase
5
4
  ResponseCodeStub = Struct.new(:code)
@@ -8,11 +7,13 @@ class ConnectionTest < Test::Unit::TestCase
8
7
  @conn = ActiveResource::Connection.new('http://localhost')
9
8
  @matz = { :id => 1, :name => 'Matz' }
10
9
  @david = { :id => 2, :name => 'David' }
10
+ @percent = { :name => '%a' }
11
11
  @people = [ @matz, @david ].to_xml(:root => 'people')
12
12
  @people_single = [ @matz ].to_xml(:root => 'people-single-elements')
13
13
  @people_empty = [ ].to_xml(:root => 'people-empty-elements')
14
14
  @matz = @matz.to_xml(:root => 'person')
15
15
  @david = @david.to_xml(:root => 'person')
16
+ @percent = @percent.to_xml(:root => 'person')
16
17
  @header = {'key' => 'value'}.freeze
17
18
 
18
19
  @default_request_headers = { 'Content-Type' => 'application/xml' }
@@ -22,12 +23,14 @@ class ConnectionTest < Test::Unit::TestCase
22
23
  mock.get "/people_single_elements.xml", {}, @people_single
23
24
  mock.get "/people_empty_elements.xml", {}, @people_empty
24
25
  mock.get "/people/1.xml", {}, @matz
26
+ mock.get "/percent.xml", {}, @percent
25
27
  mock.put "/people/1.xml", {}, nil, 204
26
28
  mock.put "/people/2.xml", {}, @header, 204
27
29
  mock.delete "/people/1.xml", {}, nil, 200
28
30
  mock.delete "/people/2.xml", @header, nil, 200
29
31
  mock.post "/people.xml", {}, nil, 201, 'Location' => '/people/5.xml'
30
32
  mock.post "/members.xml", {}, @header, 201, 'Location' => '/people/6.xml'
33
+ mock.head "/people/1.xml", {}, nil, 200
31
34
  end
32
35
  end
33
36
 
@@ -106,6 +109,12 @@ class ConnectionTest < Test::Unit::TestCase
106
109
  assert_equal "Matz", matz["name"]
107
110
  end
108
111
 
112
+ def test_head
113
+ response = @conn.head("/people/1.xml")
114
+ assert response.body.blank?
115
+ assert_equal 200, response.code
116
+ end
117
+
109
118
  def test_get_with_header
110
119
  david = @conn.get("/people/2.xml", @header)
111
120
  assert_equal "David", david["name"]
@@ -127,6 +136,11 @@ class ConnectionTest < Test::Unit::TestCase
127
136
  assert_equal [], people
128
137
  end
129
138
 
139
+ def test_get_percent_character
140
+ percent = @conn.get("/percent.xml")
141
+ assert_equal "%a", percent["name"]
142
+ end
143
+
130
144
  def test_post
131
145
  response = @conn.post("/people.xml")
132
146
  assert_equal "/people/5.xml", response["Location"]
@@ -0,0 +1,83 @@
1
+ require 'abstract_unit'
2
+ require "fixtures/person"
3
+
4
+ class FormatTest < Test::Unit::TestCase
5
+ def setup
6
+ @matz = { :id => 1, :name => 'Matz' }
7
+ @david = { :id => 2, :name => 'David' }
8
+
9
+ @programmers = [ @matz, @david ]
10
+ end
11
+
12
+ def test_formats_on_single_element
13
+ for format in [ :json, :xml ]
14
+ using_format(Person, format) do
15
+ ActiveResource::HttpMock.respond_to.get "/people/1.#{format}", {}, ActiveResource::Formats[format].encode(@david)
16
+ assert_equal @david[:name], Person.find(1).name
17
+ end
18
+ end
19
+ end
20
+
21
+ def test_formats_on_collection
22
+ for format in [ :json, :xml ]
23
+ using_format(Person, format) do
24
+ ActiveResource::HttpMock.respond_to.get "/people.#{format}", {}, ActiveResource::Formats[format].encode(@programmers)
25
+ remote_programmers = Person.find(:all)
26
+ assert_equal 2, remote_programmers.size
27
+ assert remote_programmers.select { |p| p.name == 'David' }
28
+ end
29
+ end
30
+ end
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
73
+
74
+ private
75
+ def using_format(klass, mime_type_reference)
76
+ previous_format = klass.format
77
+ klass.format = mime_type_reference
78
+
79
+ yield
80
+ ensure
81
+ klass.format = previous_format
82
+ end
83
+ end
@@ -1,4 +1,4 @@
1
- class SetterTrap < BasicObject
1
+ class SetterTrap < ActiveSupport::BasicObject
2
2
  class << self
3
3
  def rollback_sets(obj)
4
4
  returning yield(setter_trap = new(obj)) do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swivel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.160
4
+ version: 0.0.175
5
5
  platform: ruby
6
6
  authors:
7
7
  - huned
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-01-23 00:00:00 -08:00
12
+ date: 2008-02-11 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -67,40 +67,41 @@ files:
67
67
  - lib/swivel2.rb
68
68
  - bin/mysql2swivel
69
69
  - bin/swivel
70
- - vendor/activeresource-2.0.2-
71
- - vendor/activeresource-2.0.2-/CHANGELOG
72
- - vendor/activeresource-2.0.2-/lib
73
- - vendor/activeresource-2.0.2-/lib/active_resource
74
- - vendor/activeresource-2.0.2-/lib/active_resource/base.rb
75
- - vendor/activeresource-2.0.2-/lib/active_resource/connection.rb
76
- - vendor/activeresource-2.0.2-/lib/active_resource/custom_methods.rb
77
- - vendor/activeresource-2.0.2-/lib/active_resource/formats
78
- - vendor/activeresource-2.0.2-/lib/active_resource/formats/json_format.rb
79
- - vendor/activeresource-2.0.2-/lib/active_resource/formats/xml_format.rb
80
- - vendor/activeresource-2.0.2-/lib/active_resource/formats.rb
81
- - vendor/activeresource-2.0.2-/lib/active_resource/http_mock.rb
82
- - vendor/activeresource-2.0.2-/lib/active_resource/validations.rb
83
- - vendor/activeresource-2.0.2-/lib/active_resource/version.rb
84
- - vendor/activeresource-2.0.2-/lib/active_resource.rb
85
- - vendor/activeresource-2.0.2-/lib/activeresource.rb
86
- - vendor/activeresource-2.0.2-/Rakefile
87
- - vendor/activeresource-2.0.2-/README
88
- - vendor/activeresource-2.0.2-/test
89
- - vendor/activeresource-2.0.2-/test/abstract_unit.rb
90
- - vendor/activeresource-2.0.2-/test/authorization_test.rb
91
- - vendor/activeresource-2.0.2-/test/base
92
- - vendor/activeresource-2.0.2-/test/base/custom_methods_test.rb
93
- - vendor/activeresource-2.0.2-/test/base/equality_test.rb
94
- - vendor/activeresource-2.0.2-/test/base/load_test.rb
95
- - vendor/activeresource-2.0.2-/test/base_errors_test.rb
96
- - vendor/activeresource-2.0.2-/test/base_test.rb
97
- - vendor/activeresource-2.0.2-/test/connection_test.rb
98
- - vendor/activeresource-2.0.2-/test/fixtures
99
- - vendor/activeresource-2.0.2-/test/fixtures/beast.rb
100
- - vendor/activeresource-2.0.2-/test/fixtures/person.rb
101
- - vendor/activeresource-2.0.2-/test/fixtures/street_address.rb
102
- - vendor/activeresource-2.0.2-/test/format_test.rb
103
- - vendor/activeresource-2.0.2-/test/setter_trap.rb
70
+ - vendor/activeresource
71
+ - vendor/activeresource/CHANGELOG
72
+ - vendor/activeresource/lib
73
+ - vendor/activeresource/lib/active_resource
74
+ - vendor/activeresource/lib/active_resource/base.rb
75
+ - vendor/activeresource/lib/active_resource/connection.rb
76
+ - vendor/activeresource/lib/active_resource/custom_methods.rb
77
+ - vendor/activeresource/lib/active_resource/formats
78
+ - vendor/activeresource/lib/active_resource/formats/json_format.rb
79
+ - vendor/activeresource/lib/active_resource/formats/xml_format.rb
80
+ - vendor/activeresource/lib/active_resource/formats.rb
81
+ - vendor/activeresource/lib/active_resource/http_mock.rb
82
+ - vendor/activeresource/lib/active_resource/validations.rb
83
+ - vendor/activeresource/lib/active_resource/version.rb
84
+ - vendor/activeresource/lib/active_resource.rb
85
+ - vendor/activeresource/lib/activeresource.rb
86
+ - vendor/activeresource/MIT-LICENSE
87
+ - vendor/activeresource/Rakefile
88
+ - vendor/activeresource/README
89
+ - vendor/activeresource/test
90
+ - vendor/activeresource/test/abstract_unit.rb
91
+ - vendor/activeresource/test/authorization_test.rb
92
+ - vendor/activeresource/test/base
93
+ - vendor/activeresource/test/base/custom_methods_test.rb
94
+ - vendor/activeresource/test/base/equality_test.rb
95
+ - vendor/activeresource/test/base/load_test.rb
96
+ - vendor/activeresource/test/base_errors_test.rb
97
+ - vendor/activeresource/test/base_test.rb
98
+ - vendor/activeresource/test/connection_test.rb
99
+ - vendor/activeresource/test/fixtures
100
+ - vendor/activeresource/test/fixtures/beast.rb
101
+ - vendor/activeresource/test/fixtures/person.rb
102
+ - vendor/activeresource/test/fixtures/street_address.rb
103
+ - vendor/activeresource/test/format_test.rb
104
+ - vendor/activeresource/test/setter_trap.rb
104
105
  - vendor/activesupport-2.0.2-
105
106
  - vendor/activesupport-2.0.2-/CHANGELOG
106
107
  - vendor/activesupport-2.0.2-/lib
@@ -1,105 +0,0 @@
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
- module ActiveResource
33
- module CustomMethods
34
- def self.included(within)
35
- within.class_eval do
36
- extend ActiveResource::CustomMethods::ClassMethods
37
- include ActiveResource::CustomMethods::InstanceMethods
38
-
39
- class << self
40
- alias :orig_delete :delete
41
-
42
- def get(method_name, options = {})
43
- connection.get(custom_method_collection_url(method_name, options), headers)
44
- end
45
-
46
- def post(method_name, options = {}, body = '')
47
- connection.post(custom_method_collection_url(method_name, options), body, headers)
48
- end
49
-
50
- def put(method_name, options = {}, body = '')
51
- connection.put(custom_method_collection_url(method_name, options), body, headers)
52
- end
53
-
54
- # Need to jump through some hoops to retain the original class 'delete' method
55
- def delete(custom_method_name, options = {})
56
- if (custom_method_name.is_a?(Symbol))
57
- connection.delete(custom_method_collection_url(custom_method_name, options), headers)
58
- else
59
- orig_delete(custom_method_name, options)
60
- end
61
- end
62
- end
63
- end
64
- end
65
-
66
- module ClassMethods
67
- def custom_method_collection_url(method_name, options = {})
68
- prefix_options, query_options = split_options(options)
69
- "#{prefix(prefix_options)}#{collection_name}/#{method_name}.xml#{query_string(query_options)}"
70
- end
71
- end
72
-
73
- module InstanceMethods
74
- def get(method_name, options = {})
75
- connection.get(custom_method_element_url(method_name, options), self.class.headers)
76
- end
77
-
78
- def post(method_name, options = {}, body = '')
79
- if new?
80
- connection.post(custom_method_new_element_url(method_name, options), (body.nil? ? to_xml : body), self.class.headers)
81
- else
82
- connection.post(custom_method_element_url(method_name, options), body, self.class.headers)
83
- end
84
- end
85
-
86
- def put(method_name, options = {}, body = '')
87
- connection.put(custom_method_element_url(method_name, options), body, self.class.headers)
88
- end
89
-
90
- def delete(method_name, options = {})
91
- connection.delete(custom_method_element_url(method_name, options), self.class.headers)
92
- end
93
-
94
-
95
- private
96
- 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)}"
98
- end
99
-
100
- 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)}"
102
- end
103
- end
104
- end
105
- end
@@ -1,42 +0,0 @@
1
- require "#{File.dirname(__FILE__)}/abstract_unit"
2
- require "fixtures/person"
3
-
4
- class FormatTest < Test::Unit::TestCase
5
- def setup
6
- @matz = { :id => 1, :name => 'Matz' }
7
- @david = { :id => 2, :name => 'David' }
8
-
9
- @programmers = [ @matz, @david ]
10
- end
11
-
12
- def test_formats_on_single_element
13
- for format in [ :json, :xml ]
14
- using_format(Person, format) do
15
- ActiveResource::HttpMock.respond_to.get "/people/1.#{format}", {}, ActiveResource::Formats[format].encode(@david)
16
- assert_equal @david[:name], Person.find(1).name
17
- end
18
- end
19
- end
20
-
21
- def test_formats_on_collection
22
- for format in [ :json, :xml ]
23
- using_format(Person, format) do
24
- ActiveResource::HttpMock.respond_to.get "/people.#{format}", {}, ActiveResource::Formats[format].encode(@programmers)
25
- remote_programmers = Person.find(:all)
26
- assert_equal 2, remote_programmers.size
27
- assert remote_programmers.select { |p| p.name == 'David' }
28
- end
29
- end
30
- end
31
-
32
-
33
- private
34
- def using_format(klass, mime_type_reference)
35
- previous_format = klass.format
36
- klass.format = mime_type_reference
37
-
38
- yield
39
- ensure
40
- klass.format = previous_format
41
- end
42
- end