smooth_operator 1.8.8 → 1.9.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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NDYzNDA5ZmU0YzkzNDFmMzEzMzkyMjk5OWY3YWIzZjUzZWJlZGI0ZA==
4
+ M2UzYWIwNGJhMGE3YTA4YTUyNjA5MzM2NzdkMTM1MzdjZWFmZjVlYg==
5
5
  data.tar.gz: !binary |-
6
- ZGQ4ZTRhZjhlMzAyMWRlYTFiNDkwYzM1YTQwNzk1MTkxM2E1YzQ1Yw==
6
+ YTVjOTE5MWM3NmNkNjA3MWUyNmU5M2Y5YThjMDM1NzYwOTQyZjdkMw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MGQ3NDUyY2U5MzMwNGE5NGNiZDk1OWQ1ZjU2ZjM1NTA2ZGIzNTFlYzJkYWZm
10
- Yjc5MDBhNDhhYThlZjkyYmE0NjcyZWQxYjczMGZiMDYzNTdjOGMwYTBkMWRm
11
- MjE0MzdmODgzYjM3M2RhYTg4NmIxOTljNjBjOTg3YjQ2ZDUxZDQ=
9
+ N2YwN2Y3ODg3YzFhZDQxNjA1OWM4YTk3M2ExYTZkZWYxYjhkN2Y4N2M1ZTQw
10
+ NTllZTBhMGYxOGM3OTU4OTA4ZWUyMGIwNmY2YzM2NTZjNmQ2YmJiMzMwYjE1
11
+ MmQwYjgwOWI4ZjI5MjU1NTljNTg5MzY0ZWZjM2FiYzk5MDc3YWU=
12
12
  data.tar.gz: !binary |-
13
- NjgxMmJkZTAzN2E5MjlkNzcxZmQyYmI5NDhmODM1OGFkYWIyZDA4YzYwNGQw
14
- NDBmMzUyZDU4YjgwYzZlZGRmOWFmNGUwMjVjNDMwZmJiYTgwNDY4MWYxNTY3
15
- NmE5MjZhNGYwMDBjMTliNjk0NGE1OTRlMjVlZDM2NjUzMDEzNzY=
13
+ M2I2NWVhZjExZGYzN2NkYTIwNjM5YWRjNGZlZDQ4Njk5MjNlZGI1YjQzM2U3
14
+ MmVlNWZkMWUyMDI1Y2ZhMGZmZWUwY2VjYjA2MzYyNWI0YjRmNDlkM2I1MWY4
15
+ YTVjZTRmZGM4NGY0YzdlNjBmMDAwOTg4YmNiMjFkMWFiYmYxMjA=
data/console.rb CHANGED
@@ -5,7 +5,7 @@ $LOAD_PATH << './lib'
5
5
 
6
6
  require "spec/spec_helper"
7
7
 
8
- #User.post('', { user: { age: 1, posts: [{ body: 'post1' }, 2] } })
8
+ #User::Base.post('', { user: { age: 1, posts: [{ body: 'post1' }, 2] } })
9
9
 
10
10
  binding.pry
11
11
 
@@ -11,7 +11,7 @@ require "smooth_operator/finder_methods"
11
11
 
12
12
  module SmoothOperator
13
13
 
14
- class Base < OpenStruct
14
+ class Base < OpenStruct::Base
15
15
 
16
16
  extend Operator
17
17
  extend FinderMethods
@@ -1,6 +1,6 @@
1
1
  module SmoothOperator
2
2
 
3
- class ArrayWithMetaData < OpenStruct
3
+ class ArrayWithMetaData < OpenStruct::Base
4
4
 
5
5
  extend Forwardable
6
6
 
@@ -1,4 +1,5 @@
1
- require 'smooth_operator/internal_attribute'
1
+ require 'smooth_operator/attributes/base'
2
+ require 'smooth_operator/attributes/dirty'
2
3
 
3
4
  module SmoothOperator
4
5
 
@@ -10,7 +11,11 @@ module SmoothOperator
10
11
 
11
12
  module ClassMethods
12
13
 
