assembla_api 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +20 -0
  3. data/Rakefile +22 -0
  4. data/lib/assembla_api.rb +130 -0
  5. data/lib/assembla_api/api.rb +373 -0
  6. data/lib/assembla_api/api/actions.rb +58 -0
  7. data/lib/assembla_api/api/arguments.rb +248 -0
  8. data/lib/assembla_api/api/config.rb +107 -0
  9. data/lib/assembla_api/api/config/property.rb +30 -0
  10. data/lib/assembla_api/api/config/property_set.rb +119 -0
  11. data/lib/assembla_api/api/factory.rb +33 -0
  12. data/lib/assembla_api/authorization.rb +76 -0
  13. data/lib/assembla_api/client.rb +21 -0
  14. data/lib/assembla_api/client/activity.rb +30 -0
  15. data/lib/assembla_api/client/authorizations.rb +143 -0
  16. data/lib/assembla_api/client/authorizations/app.rb +98 -0
  17. data/lib/assembla_api/client/portfolio.rb +19 -0
  18. data/lib/assembla_api/client/portfolio/invitations.rb +30 -0
  19. data/lib/assembla_api/client/portfolio/spaces.rb +13 -0
  20. data/lib/assembla_api/client/portfolio/standup_reports.rb +34 -0
  21. data/lib/assembla_api/client/portfolio/tasks.rb +13 -0
  22. data/lib/assembla_api/client/portfolio/ticket_reports.rb +13 -0
  23. data/lib/assembla_api/client/portfolio/tickets.rb +13 -0
  24. data/lib/assembla_api/client/portfolio/users.rb +13 -0
  25. data/lib/assembla_api/client/spaces.rb +140 -0
  26. data/lib/assembla_api/client/spaces/documents.rb +87 -0
  27. data/lib/assembla_api/client/spaces/milestones.rb +102 -0
  28. data/lib/assembla_api/client/spaces/space_tools.rb +65 -0
  29. data/lib/assembla_api/client/spaces/space_tools/merge_requests.rb +105 -0
  30. data/lib/assembla_api/client/spaces/space_tools/merge_requests/versions.rb +41 -0
  31. data/lib/assembla_api/client/spaces/space_tools/merge_requests/versions/comments.rb +34 -0
  32. data/lib/assembla_api/client/spaces/space_tools/merge_requests/versions/votes.rb +46 -0
  33. data/lib/assembla_api/client/spaces/ssh.rb +14 -0
  34. data/lib/assembla_api/client/spaces/ssh/actions.rb +76 -0
  35. data/lib/assembla_api/client/spaces/ssh/actions/launches.rb +14 -0
  36. data/lib/assembla_api/client/spaces/ssh/keys.rb +18 -0
  37. data/lib/assembla_api/client/spaces/ssh/launches.rb +29 -0
  38. data/lib/assembla_api/client/spaces/ssh/servers.rb +63 -0
  39. data/lib/assembla_api/client/spaces/standup_away_reports.rb +41 -0
  40. data/lib/assembla_api/client/spaces/standup_reports.rb +41 -0
  41. data/lib/assembla_api/client/spaces/tags.rb +96 -0
  42. data/lib/assembla_api/client/spaces/tickets.rb +154 -0
  43. data/lib/assembla_api/client/spaces/tickets/associations.rb +57 -0
  44. data/lib/assembla_api/client/spaces/tickets/comments.rb +45 -0
  45. data/lib/assembla_api/client/spaces/tickets/custom_fields.rb +57 -0
  46. data/lib/assembla_api/client/spaces/tickets/statuses.rb +55 -0
  47. data/lib/assembla_api/client/spaces/user_roles.rb +61 -0
  48. data/lib/assembla_api/client/spaces/users.rb +11 -0
  49. data/lib/assembla_api/client/spaces/webhooks.rb +63 -0
  50. data/lib/assembla_api/client/spaces/wiki_pages.rb +78 -0
  51. data/lib/assembla_api/client/spaces/wiki_pages/versions.rb +20 -0
  52. data/lib/assembla_api/client/tasks.rb +72 -0
  53. data/lib/assembla_api/client/users.rb +49 -0
  54. data/lib/assembla_api/client/users/keys.rb +97 -0
  55. data/lib/assembla_api/configuration.rb +71 -0
  56. data/lib/assembla_api/connection.rb +66 -0
  57. data/lib/assembla_api/constants.rb +74 -0
  58. data/lib/assembla_api/core_ext/array.rb +25 -0
  59. data/lib/assembla_api/core_ext/hash.rb +92 -0
  60. data/lib/assembla_api/core_ext/ordered_hash.rb +107 -0
  61. data/lib/assembla_api/deprecation.rb +39 -0
  62. data/lib/assembla_api/error.rb +37 -0
  63. data/lib/assembla_api/error/bad_request.rb +14 -0
  64. data/lib/assembla_api/error/client_error.rb +20 -0
  65. data/lib/assembla_api/error/forbidden.rb +14 -0
  66. data/lib/assembla_api/error/internal_server_error.rb +15 -0
  67. data/lib/assembla_api/error/invalid_options.rb +18 -0
  68. data/lib/assembla_api/error/not_acceptable.rb +15 -0
  69. data/lib/assembla_api/error/not_found.rb +14 -0
  70. data/lib/assembla_api/error/required_params.rb +18 -0
  71. data/lib/assembla_api/error/service_error.rb +68 -0
  72. data/lib/assembla_api/error/service_unavailable.rb +15 -0
  73. data/lib/assembla_api/error/unauthorized.rb +15 -0
  74. data/lib/assembla_api/error/unknown_media.rb +18 -0
  75. data/lib/assembla_api/error/unknown_value.rb +18 -0
  76. data/lib/assembla_api/error/unprocessable_entity.rb +14 -0
  77. data/lib/assembla_api/error/validations.rb +18 -0
  78. data/lib/assembla_api/ext/faraday.rb +38 -0
  79. data/lib/assembla_api/jsonable.rb +18 -0
  80. data/lib/assembla_api/middleware.rb +31 -0
  81. data/lib/assembla_api/mime_type.rb +33 -0
  82. data/lib/assembla_api/normalizer.rb +25 -0
  83. data/lib/assembla_api/null_encoder.rb +25 -0
  84. data/lib/assembla_api/page_iterator.rb +142 -0
  85. data/lib/assembla_api/page_links.rb +45 -0
  86. data/lib/assembla_api/paged_request.rb +40 -0
  87. data/lib/assembla_api/pagination.rb +102 -0
  88. data/lib/assembla_api/parameter_filter.rb +32 -0
  89. data/lib/assembla_api/params_hash.rb +101 -0
  90. data/lib/assembla_api/rate_limit.rb +25 -0
  91. data/lib/assembla_api/request.rb +85 -0
  92. data/lib/assembla_api/request/basic_auth.rb +33 -0
  93. data/lib/assembla_api/request/jsonize.rb +53 -0
  94. data/lib/assembla_api/request/key_auth.rb +31 -0
  95. data/lib/assembla_api/request/oauth2.rb +42 -0
  96. data/lib/assembla_api/request/verbs.rb +60 -0
  97. data/lib/assembla_api/response.rb +28 -0
  98. data/lib/assembla_api/response/header.rb +76 -0
  99. data/lib/assembla_api/response/jsonize.rb +29 -0
  100. data/lib/assembla_api/response/mashify.rb +24 -0
  101. data/lib/assembla_api/response/raise_error.rb +18 -0
  102. data/lib/assembla_api/response/xmlize.rb +26 -0
  103. data/lib/assembla_api/response_wrapper.rb +157 -0
  104. data/lib/assembla_api/ssl_certs/cacerts.pem +2183 -0
  105. data/lib/assembla_api/utils/url.rb +59 -0
  106. data/lib/assembla_api/validations.rb +25 -0
  107. data/lib/assembla_api/validations/format.rb +24 -0
  108. data/lib/assembla_api/validations/presence.rb +30 -0
  109. data/lib/assembla_api/validations/required.rb +24 -0
  110. data/lib/assembla_api/validations/token.rb +41 -0
  111. data/lib/assembla_api/version.rb +12 -0
  112. metadata +347 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 544c0b5cf90c28355fa82a7c6705f1ac875a1ce2
