swivel 0.0.160 → 0.0.175

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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