13
- attr_accessor :turn_unknown_hash_to_open_struct
14
+ attr_writer :unknown_hash_class
15
+
16
+ def unknown_hash_class
17
+ Helpers.get_instance_variable(self, :unknown_hash_class, ::OpenStruct)
18
+ end
14
19
 
15
20
  def attributes_white_list
16
21
  Helpers.get_instance_variable(self, :attributes_white_list, Set.new)
@@ -28,6 +33,14 @@ module SmoothOperator
28
33
  attributes_black_list.merge getters.map(&:to_s)
29
34
  end
30
35
 
36
+ def dirty_attributes
37
+ @dirty_attributes = true
38
+ end
39
+
40
+ def dirty_attributes?
41
+ @dirty_attributes
42
+ end
43
+
31
44
  end
32
45
 
33
46
 
@@ -50,7 +63,15 @@ module SmoothOperator
50
63
  end
51
64
 
52
65
  def get_internal_data(field, method = :value)
53
- internal_data[field].nil? ? nil : internal_data[field].send(method)
66
+ result = internal_data[field]
67
+
68
+ if result.nil?
69
+ nil
70
+ elsif method == :value
71
+ result.is_a?(Attributes::Dirty) ? internal_data[field].send(method) : internal_data[field]
72
+ else
73
+ internal_data[field].send(method)
74
+ end
54
75
  end
55
76
 
56
77
  def push_to_internal_data(attribute_name, attribute_value)
@@ -61,9 +82,9 @@ module SmoothOperator
61
82
  known_attributes.add attribute_name
62
83
 
63
84
  if internal_data[attribute_name].nil?
64
- internal_data[attribute_name] = InternalAttribute.new(attribute_name, attribute_value, internal_structure[attribute_name], self.class.turn_unknown_hash_to_open_struct)
85
+ initiate_internal_data(attribute_name, attribute_value)
65
86
  else
66
- internal_data[attribute_name].set_value(attribute_value)
87
+ update_internal_data(attribute_name, attribute_value)
67
88
  end
68
89
  end
69
90
 
@@ -84,6 +105,29 @@ module SmoothOperator
84
105
  end
85
106
  end
86
107
 
108
+
109
+ private ######################## PRIVATE #############################
110
+
111
+ def initiate_internal_data(attribute_name, attribute_value)
112
+ internal_data[attribute_name] = new_attribute_object(attribute_name, attribute_value)
113
+
114
+ internal_data[attribute_name] = internal_data[attribute_name].value unless self.class.dirty_attributes?
115
+ end
116
+
117
+ def update_internal_data(attribute_name, attribute_value)
118
+ if self.class.dirty_attributes?
119
+ internal_data[attribute_name].set_value(attribute_value)
120
+ else
121
+ internal_data[attribute_name] = new_attribute_object(attribute_name, attribute_value)
122
+ end
123
+ end
124
+
125
+ def new_attribute_object(attribute_name, attribute_value)
126
+ attribute_class = self.class.dirty_attributes? ? Attributes::Dirty : Attributes::Base
127
+
128
+ attribute_class.new(attribute_name, attribute_value, internal_structure[attribute_name], self.class.unknown_hash_class)
129
+ end
130
+
87
131
  end
88
132
 
89
133
  end
@@ -0,0 +1,17 @@
1
+ require 'smooth_operator/type_converter'
2
+
3
+ module SmoothOperator
4
+ module Attributes
5
+
6
+ class Base
7
+
8
+ attr_reader :value
9
+
10
+ def initialize(name, value, type, unknown_hash_class)
11
+ @value = TypeConverter.cast_to_type(name, value, type, self.class, unknown_hash_class)
12
+ end
13
+
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,31 @@
1
+ require 'smooth_operator/type_converter'
2
+
3
+ module SmoothOperator
4
+ module Attributes
5
+
6
+ class Dirty
7
+
8
+ attr_reader :original_name, :original_value, :first_value, :value, :type, :unknown_hash_class
9
+
10
+ def initialize(name, value, type, unknown_hash_class)
11
+ @original_name, @original_value, @type, @unknown_hash_class = name, value, type, unknown_hash_class
12
+
13
+ @first_value = set_value(value)
14
+ end
15
+
16
+ def set_value(new_value)
17
+ @value = TypeConverter.cast_to_type(original_name, new_value, type, self.class, unknown_hash_class)
18
+ end
19
+
20
+ def changed?
21
+ @first_value != @value
22
+ end
23
+
24
+ def was
25
+ @first_value
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+ end
@@ -13,8 +13,12 @@ module SmoothOperator
13
13
 
