smooth_operator 1.20.10 → 1.21.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 (37) hide show
  1. checksums.yaml +8 -8
  2. data/README.md +2 -2
  3. data/lib/smooth_operator/array_with_meta_data.rb +20 -8
  4. data/lib/smooth_operator/attribute_assignment.rb +41 -54
  5. data/lib/smooth_operator/delegation.rb +14 -33
  6. data/lib/smooth_operator/finder_methods.rb +26 -17
  7. data/lib/smooth_operator/helpers.rb +10 -8
  8. data/lib/smooth_operator/internal_data.rb +45 -0
  9. data/lib/smooth_operator/open_struct.rb +9 -27
  10. data/lib/smooth_operator/operator.rb +11 -12
  11. data/lib/smooth_operator/persistence.rb +52 -41
  12. data/lib/smooth_operator/relation/array_relation.rb +2 -12
  13. data/lib/smooth_operator/relation/association_reflection.rb +2 -6
  14. data/lib/smooth_operator/relation/associations.rb +3 -3
  15. data/lib/smooth_operator/remote_call/base.rb +0 -4
  16. data/lib/smooth_operator/{model_name.rb → resource_name.rb} +2 -2
  17. data/lib/smooth_operator/schema.rb +9 -20
  18. data/lib/smooth_operator/serialization.rb +11 -11
  19. data/lib/smooth_operator/translation.rb +21 -12
  20. data/lib/smooth_operator/type_casting.rb +127 -0
  21. data/lib/smooth_operator/validations.rb +19 -3
  22. data/lib/smooth_operator/version.rb +1 -1
  23. data/lib/smooth_operator.rb +24 -3
  24. data/spec/smooth_operator/attribute_assignment_spec.rb +4 -13
  25. data/spec/smooth_operator/finder_methods_spec.rb +4 -9
  26. data/spec/smooth_operator/persistence_spec.rb +3 -15
  27. data/spec/smooth_operator/{model_name_spec.rb → resource_name_spec.rb} +1 -1
  28. data/spec/support/models/address.rb +0 -2
  29. data/spec/support/models/user.rb +3 -3
  30. data/spec/support/models/user_with_address_and_posts.rb +6 -14
  31. metadata +7 -12
  32. data/lib/smooth_operator/attribute_methods.rb +0 -92
  33. data/lib/smooth_operator/attributes/base.rb +0 -107
  34. data/lib/smooth_operator/attributes/dirty.rb +0 -29
  35. data/lib/smooth_operator/attributes/normal.rb +0 -15
  36. data/lib/smooth_operator/blank_slate.rb +0 -7
  37. data/spec/smooth_operator/attributes_dirty_spec.rb +0 -53
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smooth_operator
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.20.10
4
+ version: 1.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - João Gonçalves
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-30 00:00:00.000000000 Z
11
+ date: 2014-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -83,15 +83,10 @@ files:
83
83
  - lib/smooth_operator.rb
84
84
  - lib/smooth_operator/array_with_meta_data.rb
85
85
  - lib/smooth_operator/attribute_assignment.rb
86
- - lib/smooth_operator/attribute_methods.rb
87
- - lib/smooth_operator/attributes/base.rb
88
- - lib/smooth_operator/attributes/dirty.rb
89
- - lib/smooth_operator/attributes/normal.rb
90
- - lib/smooth_operator/blank_slate.rb
91
86
  - lib/smooth_operator/delegation.rb
92
87
  - lib/smooth_operator/finder_methods.rb
93
88
  - lib/smooth_operator/helpers.rb
94
- - lib/smooth_operator/model_name.rb
89
+ - lib/smooth_operator/internal_data.rb
95
90
  - lib/smooth_operator/open_struct.rb
96
91
  - lib/smooth_operator/operator.rb
97
92
  - lib/smooth_operator/operators/faraday.rb
@@ -106,22 +101,23 @@ files:
106
101
  - lib/smooth_operator/remote_call/errors/timeout.rb