4
+ data.tar.gz: 8d97d3258aa5ae4fef0838249c7230de0f00fe26
5
+ SHA512:
6
+ metadata.gz: 3068a96928b8169a1a0dce98ec74a905203b8160774e84f744649bfcc60dacd1b9d2b6a4ad920524429071c9231dc8a6fe8c9994a1a6721e123b796797c243ca
7
+ data.tar.gz: 830a2513a480adb5922289325df0c5e4527dea53284bba6422d76407899b908183174dd708e5c88131bd9b23bc9f5e8b705e903485a831152ac6085caff760dd
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2014 Assembla
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.
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ #RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ # spec.pattern = FileList['spec/**/*_spec.rb']
8
+ #end
9
+
10
+ FileList['tasks/**/*.rake'].each(&method(:import))
11
+
12
+ #desc 'Run all specs on CI'
13
+ #task ci: [:spec, :features, 'coveralls:push']
14
+
15
+ desc 'Load gem inside irb console'
16
+ task :console do
17
+ require 'irb'
18
+ require 'irb/completion'
19
+ require File.join(__FILE__, '../lib/assembla_api')
20
+ ARGV.clear
21
+ IRB.start
22
+ end
@@ -0,0 +1,130 @@
1
+ # encoding: utf-8
2
+
3
+ require 'faraday'
4
+ require 'assembla_api/version'
5
+ require 'assembla_api/configuration'
6
+ require 'assembla_api/constants'
7
+ require 'assembla_api/utils/url'
8
+ require 'assembla_api/connection'
9
+ require 'assembla_api/deprecation'
10
+ require 'assembla_api/core_ext/ordered_hash'
11
+ require 'assembla_api/ext/faraday'
12
+ require 'assembla_api/middleware'
13
+
14
+ module Assembla
15
+ LIBNAME = 'assembla_api'
16
+
17
+ LIBDIR = File.expand_path("../#{LIBNAME}", __FILE__)
18
+
19
+ class << self
20
+ def included(base)
21
+ base.extend ClassMethods
22
+ end
23
+
24
+ # Alias for Assembla::Client.new
25
+ #
26
+ # @param [Hash] options
27
+ # the configuration options
28
+ #
29
+ # @return [Assembla::Client]
30
+ #
31
+ # @api public
32
+ def new(options = {}, &block)
33
+ Client.new(options, &block)
34
+ end
35
+
36
+ # Default middleware stack that uses default adapter as specified
37
+ # by configuration setup
38
+ #
39
+ # @return [Proc]
40
+ #
41
+ # @api private
42
+ def default_middleware(options = {})
43
+ Middleware.default(options)
44
+ end
45
+
46
+ # Delegate to Assembla::Client
47
+ #
48
+ # @api private
49
+ def method_missing(method_name, *args, &block)
50
+ if new.respond_to?(method_name)
51
+ new.send(method_name, *args, &block)
52
+ elsif configuration.respond_to?(method_name)
53
+ Assembla.configuration.send(method_name, *args, &block)
54
+ else
55
+ super
56
+ end
57
+ end
58
+
59
+ def respond_to?(method_name, include_private = false)
60
+ new.respond_to?(method_name, include_private) ||
61
+ configuration.respond_to?(method_name) ||
62
+ super(method_name, include_private)
63
+ end
64
+ end
65
+
66
+ module ClassMethods
67
+
68
+ # Requires internal libraries
69
+ #
70
+ # @param [String] prefix
71
+ # the relative path prefix
72
+ # @param [Array[String]] libs
73
+ # the array of libraries to require
74
+ #
75
+ # @return [self]
76
+ def require_all(prefix, *libs)
77
+ libs.each do |lib|
78
+ require "#{File.join(prefix, lib)}"
79
+ end
80
+ end
81
+
82
+ # The client configuration
83
+ #
84
+ # @return [Configuration]
85
+ #
86
+ # @api public
87
+ def configuration
88
+ @configuration ||= Configuration.new
89
+ end
90
+
91
+ # Configure options
92
+ #
93
+ # @example
94
+ # Assembla.configure do |c|
95
+ # c.some_option = true
96
+ # end
97
+ #
98
+ # @yield the configuration block
99
+ # @yieldparam configuration [Assembla::Configuration]
100
+ # the configuration instance
101
+ #
102
+ # @return [nil]
103
+ #
104
+ # @api public
105
+ def configure
106
+ yield configuration
107
+ end
108
+ end
109
+
110
+ extend ClassMethods
111
+
112
+ require_all LIBDIR,
113
+ 'authorization',
114
+ 'validations',
115
+ 'normalizer',
116
+ 'parameter_filter',
117
+ 'api',
118
+ 'client',
119
+ 'pagination',
120
+ 'request',
121
+ 'response',
122
+ 'response_wrapper',
123
+ 'error',
124
+ 'mime_type',
125
+ 'page_links',
126
+ 'paged_request',
127
+ 'page_iterator',
128
+ 'params_hash'
129
+
130
+ end # Assembla
@@ -0,0 +1,373 @@
1
+ # encoding: utf-8
2
+
3
+ require 'assembla_api/configuration'
4
+ require 'assembla_api/mime_type'
5
+ require 'assembla_api/rate_limit'
6
+ require 'assembla_api/core_ext/hash'
7
+ require 'assembla_api/core_ext/array'
8
+ require 'assembla_api/null_encoder'
9
+
10
+ require 'assembla_api/request/verbs'
11
+
12
+ require 'assembla_api/api/actions'
13
+ require 'assembla_api/api/factory'
14
+ require 'assembla_api/api/arguments'
15
+
16
+ module Assembla
17
+ # Core class responsible for api interface operations
18
+ class API
19
+ extend Assembla::ClassMethods
20
+ include Constants
21
+ include Authorization
22
+ include MimeType
23
+ include Request::Verbs
24
+ include RateLimit
25
+
26
+ attr_reader *Assembla.configuration.property_names
27
+
28
+ attr_accessor *Validations::VALID_API_KEYS
29
+
30
+ attr_accessor :current_options
31
+
32
+ # Callback to update current configuration options
33
+ class_eval do
34
+ Assembla.configuration.property_names.each do |key|
35
+ define_method "#{key}=" do |arg|
36
+ self.instance_variable_set("@#{key}", arg)
37
+ self.current_options.merge!({:"#{key}" => arg})
38
+ end
39
+ end
40
+ end
41
+
42
+ # Create new API
43
+ #
44
+ # @api public
45
+ def initialize(options={}, &block)
46
+ setup(options)
47
+ yield_or_eval(&block) if block_given?
48
+ end
49
+
50
+ def yield_or_eval(&block)
51
+ return unless block
52
+ block.arity > 0 ? yield(self) : self.instance_eval(&block)
53
+ end
54
+
55
+ # Configure options and process basic authorization
56
+ #
57
+ # @api private
58
+ def setup(options={})
59
+ options = Assembla.configuration.fetch.merge(options)
60
+ self.current_options = options
61
+ Assembla.configuration.property_names.each do |key|
62
+ send("#{key}=", options[key])
63
+ end
64
+ process_basic_auth(options[:basic_auth])
65
+ end
66
+
67
+ # Extract login and password from basic_auth parameter
68
+ #
69
+ def process_basic_auth(auth)
70
+ case auth
71
+ when String
72
+ self.login, self.password = auth.split(':', 2)
73
+ when Hash
74
+ self.login = auth[:login]
75
+ self.password = auth[:password]
76
+ end
77
+ end
78
+
79
+ # List of before callbacks
80
+ #
81
+ # @api public
82
+ def self.before_callbacks
83
+ @before_callbacks ||= []
84
+ end
85
+
86
+ # List of after callbacks
87
+ #
88
+ # @api public
89
+ def self.after_callbacks
90
+ @after_callbacks ||= []
91
+ end
92
+
93
+ # Before request filter
94
+ #
95
+ # @api public
96
+ def self.before_request(callback, params = {})
97
+ before_callbacks << params.merge(callback: callback)
98
+ end
99
+
100
+ # After request filter
101
+ #
102
+ # @api public
103
+ def self.after_request(callback, params = {})
104
+ after_callbacks << params.merge(callback: callback)
105
+ end
106
+
107
+ class << self
108
+ attr_reader :root
109
+ alias_method :root?, :root
110
+ end
111
+
112
+ def self.root!
113
+ @root = true
114
+ end
115
+
116
+ def self.inherited(child_class)
117
+ before_callbacks.reverse_each { |callback|
118
+ child_class.before_callbacks.unshift(callback)
119
+ }
120
+ after_callbacks.reverse_each { |callback|
121
+ child_class.after_callbacks.unshift(callback)
122
+ }
123
+ extend_with_actions(child_class)
124
+ unless child_class.instance_variable_defined?(:@root)
125
+ child_class.instance_variable_set(:@root, false)
126
+ end
127
+ super
128
+ end
129
+
130
+ root!
131
+
132
+ def self.internal_methods
133
+ api = self
134
+ api = api.superclass until api.root?
135
+ api.public_instance_methods(true)
136
+ end
137
+
138
+ def self.extra_methods
139
+ ['actions']
140
+ end
141
+
142
+ # Find all the api methods that should be considred by
143
+ # request callbacks.
144
+ #
145
+ # @return [Set]
146
+ #
147
+ # @api private
148
+ def self.request_methods
149
+ @request_methods ||= begin
150
+ methods = (public_instance_methods(true) -
151
+ internal_methods +
152
+ public_instance_methods(false)).uniq.map(&:to_s)
153
+ Set.new(methods - extra_methods)
154
+ end
155
+ end
156
+
157
+ def self.clear_request_methods!
158
+ @request_methods = nil
159
+ end
160
+
161
+ def self.method_added(method_name)
162
+ method_name = method_name.to_s.gsub(/_with(out)?_callback_.*$/, '')
163
+ # Only subclasses matter
164
+ return if self.root?
165
+ return if extra_methods.include?(method_name)
166
+ # Only public methods are of interest
167
+ return unless request_methods.include?(method_name)
168
+ # Do not redefine
169
+ return if (@__methods_added ||= []).include?(method_name)
170
+
171
+ class_name = self.name.to_s.split('::').last.downcase
172
+ with_method = "#{method_name}_with_callback_#{class_name}"
173
+ without_method = "#{method_name}_without_callback_#{class_name}"
174
+
175
+ return if public_method_defined?(with_method)
176
+
177
+ [method_name, with_method, without_method].each do |met|
178
+ @__methods_added << met
179
+ end
180
+ return if public_method_defined?(with_method)
181
+
182
+ define_method(with_method) do |*args, &block|
183
+ send(:execute, without_method, *args, &block)
184
+ end
185
+ alias_method without_method, method_name
186
+ alias_method method_name, with_method
187
+ clear_request_methods!
188
+ end
189
+
190
+ # Filter callbacks based on kind
191
+ #
192
+ # @param [Symbol] kind
193
+ # one of :before or :after
194
+ #
195
+ # @return [Array[Hash]]
196
+ #
197
+ # @api private
198
+ def filter_callbacks(kind, action_name)
199
+ matched_callbacks = self.class.send("#{kind}_callbacks").select do |callback|
200
+ callback[:only].nil? || callback[:only].include?(action_name)
201
+ end
202
+ end
203
+
204
+ # Run all callbacks associated with this action
205
+ #
206
+ # @apram [Symbol] action_name
207
+ #
208
+ # @api private
209
+ def run_callbacks(action_name, &block)
210
+ filter_callbacks(:before, action_name).each { |hook| send hook[:callback] }
211
+ yield if block_given?
212
+ filter_callbacks(:after, action_name).each { |hook| send hook[:callback] }
213
+ end
214
+
215
+ # Execute action
216
+ #
217
+ # @param [Symbol] action
218
+ #
219
+ # @api private
220
+ def execute(action, *args, &block)
221
+ action_name = action.to_s.gsub(/_with(out)?_callback_.*$/, '')
222
+ result = nil
223
+ run_callbacks(action_name) do
224
+ result = send(action, *args, &block)
225
+ end
226
+ result
227
+ end
228
+
229
+ # Responds to attribute query or attribute clear
230
+ #
231
+ # @api private
232
+ def method_missing(method_name, *args, &block) # :nodoc:
233
+ case method_name.to_s
234
+ when /^(.*)\?$/
235
+ return !!send($1.to_s)
236
+ when /^clear_(.*)$/
237
+ send("#{$1.to_s}=", nil)
238
+ else
239
+ super
240
+ end
241
+ end
242
+
243
+ # Acts as setter and getter for api requests arguments parsing.
244
+ #
245
+ # Returns Arguments instance.
246
+ #
247
+ def arguments(args=(not_set = true), options={}, &block)
248
+ if not_set
249
+ @arguments
250
+ else
251
+ @arguments = Arguments.new(options.merge!(api: self)).parse(*args, &block)
252
+ end
253
+ end
254
+
255
+ # Scope for passing request required arguments.
256
+ #
257
+ def with(args)
258
+ case args
259
+ when Hash
260
+ set args
261
+ when /.*\/.*/i
262
+ user, repo = args.split('/')
263
+ set :user => user, :repo => repo
264
+ else
265
+ ::Kernel.raise ArgumentError, 'This api does not support passed in arguments'
266
+ end
267
+ end
268
+
269
+ # Set a configuration option for a given namespace
270
+ #
271
+ # @param [String] option
272
+ # @param [Object] value
273
+ # @param [Boolean] ignore_setter
274
+ #
275
+ # @return [self]
276
+ #
277
+ # @api public
278
+ def set(option, value=(not_set=true), ignore_setter=false, &block)
279
+ raise ArgumentError, 'value not set' if block and !not_set
280
+ return self if !not_set and value.nil?
281
+
282
+ if not_set
283
+ set_options option
284
+ return self
285
+ end
286
+
287
+ if respond_to?("#{option}=") and not ignore_setter
288
+ return __send__("#{option}=", value)
289
+ end
290
+
291
+ define_accessors option, value
292
+ self
293
+ end
294
+
295
+ # Defines a namespace
296
+ #
297
+ # @param [Array[Symbol]] names
298
+ # the name for the scope
299
+ #
300
+ # @return [self]
301
+ #
302
+ # @api public
303
+ def self.namespace(*names)
304
+ options = names.last.is_a?(Hash) ? names.pop : {}
305
+ names = names.map(&:to_sym)
306
+ name = names.pop
307
+ return if public_method_defined?(name)
308
+
309
+ class_name = extract_class_name(name, options)
310
+ define_method(name) do |*args, &block|
311
+ options = args.last.is_a?(Hash) ? args.pop : {}
312
+ API::Factory.new(class_name, current_options.merge(options), &block)
313
+ end
314
+ self
315
+ end
316
+
317
+ # Extracts class name from options
318
+ #
319
+ # @param [Hash] options
320
+ # @option options [String] :full_name
321
+ # the full name for the class
322
+ # @option options [Boolean] :root
323
+ # if the class is at the root or not
324
+ #
325
+ # @return [String]
326
+ #
327
+ # @api private
328
+ def self.extract_class_name(name, options)
329
+ converted = options.fetch(:full_name, name).to_s
330
+ converted = converted.split('_').map(&:capitalize).join
331
+ class_name = options.fetch(:root, false) ? '': "#{self.name}::"
332
+ class_name += converted
333
+ class_name
334
+ end
335
+
336
+ private
337
+
338
+ # Set multiple options
339
+ #
340
+ # @api private
341
+ def set_options(options)
342
+ unless options.respond_to?(:each)
343
+ raise ArgumentError, 'cannot iterate over value'
344
+ end
345
+ options.each { |key, value| set(key, value) }
346
+ end
347
+
348
+ # Define setters and getters
349
+ #
350
+ # @api private
351
+ def define_accessors(option, value)
352
+ setter = proc { |val| set option, val, true }
353
+ getter = proc { value }
354
+
355
+ define_singleton_method("#{option}=", setter) if setter
356
+ define_singleton_method(option, getter) if getter
357
+ end
358
+
359
+ # Dynamically define a method for setting request option
360
+ #
361
+ # @api private
362
+ def define_singleton_method(method_name, content=Proc.new)
363
+ (class << self; self; end).class_eval do
364
+ undef_method(method_name) if method_defined?(method_name)
365
+ if String === content
366
+ class_eval("def #{method_name}() #{content}; end")
367
+ else
368
+ define_method(method_name, &content)
369
+ end
370
+ end
371
+ end
372
+ end # API
373
+ end # Assembla