14
14
  return instance_var unless instance_var.nil?
15
15
 
16
- (super_method(object, variable) || default_value).dup.tap do |instance_var|
16
+ instance_var = (super_method(object, variable) || default_value)
17
+
18
+ if instance_var.class == Class
17
19
  object.instance_variable_set("@#{variable}", instance_var)
20
+ else
21
+ object.instance_variable_set("@#{variable}", duplicate(instance_var))
18
22
  end
19
23
  end
20
24
 
@@ -5,15 +5,23 @@ require "smooth_operator/serialization"
5
5
  require "smooth_operator/attribute_assignment"
6
6
 
7
7
  module SmoothOperator
8
+ module OpenStruct
8
9
 
9
- class OpenStruct
10
+ class Base
10
11
 
11
- include Delegation
12
- include Validations
13
- include ModelSchema
14
- include Serialization
15
- include AttributeAssignment
12
+ include Delegation
13
+ include Validations
14
+ include ModelSchema
15
+ include Serialization
16
+ include AttributeAssignment
16
17
 
17
- end
18
+ end
19
+
20
+ class Dirty < Base
18
21
 
22
+ dirty_attributes
23
+
24
+ end
25
+
26
+ end
19
27
  end
@@ -4,6 +4,17 @@ module SmoothOperator
4
4
 
5
5
  extend self
6
6
 
7
+ def cast_to_type(name, value, type, array_class, unknown_hash_class)
8
+ case value
9
+ when Array
10
+ value.map { |array_entry| array_class.new(name, array_entry, type, unknown_hash_class).value }
11
+ when Hash
12
+ type.nil? ? new_unknown_hash(value, array_class, unknown_hash_class) : type.new(value)
13
+ else
14
+ TypeConverter.convert(value, type)
15
+ end
16
+ end
17
+
7
18
  def convert(value, type)
8
19
  case type
9
20
 
@@ -63,6 +74,30 @@ module SmoothOperator
63
74
 
64
75
  value.nil? ? 0 : value
65
76
  end
77
+
78
+
79
+ protected ################### PROTECTED #####################
80
+
81
+ def new_unknown_hash(hash, array_class, unknown_hash_class)
82
+ if unknown_hash_class == :none
83
+ hash
84
+ else
85
+ unknown_hash_class.new(cast_params(hash, array_class, unknown_hash_class))
86
+ end
87
+ end
88
+
89
+
90
+ private ################### PRIVATE #####################
91
+
92
+ def cast_params(attributes, array_class, unknown_hash_class)
93
+ hash = {}
94
+
95
+ attributes.each do |key, value|
96
+ hash[key] = cast_to_type(key, value, nil, array_class, unknown_hash_class)
97
+ end
98
+
99
+ hash
100
+ end
66
101
 
67
102
  end
68
103
 
@@ -1,3 +1,3 @@
1
1
  module SmoothOperator
2
- VERSION = "1.8.8"
2
+ VERSION = "1.9.0"
3
3
  end
@@ -1,6 +1,6 @@
1
1
  FactoryGirl.define do
2
2
 
3
- factory :user, class: User do
3
+ factory :user, class: User::Base do
4
4
 
5
5
  id 1
6
6
  admin true
@@ -20,12 +20,12 @@ FactoryGirl.define do
20
20
 
21
21
  end
22
22
 
23
- factory :white_list, class: User do
23
+ factory :white_list, class: User::Base do
24
24
  id 1
25
25
  first_name 'John'
26
26
  end
27
27
 
28
- factory :black_list, class: User do
28
+ factory :black_list, class: User::Base do
29
29
  admin true
30
30
  last_name 'Doe'
31
31
  end
@@ -34,28 +34,42 @@ describe SmoothOperator::AttributeAssignment do
34
34
  context "when something other than a hash is introduced" do
