swivel 0.0.160 → 0.0.175
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/swivel.rb +7 -7
- data/lib/swivel2.rb +3 -1
- data/lib/swivel2/connection.rb +15 -1
- data/lib/swivel2/swivelrc.default +1 -2
- data/vendor/{activeresource-2.0.2- → activeresource}/CHANGELOG +17 -0
- data/vendor/activeresource/MIT-LICENSE +20 -0
- data/vendor/{activeresource-2.0.2- → activeresource}/README +0 -0
- data/vendor/{activeresource-2.0.2- → activeresource}/Rakefile +1 -1
- data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource.rb +1 -1
- data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/base.rb +55 -26
- data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/connection.rb +7 -1
- data/vendor/activeresource/lib/active_resource/custom_methods.rb +119 -0
- data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/formats.rb +0 -0
- data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/formats/json_format.rb +0 -0
- data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/formats/xml_format.rb +0 -0
- data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/http_mock.rb +8 -9
- data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/validations.rb +0 -0
- data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/version.rb +0 -0
- data/vendor/{activeresource-2.0.2- → activeresource}/lib/activeresource.rb +0 -0
- data/vendor/{activeresource-2.0.2- → activeresource}/test/abstract_unit.rb +0 -0
- data/vendor/{activeresource-2.0.2- → activeresource}/test/authorization_test.rb +4 -5
- data/vendor/{activeresource-2.0.2- → activeresource}/test/base/custom_methods_test.rb +3 -3
- data/vendor/{activeresource-2.0.2- → activeresource}/test/base/equality_test.rb +1 -1
- data/vendor/{activeresource-2.0.2- → activeresource}/test/base/load_test.rb +36 -1
- data/vendor/{activeresource-2.0.2- → activeresource}/test/base_errors_test.rb +1 -1
- data/vendor/{activeresource-2.0.2- → activeresource}/test/base_test.rb +6 -1
- data/vendor/{activeresource-2.0.2- → activeresource}/test/connection_test.rb +16 -2
- data/vendor/{activeresource-2.0.2- → activeresource}/test/fixtures/beast.rb +0 -0
- data/vendor/{activeresource-2.0.2- → activeresource}/test/fixtures/person.rb +0 -0
- data/vendor/{activeresource-2.0.2- → activeresource}/test/fixtures/street_address.rb +0 -0
- data/vendor/activeresource/test/format_test.rb +83 -0
- data/vendor/{activeresource-2.0.2- → activeresource}/test/setter_trap.rb +1 -1
- metadata +37 -36
- data/vendor/activeresource-2.0.2-/lib/active_resource/custom_methods.rb +0 -105
- data/vendor/activeresource-2.0.2-/test/format_test.rb +0 -42
data/lib/swivel.rb
CHANGED
@@ -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
|
-
|
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'
|
data/lib/swivel2.rb
CHANGED
@@ -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
|
-
|
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'
|
data/lib/swivel2/connection.rb
CHANGED
@@ -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 =
|
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,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.
|
File without changes
|
@@ -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
|
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
|
-
#
|
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
|
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
|
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
|
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
|
-
#
|
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
|
129
|
-
# then fail (with a
|
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
|
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
|
-
|
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
|
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
|
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
|
773
|
-
#
|
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
|
-
|
839
|
-
|
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
|
File without changes
|
data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/formats/json_format.rb
RENAMED
File without changes
|
data/vendor/{activeresource-2.0.2- → activeresource}/lib/active_resource/formats/xml_format.rb
RENAMED
File without changes
|
@@ -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
|
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
|
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.
|
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)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,5 +1,4 @@
|
|
1
|
-
require
|
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
|
2
|
-
require
|
3
|
-
require
|
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
|
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
|
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
|
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"]
|
File without changes
|
File without changes
|
File without changes
|
@@ -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
|
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.
|
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-
|
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
|
71
|
-
- vendor/activeresource
|
72
|
-
- vendor/activeresource
|
73
|
-
- vendor/activeresource
|
74
|
-
- vendor/activeresource
|
75
|
-
- vendor/activeresource
|
76
|
-
- vendor/activeresource
|
77
|
-
- vendor/activeresource
|
78
|
-
- vendor/activeresource
|
79
|
-
- vendor/activeresource
|
80
|
-
- vendor/activeresource
|
81
|
-
- vendor/activeresource
|
82
|
-
- vendor/activeresource
|
83
|
-
- vendor/activeresource
|
84
|
-
- vendor/activeresource
|
85
|
-
- vendor/activeresource
|
86
|
-
- vendor/activeresource-
|
87
|
-
- vendor/activeresource
|
88
|
-
- vendor/activeresource
|
89
|
-
- vendor/activeresource
|
90
|
-
- vendor/activeresource
|
91
|
-
- vendor/activeresource
|
92
|
-
- vendor/activeresource
|
93
|
-
- vendor/activeresource
|
94
|
-
- vendor/activeresource
|
95
|
-
- vendor/activeresource
|
96
|
-
- vendor/activeresource
|
97
|
-
- vendor/activeresource
|
98
|
-
- vendor/activeresource
|
99
|
-
- vendor/activeresource
|
100
|
-
- vendor/activeresource
|
101
|
-
- vendor/activeresource
|
102
|
-
- vendor/activeresource
|
103
|
-
- vendor/activeresource
|
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
|