swivel 0.0.146 → 0.0.149
Sign up to get free protection for your applications and to get access to all the features.
- data/README +4 -1
- data/Rakefile +1 -1
- data/lib/swivel.rb +1 -1
- data/lib/swivel2/benchmarking.rb +1 -0
- data/lib/swivel2/config.rb +45 -0
- data/lib/swivel2/connection.rb +89 -0
- data/lib/swivel2/formats.rb +11 -0
- data/lib/swivel2/logging.rb +1 -0
- data/lib/swivel2/performance.rb +21 -0
- data/lib/swivel2/response.rb +5 -0
- data/lib/swivel2/swivelrc.default +5 -0
- data/vendor/activeresource-2.0.2-/CHANGELOG +223 -0
- data/vendor/activeresource-2.0.2-/README +165 -0
- data/vendor/activeresource-2.0.2-/Rakefile +133 -0
- data/vendor/activeresource-2.0.2-/lib/active_resource.rb +47 -0
- data/vendor/activeresource-2.0.2-/lib/active_resource/base.rb +872 -0
- data/vendor/activeresource-2.0.2-/lib/active_resource/connection.rb +172 -0
- data/vendor/activeresource-2.0.2-/lib/active_resource/custom_methods.rb +105 -0
- data/vendor/activeresource-2.0.2-/lib/active_resource/formats.rb +14 -0
- data/vendor/activeresource-2.0.2-/lib/active_resource/formats/json_format.rb +23 -0
- data/vendor/activeresource-2.0.2-/lib/active_resource/formats/xml_format.rb +34 -0
- data/vendor/activeresource-2.0.2-/lib/active_resource/http_mock.rb +147 -0
- data/vendor/activeresource-2.0.2-/lib/active_resource/validations.rb +288 -0
- data/vendor/activeresource-2.0.2-/lib/active_resource/version.rb +9 -0
- data/vendor/activeresource-2.0.2-/lib/activeresource.rb +1 -0
- data/vendor/activeresource-2.0.2-/test/abstract_unit.rb +10 -0
- data/vendor/activeresource-2.0.2-/test/authorization_test.rb +82 -0
- data/vendor/activeresource-2.0.2-/test/base/custom_methods_test.rb +96 -0
- data/vendor/activeresource-2.0.2-/test/base/equality_test.rb +43 -0
- data/vendor/activeresource-2.0.2-/test/base/load_test.rb +111 -0
- data/vendor/activeresource-2.0.2-/test/base_errors_test.rb +48 -0
- data/vendor/activeresource-2.0.2-/test/base_test.rb +454 -0
- data/vendor/activeresource-2.0.2-/test/connection_test.rb +170 -0
- data/vendor/activeresource-2.0.2-/test/fixtures/beast.rb +14 -0
- data/vendor/activeresource-2.0.2-/test/fixtures/person.rb +3 -0
- data/vendor/activeresource-2.0.2-/test/fixtures/street_address.rb +4 -0
- data/vendor/activeresource-2.0.2-/test/format_test.rb +42 -0
- data/vendor/activeresource-2.0.2-/test/setter_trap.rb +27 -0
- data/vendor/activesupport-2.0.2-/CHANGELOG +986 -0
- data/vendor/activesupport-2.0.2-/README +43 -0
- data/vendor/activesupport-2.0.2-/lib/active_support.rb +49 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/basic_object.rb +5 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/buffered_logger.rb +107 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/clean_logger.rb +127 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext.rb +4 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array.rb +13 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/access.rb +28 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/conversions.rb +94 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/extract_options.rb +19 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/grouping.rb +68 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/random_access.rb +12 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/bigdecimal.rb +2 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/bigdecimal/conversions.rb +6 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/blank.rb +50 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/cgi.rb +5 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +14 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class.rb +4 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class/attribute_accessors.rb +48 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class/delegating_attributes.rb +40 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class/inheritable_attributes.rb +140 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class/removal.rb +24 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date.rb +10 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date/behavior.rb +13 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date/calculations.rb +188 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date/conversions.rb +98 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date_time.rb +10 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date_time/calculations.rb +77 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date_time/conversions.rb +74 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/duplicable.rb +37 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/enumerable.rb +63 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/exception.rb +33 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/file.rb +21 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/float.rb +5 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/float/rounding.rb +24 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash.rb +13 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/conversions.rb +242 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/diff.rb +19 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/except.rb +24 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/indifferent_access.rb +102 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/keys.rb +54 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/reverse_merge.rb +25 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/slice.rb +28 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/integer.rb +7 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/integer/even_odd.rb +24 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/integer/inflections.rb +21 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel.rb +5 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/agnostics.rb +11 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/daemonizing.rb +15 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/debugger.rb +13 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/reporting.rb +51 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/requires.rb +24 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/load_error.rb +38 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/logger.rb +16 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module.rb +8 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/aliasing.rb +70 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/attr_accessor_with_default.rb +31 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/attr_internal.rb +31 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/attribute_accessors.rb +48 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/delegation.rb +62 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/inclusion.rb +11 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/introspection.rb +35 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/loading.rb +13 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/name_error.rb +17 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/numeric.rb +7 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/numeric/bytes.rb +44 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/numeric/time.rb +91 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object.rb +4 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object/conversions.rb +14 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object/extending.rb +58 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object/instance_variables.rb +22 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object/misc.rb +59 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/pathname.rb +7 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/pathname/clean_within.rb +14 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/proc.rb +12 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range.rb +11 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range/blockless_step.rb +22 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range/conversions.rb +23 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range/include_range.rb +22 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range/overlaps.rb +12 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string.rb +23 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/access.rb +58 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/conversions.rb +28 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/inflections.rb +153 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/iterators.rb +17 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/starts_ends_with.rb +27 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/unicode.rb +42 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/xchar.rb +11 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/symbol.rb +14 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/test.rb +1 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/test/unit/assertions.rb +62 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/time.rb +19 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/time/behavior.rb +13 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/time/calculations.rb +224 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/time/conversions.rb +94 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/dependencies.rb +540 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/deprecation.rb +204 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/duration.rb +96 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/inflections.rb +53 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/inflector.rb +282 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/json.rb +31 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/json/decoding.rb +60 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/date.rb +5 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/date_time.rb +5 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/enumerable.rb +12 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/false_class.rb +5 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/hash.rb +50 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/nil_class.rb +5 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/numeric.rb +5 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/object.rb +6 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/regexp.rb +5 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/string.rb +30 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/symbol.rb +5 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/time.rb +5 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/true_class.rb +5 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/json/encoding.rb +38 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/json/variable.rb +10 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/multibyte.rb +9 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/chars.rb +141 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/generators/generate_tables.rb +149 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/handlers/passthru_handler.rb +9 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/handlers/utf8_handler.rb +564 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/handlers/utf8_handler_proc.rb +43 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/option_merger.rb +25 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/ordered_options.rb +49 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/test_case.rb +5 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/testing.rb +1 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/testing/default.rb +12 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/values/time_zone.rb +181 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/values/unicode_tables.dat +0 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/vendor.rb +14 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/blankslate.rb +113 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder.rb +13 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb +20 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/css.rb +250 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb +115 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb +139 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb +63 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb +328 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/vendor/xml-simple-1.0.11/xmlsimple.rb +1021 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/version.rb +9 -0
- data/vendor/activesupport-2.0.2-/lib/active_support/whiny_nil.rb +38 -0
- data/vendor/activesupport-2.0.2-/lib/activesupport.rb +1 -0
- metadata +222 -2
@@ -0,0 +1,288 @@
|
|
1
|
+
module ActiveResource
|
2
|
+
class ResourceInvalid < ClientError #:nodoc:
|
3
|
+
end
|
4
|
+
|
5
|
+
# Active Resource validation is reported to and from this object, which is used by Base#save
|
6
|
+
# to determine whether the object in a valid state to be saved. See usage example in Validations.
|
7
|
+
class Errors
|
8
|
+
include Enumerable
|
9
|
+
attr_reader :errors
|
10
|
+
|
11
|
+
delegate :empty?, :to => :errors
|
12
|
+
|
13
|
+
def initialize(base) # :nodoc:
|
14
|
+
@base, @errors = base, {}
|
15
|
+
end
|
16
|
+
|
17
|
+
# Add an error to the base Active Resource object rather than an attribute.
|
18
|
+
#
|
19
|
+
# ==== Examples
|
20
|
+
# my_folder = Folder.find(1)
|
21
|
+
# my_folder.errors.add_to_base("You can't edit an existing folder")
|
22
|
+
# my_folder.errors.on_base
|
23
|
+
# # => "You can't edit an existing folder"
|
24
|
+
#
|
25
|
+
# my_folder.errors.add_to_base("This folder has been tagged as frozen")
|
26
|
+
# my_folder.valid?
|
27
|
+
# # => false
|
28
|
+
# my_folder.errors.on_base
|
29
|
+
# # => ["You can't edit an existing folder", "This folder has been tagged as frozen"]
|
30
|
+
#
|
31
|
+
def add_to_base(msg)
|
32
|
+
add(:base, msg)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Adds an error to an Active Resource object's attribute (named for the +attribute+ parameter)
|
36
|
+
# with the error message in +msg+.
|
37
|
+
#
|
38
|
+
# ==== Examples
|
39
|
+
# my_resource = Node.find(1)
|
40
|
+
# my_resource.errors.add('name', 'can not be "base"') if my_resource.name == 'base'
|
41
|
+
# my_resource.errors.on('name')
|
42
|
+
# # => 'can not be "base"!'
|
43
|
+
#
|
44
|
+
# my_resource.errors.add('desc', 'can not be blank') if my_resource.desc == ''
|
45
|
+
# my_resource.valid?
|
46
|
+
# # => false
|
47
|
+
# my_resource.errors.on('desc')
|
48
|
+
# # => 'can not be blank!'
|
49
|
+
#
|
50
|
+
def add(attribute, msg)
|
51
|
+
@errors[attribute.to_s] = [] if @errors[attribute.to_s].nil?
|
52
|
+
@errors[attribute.to_s] << msg
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns true if the specified +attribute+ has errors associated with it.
|
56
|
+
#
|
57
|
+
# ==== Examples
|
58
|
+
# my_resource = Disk.find(1)
|
59
|
+
# my_resource.errors.add('location', 'must be Main') unless my_resource.location == 'Main'
|
60
|
+
# my_resource.errors.on('location')
|
61
|
+
# # => 'must be Main!'
|
62
|
+
#
|
63
|
+
# my_resource.errors.invalid?('location')
|
64
|
+
# # => true
|
65
|
+
# my_resource.errors.invalid?('name')
|
66
|
+
# # => false
|
67
|
+
def invalid?(attribute)
|
68
|
+
!@errors[attribute.to_s].nil?
|
69
|
+
end
|
70
|
+
|
71
|
+
# A method to return the errors associated with +attribute+, which returns nil, if no errors are
|
72
|
+
# associated with the specified +attribute+, the error message if one error is associated with the specified +attribute+,
|
73
|
+
# or an array of error messages if more than one error is associated with the specified +attribute+.
|
74
|
+
#
|
75
|
+
# ==== Examples
|
76
|
+
# my_person = Person.new(params[:person])
|
77
|
+
# my_person.errors.on('login')
|
78
|
+
# # => nil
|
79
|
+
#
|
80
|
+
# my_person.errors.add('login', 'can not be empty') if my_person.login == ''
|
81
|
+
# my_person.errors.on('login')
|
82
|
+
# # => 'can not be empty'
|
83
|
+
#
|
84
|
+
# my_person.errors.add('login', 'can not be longer than 10 characters') if my_person.login.length > 10
|
85
|
+
# my_person.errors.on('login')
|
86
|
+
# # => ['can not be empty', 'can not be longer than 10 characters']
|
87
|
+
def on(attribute)
|
88
|
+
errors = @errors[attribute.to_s]
|
89
|
+
return nil if errors.nil?
|
90
|
+
errors.size == 1 ? errors.first : errors
|
91
|
+
end
|
92
|
+
|
93
|
+
alias :[] :on
|
94
|
+
|
95
|
+
# A method to return errors assigned to +base+ object through add_to_base, which returns nil, if no errors are
|
96
|
+
# associated with the specified +attribute+, the error message if one error is associated with the specified +attribute+,
|
97
|
+
# or an array of error messages if more than one error is associated with the specified +attribute+.
|
98
|
+
#
|
99
|
+
# ==== Examples
|
100
|
+
# my_account = Account.find(1)
|
101
|
+
# my_account.errors.on_base
|
102
|
+
# # => nil
|
103
|
+
#
|
104
|
+
# my_account.errors.add_to_base("This account is frozen")
|
105
|
+
# my_account.errors.on_base
|
106
|
+
# # => "This account is frozen"
|
107
|
+
#
|
108
|
+
# my_account.errors.add_to_base("This account has been closed")
|
109
|
+
# my_account.errors.on_base
|
110
|
+
# # => ["This account is frozen", "This account has been closed"]
|
111
|
+
#
|
112
|
+
def on_base
|
113
|
+
on(:base)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Yields each attribute and associated message per error added.
|
117
|
+
#
|
118
|
+
# ==== Examples
|
119
|
+
# my_person = Person.new(params[:person])
|
120
|
+
#
|
121
|
+
# my_person.errors.add('login', 'can not be empty') if my_person.login == ''
|
122
|
+
# my_person.errors.add('password', 'can not be empty') if my_person.password == ''
|
123
|
+
# messages = ''
|
124
|
+
# my_person.errors.each {|attr, msg| messages += attr.humanize + " " + msg + "<br />"}
|
125
|
+
# messages
|
126
|
+
# # => "Login can not be empty<br />Password can not be empty<br />"
|
127
|
+
#
|
128
|
+
def each
|
129
|
+
@errors.each_key { |attr| @errors[attr].each { |msg| yield attr, msg } }
|
130
|
+
end
|
131
|
+
|
132
|
+
# Yields each full error message added. So Person.errors.add("first_name", "can't be empty") will be returned
|
133
|
+
# through iteration as "First name can't be empty".
|
134
|
+
#
|
135
|
+
# ==== Examples
|
136
|
+
# my_person = Person.new(params[:person])
|
137
|
+
#
|
138
|
+
# my_person.errors.add('login', 'can not be empty') if my_person.login == ''
|
139
|
+
# my_person.errors.add('password', 'can not be empty') if my_person.password == ''
|
140
|
+
# messages = ''
|
141
|
+
# my_person.errors.each_full {|msg| messages += msg + "<br/>"}
|
142
|
+
# messages
|
143
|
+
# # => "Login can not be empty<br />Password can not be empty<br />"
|
144
|
+
#
|
145
|
+
def each_full
|
146
|
+
full_messages.each { |msg| yield msg }
|
147
|
+
end
|
148
|
+
|
149
|
+
# Returns all the full error messages in an array.
|
150
|
+
#
|
151
|
+
# ==== Examples
|
152
|
+
# my_person = Person.new(params[:person])
|
153
|
+
#
|
154
|
+
# my_person.errors.add('login', 'can not be empty') if my_person.login == ''
|
155
|
+
# my_person.errors.add('password', 'can not be empty') if my_person.password == ''
|
156
|
+
# messages = ''
|
157
|
+
# my_person.errors.full_messages.each {|msg| messages += msg + "<br/>"}
|
158
|
+
# messages
|
159
|
+
# # => "Login can not be empty<br />Password can not be empty<br />"
|
160
|
+
#
|
161
|
+
def full_messages
|
162
|
+
full_messages = []
|
163
|
+
|
164
|
+
@errors.each_key do |attr|
|
165
|
+
@errors[attr].each do |msg|
|
166
|
+
next if msg.nil?
|
167
|
+
|
168
|
+
if attr == "base"
|
169
|
+
full_messages << msg
|
170
|
+
else
|
171
|
+
full_messages << [attr.humanize, msg].join(' ')
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
full_messages
|
176
|
+
end
|
177
|
+
|
178
|
+
def clear
|
179
|
+
@errors = {}
|
180
|
+
end
|
181
|
+
|
182
|
+
# Returns the total number of errors added. Two errors added to the same attribute will be counted as such
|
183
|
+
# with this as well.
|
184
|
+
#
|
185
|
+
# ==== Examples
|
186
|
+
# my_person = Person.new(params[:person])
|
187
|
+
# my_person.errors.size
|
188
|
+
# # => 0
|
189
|
+
#
|
190
|
+
# my_person.errors.add('login', 'can not be empty') if my_person.login == ''
|
191
|
+
# my_person.errors.add('password', 'can not be empty') if my_person.password == ''
|
192
|
+
# my_person.error.size
|
193
|
+
# # => 2
|
194
|
+
#
|
195
|
+
def size
|
196
|
+
@errors.values.inject(0) { |error_count, attribute| error_count + attribute.size }
|
197
|
+
end
|
198
|
+
|
199
|
+
alias_method :count, :size
|
200
|
+
alias_method :length, :size
|
201
|
+
|
202
|
+
# Grabs errors from the XML response.
|
203
|
+
def from_xml(xml)
|
204
|
+
clear
|
205
|
+
humanized_attributes = @base.attributes.keys.inject({}) { |h, attr_name| h.update(attr_name.humanize => attr_name) }
|
206
|
+
messages = Hash.from_xml(xml)['errors']['error'] rescue []
|
207
|
+
messages.each do |message|
|
208
|
+
attr_message = humanized_attributes.keys.detect do |attr_name|
|
209
|
+
if message[0, attr_name.size + 1] == "#{attr_name} "
|
210
|
+
add humanized_attributes[attr_name], message[(attr_name.size + 1)..-1]
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
add_to_base message if attr_message.nil?
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
# Module to allow validation of ActiveResource objects, which creates an Errors instance for every resource.
|
220
|
+
# Methods are implemented by overriding +Base#validate+ or its variants Each of these methods can inspect
|
221
|
+
# the state of the object, which usually means ensuring that a number of attributes have a certain value
|
222
|
+
# (such as not empty, within a given range, matching a certain regular expression and so on).
|
223
|
+
#
|
224
|
+
# ==== Example
|
225
|
+
#
|
226
|
+
# class Person < ActiveResource::Base
|
227
|
+
# self.site = "http://www.localhost.com:3000/"
|
228
|
+
# protected
|
229
|
+
# def validate
|
230
|
+
# errors.add_on_empty %w( first_name last_name )
|
231
|
+
# errors.add("phone_number", "has invalid format") unless phone_number =~ /[0-9]*/
|
232
|
+
# end
|
233
|
+
#
|
234
|
+
# def validate_on_create # is only run the first time a new object is saved
|
235
|
+
# unless valid_member?(self)
|
236
|
+
# errors.add("membership_discount", "has expired")
|
237
|
+
# end
|
238
|
+
# end
|
239
|
+
#
|
240
|
+
# def validate_on_update
|
241
|
+
# errors.add_to_base("No changes have occurred") if unchanged_attributes?
|
242
|
+
# end
|
243
|
+
# end
|
244
|
+
#
|
245
|
+
# person = Person.new("first_name" => "Jim", "phone_number" => "I will not tell you.")
|
246
|
+
# person.save # => false (and doesn't do the save)
|
247
|
+
# person.errors.empty? # => false
|
248
|
+
# person.errors.count # => 2
|
249
|
+
# person.errors.on "last_name" # => "can't be empty"
|
250
|
+
# person.attributes = { "last_name" => "Halpert", "phone_number" => "555-5555" }
|
251
|
+
# person.save # => true (and person is now saved to the remote service)
|
252
|
+
#
|
253
|
+
module Validations
|
254
|
+
def self.included(base) # :nodoc:
|
255
|
+
base.class_eval do
|
256
|
+
alias_method_chain :save, :validation
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
# Validate a resource and save (POST) it to the remote web service.
|
261
|
+
def save_with_validation
|
262
|
+
save_without_validation
|
263
|
+
true
|
264
|
+
rescue ResourceInvalid => error
|
265
|
+
errors.from_xml(error.response.body)
|
266
|
+
false
|
267
|
+
end
|
268
|
+
|
269
|
+
# Checks for errors on an object (i.e., is resource.errors empty?).
|
270
|
+
#
|
271
|
+
# ==== Examples
|
272
|
+
# my_person = Person.create(params[:person])
|
273
|
+
# my_person.valid?
|
274
|
+
# # => true
|
275
|
+
#
|
276
|
+
# my_person.errors.add('login', 'can not be empty') if my_person.login == ''
|
277
|
+
# my_person.valid?
|
278
|
+
# # => false
|
279
|
+
def valid?
|
280
|
+
errors.empty?
|
281
|
+
end
|
282
|
+
|
283
|
+
# Returns the Errors object that holds all information about attribute error messages.
|
284
|
+
def errors
|
285
|
+
@errors ||= Errors.new(self)
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'active_resource'
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
$:.unshift "#{File.dirname(__FILE__)}/../lib"
|
4
|
+
require 'active_resource'
|
5
|
+
require 'active_resource/http_mock'
|
6
|
+
|
7
|
+
$:.unshift "#{File.dirname(__FILE__)}/../test"
|
8
|
+
require 'setter_trap'
|
9
|
+
|
10
|
+
ActiveResource::Base.logger = Logger.new("#{File.dirname(__FILE__)}/debug.log")
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/abstract_unit"
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
class AuthorizationTest < Test::Unit::TestCase
|
5
|
+
Response = Struct.new(:code)
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@conn = ActiveResource::Connection.new('http://localhost')
|
9
|
+
@matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person')
|
10
|
+
@david = { :id => 2, :name => 'David' }.to_xml(:root => 'person')
|
11
|
+
@authenticated_conn = ActiveResource::Connection.new("http://david:test123@localhost")
|
12
|
+
@authorization_request_header = { 'Authorization' => 'Basic ZGF2aWQ6dGVzdDEyMw==' }
|
13
|
+
|
14
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
15
|
+
mock.get "/people/2.xml", @authorization_request_header, @david
|
16
|
+
mock.put "/people/2.xml", @authorization_request_header, nil, 204
|
17
|
+
mock.delete "/people/2.xml", @authorization_request_header, nil, 200
|
18
|
+
mock.post "/people/2/addresses.xml", @authorization_request_header, nil, 201, 'Location' => '/people/1/addresses/5'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_authorization_header
|
23
|
+
authorization_header = @authenticated_conn.send!(:authorization_header)
|
24
|
+
assert_equal @authorization_request_header['Authorization'], authorization_header['Authorization']
|
25
|
+
authorization = authorization_header["Authorization"].to_s.split
|
26
|
+
|
27
|
+
assert_equal "Basic", authorization[0]
|
28
|
+
assert_equal ["david", "test123"], Base64.decode64(authorization[1]).split(":")[0..1]
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_authorization_header_with_username_but_no_password
|
32
|
+
@conn = ActiveResource::Connection.new("http://david:@localhost")
|
33
|
+
authorization_header = @conn.send!(:authorization_header)
|
34
|
+
authorization = authorization_header["Authorization"].to_s.split
|
35
|
+
|
36
|
+
assert_equal "Basic", authorization[0]
|
37
|
+
assert_equal ["david"], Base64.decode64(authorization[1]).split(":")[0..1]
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_authorization_header_with_password_but_no_username
|
41
|
+
@conn = ActiveResource::Connection.new("http://:test123@localhost")
|
42
|
+
authorization_header = @conn.send!(:authorization_header)
|
43
|
+
authorization = authorization_header["Authorization"].to_s.split
|
44
|
+
|
45
|
+
assert_equal "Basic", authorization[0]
|
46
|
+
assert_equal ["", "test123"], Base64.decode64(authorization[1]).split(":")[0..1]
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_get
|
50
|
+
david = @authenticated_conn.get("/people/2.xml")
|
51
|
+
assert_equal "David", david["name"]
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_post
|
55
|
+
response = @authenticated_conn.post("/people/2/addresses.xml")
|
56
|
+
assert_equal "/people/1/addresses/5", response["Location"]
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_put
|
60
|
+
response = @authenticated_conn.put("/people/2.xml")
|
61
|
+
assert_equal 204, response.code
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_delete
|
65
|
+
response = @authenticated_conn.delete("/people/2.xml")
|
66
|
+
assert_equal 200, response.code
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_raises_invalid_request_on_unauthorized_requests
|
70
|
+
assert_raises(ActiveResource::InvalidRequestError) { @conn.post("/people/2.xml") }
|
71
|
+
assert_raises(ActiveResource::InvalidRequestError) { @conn.post("/people/2/addresses.xml") }
|
72
|
+
assert_raises(ActiveResource::InvalidRequestError) { @conn.put("/people/2.xml") }
|
73
|
+
assert_raises(ActiveResource::InvalidRequestError) { @conn.delete("/people/2.xml") }
|
74
|
+
end
|
75
|
+
|
76
|
+
protected
|
77
|
+
def assert_response_raises(klass, code)
|
78
|
+
assert_raise(klass, "Expected response code #{code} to raise #{klass}") do
|
79
|
+
@conn.send!(:handle_response, Response.new(code))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../abstract_unit"
|
2
|
+
require "#{File.dirname(__FILE__)}/../fixtures/person"
|
3
|
+
require "#{File.dirname(__FILE__)}/../fixtures/street_address"
|
4
|
+
|
5
|
+
class CustomMethodsTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person')
|
8
|
+
@matz_deep = { :id => 1, :name => 'Matz', :other => 'other' }.to_xml(:root => 'person')
|
9
|
+
@matz_array = [{ :id => 1, :name => 'Matz' }].to_xml(:root => 'people')
|
10
|
+
@ryan = { :name => 'Ryan' }.to_xml(:root => 'person')
|
11
|
+
@addy = { :id => 1, :street => '12345 Street' }.to_xml(:root => 'address')
|
12
|
+
@addy_deep = { :id => 1, :street => '12345 Street', :zip => "27519" }.to_xml(:root => 'address')
|
13
|
+
@default_request_headers = { 'Content-Type' => 'application/xml' }
|
14
|
+
|
15
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
16
|
+
mock.get "/people/1.xml", {}, @matz
|
17
|
+
mock.get "/people/1/shallow.xml", {}, @matz
|
18
|
+
mock.get "/people/1/deep.xml", {}, @matz_deep
|
19
|
+
mock.get "/people/retrieve.xml?name=Matz", {}, @matz_array
|
20
|
+
mock.get "/people/managers.xml", {}, @matz_array
|
21
|
+
mock.post "/people/hire.xml?name=Matz", {}, nil, 201
|
22
|
+
mock.put "/people/1/promote.xml?position=Manager", {}, nil, 204
|
23
|
+
mock.put "/people/promote.xml?name=Matz", {}, nil, 204, {}
|
24
|
+
mock.put "/people/sort.xml?by=name", {}, nil, 204
|
25
|
+
mock.delete "/people/deactivate.xml?name=Matz", {}, nil, 200
|
26
|
+
mock.delete "/people/1/deactivate.xml", {}, nil, 200
|
27
|
+
mock.post "/people/new/register.xml", {}, @ryan, 201, 'Location' => '/people/5.xml'
|
28
|
+
mock.post "/people/1/register.xml", {}, @matz, 201
|
29
|
+
mock.get "/people/1/addresses/1.xml", {}, @addy
|
30
|
+
mock.get "/people/1/addresses/1/deep.xml", {}, @addy_deep
|
31
|
+
mock.put "/people/1/addresses/1/normalize_phone.xml?locale=US", {}, nil, 204
|
32
|
+
mock.put "/people/1/addresses/sort.xml?by=name", {}, nil, 204
|
33
|
+
mock.post "/people/1/addresses/new/link.xml", {}, { :street => '12345 Street' }.to_xml(:root => 'address'), 201, 'Location' => '/people/1/addresses/2.xml'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def teardown
|
38
|
+
ActiveResource::HttpMock.reset!
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_custom_collection_method
|
42
|
+
# GET
|
43
|
+
assert_equal([{ "id" => 1, "name" => 'Matz' }], Person.get(:retrieve, :name => 'Matz'))
|
44
|
+
|
45
|
+
# POST
|
46
|
+
assert_equal(ActiveResource::Response.new("", 201, {}), Person.post(:hire, :name => 'Matz'))
|
47
|
+
|
48
|
+
# PUT
|
49
|
+
assert_equal ActiveResource::Response.new("", 204, {}),
|
50
|
+
Person.put(:promote, {:name => 'Matz'}, 'atestbody')
|
51
|
+
assert_equal ActiveResource::Response.new("", 204, {}), Person.put(:sort, :by => 'name')
|
52
|
+
|
53
|
+
# DELETE
|
54
|
+
Person.delete :deactivate, :name => 'Matz'
|
55
|
+
|
56
|
+
# Nested resource
|
57
|
+
assert_equal ActiveResource::Response.new("", 204, {}), StreetAddress.put(:sort, :person_id => 1, :by => 'name')
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_custom_element_method
|
61
|
+
# Test GET against an element URL
|
62
|
+
assert_equal Person.find(1).get(:shallow), {"id" => 1, "name" => 'Matz'}
|
63
|
+
assert_equal Person.find(1).get(:deep), {"id" => 1, "name" => 'Matz', "other" => 'other'}
|
64
|
+
|
65
|
+
# Test PUT against an element URL
|
66
|
+
assert_equal ActiveResource::Response.new("", 204, {}), Person.find(1).put(:promote, {:position => 'Manager'}, 'body')
|
67
|
+
|
68
|
+
# Test DELETE against an element URL
|
69
|
+
assert_equal ActiveResource::Response.new("", 200, {}), Person.find(1).delete(:deactivate)
|
70
|
+
|
71
|
+
# With nested resources
|
72
|
+
assert_equal StreetAddress.find(1, :params => { :person_id => 1 }).get(:deep),
|
73
|
+
{ "id" => 1, "street" => '12345 Street', "zip" => "27519" }
|
74
|
+
assert_equal ActiveResource::Response.new("", 204, {}),
|
75
|
+
StreetAddress.find(1, :params => { :person_id => 1 }).put(:normalize_phone, :locale => 'US')
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_custom_new_element_method
|
79
|
+
# Test POST against a new element URL
|
80
|
+
ryan = Person.new(:name => 'Ryan')
|
81
|
+
assert_equal ActiveResource::Response.new(@ryan, 201, {'Location' => '/people/5.xml'}), ryan.post(:register)
|
82
|
+
|
83
|
+
# Test POST against a nested collection URL
|
84
|
+
addy = StreetAddress.new(:street => '123 Test Dr.', :person_id => 1)
|
85
|
+
assert_equal ActiveResource::Response.new({ :street => '12345 Street' }.to_xml(:root => 'address'),
|
86
|
+
201, {'Location' => '/people/1/addresses/2.xml'}),
|
87
|
+
addy.post(:link)
|
88
|
+
|
89
|
+
matz = Person.new(:id => 1, :name => 'Matz')
|
90
|
+
assert_equal ActiveResource::Response.new(@matz, 201), matz.post(:register)
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_find_custom_resources
|
94
|
+
assert_equal 'Matz', Person.find(:all, :from => :managers).first.name
|
95
|
+
end
|
96
|
+
end
|