35
35
  it "should do nothing" do
36
36
  [nil, '', [1, 2], 'test', 1, 2].each do |something_other_than_a_hash|
37
- expect(User.new(something_other_than_a_hash).internal_data).to eq({})
37
+ expect(User::Base.new(something_other_than_a_hash).internal_data).to eq({})
38
38
  end
39
39
  end
40
40
  end
41
41
 
42
42
  context "when one of the attribute's value, is an hash and is unknown to the schema" do
43
- context "when the .turn_unknown_hash_to_open_struct is set to true or unused" do
44
- subject { User.new(address: { street: 'something', postal_code: { code: '123' } }) }
43
+ context "when the .unknown_hash_class is unused" do
44
+ subject { User::Base.new(address: { street: 'something', postal_code: { code: '123' } }) }
45
45
 
46
- it "a new instance of SmoothOperator::OpenStruct will be initialized with that hash" do
46
+ it "a new instance of OpenStruct will be initialized with that hash" do
47
47
  address = subject.address
48
48
 
49
- expect(address).to be_instance_of(SmoothOperator::OpenStruct)
49
+ expect(address).to be_instance_of(OpenStruct)
50
50
  expect(address.street).to eq('something')
51
51
 
52
- expect(address.postal_code).to be_instance_of(SmoothOperator::OpenStruct)
52
+ expect(address.postal_code).to be_instance_of(OpenStruct)
53
53
  expect(address.postal_code.code).to eq('123')
54
54
  end
55
55
  end
56
-
57
- context "when the .turn_unknown_hash_to_open_struct is set to false", current: true do
58
- subject { Post.new(creator: { first_name: 'admin', address: { street: 'something' } }) }
56
+
57
+ context "when the .unknown_hash_class is set to SmoothOperator::OpenStruct::Base" do
58
+ subject { User::UnknownHashClass::OpenStructBase.new(address: { street: 'something', postal_code: { code: '123' } }) }
59
+
60
+ it "a new instance of SmoothOperator::OpenStruct::Base will be initialized with that hash" do
61
+ address = subject.address
62
+
63
+ expect(address).to be_instance_of(SmoothOperator::OpenStruct::Base)
64
+ expect(address.street).to eq('something')
65
+
66
+ expect(address.postal_code).to be_instance_of(SmoothOperator::OpenStruct::Base)
67
+ expect(address.postal_code.code).to eq('123')
68
+ end
69
+ end
70
+
71
+ context "when the .unknown_hash_class is set to :none" do
72
+ subject { User::UnknownHashClass::None.new(creator: { first_name: 'admin', address: { street: 'something' } }) }
59
73
 
60
74
  it "the hash will be copied as it is" do
61
75
  creator = subject.creator
@@ -70,7 +84,7 @@ describe SmoothOperator::AttributeAssignment do
70
84
  end
71
85
 
72
86
  context "when there is no declared schema" do
73
- subject { User.new(attributes_for(:user)) }
87
+ subject { User::Base.new(attributes_for(:user)) }
74
88
  let(:expected_internal_data) { SmoothOperator::Helpers.stringify_keys(attributes_for(:user)) }
75
89
 
76
90
  it "it should populate 'internal_data' with unaltered duplicate data from the received hash" do
@@ -0,0 +1,53 @@
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
@@ -45,7 +45,7 @@ describe SmoothOperator::Delegation do
45
45
  describe "#method_missing" do
46
46
 
47
47
  context "when calling a method that matches the initialized attributes" do
48
- subject { User.new(attributes_for(:user)) }
48
+ subject { User::Base.new(attributes_for(:user)) }
49
49
 
50
50
  it 'it should return the value of that same attribute' do
51
51
  attributes_for(:user).each do |key, value|
@@ -85,52 +85,6 @@ describe SmoothOperator::Delegation do
85
85
  end
86
86
  end
87
87
 
