smooth_operator 1.3.0 → 1.8.0

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 (60) hide show
  1. checksums.yaml +8 -8
  2. data/Gemfile +0 -5
  3. data/README.md +11 -308
  4. data/console.rb +3 -28
  5. data/lib/smooth_operator.rb +7 -75
  6. data/lib/smooth_operator/array_with_meta_data.rb +21 -20
  7. data/lib/smooth_operator/attribute_assignment.rb +53 -57
  8. data/lib/smooth_operator/delegation.rb +34 -15
  9. data/lib/smooth_operator/finder_methods.rb +17 -33
  10. data/lib/smooth_operator/helpers.rb +7 -37
  11. data/lib/smooth_operator/internal_attribute.rb +49 -0
  12. data/lib/smooth_operator/model_schema.rb +72 -0
  13. data/lib/smooth_operator/open_struct.rb +4 -7
  14. data/lib/smooth_operator/operator.rb +64 -102
  15. data/lib/smooth_operator/persistence.rb +64 -94
  16. data/lib/smooth_operator/remote_call.rb +70 -0
  17. data/lib/smooth_operator/serialization.rb +33 -89
  18. data/lib/smooth_operator/translation.rb +13 -26
  19. data/lib/smooth_operator/type_converter.rb +69 -0
  20. data/lib/smooth_operator/validations.rb +3 -25
  21. data/lib/smooth_operator/version.rb +1 -1
  22. data/smooth_operator.gemspec +5 -9
  23. data/spec/factories/user_factory.rb +4 -5
  24. data/spec/smooth_operator/attribute_assignment_spec.rb +11 -145
  25. data/spec/smooth_operator/delegation_spec.rb +54 -57
  26. data/spec/smooth_operator/finder_methods_spec.rb +2 -91
  27. data/spec/smooth_operator/{resource_name_spec.rb → model_schema_spec.rb} +2 -2
  28. data/spec/smooth_operator/operator_spec.rb +1 -1
  29. data/spec/smooth_operator/persistence_spec.rb +20 -140
  30. data/spec/smooth_operator/serialization_spec.rb +4 -28
  31. data/spec/spec_helper.rb +9 -7
  32. data/spec/support/models/address.rb +0 -9
  33. data/spec/support/models/post.rb +3 -9
  34. data/spec/support/models/user.rb +7 -30
  35. data/spec/support/models/user_with_address_and_posts.rb +12 -20
  36. data/spec/support/test_server.rb +7 -63
  37. metadata +18 -55
  38. data/lib/smooth_operator/associations.rb +0 -110
  39. data/lib/smooth_operator/associations/association_reflection.rb +0 -79
  40. data/lib/smooth_operator/associations/has_many_relation.rb +0 -45
  41. data/lib/smooth_operator/associations/reflection.rb +0 -41
  42. data/lib/smooth_operator/cookie_jar.rb +0 -21
  43. data/lib/smooth_operator/http_methods.rb +0 -17
  44. data/lib/smooth_operator/internal_data.rb +0 -45
  45. data/lib/smooth_operator/operators/connection_wrapper.rb +0 -15
  46. data/lib/smooth_operator/operators/faraday.rb +0 -75
  47. data/lib/smooth_operator/operators/typhoeus.rb +0 -87
  48. data/lib/smooth_operator/options.rb +0 -30
  49. data/lib/smooth_operator/remote_call/base.rb +0 -76
  50. data/lib/smooth_operator/remote_call/errors/connection_failed.rb +0 -20
  51. data/lib/smooth_operator/remote_call/errors/timeout.rb +0 -20
  52. data/lib/smooth_operator/remote_call/faraday.rb +0 -19
  53. data/lib/smooth_operator/remote_call/typhoeus.rb +0 -19
  54. data/lib/smooth_operator/resource_name.rb +0 -46
  55. data/lib/smooth_operator/schema.rb +0 -21
  56. data/lib/smooth_operator/type_casting.rb +0 -127
  57. data/spec/require_helper.rb +0 -11
  58. data/spec/smooth_operator/remote_call_spec.rb +0 -340
  59. data/spec/smooth_operator/validations_spec.rb +0 -42
  60. data/spec/support/models/comment.rb +0 -5