107
102
  - lib/smooth_operator/remote_call/faraday.rb
108
103
  - lib/smooth_operator/remote_call/typhoeus.rb
104
+ - lib/smooth_operator/resource_name.rb
109
105
  - lib/smooth_operator/schema.rb
110
106
  - lib/smooth_operator/serialization.rb
111
107
  - lib/smooth_operator/translation.rb
108
+ - lib/smooth_operator/type_casting.rb
112
109
  - lib/smooth_operator/validations.rb
113
110
  - lib/smooth_operator/version.rb
114
111
  - smooth_operator.gemspec
115
112
  - spec/factories/user_factory.rb
116
113
  - spec/require_helper.rb
117
114
  - spec/smooth_operator/attribute_assignment_spec.rb
118
- - spec/smooth_operator/attributes_dirty_spec.rb
119
115
  - spec/smooth_operator/delegation_spec.rb
120
116
  - spec/smooth_operator/finder_methods_spec.rb
121
- - spec/smooth_operator/model_name_spec.rb
122
117
  - spec/smooth_operator/operator_spec.rb
123
118
  - spec/smooth_operator/persistence_spec.rb
124
119
  - spec/smooth_operator/remote_call_spec.rb
120
+ - spec/smooth_operator/resource_name_spec.rb
125
121
  - spec/smooth_operator/serialization_spec.rb
126
122
  - spec/smooth_operator/validations_spec.rb
127
123
  - spec/spec_helper.rb
@@ -162,13 +158,12 @@ test_files:
162
158
  - spec/factories/user_factory.rb
163
159
  - spec/require_helper.rb
164
160
  - spec/smooth_operator/attribute_assignment_spec.rb
165
- - spec/smooth_operator/attributes_dirty_spec.rb
166
161
  - spec/smooth_operator/delegation_spec.rb
167
162
  - spec/smooth_operator/finder_methods_spec.rb
168
- - spec/smooth_operator/model_name_spec.rb
169
163
  - spec/smooth_operator/operator_spec.rb
170
164
  - spec/smooth_operator/persistence_spec.rb
171
165
  - spec/smooth_operator/remote_call_spec.rb
166
+ - spec/smooth_operator/resource_name_spec.rb
172
167
  - spec/smooth_operator/serialization_spec.rb
173
168
  - spec/smooth_operator/validations_spec.rb
174
169
  - spec/spec_helper.rb
