datamappify 0.10.1 → 0.20.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/.rspec +1 -0
- data/.travis.yml +2 -0
- data/CHANGELOG.md +11 -0
- data/README.md +55 -29
- data/datamappify.gemspec +4 -4
- data/lib/datamappify/data/errors.rb +3 -0
- data/lib/datamappify/data/provider/active_record/persistence.rb +31 -0
- data/lib/datamappify/data/provider/active_record.rb +16 -0
- data/lib/datamappify/data/provider/common/persistence.rb +57 -0
- data/lib/datamappify/data/provider/common/relational/persistence.rb +85 -0
- data/lib/datamappify/data/provider/common/relational/record/mapper.rb +24 -0
- data/lib/datamappify/data/provider/common/relational/record/writer.rb +67 -0
- data/lib/datamappify/data/provider/sequel/persistence.rb +31 -0
- data/lib/datamappify/data/provider/sequel.rb +18 -0
- data/lib/datamappify/data.rb +0 -1
- data/lib/datamappify/repository/attribute_source_data_class_builder.rb +16 -11
- data/lib/datamappify/repository/attributes_mapper.rb +17 -13
- data/lib/datamappify/repository/dsl.rb +9 -0
- data/lib/datamappify/repository/mapping_hash.rb +8 -0
- data/lib/datamappify/repository.rb +96 -4
- data/lib/datamappify/util.rb +13 -0
- data/lib/datamappify/version.rb +1 -1
- data/spec/entity_spec.rb +9 -8
- data/spec/repository/persistence_spec.rb +156 -56
- data/spec/repository_spec.rb +10 -33
- data/spec/spec_helper.rb +14 -8
- data/spec/support/entities/hero_user.rb +11 -0
- data/spec/support/entities/user.rb +5 -5
- data/spec/support/repositories/active_record/comment_repository.rb +6 -0
- data/spec/support/repositories/active_record/group_repository.rb +6 -0
- data/spec/support/repositories/active_record/role_repository.rb +6 -0
- data/spec/support/repositories/active_record/user_repository.rb +11 -0
- data/spec/support/repositories/hero_user_repository.rb +9 -0
- data/spec/support/repositories/sequel/comment_repository.rb +6 -0
- data/spec/support/repositories/sequel/group_repository.rb +6 -0
- data/spec/support/repositories/sequel/role_repository.rb +6 -0
- data/spec/support/repositories/sequel/user_repository.rb +11 -0
- data/spec/support/{active_record_tables.rb → tables/active_record.rb} +15 -9
- data/spec/support/tables/sequel.rb +76 -0
- metadata +64 -41
- data/lib/datamappify/data/base.rb +0 -7
- data/lib/datamappify/repository/persistence.rb +0 -137
- data/spec/support/repositories/comment_repository.rb +0 -7
- data/spec/support/repositories/group_repository.rb +0 -7
- data/spec/support/repositories/role_repository.rb +0 -7
- data/spec/support/repositories/user_repository.rb +0 -11
@@ -5,6 +5,15 @@ module Datamappify
|
|
5
5
|
self.entity_class = entity_class
|
6
6
|
end
|
7
7
|
|
8
|
+
def default_provider(provider_name)
|
9
|
+
self.class_eval { require "datamappify/data/provider/#{provider_name.to_s.underscore}" }
|
10
|
+
|
11
|
+
provider_namespace = "Datamappify::Data::#{provider_name}"
|
12
|
+
|
13
|
+
self.default_provider_class_name = provider_name.to_s
|
14
|
+
self.default_data_class_name = self.entity_class.name
|
15
|
+
end
|
16
|
+
|
8
17
|
def map_attribute(attribute, source)
|
9
18
|
self.custom_attributes_mapping[attribute] = source
|
10
19
|
end
|
@@ -1,20 +1,21 @@
|
|
1
1
|
require 'singleton'
|
2
|
-
require 'datamappify/
|
2
|
+
require 'datamappify/util'
|
3
|
+
require 'datamappify/repository/mapping_hash'
|
3
4
|
require 'datamappify/repository/dsl'
|
4
5
|
require 'datamappify/repository/attributes_mapper'
|
5
6
|
|
6
7
|
module Datamappify
|
7
8
|
module Repository
|
8
|
-
include Persistence
|
9
|
-
|
10
9
|
def self.included(klass)
|
11
10
|
klass.class_eval do
|
12
11
|
mattr_accessor :entity_class
|
12
|
+
mattr_accessor :default_provider_class_name
|
13
|
+
mattr_accessor :default_data_class_name
|
13
14
|
mattr_accessor :custom_attributes_mapping
|
14
15
|
mattr_accessor :data_mapping
|
15
16
|
|
16
17
|
klass.custom_attributes_mapping = {}
|
17
|
-
klass.data_mapping
|
18
|
+
klass.data_mapping = {}
|
18
19
|
|
19
20
|
include Singleton
|
20
21
|
extend DSL
|
@@ -23,6 +24,97 @@ module Datamappify
|
|
23
24
|
|
24
25
|
def initialize
|
25
26
|
AttributesMapper.new(self).build_data_classes
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def find(id_or_ids)
|
31
|
+
entities = Array.wrap(id_or_ids).map { |id| entity_class.new(:id => id) }
|
32
|
+
|
33
|
+
data_mapping_walker do |provider_class_name, data_class_name, data_fields_mapping|
|
34
|
+
persistence_class(provider_class_name).new(
|
35
|
+
provider_class_name, entities, data_class_name
|
36
|
+
).find(data_fields_mapping)
|
37
|
+
end
|
38
|
+
|
39
|
+
id_or_ids.is_a?(Array) ? entities : entities[0]
|
40
|
+
end
|
41
|
+
|
42
|
+
def save(entity_or_entities)
|
43
|
+
Array.wrap(entity_or_entities).each do |entity|
|
44
|
+
create_or_update(entity)
|
45
|
+
end
|
46
|
+
|
47
|
+
entity_or_entities
|
48
|
+
rescue Datamappify::Data::EntityInvalid
|
49
|
+
false
|
50
|
+
end
|
51
|
+
|
52
|
+
def save!(entity_or_entities)
|
53
|
+
save(entity_or_entities) || raise(Datamappify::Data::EntityNotSaved)
|
54
|
+
end
|
55
|
+
|
56
|
+
def destroy(id_ids_or_entity_entities)
|
57
|
+
ids = Array.wrap(id_ids_or_entity_entities).map do |id_or_entity|
|
58
|
+
Util.extract_entity_id(id_or_entity)
|
59
|
+
end
|
60
|
+
|
61
|
+
default_persistence.destroy(ids)
|
62
|
+
end
|
63
|
+
|
64
|
+
def destroy!(id_ids_or_entity_entities)
|
65
|
+
destroy(id_ids_or_entity_entities) || raise(Datamappify::Data::EntityNotDestroyed)
|
66
|
+
end
|
67
|
+
|
68
|
+
def method_missing(symbol, *args)
|
69
|
+
default_persistence.send symbol, *args
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def default_persistence
|
75
|
+
persistence_class(default_provider_class_name).new(
|
76
|
+
default_provider_class_name, [], default_data_class_name
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
def persistence_class(provider_class_name)
|
81
|
+
"Datamappify::Data::Provider::#{provider_class_name}::Persistence".constantize
|
82
|
+
end
|
83
|
+
|
84
|
+
def create_or_update(entity)
|
85
|
+
raise Datamappify::Data::EntityInvalid.new(entity) if entity.invalid?
|
86
|
+
|
87
|
+
default_persistence.exists?(entity.id) ? update(entity) : create(entity)
|
88
|
+
end
|
89
|
+
|
90
|
+
def create(entity)
|
91
|
+
data_mapping_walker do |provider_class_name, data_class_name, data_fields_mapping|
|
92
|
+
persistence_class(provider_class_name).new(
|
93
|
+
provider_class_name, [entity], data_class_name
|
94
|
+
).create(data_fields_mapping)
|
95
|
+
end
|
96
|
+
|
97
|
+
entity
|
98
|
+
end
|
99
|
+
|
100
|
+
def update(entity)
|
101
|
+
data_mapping_walker do |provider_class_name, data_class_name, data_fields_mapping|
|
102
|
+
persistence_class(provider_class_name).new(
|
103
|
+
provider_class_name, [entity], data_class_name
|
104
|
+
).update(data_fields_mapping)
|
105
|
+
end
|
106
|
+
|
107
|
+
entity
|
108
|
+
end
|
109
|
+
|
110
|
+
def data_mapping_walker
|
111
|
+
default_persistence.transaction do
|
112
|
+
data_mapping.each do |provider_class_name, data_class_mapping|
|
113
|
+
data_class_mapping.each do |data_class_name, data_fields_mapping|
|
114
|
+
yield(provider_class_name, data_class_name, data_fields_mapping)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
26
118
|
end
|
27
119
|
end
|
28
120
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Datamappify
|
2
|
+
class Util
|
3
|
+
class << self
|
4
|
+
def attributes_filtered_by(entity, attribute_names)
|
5
|
+
entity.attributes.select { |attr| attribute_names.include?(attr) }
|
6
|
+
end
|
7
|
+
|
8
|
+
def extract_entity_id(id_or_entity)
|
9
|
+
id_or_entity.is_a?(Integer) ? id_or_entity : id_or_entity.id
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/datamappify/version.rb
CHANGED
data/spec/entity_spec.rb
CHANGED
@@ -7,32 +7,33 @@ describe Datamappify::Entity do
|
|
7
7
|
|
8
8
|
describe "attributes" do
|
9
9
|
it "has defined attributes" do
|
10
|
-
user.first_name.
|
10
|
+
user.first_name.should be_nil
|
11
|
+
user.last_name.should be_nil
|
11
12
|
end
|
12
13
|
|
13
14
|
it "raises error on undefined attributes" do
|
14
|
-
-> { user.
|
15
|
+
-> { user.surname }.should raise_error(NoMethodError)
|
15
16
|
end
|
16
17
|
|
17
18
|
it "assigns an attribute" do
|
18
19
|
user.first_name = 'Fred'
|
19
|
-
user.first_name.
|
20
|
+
user.first_name.should == 'Fred'
|
20
21
|
end
|
21
22
|
|
22
23
|
it "coerces an attribute" do
|
23
24
|
user.age = '42'
|
24
|
-
user.age.
|
25
|
-
user.age.
|
25
|
+
user.age.should be_kind_of(Fixnum)
|
26
|
+
user.age.should == 42
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
29
30
|
describe "validations" do
|
30
31
|
it "validates attributes" do
|
31
|
-
user.valid?.
|
32
|
+
user.valid?.should == false
|
32
33
|
|
33
34
|
user.first_name = 'Fred'
|
34
|
-
user.
|
35
|
-
user.valid?.
|
35
|
+
user.driver_license = 'FREDWU42'
|
36
|
+
user.valid?.should == true
|
36
37
|
end
|
37
38
|
end
|
38
39
|
end
|
@@ -1,95 +1,195 @@
|
|
1
1
|
require_relative '../spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
let(:user_repository)
|
5
|
-
let(:
|
6
|
-
let(:
|
7
|
-
let(:
|
8
|
-
|
9
|
-
let(:
|
10
|
-
|
11
|
-
|
12
|
-
end
|
3
|
+
shared_examples_for "repository persistence" do |data_provider|
|
4
|
+
let!(:user_repository) { "UserRepository#{data_provider}".constantize.instance }
|
5
|
+
let(:existing_user) { User.new(:id => 1, :first_name => 'Fred', :driver_license => 'FREDWU42') }
|
6
|
+
let(:new_valid_user) { User.new(:first_name => 'Batman', :driver_license => 'ARKHAMCITY') }
|
7
|
+
let(:new_valid_user2) { User.new(:first_name => 'Ironman', :driver_license => 'NEWYORKCITY') }
|
8
|
+
let(:new_invalid_user) { User.new(:first_name => 'a') }
|
9
|
+
let(:new_invalid_user2) { User.new(:first_name => 'b') }
|
10
|
+
let(:data_passports) { "Datamappify::Data::#{data_provider}::UserPassport".constantize }
|
11
|
+
let(:data_driver_licenses) { "Datamappify::Data::#{data_provider}::UserDriverLicense".constantize }
|
13
12
|
|
14
13
|
before do
|
15
|
-
user_repository
|
14
|
+
user_repository.save(existing_user)
|
16
15
|
end
|
17
16
|
|
18
17
|
describe "#find" do
|
19
|
-
|
20
|
-
|
18
|
+
describe "resource" do
|
19
|
+
let!(:user) { user_repository.save(existing_user) }
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
it "found" do
|
22
|
+
user_repository.find(user.id).should == existing_user
|
23
|
+
user_repository.find([user.id]).should == [existing_user]
|
24
|
+
end
|
25
25
|
|
26
|
-
|
27
|
-
|
26
|
+
it "not found" do
|
27
|
+
user_repository.find(42).should == nil
|
28
|
+
end
|
28
29
|
end
|
29
30
|
|
30
|
-
|
31
|
-
|
31
|
+
describe "collection" do
|
32
|
+
let!(:user) { user_repository.save(existing_user) }
|
33
|
+
|
34
|
+
it "found" do
|
35
|
+
user_repository.find([user.id]).should == [existing_user]
|
36
|
+
end
|
37
|
+
|
38
|
+
it "partial found" do
|
39
|
+
user_repository.find([user.id, 42]).should == [existing_user]
|
40
|
+
end
|
32
41
|
|
33
|
-
|
42
|
+
it "not found" do
|
43
|
+
user_repository.find([42, 255]).should == []
|
44
|
+
end
|
34
45
|
end
|
35
46
|
end
|
36
47
|
|
37
48
|
describe "#save" do
|
38
49
|
it "success" do
|
39
|
-
|
40
|
-
user_repository.count.must_equal 1
|
50
|
+
new_user = nil
|
41
51
|
|
42
|
-
new_user = user_repository.
|
43
|
-
|
44
|
-
new_user.
|
45
|
-
new_user.
|
52
|
+
expect { new_user = user_repository.save(new_valid_user) }.to change { user_repository.count }.by(1)
|
53
|
+
|
54
|
+
new_user.should be_kind_of(User)
|
55
|
+
new_user.first_name.should == 'Batman'
|
56
|
+
new_user.driver_license.should == 'ARKHAMCITY'
|
46
57
|
end
|
47
58
|
|
48
59
|
it "failure" do
|
49
|
-
-> { user_repository.save!(
|
60
|
+
-> { user_repository.save!(new_invalid_user) }.should raise_error(Datamappify::Data::EntityNotSaved)
|
50
61
|
end
|
51
62
|
|
52
63
|
it "transaction" do
|
53
|
-
|
54
|
-
|
64
|
+
new_valid_user.passport = 'DEVOPS'
|
65
|
+
|
66
|
+
save_action = Proc.new { -> { user_repository.save(new_valid_user) }.should raise_error }
|
55
67
|
|
56
|
-
user_repository.count.
|
57
|
-
|
58
|
-
|
68
|
+
expect { save_action.call }.to change { user_repository.count }.by(0)
|
69
|
+
expect { save_action.call }.to change { data_passports.count }.by(0)
|
70
|
+
expect { save_action.call }.to change { data_driver_licenses.count }.by(0)
|
59
71
|
end
|
60
|
-
end
|
61
72
|
|
62
|
-
|
63
|
-
|
73
|
+
describe "update multiple entities" do
|
74
|
+
describe "#save" do
|
75
|
+
it "all successes" do
|
76
|
+
expect { user_repository.save([new_valid_user, new_valid_user2]) }.to change { user_repository.count }.by(2)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "successes + failures" do
|
80
|
+
expect { user_repository.save([new_valid_user, new_invalid_user]) }.to change { user_repository.count }.by(1)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "all failures" do
|
84
|
+
expect { user_repository.save([new_invalid_user, new_invalid_user2]) }.to change { user_repository.count }.by(0)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "#save!" do
|
89
|
+
it "all successes" do
|
90
|
+
expect { user_repository.save!([new_valid_user, new_valid_user2]) }.to change { user_repository.count }.by(2)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "successes + failures" do
|
94
|
+
expect { -> { user_repository.save!([new_valid_user, new_invalid_user]) }.should raise_error(Datamappify::Data::EntityNotSaved) }.to change { user_repository.count }.by(1)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "all failures" do
|
98
|
+
expect { -> { user_repository.save!([new_invalid_user, new_invalid_user2]) }.should raise_error(Datamappify::Data::EntityNotSaved) }.to change { user_repository.count }.by(0)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "update an existing entity" do
|
104
|
+
it "updates existing records" do
|
105
|
+
user = user_repository.find(1)
|
106
|
+
|
107
|
+
user.first_name = 'Vivian'
|
108
|
+
user.driver_license = 'LOCOMOTE'
|
109
|
+
|
110
|
+
updated_user = nil
|
111
|
+
|
112
|
+
expect { updated_user = user_repository.save(user) }.to change { user_repository.count }.by(0)
|
113
|
+
|
114
|
+
updated_user.first_name.should == 'Vivian'
|
115
|
+
updated_user.driver_license.should == 'LOCOMOTE'
|
116
|
+
|
117
|
+
persisted_user = user_repository.find(updated_user.id)
|
118
|
+
|
119
|
+
persisted_user.first_name.should == 'Vivian'
|
120
|
+
persisted_user.driver_license.should == 'LOCOMOTE'
|
121
|
+
end
|
122
|
+
|
123
|
+
it "updates existing and new records" do
|
124
|
+
user = user_repository.find(1)
|
64
125
|
|
65
|
-
|
66
|
-
|
67
|
-
user.passport = 'LOCOMOTE'
|
126
|
+
user.first_name = 'Vivian'
|
127
|
+
user.health_care = 'BATMANCAVE'
|
68
128
|
|
69
|
-
|
70
|
-
updated_user.first_name.must_equal 'Vivian'
|
71
|
-
updated_user.gender.must_equal 'female'
|
72
|
-
updated_user.passport.must_equal 'LOCOMOTE'
|
129
|
+
updated_user = nil
|
73
130
|
|
74
|
-
|
75
|
-
persisted_user.first_name.must_equal 'Vivian'
|
76
|
-
persisted_user.gender.must_equal 'female'
|
77
|
-
persisted_user.passport.must_equal 'LOCOMOTE'
|
131
|
+
expect { updated_user = user_repository.save(user) }.to change { user_repository.count }.by(0)
|
78
132
|
|
79
|
-
|
133
|
+
updated_user.first_name.should == 'Vivian'
|
134
|
+
updated_user.health_care.should == 'BATMANCAVE'
|
135
|
+
|
136
|
+
persisted_user = user_repository.find(updated_user.id)
|
137
|
+
|
138
|
+
persisted_user.first_name.should == 'Vivian'
|
139
|
+
persisted_user.health_care.should == 'BATMANCAVE'
|
140
|
+
end
|
141
|
+
end
|
80
142
|
end
|
81
143
|
|
82
|
-
|
83
|
-
|
144
|
+
describe "#destroy" do
|
145
|
+
describe "resource" do
|
146
|
+
let!(:user) { user_repository.save(new_valid_user) }
|
84
147
|
|
85
|
-
|
86
|
-
|
148
|
+
it "via id" do
|
149
|
+
expect { user_repository.destroy!(user.id) }.to change { user_repository.count }.by(-1)
|
150
|
+
end
|
151
|
+
|
152
|
+
it "via entity" do
|
153
|
+
expect { user_repository.destroy!(user) }.to change { user_repository.count }.by(-1)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "collection" do
|
158
|
+
let!(:users) { user_repository.save([new_valid_user, new_valid_user2]) }
|
159
|
+
|
160
|
+
it "via id" do
|
161
|
+
expect { user_repository.destroy!(users.map(&:id)) }.to change { user_repository.count }.by(-2)
|
162
|
+
end
|
163
|
+
|
164
|
+
it "via entity" do
|
165
|
+
expect { user_repository.destroy!(users) }.to change { user_repository.count }.by(-2)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe Datamappify::Repository do
|
172
|
+
DATA_PROVIDERS.each do |data_provider|
|
173
|
+
it_behaves_like "repository persistence", data_provider
|
87
174
|
end
|
88
175
|
|
89
|
-
|
90
|
-
|
176
|
+
describe "entity composed from multiple data providers" do
|
177
|
+
let!(:hero_repository) { HeroUserRepository.instance }
|
178
|
+
let!(:hero) { HeroUser.new :first_name => 'Aaron', :last_name => 'Patterson' }
|
91
179
|
|
92
|
-
|
93
|
-
|
180
|
+
it "#find" do
|
181
|
+
saved_hero = nil
|
182
|
+
|
183
|
+
expect { saved_hero = hero_repository.save!(hero) }.to change { hero_repository.count }.by(1)
|
184
|
+
|
185
|
+
saved_hero.first_name.should == 'Aaron'
|
186
|
+
saved_hero.last_name.should == 'Patterson'
|
187
|
+
saved_hero.nickname = 'unsaved nickname'
|
188
|
+
|
189
|
+
persisted_hero = hero_repository.find(saved_hero.id)
|
190
|
+
persisted_hero.first_name.should == 'Aaron'
|
191
|
+
persisted_hero.last_name.should == 'Patterson'
|
192
|
+
persisted_hero.nickname.should be_nil
|
193
|
+
end
|
94
194
|
end
|
95
195
|
end
|
data/spec/repository_spec.rb
CHANGED
@@ -1,40 +1,17 @@
|
|
1
1
|
require_relative 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
let(:
|
5
|
-
let(:
|
6
|
-
|
7
|
-
let(:group_repository) { GroupRepository.instance }
|
3
|
+
shared_examples_for "a repository" do |data_provider|
|
4
|
+
let(:data_provider_module) { "Datamappify::Data::#{data_provider}".constantize }
|
5
|
+
let!(:user_repository) { "UserRepository#{data_provider}".constantize.instance }
|
6
|
+
subject { data_provider_module }
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
comment_repository
|
12
|
-
role_repository
|
13
|
-
group_repository
|
8
|
+
it "defines the data class after the repository is initialised" do
|
9
|
+
subject.const_defined?(:User, false).should == true
|
14
10
|
end
|
11
|
+
end
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
describe "data objects" do
|
22
|
-
subject { Datamappify::Data::User }
|
23
|
-
|
24
|
-
it "inherites from Datamappify::Data::Base" do
|
25
|
-
subject.superclass.must_equal Datamappify::Data::Base
|
26
|
-
subject.ancestors.must_include ActiveRecord::Base
|
27
|
-
end
|
28
|
-
|
29
|
-
it "has 'users' as the table name" do
|
30
|
-
subject.table_name.must_equal 'users'
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def assert_correct_associated_data_class_name(klass, association_name, data_class_name)
|
35
|
-
klass.class.reflect_on_all_associations.find { |a|
|
36
|
-
a.name == association_name
|
37
|
-
}.klass.name.must_equal data_class_name
|
38
|
-
end
|
13
|
+
describe Datamappify::Repository do
|
14
|
+
DATA_PROVIDERS.each do |data_provider|
|
15
|
+
it_behaves_like "a repository", data_provider
|
39
16
|
end
|
40
17
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
+
require 'coveralls'
|
1
2
|
require 'simplecov'
|
2
3
|
require 'pry'
|
3
|
-
require '
|
4
|
-
require 'minitest/spec'
|
5
|
-
require 'minitest/colorize'
|
4
|
+
require 'rspec/autorun'
|
6
5
|
require 'database_cleaner'
|
7
6
|
|
8
|
-
|
7
|
+
case ENV['COV'].to_i
|
8
|
+
when 1 then SimpleCov.start
|
9
|
+
when 2 then Coveralls.wear!
|
10
|
+
end
|
9
11
|
|
10
12
|
SimpleCov.configure do
|
11
13
|
add_filter "/spec/"
|
@@ -13,12 +15,16 @@ end
|
|
13
15
|
|
14
16
|
require File.expand_path('../../lib/datamappify', __FILE__)
|
15
17
|
|
16
|
-
|
18
|
+
%w{tables entities repositories}.each do |sub_dir|
|
19
|
+
Dir[File.expand_path("../support/#{sub_dir}/**/*.rb", __FILE__)].each { |f| require f }
|
20
|
+
end
|
21
|
+
|
22
|
+
DATA_PROVIDERS = %w{ActiveRecord Sequel}
|
17
23
|
|
18
|
-
|
24
|
+
RSpec.configure do |config|
|
25
|
+
DatabaseCleaner.strategy = :truncation
|
19
26
|
|
20
|
-
|
21
|
-
before do
|
27
|
+
config.before do
|
22
28
|
DatabaseCleaner.clean
|
23
29
|
end
|
24
30
|
end
|
@@ -3,15 +3,15 @@ class User
|
|
3
3
|
|
4
4
|
attribute :first_name, String
|
5
5
|
attribute :last_name, String
|
6
|
-
attribute :gender, String
|
7
6
|
attribute :age, Integer
|
8
7
|
attribute :passport, String
|
9
8
|
attribute :driver_license, String
|
9
|
+
attribute :health_care, String
|
10
10
|
|
11
|
-
validates :first_name,
|
12
|
-
|
13
|
-
validates :
|
14
|
-
|
11
|
+
validates :first_name, :presence => true,
|
12
|
+
:length => { :minimum => 2 }
|
13
|
+
validates :driver_license, :presence => true,
|
14
|
+
:length => { :minimum => 8 }
|
15
15
|
|
16
16
|
def full_name
|
17
17
|
"#{first_name} #{last_name}"
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class UserRepositoryActiveRecord
|
2
|
+
include Datamappify::Repository
|
3
|
+
|
4
|
+
for_entity User
|
5
|
+
default_provider :ActiveRecord
|
6
|
+
|
7
|
+
map_attribute :last_name, 'ActiveRecord::User#surname'
|
8
|
+
map_attribute :driver_license, 'ActiveRecord::UserDriverLicense#number'
|
9
|
+
map_attribute :passport, 'ActiveRecord::UserPassport#number'
|
10
|
+
map_attribute :health_care, 'ActiveRecord::UserHealthCare#number'
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class UserRepositorySequel
|
2
|
+
include Datamappify::Repository
|
3
|
+
|
4
|
+
for_entity User
|
5
|
+
default_provider :Sequel
|
6
|
+
|
7
|
+
map_attribute :last_name, 'Sequel::User#surname'
|
8
|
+
map_attribute :driver_license, 'Sequel::UserDriverLicense#number'
|
9
|
+
map_attribute :passport, 'Sequel::UserPassport#number'
|
10
|
+
map_attribute :health_care, 'Sequel::UserHealthCare#number'
|
11
|
+
end
|