swivel 0.0.146 → 0.0.149

Sign up to get free protection for your applications and to get access to all the features.
Files changed (183) hide show
  1. data/README +4 -1
  2. data/Rakefile +1 -1
  3. data/lib/swivel.rb +1 -1
  4. data/lib/swivel2/benchmarking.rb +1 -0
  5. data/lib/swivel2/config.rb +45 -0
  6. data/lib/swivel2/connection.rb +89 -0
  7. data/lib/swivel2/formats.rb +11 -0
  8. data/lib/swivel2/logging.rb +1 -0
  9. data/lib/swivel2/performance.rb +21 -0
  10. data/lib/swivel2/response.rb +5 -0
  11. data/lib/swivel2/swivelrc.default +5 -0
  12. data/vendor/activeresource-2.0.2-/CHANGELOG +223 -0
  13. data/vendor/activeresource-2.0.2-/README +165 -0
  14. data/vendor/activeresource-2.0.2-/Rakefile +133 -0
  15. data/vendor/activeresource-2.0.2-/lib/active_resource.rb +47 -0
  16. data/vendor/activeresource-2.0.2-/lib/active_resource/base.rb +872 -0
  17. data/vendor/activeresource-2.0.2-/lib/active_resource/connection.rb +172 -0
  18. data/vendor/activeresource-2.0.2-/lib/active_resource/custom_methods.rb +105 -0
  19. data/vendor/activeresource-2.0.2-/lib/active_resource/formats.rb +14 -0
  20. data/vendor/activeresource-2.0.2-/lib/active_resource/formats/json_format.rb +23 -0
  21. data/vendor/activeresource-2.0.2-/lib/active_resource/formats/xml_format.rb +34 -0
  22. data/vendor/activeresource-2.0.2-/lib/active_resource/http_mock.rb +147 -0
  23. data/vendor/activeresource-2.0.2-/lib/active_resource/validations.rb +288 -0
  24. data/vendor/activeresource-2.0.2-/lib/active_resource/version.rb +9 -0
  25. data/vendor/activeresource-2.0.2-/lib/activeresource.rb +1 -0
  26. data/vendor/activeresource-2.0.2-/test/abstract_unit.rb +10 -0
  27. data/vendor/activeresource-2.0.2-/test/authorization_test.rb +82 -0
  28. data/vendor/activeresource-2.0.2-/test/base/custom_methods_test.rb +96 -0
  29. data/vendor/activeresource-2.0.2-/test/base/equality_test.rb +43 -0
  30. data/vendor/activeresource-2.0.2-/test/base/load_test.rb +111 -0
  31. data/vendor/activeresource-2.0.2-/test/base_errors_test.rb +48 -0
  32. data/vendor/activeresource-2.0.2-/test/base_test.rb +454 -0
  33. data/vendor/activeresource-2.0.2-/test/connection_test.rb +170 -0
  34. data/vendor/activeresource-2.0.2-/test/fixtures/beast.rb +14 -0
  35. data/vendor/activeresource-2.0.2-/test/fixtures/person.rb +3 -0
  36. data/vendor/activeresource-2.0.2-/test/fixtures/street_address.rb +4 -0
  37. data/vendor/activeresource-2.0.2-/test/format_test.rb +42 -0
  38. data/vendor/activeresource-2.0.2-/test/setter_trap.rb +27 -0
  39. data/vendor/activesupport-2.0.2-/CHANGELOG +986 -0
  40. data/vendor/activesupport-2.0.2-/README +43 -0
  41. data/vendor/activesupport-2.0.2-/lib/active_support.rb +49 -0
  42. data/vendor/activesupport-2.0.2-/lib/active_support/basic_object.rb +5 -0
  43. data/vendor/activesupport-2.0.2-/lib/active_support/buffered_logger.rb +107 -0
  44. data/vendor/activesupport-2.0.2-/lib/active_support/clean_logger.rb +127 -0
  45. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext.rb +4 -0
  46. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array.rb +13 -0
  47. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/access.rb +28 -0
  48. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/conversions.rb +94 -0
  49. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/extract_options.rb +19 -0
  50. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/grouping.rb +68 -0
  51. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/array/random_access.rb +12 -0
  52. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/bigdecimal.rb +2 -0
  53. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/bigdecimal/conversions.rb +6 -0
  54. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/blank.rb +50 -0
  55. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/cgi.rb +5 -0
  56. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +14 -0
  57. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class.rb +4 -0
  58. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class/attribute_accessors.rb +48 -0
  59. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class/delegating_attributes.rb +40 -0
  60. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class/inheritable_attributes.rb +140 -0
  61. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/class/removal.rb +24 -0
  62. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date.rb +10 -0
  63. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date/behavior.rb +13 -0
  64. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date/calculations.rb +188 -0
  65. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date/conversions.rb +98 -0
  66. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date_time.rb +10 -0
  67. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date_time/calculations.rb +77 -0
  68. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/date_time/conversions.rb +74 -0
  69. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/duplicable.rb +37 -0
  70. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/enumerable.rb +63 -0
  71. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/exception.rb +33 -0
  72. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/file.rb +21 -0
  73. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/float.rb +5 -0
  74. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/float/rounding.rb +24 -0
  75. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash.rb +13 -0
  76. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/conversions.rb +242 -0
  77. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/diff.rb +19 -0
  78. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/except.rb +24 -0
  79. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/indifferent_access.rb +102 -0
  80. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/keys.rb +54 -0
  81. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/reverse_merge.rb +25 -0
  82. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/hash/slice.rb +28 -0
  83. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/integer.rb +7 -0
  84. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/integer/even_odd.rb +24 -0
  85. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/integer/inflections.rb +21 -0
  86. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel.rb +5 -0
  87. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/agnostics.rb +11 -0
  88. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/daemonizing.rb +15 -0
  89. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/debugger.rb +13 -0
  90. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/reporting.rb +51 -0
  91. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/kernel/requires.rb +24 -0
  92. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/load_error.rb +38 -0
  93. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/logger.rb +16 -0
  94. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module.rb +8 -0
  95. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/aliasing.rb +70 -0
  96. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/attr_accessor_with_default.rb +31 -0
  97. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/attr_internal.rb +31 -0
  98. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/attribute_accessors.rb +48 -0
  99. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/delegation.rb +62 -0
  100. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/inclusion.rb +11 -0
  101. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/introspection.rb +35 -0
  102. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/module/loading.rb +13 -0
  103. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/name_error.rb +17 -0
  104. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/numeric.rb +7 -0
  105. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/numeric/bytes.rb +44 -0
  106. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/numeric/time.rb +91 -0
  107. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object.rb +4 -0
  108. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object/conversions.rb +14 -0
  109. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object/extending.rb +58 -0
  110. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object/instance_variables.rb +22 -0
  111. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/object/misc.rb +59 -0
  112. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/pathname.rb +7 -0
  113. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/pathname/clean_within.rb +14 -0
  114. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/proc.rb +12 -0
  115. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range.rb +11 -0
  116. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range/blockless_step.rb +22 -0
  117. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range/conversions.rb +23 -0
  118. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range/include_range.rb +22 -0
  119. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/range/overlaps.rb +12 -0
  120. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string.rb +23 -0
  121. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/access.rb +58 -0
  122. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/conversions.rb +28 -0
  123. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/inflections.rb +153 -0
  124. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/iterators.rb +17 -0
  125. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/starts_ends_with.rb +27 -0
  126. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/unicode.rb +42 -0
  127. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/string/xchar.rb +11 -0
  128. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/symbol.rb +14 -0
  129. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/test.rb +1 -0
  130. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/test/unit/assertions.rb +62 -0
  131. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/time.rb +19 -0
  132. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/time/behavior.rb +13 -0
  133. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/time/calculations.rb +224 -0
  134. data/vendor/activesupport-2.0.2-/lib/active_support/core_ext/time/conversions.rb +94 -0
  135. data/vendor/activesupport-2.0.2-/lib/active_support/dependencies.rb +540 -0
  136. data/vendor/activesupport-2.0.2-/lib/active_support/deprecation.rb +204 -0
  137. data/vendor/activesupport-2.0.2-/lib/active_support/duration.rb +96 -0
  138. data/vendor/activesupport-2.0.2-/lib/active_support/inflections.rb +53 -0
  139. data/vendor/activesupport-2.0.2-/lib/active_support/inflector.rb +282 -0
  140. data/vendor/activesupport-2.0.2-/lib/active_support/json.rb +31 -0
  141. data/vendor/activesupport-2.0.2-/lib/active_support/json/decoding.rb +60 -0
  142. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/date.rb +5 -0
  143. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/date_time.rb +5 -0
  144. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/enumerable.rb +12 -0
  145. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/false_class.rb +5 -0
  146. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/hash.rb +50 -0
  147. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/nil_class.rb +5 -0
  148. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/numeric.rb +5 -0
  149. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/object.rb +6 -0
  150. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/regexp.rb +5 -0
  151. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/string.rb +30 -0
  152. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/symbol.rb +5 -0
  153. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/time.rb +5 -0
  154. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoders/true_class.rb +5 -0
  155. data/vendor/activesupport-2.0.2-/lib/active_support/json/encoding.rb +38 -0
  156. data/vendor/activesupport-2.0.2-/lib/active_support/json/variable.rb +10 -0
  157. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte.rb +9 -0
  158. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/chars.rb +141 -0
  159. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/generators/generate_tables.rb +149 -0
  160. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/handlers/passthru_handler.rb +9 -0
  161. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/handlers/utf8_handler.rb +564 -0
  162. data/vendor/activesupport-2.0.2-/lib/active_support/multibyte/handlers/utf8_handler_proc.rb +43 -0
  163. data/vendor/activesupport-2.0.2-/lib/active_support/option_merger.rb +25 -0
  164. data/vendor/activesupport-2.0.2-/lib/active_support/ordered_options.rb +49 -0
  165. data/vendor/activesupport-2.0.2-/lib/active_support/test_case.rb +5 -0
  166. data/vendor/activesupport-2.0.2-/lib/active_support/testing.rb +1 -0
  167. data/vendor/activesupport-2.0.2-/lib/active_support/testing/default.rb +12 -0
  168. data/vendor/activesupport-2.0.2-/lib/active_support/values/time_zone.rb +181 -0
  169. data/vendor/activesupport-2.0.2-/lib/active_support/values/unicode_tables.dat +0 -0
  170. data/vendor/activesupport-2.0.2-/lib/active_support/vendor.rb +14 -0
  171. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/blankslate.rb +113 -0
  172. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder.rb +13 -0
  173. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb +20 -0
  174. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/css.rb +250 -0
  175. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb +115 -0
  176. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb +139 -0
  177. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb +63 -0
  178. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb +328 -0
  179. data/vendor/activesupport-2.0.2-/lib/active_support/vendor/xml-simple-1.0.11/xmlsimple.rb +1021 -0
  180. data/vendor/activesupport-2.0.2-/lib/active_support/version.rb +9 -0
  181. data/vendor/activesupport-2.0.2-/lib/active_support/whiny_nil.rb +38 -0
  182. data/vendor/activesupport-2.0.2-/lib/activesupport.rb +1 -0
  183. 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,9 @@
1
+ module ActiveResource
2
+ module VERSION #:nodoc:
3
+ MAJOR = 2
4
+ MINOR = 0
5
+ TINY = 2
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ 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