@@ -1,92 +0,0 @@
1
- module SmoothOperator
2
- module AttributeMethods
3
-
4
- module ClassMethods
5
- def known_attributes
6
- Helpers.get_instance_variable(self, :known_attributes, Set.new)
7
- end
8
- end
9
-
10
- def self.included(base)
11
- base.extend(ClassMethods)
12
- end
13
-
14
- def known_attribute?(attribute)
15
- known_attributes.include?(attribute.to_s)
16
- end
17
-
18
- def known_attributes
19
- @known_attributes ||= self.class.known_attributes.dup
20
- end
21
-
22
- def internal_data
23
- @internal_data ||= {}
24
- end
25
-
26
- def get_internal_data(field, method = :value)
27
- result = internal_data[field]
28
-
29
- if result.nil?
30
- nil
31
- elsif method == :value
32
- result.is_a?(Attributes::Dirty) ? internal_data[field].send(method) : internal_data[field]
33
- else
34
- internal_data[field].send(method)
35
- end
36
- end
37
-
38
- def push_to_internal_data(attribute_name, attribute_value)
39
- attribute_name = attribute_name.to_s
40
-
41
- return nil unless allowed_attribute(attribute_name)
42
-
43
- known_attributes.add attribute_name
44
-
45
- initiate_or_update_internal_data(attribute_name, attribute_value)
46
-
47
- new_record_or_mark_for_destruction?(attribute_name, attribute_value)
48
- end
49
-
50
- protected #################### PROTECTED METHODS DOWN BELOW ######################
51
-
52
- def initiate_or_update_internal_data(attribute_name, attribute_value)
53
- if internal_data[attribute_name].nil?
54
- initiate_internal_data(attribute_name, attribute_value)
55
- else
56
- update_internal_data(attribute_name, attribute_value)
57
- end
58
- end
59
-
60
- def new_record_or_mark_for_destruction?(attribute_name, attribute_value)
61
- return nil unless self.class.respond_to?(:smooth_operator?)
62
-
63
- marked_for_destruction?(attribute_value) if attribute_name == self.class.destroy_key
64
-
65
- new_record?(true) if attribute_name == self.class.primary_key
66
- end
67
-
68
- private ######################## PRIVATE #############################
69
-
70
- def initiate_internal_data(attribute_name, attribute_value)
71
- internal_data[attribute_name] = new_attribute_object(attribute_name, attribute_value)
72
-
73
- internal_data[attribute_name] = internal_data[attribute_name].value unless self.class.dirty_attributes?
74
- end
75
-
76
- def update_internal_data(attribute_name, attribute_value)
77
- if self.class.dirty_attributes?
78
- internal_data[attribute_name].set_value(attribute_value, self)
79
- else
80
- internal_data[attribute_name] = new_attribute_object(attribute_name, attribute_value).value
81
- end
82
- end
83
-
84
- def new_attribute_object(attribute_name, attribute_value)
85
- attribute_class = self.class.dirty_attributes? ? Attributes::Dirty : Attributes::Normal
86
-
87
- attribute_class.new(attribute_name, attribute_value, self)
88
- end
89
-
90
- end
91
-
92
- end
@@ -1,107 +0,0 @@
1
- module SmoothOperator
2
- module Attributes
3
-
4
- class Base
5
-
6
- protected ##################### PROTECTED ########################
7
-
8
- def cast_to_type(name, value, parent_object)
9
- known_by_schema, type, unknown_hash_class = parent_object.known_by_schema?(name), parent_object.get_attribute_type(name), parent_object.class.unknown_hash_class
10
-
11
- return Helpers.duplicate(value) if known_by_schema && type.nil?
12
-
13
- case value
14
- when Array
15
- value.map { |array_entry| self.class.new(name, array_entry, parent_object).value }
16
- when Hash
17
- type.nil? ? new_unknown_hash(value, unknown_hash_class, parent_object) : type.new(value, parent_object: parent_object)
18
- else
19
- convert(value, type)
20
- end
21
- end
22
-
23
- def convert(value, type)
24
- case type
25
-
26
- when :string, :text, String
27
- value.to_s
28
-
29
- when :int, :integer, Integer, Fixnum
30
- to_int(value)
31
-
32
- when :date, Date
33
- to_date(value)
34
-
35
- when :float, Float
36
- to_float(value)
37
-
38
- when :bool, :boolean
39
- to_boolean(value)
40
-
41
- when :datetime, :date_time, DateTime
42
- to_datetime(value)
43
-
44
- else
45
- Helpers.duplicate(value)
46
- end
47
- end
48
-
49
- def to_date(string)
50
- return string if string.is_a?(Date)
51
-
52
- Date.parse(string) rescue nil
53
- end
54
-
55
- def to_datetime(string)
56
- return string if string.is_a?(DateTime)
57
-
58
- DateTime.parse(string) rescue nil
59
- end
60
-
61
- def to_boolean(string)
62
- value = string.to_s.downcase
63
-
64
- ['1', 'true'].include?(value) ? true : ['0', 'false'].include?(value) ? false : nil
65
- end
66
-
67
- def to_int(string)
68
- return string if string.is_a?(Fixnum)
69
-
70
- to_float(string).to_i
71
- end
72
-
73
- def to_float(string)
74
- return string if string.is_a?(Float)
75
-
76
- return 0 if string.nil? || !(string.is_a?(String) || string.is_a?(Fixnum))
77
-
78
- value = string.to_s.gsub(',', '.').scan(/-*\d+[.]*\d*/).flatten.map(&:to_f).first
79
-
80
- value.nil? ? 0 : value
81
- end
82
-
83
- def new_unknown_hash(hash, unknown_hash_class, parent_object)
84
- if unknown_hash_class == :none
85
- hash
86
- else
87
- unknown_hash_class.new(cast_params(hash, unknown_hash_class, parent_object))
88
- end
89
- end
90
-
91
-
92
- private ################### PRIVATE #####################
93
-
94
- def cast_params(attributes, unknown_hash_class, parent_object)
95
- hash = {}
96
-
97
- attributes.each do |key, value|
98
- hash[key] = cast_to_type(key, value, parent_object)
99
- end
100
-
101
- hash
102
- end
103
-
104
- end
105
-
106
- end
107
- end
@@ -1,29 +0,0 @@
1
- module SmoothOperator
2
- module Attributes
3
-
4
- class Dirty < Base
5
-
6
- attr_reader :original_name, :original_value, :first_value, :value
7
-
8
- def initialize(name, value, parent_object)
9
- @original_name, @original_value = name, value
10
-
11
- @first_value = set_value(value, parent_object)
12
- end
13
-
14
- def set_value(new_value, parent_object)
15
- @value = cast_to_type(original_name, new_value, parent_object)
16
- end
17
-
18
- def changed?
19
- @first_value != @value
20
- end
21
-
22
- def was
23
- @first_value
24
- end
25
-
26
- end
27
-
28
- end
29
- end
@@ -1,15 +0,0 @@
1
- module SmoothOperator
2
- module Attributes
3
-
4
- class Normal < Base
5
-
6
- attr_reader :value
7
-
8
- def initialize(name, value, parent_object)
9
- @value = cast_to_type(name, value, parent_object)
10
- end
11
-
12
- end
13
-
14
- end
15
- end
@@ -1,7 +0,0 @@
1
- # THANKS tdantas! https://github.com/tdantas
2
-
3
- module SmoothOperator
4
- class BlankSlate
5
- instance_methods.each { |m| undef_method m unless m =~ /^__|object_id/ }
6
- end
7
- end
@@ -1,53 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe SmoothOperator::Attributes::Dirty do
4
-
5
- subject { UserWithAddressAndPosts::DirtyAttributes.new(attributes_for(:user_with_address_and_posts)) }
6
-
7
- context "when no changes are made to an attribute" do
8
- it "checking if that attribute is changed, should return false" do
9
- expect(subject.first_name_changed?).to be false
10
- end
11
-
12
- it "checking that attribute past value, should its original value" do
13
- expect(subject.first_name_was).to eq('John')
14
- end
15
- end
16
-
17
- context "when there are changes made to an attribute" do
18
- before { subject.first_name = 'nhoJ' }
19
-
20
- it "checking if that attribute is changed, should return true" do
21
- expect(subject.first_name_changed?).to be true
22
- end
23
-
24
- it "checking that attribute past value, should its original value" do
25
- expect(subject.first_name_was).to eq('John')
26
- end
27
-
28
- context "when there are changes to the changes made to an attribute" do
29
- before { subject.first_name = 'no_name' }
30
-
31
- it "checking if that attribute is changed, should return true" do
32
- expect(subject.first_name_changed?).to be true
33
- end
34
-
35
- it "checking that attribute past value, should its first original value" do
36
- expect(subject.first_name_was).to eq('John')
37
- end
38
- end
39
- end
40
-
41
- context "when there are changes made to a nested object" do
42
- before { subject.address.street = 'my street' }
43
-
44
- it "checking if the nested object as changed, should return false" do
45
- expect(subject.address_changed?).to be false
46
- end
47
-
48
- it "checking if the nested object's attribute as changed, should return true" do
49
- expect(subject.address.street_changed?).to be true
50
- end
51
- end
52
-
53
- end