@@ -1,79 +0,0 @@
1
- require "smooth_operator/associations/reflection"
2
-
3
- module SmoothOperator
4
- module Associations
5
- class AssociationReflection < Reflection
6
-
7
- attr_reader :related_reflection, :macro
8
-
9
- def initialize(association, related_reflection, options)
10
- super(association, options)
11
-
12
- @related_reflection, @macro = related_reflection, options[:macro]
13
- end
14
-
15
- def primary_key
16
- @primary_key ||= options[:primary_key] || :id
17
- end
18
-
19
- def foreign_key
20
- @foreign_key ||= options[:foreign_key] || foreign_key_default
21
- end
22
-
23
- def set_relational_keys(origin, destination)
24
- return nil if options[:standalone] == true
25
-
26
- if has_many? || has_one?
27
- set_foreign_key(destination, primary_key_of(origin))
28
- elsif belongs_to?
29
- set_foreign_key(origin, primary_key_of(destination))
30
- end
31
- end
32
-
33
- def set_foreign_key(object, id)
34
- setter = "#{foreign_key}="
35
-
36
- if object.respond_to?(setter)
37
- object.send(setter, id)
38
- elsif object.respond_to?("send_to_representative")
39
- object.send_to_representative(setter, id)
40
- end
41
- end
42
-
43
- def primary_key_of(object)
44
- object.send(primary_key)
45
- end
46
-
47
- def has_many?
48
- macro == :has_many
49
- end
50
-
51
- def has_one?
52
- macro == :has_one
53
- end
54
-
55
- def belongs_to?
56
- macro == :belongs_to
57
- end
58
-
59
- def collection?
60
- has_many?
61
- end
62
-
63
- def rails_serialization?
64
- options[:rails_serialization] == true
65
- end
66
-
67
- private ################################# private
68
-
69
- def foreign_key_default
70
- if has_many? || has_one?
71
- "#{related_reflection.single_name}_id"
72
- elsif belongs_to?
73
- "#{single_name}_id"
74
- end.to_sym
75
- end
76
-
77
- end
78
- end
79
- end
@@ -1,45 +0,0 @@
1
- module SmoothOperator
2
- module Associations
3
- class HasManyRelation < SimpleDelegator
4
-
5
- attr_reader :object, :association
6
-
7
- def initialize(object, association)
8
- @object, @association = object, association
9
- end
10
-
11
- def reload
12
- "TODO"
13
- end
14
-
15
- def new(attributes = {})
16
- object.class.reflect_on_association(association).klass.new(attributes)
17
- end
18
-
19
- def build(attributes = {})
20
- new_array, new_array_entry = get_array, new(attributes)
21
-
22
- new_array.push new_array_entry
23
-
24
- object.send("#{association}=", new_array)
25
-
26
- new_array_entry
27
- end
28
-
29
- undef :is_a?
30
-
31
- protected ############### PROTECTED ###############
32
-
33
- def get_array
34
- data = object.internal_data_get(association.to_s)
35
-
36
- data.nil? ? [] : [*data]
37
- end
38
-
39
- def refresh
40
- __setobj__ get_array
41
- end
42
-
43
- end
44
- end
45
- end
@@ -1,41 +0,0 @@
1
- module SmoothOperator
2
- module Associations
3
- class Reflection
4
-
5
- attr_reader :name, :klass, :options
6
-
7
- def initialize(class_name, options)
8
- options = options.is_a?(Hash) ? options : {}
9
-
10
- @name, @options = class_name, options
11
-
12
- @klass = options[:class_name] || klass_default(@name)
13
-
14
- if options.include?(:class_name) && options[:class_name].nil?
15
- @klass = nil
16
- elsif @klass.is_a?(String)
17
- @klass = @klass.constantize rescue OpenStruct
18
- end
19
- end
20
-
21
- def single_name
22
- @single_name ||= options[:single_name] || name.to_s.singularize
23
- end
24
-
25
- def plural_name
26
- @plural_name ||= options[:plural_name] || name.to_s.pluralize
27
- end
28
-
29
- private ################################# private
30
-
31
- def klass_default(class_name)
32
- if Helpers.plural?(class_name)
33
- class_name.to_s.singularize.camelize
34
- else
35
- class_name.to_s.camelize
36
- end
37
- end
38
-
39
- end
40
- end
41
- end
@@ -1,21 +0,0 @@
1
- module SmoothOperator
2
- class CookieJar < Hash
3
-
4
- def to_s
5
- self.map { |key, value| "#{key}=#{value}"}.join("; ")
6
- end
7
-
8
- def parse(*cookie_strings)
9
- cookie_strings.each do |cookie_string|
10
- next unless cookie_string.is_a?(String)
11
-
12
- key, value = cookie_string.split('; ').first.split('=', 2)
13
-
14
- self[key] = value
15
- end
16
-
17
- self
18
- end
19
-
20
- end
21
- end
@@ -1,17 +0,0 @@
1
- module SmoothOperator
2
- module HttpMethods
3
-
4
- HTTP_VERBS = %w[get post put patch delete]
5
-
6
- HTTP_VERBS.each do |method|
7
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
8
- def #{method}(relative_path = '', params = {}, options = {})
9
- make_the_call(:#{method}, relative_path, params, options) do |remote_call|
10
- block_given? ? yield(remote_call) : remote_call
11
- end
12
- end
13
- RUBY
14
- end
15
-
16
- end
17
- end
@@ -1,45 +0,0 @@
1
- require 'smooth_operator/type_casting'
2
-
3
- module SmoothOperator
4
- module InternalData
5
-
6
- def internal_data
7
- @internal_data ||= {}
8
- end
9
-
10
- def known_attributes
11
- return @known_attributes if defined?(@known_attributes)
12
-
13
- schema_attributes = if self.class.respond_to?(:internal_structure)
14
- self.class.internal_structure.keys
15
- else
16
- []
17
- end
18
-
19
- @known_attributes = Set.new(schema_attributes)
20
- end
21
-
22
- def known_attribute?(attribute)
23
- known_attributes.include?(attribute.to_s)
24
- end
25
-
26
- def internal_data_get(attribute_name)
27
- internal_data[attribute_name]
28
- end
29
-
30
- def internal_data_push(attribute_name, attribute_value)
31
- attribute_name = attribute_name.to_s
32
-
33
- known_attributes.add attribute_name
34
-
35
- internal_data[attribute_name] = TypeCasting.cast_to_type(attribute_name, attribute_value, self)
36
-
37
- if self.class.respond_to?(:smooth_operator?)
38
- marked_for_destruction?(attribute_value) if attribute_name == self.class.destroy_key
39
-
40
- new_record?(true) if attribute_name == self.class.primary_key
41
- end
42
- end
43
-
44
- end
45
- end
@@ -1,15 +0,0 @@
1
- module SmoothOperator
2
- class ConnectionWrapper
3
-
4
- attr_reader :connection
5
-
6
- def initialize(connection)
7
- @connection = connection
8
- end
9
-
10
- def run
11
- connection.run
12
- end
13
-
14
- end
15
- end
@@ -1,75 +0,0 @@
1
- require 'faraday'
2
- require 'typhoeus/adapters/faraday'
3
- require "smooth_operator/remote_call/faraday"
4
-
5
- module SmoothOperator
6
-
7
- module Operators
8
-
9
- module Faraday
10
-
11
- extend self
12
-
13
- # def generate_parallel_connection
14
- # generate_connection(:typhoeus)
15
- # end
16
-
17
- def generate_connection(adapter = nil, options = nil)
18
- adapter ||= :net_http
19
-
20
- ConnectionWrapper.new(::Faraday.new(url: options[:endpoint]) do |builder|
21
- builder.options[:timeout] = options[:timeout].to_i unless Helpers.blank?(options[:timeout])
22
- builder.request :url_encoded
23
- builder.adapter adapter
24
- end)
25
- end
26
-
27
- def make_the_call(http_verb, resource_path, params, body, options)
28
- connection, request_options, options = strip_options(options)
29
-
30
- remote_call = begin
31
- set_basic_authentication(connection, options)
32
-
33
- response = connection.send(http_verb, resource_path) do |request|
34
- request_configuration(request, request_options, options, params, body)
35
- end
36
-
37
- RemoteCall::Faraday.new(response)
38
- rescue ::Faraday::Error::ConnectionFailed
39
- RemoteCall::Errors::ConnectionFailed.new(response)
40
- rescue ::Faraday::Error::TimeoutError
41
- RemoteCall::Errors::Timeout.new(response)
42
- end
43
-
44
- block_given? ? yield(remote_call) : remote_call
45
- end
46
-
47
-
48
- protected ################ PROTECTED ################
49
-
50
- def strip_options(options)
51
- request_options = options.delete(:request_options) || {}
52
-
53
- connection = (options.delete(:connection) || generate_connection(nil, options)).connection
54
-
55
- [connection, request_options, options]
56
- end
57
-
58
- def set_basic_authentication(connection, options)
59
- connection.basic_auth(options[:endpoint_user], options[:endpoint_pass]) if Helpers.present?(options[:endpoint_user])
60
- end
61
-
62
- def request_configuration(request, request_options, options, params, body)
63
- request_options.each { |key, value| request.options.send("#{key}=", value) }
64
-
65
- options[:headers].each { |key, value| request.headers[key] = value }
66
-
67
- params.each { |key, value| request.params[key] = value }
68
-
69
- request.body = body
70
- end
71
-
72
- end
73
-
74
- end
75
- end
@@ -1,87 +0,0 @@
1
- require 'typhoeus'
2
- require "smooth_operator/remote_call/typhoeus"
3
-
4
- module SmoothOperator
5
-
6
- module Operators
7
-
8
- module Typhoeus
9
-
10
- extend self
11
-
12
- def generate_parallel_connection
13
- generate_connection
14
- end
15
-
16
- def generate_connection(adapter = nil, options = nil)
17
- ConnectionWrapper.new(::Typhoeus::Hydra::hydra)
18
- end
19
-
20
- def make_the_call(http_verb, resource_path, params, body, options)
21
- request = ::Typhoeus::Request.new *typhoeus_request_args(http_verb, resource_path, params, body, options)
22
-
23
- hydra = (options[:connection] || generate_connection).connection
24
-
25
- request_result = nil
26
-
27
- hydra.queue(request)
28
-
29
- request.on_complete do |typhoeus_response|
30
- remote_call = remote_call(typhoeus_response)
31
-
32
- if block_given?
33
- request_result = yield(remote_call)
34
- else
35
- request_result = remote_call
36
- end
37
- end
38
-
39
- hydra.run if Helpers.blank?(options[:connection])
40
-
41
- request_result
42
- end
43
-
44
- protected ################ PROTECTED ################
45
-
46
- def typhoeus_request_args(http_verb, relative_path, params, body, options)
47
- [url(options, relative_path), build_typhoeus_options(http_verb, params, body, options)]
48
- end
49
-
50
- def remote_call(typhoeus_response)
51
- if typhoeus_response.return_code == :couldnt_connect
52
- RemoteCall::Errors::ConnectionFailed
53
- elsif typhoeus_response.timed_out?
54
- RemoteCall::Errors::Timeout
55
- else
56
- RemoteCall::Typhoeus
57
- end.new(typhoeus_response)
58
- end
59
-
60
- private ################### PRIVATE ###############
61
-
62
- def build_typhoeus_options(http_verb, params, body, options)
63
- typhoeus_options = { method: http_verb, headers: options[:headers].merge({ "Content-type" => "application/x-www-form-urlencoded" }) }
64
-
65
- typhoeus_options[:timeout] = options[:timeout] if Helpers.present?(options[:timeout])
66
-
67
- typhoeus_options[:body] = body if Helpers.present?(body)
68
-
69
- typhoeus_options[:params] = params if Helpers.present?(params)
70
-
71
- typhoeus_options[:userpwd] = "#{options[:endpoint_user]}:#{options[:endpoint_pass]}" if Helpers.present?(options[:endpoint_user])
72
-
73
- typhoeus_options
74
- end
75
-
76
- def url(options, relative_path)
77
- url = options[:endpoint]
78
-
79
- slice = url[-1] != '/' ? '/' : ''
80
-
81
- url = "#{url}#{slice}#{relative_path}" if Helpers.present?(relative_path)
82
- end
83
-
84
- end
85
-
86
- end
87
- end
@@ -1,30 +0,0 @@
1
- module SmoothOperator
2
- module Options
3
-
4
- def get_option(option, default, *args)
5
- return default unless config_options.include?(option)
6
-
7
- _option = config_options[option]
8
-
9
- case _option
10
- when Symbol
11
- respond_to?(_option) ? send(_option, *args) : _option
12
- when Proc
13
- _option.call(*args)
14
- else
15
- _option
16
- end
17
- end
18
-
19
- def config_options
20
- Helpers.get_instance_variable(self, :config_options, {})
21
- end
22
-
23
- def smooth_operator_options(options = {})
24
- config_options.merge!(options)
25
- end
26
-
27
- alias_method :options, :smooth_operator_options
28
-
29
- end
30
- end