88
- context "when no changes are made to an attribute" do
89
- it "checking it that attribute is changed, should return false" do
90
- expect(subject.first_name_changed?).to be false
91
- end
92
-
93
- it "checking that attribute past value, should its original value" do
94
- expect(subject.first_name_was).to eq('John')
95
- end
96
- end
97
-
98
- context "when there are changes made to an attribute" do
99
- before { subject.first_name = 'nhoJ' }
100
-
101
- it "checking if that attribute is changed, should return true" do
102
- expect(subject.first_name_changed?).to be true
103
- end
104
-
105
- it "checking that attribute past value, should its original value" do
106
- expect(subject.first_name_was).to eq('John')
107
- end
108
-
109
- context "when there are changes to the changes made to an attribute" do
110
- before { subject.first_name = 'no_name' }
111
-
112
- it "checking it that attribute is changed, should return true" do
113
- expect(subject.first_name_changed?).to be true
114
- end
115
-
116
- it "checking that attribute past value, should its first original value" do
117
- expect(subject.first_name_was).to eq('John')
118
- end
119
- end
120
- end
121
-
122
- context "when there are changes made to a nested object" do
123
- before { subject.address.street = 'my street' }
124
-
125
- it "checking if the nested object as changed, should return false" do
126
- expect(subject.address_changed?).to be false
127
- end
128
-
129
- it "checking if the nested object's attribute as changed, should return true" do
130
- expect(subject.address.street_changed?).to be true
131
- end
132
- end
133
-
134
88
  end
135
89
 
136
90
  end
@@ -6,7 +6,7 @@ describe SmoothOperator::ModelSchema do
6
6
  let(:initial_attributes_keys) { attributes_for(:user).keys.map(&:to_s) }
7
7
 
8
8
  context "when there is no declared schema" do
9
- subject { User.new(attributes_for(:user)) }
9
+ subject { User::Base.new(attributes_for(:user)) }
10
10
 
11
11
  it 'it should reflect the attributes used uppon initialization' do
12
12
  expect(subject.known_attributes.to_a).to match_array(initial_attributes_keys)
@@ -1,7 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe SmoothOperator::Operator do
4
- subject { User }
4
+ subject { User::Base }
5
5
 
6
6
  describe "#get" do
7
7
 
@@ -1,7 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe SmoothOperator::Validations do
4
- subject { User.new(attributes_for(:user)) }
4
+ subject { User::Base.new(attributes_for(:user)) }
5
5
 
6
6
  describe "#valid?" do
7
7
  context "when executing a persistence method, and the server response has a hash with the key 'errors'" do
@@ -1,4 +1,7 @@
1
1
  class Address < SmoothOperator::Base
2
+
3
+ self.dirty_attributes
4
+
2
5
  self.model_name = :none
3
6
 
4
7
  self.endpoint_user = 'admin'
@@ -7,4 +10,5 @@ class Address < SmoothOperator::Base
7
10
  self.endpoint = 'http://localhost:4567/'
8
11
 
9
12
  self.headers = { "X-APPTOKEN" => "joaquim_app_token", "X-LAYERTOKEN" => "joaquim_layer_token" }
13
+
10
14
  end
@@ -1,6 +1,4 @@
1
1
  class Post < SmoothOperator::Base
2
-
3
- self.turn_unknown_hash_to_open_struct = false
4
2
 
5
3
  self.endpoint = 'http://localhost:3000/api/v0'
6
4
 
@@ -1,15 +1,33 @@
1
- class User < SmoothOperator::Base
1
+ module User
2
+
3
+ class Base < SmoothOperator::Base
2
4
 
3
- self.endpoint_user = 'admin'
5
+ self.model_name = 'user'
4
6
 
5
- self.endpoint_pass = 'admin'
7
+ self.endpoint_user = 'admin'
6
8
 
7
- self.endpoint = 'http://localhost:4567/'
9
+ self.endpoint_pass = 'admin'
8
10
 
9
- def self.query_string(params)
10
- params['query_string_param'] = true
11
+ self.endpoint = 'http://localhost:4567/'
12
+
13
+ def self.query_string(params)
14
+ params['query_string_param'] = true
15
+
16
+ params
17
+ end
18
+
19
+ end
20
+
21
+ module UnknownHashClass
22
+
23
+ class OpenStructBase < User::Base
24
+ self.unknown_hash_class = SmoothOperator::OpenStruct::Base
25
+ end
26
+
27
+ class None < User::Base
28
+ self.unknown_hash_class = :none
29
+ end
11
30
 
