virtus-mapper 0.1.3 → 0.2.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 +4 -4
- data/lib/virtus/mapper/version.rb +1 -1
- data/lib/virtus/mapper.rb +28 -2
- data/scratchpad.md +9 -0
- data/spec/virtus/mapper_spec.rb +114 -15
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1668de6a4647f8f728f267188e4d4709a6f539bb
|
4
|
+
data.tar.gz: 68dc9ee28a36a7d481158b8a3d66c0a84a5e75fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf729a2b109bafa2598e55384f2c64e9d8ed064f86f8077f384e421e1be5be91fd9c0aae56c7bf9f10f1a86c087fd1c4dc2ce572719e9d67a1aa59f634f81254
|
7
|
+
data.tar.gz: 501be5a33044479639d4c5ed74fc883129370e215eadb23597ae4bc00e622df9ae7b396c3d5bc631cb3c00fbf4303b4286fb1f1a7d7e87e0c3af2057ee309391
|
data/lib/virtus/mapper.rb
CHANGED
@@ -7,13 +7,23 @@ HWIA = ActiveSupport::HashWithIndifferentAccess
|
|
7
7
|
module Virtus
|
8
8
|
module Mapper
|
9
9
|
|
10
|
+
attr_reader :mapped_attributes
|
11
|
+
|
10
12
|
def initialize(attrs={})
|
11
|
-
|
13
|
+
@mapped_attributes = HWIA.new(attrs)
|
14
|
+
super(prepare_attributes_for_assignment!(@mapped_attributes))
|
15
|
+
end
|
16
|
+
|
17
|
+
def extend_with(mod)
|
18
|
+
attr_set = attribute_set
|
19
|
+
self.extend(mod) # Virtus modifies attribute_set
|
20
|
+
set_attr_values(attribute_set.collect(&:name))
|
21
|
+
update_attribute_set(attr_set)
|
12
22
|
end
|
13
23
|
|
14
24
|
private
|
15
25
|
|
16
|
-
def
|
26
|
+
def prepare_attributes_for_assignment!(attrs)
|
17
27
|
attrs.tap do |h|
|
18
28
|
attributes_to_map_by_symbol(attrs).each do |att|
|
19
29
|
h[att.name] = h.delete(from(att))
|
@@ -42,5 +52,21 @@ module Virtus
|
|
42
52
|
def from(attribute)
|
43
53
|
attribute.options[:from]
|
44
54
|
end
|
55
|
+
|
56
|
+
def update_attribute_set(attr_set)
|
57
|
+
attr_set.merge(attribute_set)
|
58
|
+
self.attribute_set = attr_set
|
59
|
+
end
|
60
|
+
|
61
|
+
def attribute_set=(attr_set)
|
62
|
+
instance_variable_set(:@attribute_set, attr_set)
|
63
|
+
end
|
64
|
+
|
65
|
+
def set_attr_values(names)
|
66
|
+
attrs = prepare_attributes_for_assignment!(mapped_attributes)
|
67
|
+
names.each do |name|
|
68
|
+
self.send("#{name}=", attrs[name])
|
69
|
+
end
|
70
|
+
end
|
45
71
|
end
|
46
72
|
end
|
data/scratchpad.md
ADDED
data/spec/virtus/mapper_spec.rb
CHANGED
@@ -19,11 +19,27 @@ module Virtus
|
|
19
19
|
from: lambda { |atts| atts[:address][:street] rescue '' }
|
20
20
|
end
|
21
21
|
|
22
|
-
|
22
|
+
module Employment
|
23
|
+
include Virtus.module
|
24
|
+
include Virtus::Mapper
|
25
|
+
|
26
|
+
attribute :company, String, from: :business
|
27
|
+
attribute :job_title, String, from: :position
|
28
|
+
attribute :salary, Integer
|
29
|
+
end
|
30
|
+
|
31
|
+
module Traits
|
32
|
+
include Virtus.module
|
33
|
+
include Virtus::Mapper
|
34
|
+
|
35
|
+
attribute :eye_color, String, from: :eyecolor
|
36
|
+
end
|
37
|
+
|
38
|
+
class Dog
|
23
39
|
include Virtus.model
|
24
40
|
include Virtus::Mapper
|
25
41
|
|
26
|
-
attribute :name, String, from: :
|
42
|
+
attribute :name, String, from: :shelter
|
27
43
|
end
|
28
44
|
end
|
29
45
|
end
|
@@ -32,21 +48,24 @@ module Virtus
|
|
32
48
|
let(:first_name) { 'John' }
|
33
49
|
let(:last_name) { 'Doe' }
|
34
50
|
let(:address) { '1122 Something Avenue' }
|
35
|
-
let(:
|
51
|
+
let(:person_attrs) {
|
36
52
|
{ person_id: person_id,
|
37
53
|
first_name: first_name,
|
38
54
|
surname: last_name,
|
39
55
|
address: { 'street' => address } }
|
40
56
|
}
|
41
|
-
let(:
|
57
|
+
let(:employment_attrs) {
|
58
|
+
{ salary: 100, business: 'RentPath', position: 'Programmer' }
|
59
|
+
}
|
60
|
+
let(:person) { Examples::Person.new(person_attrs) }
|
42
61
|
|
43
62
|
describe 'attribute with from option as symbol' do
|
44
63
|
it 'translates key' do
|
45
|
-
expect(
|
64
|
+
expect(person.last_name).to eq(last_name)
|
46
65
|
end
|
47
66
|
|
48
67
|
it 'does not create method from original key' do
|
49
|
-
expect {
|
68
|
+
expect { person.surname }.to raise_error(NoMethodError)
|
50
69
|
end
|
51
70
|
|
52
71
|
describe 'with attribute name as key' do
|
@@ -63,34 +82,114 @@ module Virtus
|
|
63
82
|
describe 'attribute with from option as callable object' do
|
64
83
|
it 'calls the object and passes the attributes hash' do
|
65
84
|
callable = Examples::Person.attribute_set[:address].options[:from]
|
66
|
-
expect(callable).to receive(:call) {
|
67
|
-
Examples::Person.new(
|
85
|
+
expect(callable).to receive(:call) { person_attrs }
|
86
|
+
Examples::Person.new(person_attrs)
|
68
87
|
end
|
69
88
|
|
70
89
|
it 'sets attribute to result of call' do
|
71
|
-
expect(
|
90
|
+
expect(person.address).to eq(address)
|
72
91
|
end
|
73
92
|
end
|
74
93
|
|
75
94
|
|
76
95
|
describe 'attribute without from option' do
|
77
96
|
it 'behaves as usual' do
|
78
|
-
expect(
|
97
|
+
expect(person.first_name).to eq(first_name)
|
79
98
|
end
|
80
99
|
end
|
81
100
|
|
82
101
|
it 'maps attributes with indifferent access' do
|
83
|
-
|
102
|
+
person = Examples::Person.new({ person_id: 1,
|
84
103
|
first_name: first_name,
|
85
104
|
'surname' => last_name })
|
86
|
-
expect(
|
105
|
+
expect(person.last_name).to eq('Doe')
|
87
106
|
end
|
88
107
|
|
89
108
|
describe 'given no arguments to constructor' do
|
90
109
|
it 'does not raise error' do
|
91
|
-
expect {
|
92
|
-
|
93
|
-
|
110
|
+
expect { Examples::Dog.new }.not_to raise_error
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# describe '#mapped_attributes' do
|
115
|
+
# let(:person) { Examples::Person.new(person_attrs.merge({ unused: true })) }
|
116
|
+
|
117
|
+
# it 'preserves unused attributes' do
|
118
|
+
# expect(person.mapped_attributes[:unused]).to be true
|
119
|
+
# end
|
120
|
+
|
121
|
+
# it 'does not create instance methods for unused attributes' do
|
122
|
+
# expect { person.unused }.to raise_error(NoMethodError)
|
123
|
+
# end
|
124
|
+
# end
|
125
|
+
|
126
|
+
describe '#extend_with' do
|
127
|
+
describe 'for single extended module' do
|
128
|
+
let(:person) {
|
129
|
+
Examples::Person.new(person_attrs.merge(employment_attrs))
|
130
|
+
}
|
131
|
+
|
132
|
+
before do
|
133
|
+
person.extend_with(Examples::Employment)
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'updates unmapped attribute values for extended modules' do
|
137
|
+
expect(person.salary).to eq(100)
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'updates mapped attribute values for extended modules' do
|
141
|
+
expect(person.job_title).to eq('Programmer')
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'adds module attributes to attribute_set' do
|
145
|
+
attr_names = person.instance_eval { attribute_set }.collect(&:name)
|
146
|
+
[:id,
|
147
|
+
:first_name,
|
148
|
+
:last_name,
|
149
|
+
:address,
|
150
|
+
:company,
|
151
|
+
:job_title,
|
152
|
+
:salary].each do |attr_name|
|
153
|
+
expect(attr_names).to include(attr_name)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe 'for multiple extended modules' do
|
159
|
+
let(:person) {
|
160
|
+
Examples::Person.new(
|
161
|
+
person_attrs.merge(employment_attrs.merge({ eyecolor: 'green' }))
|
162
|
+
)
|
163
|
+
}
|
164
|
+
|
165
|
+
before do
|
166
|
+
person.extend_with(Examples::Employment)
|
167
|
+
person.extend_with(Examples::Traits)
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'updates mapped attributes for last module extended' do
|
171
|
+
expect(person.eye_color).to eq('green')
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'updates mapped attributes for first module extended' do
|
175
|
+
expect(person.salary).to eq(100)
|
176
|
+
expect(person.company).to eq('RentPath')
|
177
|
+
expect(person.job_title).to eq('Programmer')
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'adds module attributes to attribute_set' do
|
181
|
+
attr_names = person.instance_eval { attribute_set }.collect(&:name)
|
182
|
+
[:id,
|
183
|
+
:first_name,
|
184
|
+
:last_name,
|
185
|
+
:address,
|
186
|
+
:company,
|
187
|
+
:job_title,
|
188
|
+
:salary,
|
189
|
+
:eye_color].each do |attr_name|
|
190
|
+
expect(attr_names).to include(attr_name)
|
191
|
+
end
|
192
|
+
end
|
94
193
|
end
|
95
194
|
end
|
96
195
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: virtus-mapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- RentPath
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: virtus
|
@@ -109,6 +109,7 @@ files:
|
|
109
109
|
- Rakefile
|
110
110
|
- lib/virtus/mapper.rb
|
111
111
|
- lib/virtus/mapper/version.rb
|
112
|
+
- scratchpad.md
|
112
113
|
- spec/spec_helper.rb
|
113
114
|
- spec/virtus/mapper_spec.rb
|
114
115
|
- virtus-mapper.gemspec
|