12
- params
13
31
  end
14
32
 
15
33
  end
@@ -1,6 +1,6 @@
1
1
  module UserWithAddressAndPosts
2
2
 
3
- class Father < User
3
+ class Father < User::Base
4
4
 
5
5
  schema(
6
6
  posts: Post,
@@ -70,4 +70,12 @@ module UserWithAddressAndPosts
70
70
 
71
71
  end
72
72
 
73
+ class DirtyAttributes < UserWithAddressAndPosts::Son
74
+
75
+ self.dirty_attributes
76
+
77
+ self.unknown_hash_class = SmoothOperator::OpenStruct::Dirty
78
+
79
+ end
80
+
73
81
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smooth_operator
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.8
4
+ version: 1.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - João Gonçalves
@@ -69,10 +69,11 @@ files:
69
69
  - lib/smooth_operator.rb
70
70
  - lib/smooth_operator/array_with_meta_data.rb
71
71
  - lib/smooth_operator/attribute_assignment.rb
72
+ - lib/smooth_operator/attributes/base.rb
73
+ - lib/smooth_operator/attributes/dirty.rb
72
74
  - lib/smooth_operator/delegation.rb
73
75
  - lib/smooth_operator/finder_methods.rb
74
76
  - lib/smooth_operator/helpers.rb
75
- - lib/smooth_operator/internal_attribute.rb
76
77
  - lib/smooth_operator/model_schema.rb
77
78
  - lib/smooth_operator/open_struct.rb
78
79
  - lib/smooth_operator/operator.rb
@@ -86,6 +87,7 @@ files:
86
87
  - smooth_operator.gemspec
87
88
  - spec/factories/user_factory.rb
88
89
  - spec/smooth_operator/attribute_assignment_spec.rb
90
+ - spec/smooth_operator/attributes_dirty_spec.rb
89
91
  - spec/smooth_operator/delegation_spec.rb
90
92
  - spec/smooth_operator/finder_methods_spec.rb
91
93
  - spec/smooth_operator/model_schema_spec.rb
@@ -130,6 +132,7 @@ summary: Simple and fully customizable alternative to ActiveResource, using fara
130
132
  test_files:
131
133
  - spec/factories/user_factory.rb
132
134
  - spec/smooth_operator/attribute_assignment_spec.rb
135
+ - spec/smooth_operator/attributes_dirty_spec.rb
133
136
  - spec/smooth_operator/delegation_spec.rb
134
137
  - spec/smooth_operator/finder_methods_spec.rb
135
138
  - spec/smooth_operator/model_schema_spec.rb
@@ -1,49 +0,0 @@
1
- require 'smooth_operator/type_converter'
2
-
3
- module SmoothOperator
4
-
5
- class InternalAttribute
6
-
7
- attr_reader :original_name, :original_value, :first_value, :value, :type, :turn_unknown_hash_to_open_struct
8
-
9
- def initialize(name, value, type, turn_to_open_struct = nil)
10
- @original_name, @original_value, @type = name, value, type
11
-
12
- @turn_unknown_hash_to_open_struct = turn_to_open_struct.nil? ? true : turn_to_open_struct
13
-
14
- @first_value = set_value(value)
15
- end
16
-
17
- def set_value(new_value)
18
- @value = cast_to_type(new_value)
19
- end
20
-
21
- def changed?
22
- @first_value != @value
23
- end
24
-
25
- def was
26
- @first_value
27
- end
28
-
29
-
30
- protected ######################## PROTECTED #####################
31
-
32
- def cast_to_type(_value)
33
- case _value
34
- when Array
35
- _value.map { |array_entry| InternalAttribute.new(original_name, array_entry, type, turn_unknown_hash_to_open_struct).value }
36
- when Hash
37
- if turn_unknown_hash_to_open_struct
38
- (type || OpenStruct).new(_value)
39
- else
40
- type.nil? ? _value : type.new(_value)
41
- end
42
- else
43
- TypeConverter.convert(_value, type)
44
- end
45
- end
46
-
47
- end
48
-
49
- end