zyra 0.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Zyra do
6
+ describe 'yard' do
7
+ describe '.register' do
8
+ it 'Register models searching' do
9
+ Zyra.register(User, find_by: :email)
10
+ Zyra
11
+ .register(User, :user_by_name, find_by: :name)
12
+ .on(:return) do |user|
13
+ user.update(email: "#{user.name.gsub(/ /, '_')}@srv.com")
14
+ end
15
+
16
+ attributes = {
17
+ name: 'my name',
18
+ email: 'my_email@srv.com'
19
+ }
20
+
21
+ user = Zyra.find_or_create(:user, attributes)
22
+ expect(user.email).to eq('my_email@srv.com')
23
+
24
+ user = Zyra.find_or_create(:user_by_name, attributes)
25
+ expect(user.email).to eq('my_name@srv.com')
26
+ end
27
+ end
28
+
29
+ describe '.find_or_create' do
30
+ it 'Regular usage passing all attributes' do
31
+ Zyra.register(User, find_by: :email)
32
+
33
+ email = 'email@srv.com'
34
+
35
+ user = Zyra.find_or_create(
36
+ :user,
37
+ email: email, name: 'initial name'
38
+ )
39
+
40
+ expect(user.name).to eq('initial name')
41
+
42
+ user = Zyra.find_or_create(
43
+ :user,
44
+ email: email, name: 'final name'
45
+ )
46
+
47
+ expect(user.name).to eq('initial name')
48
+ end
49
+ end
50
+
51
+ describe '.on' do
52
+ it 'Adding a hook on return' do
53
+ Zyra.register(User, find_by: :email)
54
+ Zyra.on(:user, :return) do |user|
55
+ user.update(name: 'initial name')
56
+ end
57
+
58
+ email = 'email@srv.com'
59
+
60
+ user = Zyra.find_or_create(
61
+ :user,
62
+ email: email
63
+ )
64
+
65
+ expect(user.name).to eq('initial name')
66
+ user.update(name: 'some other name')
67
+
68
+ user = Zyra.find_or_create(:user, email: email)
69
+
70
+ expect(user.name).to eq('initial name')
71
+ end
72
+
73
+ it 'Adding a hook on found' do
74
+ Zyra.register(User, find_by: :email)
75
+ Zyra.on(:user, :found) do |user|
76
+ user.update(name: 'final name')
77
+ end
78
+
79
+ email = 'email@srv.com'
80
+ attributes = { email: email, name: 'initial name' }
81
+
82
+ user = Zyra.find_or_create(:user, attributes)
83
+
84
+ expect(user.name).to eq('initial name')
85
+
86
+ user = Zyra.find_or_create(:user, attributes)
87
+
88
+ expect(user.name).to eq('final name')
89
+ end
90
+
91
+ it 'Adding a hook on build' do
92
+ Zyra.register(User, find_by: :email)
93
+ Zyra.on(:user, :build) do |user|
94
+ user.name = 'initial name'
95
+ end
96
+
97
+ email = 'email@srv.com'
98
+
99
+ user = Zyra.find_or_create(:user, email: email)
100
+
101
+ expect(user.name).to eq('initial name')
102
+ user.update(name: 'some other name')
103
+
104
+ user = Zyra.find_or_create(:user, email: email)
105
+
106
+ expect(user.name).to eq('some other name')
107
+ end
108
+
109
+ it 'Adding a hook on create' do
110
+ Zyra.register(User, find_by: :email)
111
+ Zyra.on(:user, :create) do |user|
112
+ user.update(name: 'initial name')
113
+ end
114
+
115
+ email = 'email@srv.com'
116
+
117
+ user = Zyra.find_or_create(:user, email: email)
118
+
119
+ expect(user.name).to eq('initial name')
120
+ user.update(name: 'some other name')
121
+
122
+ user = Zyra.find_or_create(:user, email: email)
123
+
124
+ expect(user.name).to eq('some other name')
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Zyra::Creator do
6
+ subject(:creator) do
7
+ described_class.new(model_class, event_registry: event_registry)
8
+ end
9
+
10
+ let(:event_registry) { Jace::Registry.new }
11
+ let(:model_class) { User }
12
+
13
+ describe '#create' do
14
+ it do
15
+ expect(creator.create).to be_a(model_class)
16
+ end
17
+
18
+ it do
19
+ expect(creator.create)
20
+ .to be_persisted
21
+ end
22
+
23
+ context 'when attributes are given' do
24
+ let(:name) { SecureRandom.hex(10) }
25
+
26
+ it 'initializes the model with the given attribute' do
27
+ expect(creator.create(name: name).name)
28
+ .to eq(name)
29
+ end
30
+ end
31
+
32
+ context 'when a block is given' do
33
+ let(:name) { SecureRandom.hex(10) }
34
+
35
+ it 'initializes the model with the given attribute' do
36
+ value = name
37
+ expect(creator.create { |model| model.name = value }.name)
38
+ .to eq(name)
39
+ end
40
+ end
41
+
42
+ context 'when building has an after build handler' do
43
+ let(:name) { SecureRandom.hex(10) }
44
+
45
+ before do
46
+ value = name
47
+ event_registry.register(:build) do |model|
48
+ model.name = "#{value}#{model.id}"
49
+ end
50
+ end
51
+
52
+ it 'runs the event handler' do
53
+ expect(creator.create.name)
54
+ .to eq(name)
55
+ end
56
+ end
57
+
58
+ context 'when building has an after create handler' do
59
+ let(:name) { SecureRandom.hex(10) }
60
+
61
+ before do
62
+ value = name
63
+ event_registry.register(:create) do |model|
64
+ model.name = "#{value}#{model.id}"
65
+ end
66
+ end
67
+
68
+ it 'runs the event handler' do
69
+ model = creator.create
70
+ expect(model.name)
71
+ .to eq("#{name}#{model.id}")
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,263 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Zyra::FinderCreator do
6
+ subject(:finder) do
7
+ described_class.new(model_class, keys)
8
+ end
9
+
10
+ let(:event_registry) { Jace::Registry.new }
11
+ let(:model_class) { User }
12
+ let(:keys) { :email }
13
+ let(:email) { SecureRandom.hex(10) }
14
+
15
+ describe '#find_or_create' do
16
+ let(:attributes) do
17
+ {
18
+ name: 'Some Name',
19
+ email: email,
20
+ password: 'SomePassword'
21
+ }
22
+ end
23
+
24
+ context 'when there is no entry in the database' do
25
+ it do
26
+ expect(finder.find_or_create(attributes)).to be_a(model_class)
27
+ end
28
+
29
+ it do
30
+ expect { finder.find_or_create(attributes) }
31
+ .to change(model_class, :count)
32
+ end
33
+
34
+ context 'when a block is given' do
35
+ it 'runs the block' do
36
+ user = finder.find_or_create(attributes) do |u|
37
+ u.update(name: 'new name')
38
+ end
39
+
40
+ expect(user.name).to eq('new name')
41
+ end
42
+ end
43
+ end
44
+
45
+ context 'when there is an entry and a block is given' do
46
+ before { create(:user, **attributes) }
47
+
48
+ it 'runs the block' do
49
+ user = finder.find_or_create(attributes) do |u|
50
+ u.update(name: 'new name')
51
+ end
52
+
53
+ expect(user.name).to eq('new name')
54
+ end
55
+ end
56
+
57
+ context 'when the entry is there with the same attributes' do
58
+ let!(:user) { create(:user, **attributes) }
59
+
60
+ it 'returns the user' do
61
+ expect(finder.find_or_create(attributes)).to eq(user)
62
+ end
63
+ end
64
+
65
+ context 'when the entry is there with other attributes' do
66
+ let!(:user) { create(:user, email: email) }
67
+
68
+ it 'returns the user' do
69
+ expect(finder.find_or_create(attributes)).to eq(user)
70
+ end
71
+ end
72
+
73
+ context 'when there is another entry' do
74
+ before { create(:user) }
75
+
76
+ it 'returns a new model' do
77
+ expect(finder.find_or_create(attributes)).to be_a(model_class)
78
+ end
79
+
80
+ it do
81
+ expect { finder.find_or_create(attributes) }
82
+ .to change(model_class, :count)
83
+ end
84
+ end
85
+
86
+ context 'when the keys is set as string' do
87
+ let(:keys) { 'email' }
88
+ let!(:user) { create(:user, **attributes) }
89
+
90
+ it 'finds the user the same way' do
91
+ expect(finder.find_or_create(attributes)).to eq(user)
92
+ end
93
+ end
94
+
95
+ context 'when the attributes have string keys' do
96
+ let(:attributes) { { 'email' => email } }
97
+ let!(:user) { create(:user, **attributes) }
98
+
99
+ it 'finds the user the same way' do
100
+ expect(finder.find_or_create(attributes)).to eq(user)
101
+ end
102
+ end
103
+
104
+ context 'when there is an event handler on found' do
105
+ let(:name) { 'new_name' }
106
+
107
+ before do
108
+ new_name = name
109
+
110
+ finder.on(:found) do |model|
111
+ model.update(name: new_name)
112
+ end
113
+ end
114
+
115
+ context 'when the model is found' do
116
+ let!(:user) { create(:user, **attributes) }
117
+
118
+ it 'runs the event after the model was found' do
119
+ expect { finder.find_or_create(attributes) }
120
+ .to change { user.reload.name }
121
+ .to(name)
122
+ end
123
+
124
+ it do
125
+ expect { finder.find_or_create(attributes) }
126
+ .not_to change(model_class, :count)
127
+ end
128
+ end
129
+
130
+ context 'when the model is not found' do
131
+ it 'does not run the event after the model was found' do
132
+ expect(finder.find_or_create(attributes).name)
133
+ .not_to eq(name)
134
+ end
135
+
136
+ it do
137
+ expect(finder.find_or_create(attributes)).to be_a(model_class)
138
+ end
139
+
140
+ it do
141
+ expect { finder.find_or_create(attributes) }
142
+ .to change(model_class, :count)
143
+ end
144
+ end
145
+ end
146
+
147
+ context 'when there is an event handler on build' do
148
+ let(:name) { 'new_name' }
149
+
150
+ before do
151
+ new_name = name
152
+
153
+ finder.on(:build) do |model|
154
+ model.name = new_name
155
+ end
156
+ end
157
+
158
+ context 'when the model is found' do
159
+ let!(:user) { create(:user, **attributes) }
160
+
161
+ it 'does not run the event after the model was found' do
162
+ expect { finder.find_or_create(attributes) }
163
+ .not_to change { user.reload.name }
164
+ end
165
+ end
166
+
167
+ context 'when the model is not found' do
168
+ it 'runs the event after the model was build' do
169
+ expect(finder.find_or_create(attributes).reload.name)
170
+ .to eq(name)
171
+ end
172
+
173
+ it do
174
+ expect(finder.find_or_create(attributes)).to be_a(model_class)
175
+ end
176
+
177
+ it do
178
+ expect { finder.find_or_create(attributes) }
179
+ .to change(model_class, :count)
180
+ end
181
+ end
182
+ end
183
+
184
+ context 'when there is an event handler on create' do
185
+ let(:name) { 'new_name' }
186
+
187
+ before do
188
+ new_name = name
189
+
190
+ finder.on(:create) do |model|
191
+ model.name = new_name
192
+ end
193
+ end
194
+
195
+ context 'when the model is found' do
196
+ before { create(:user, **attributes) }
197
+
198
+ it 'does not run the event after the model was found' do
199
+ expect(finder.find_or_create(attributes).name)
200
+ .not_to eq(name)
201
+ end
202
+ end
203
+
204
+ context 'when the model is not found' do
205
+ it 'runs the event after the model was created' do
206
+ expect(finder.find_or_create(attributes).name)
207
+ .to eq(name)
208
+ end
209
+
210
+ it 'does not run the event after the model was build' do
211
+ expect(finder.find_or_create(attributes).reload.name)
212
+ .not_to eq(name)
213
+ end
214
+
215
+ it do
216
+ expect(finder.find_or_create(attributes)).to be_a(model_class)
217
+ end
218
+
219
+ it do
220
+ expect { finder.find_or_create(attributes) }
221
+ .to change(model_class, :count)
222
+ end
223
+ end
224
+ end
225
+
226
+ context 'when there is an event handler on return' do
227
+ let(:name) { 'new_name' }
228
+
229
+ before do
230
+ new_name = name
231
+
232
+ finder.on(:return) do |model|
233
+ model.update(name: new_name)
234
+ end
235
+ end
236
+
237
+ context 'when the model is found' do
238
+ let!(:user) { create(:user, **attributes) }
239
+
240
+ it 'does not run the event after the model was found' do
241
+ expect { finder.find_or_create(attributes) }
242
+ .to change { user.reload.name }
243
+ end
244
+ end
245
+
246
+ context 'when the model is not found' do
247
+ it 'runs the event after the model was returned' do
248
+ expect(finder.find_or_create(attributes).reload.name)
249
+ .to eq(name)
250
+ end
251
+
252
+ it do
253
+ expect(finder.find_or_create(attributes)).to be_a(model_class)
254
+ end
255
+
256
+ it do
257
+ expect { finder.find_or_create(attributes) }
258
+ .to change(model_class, :count)
259
+ end
260
+ end
261
+ end
262
+ end
263
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Zyra::Finder do
6
+ subject(:finder) do
7
+ described_class.new(model_class, keys, event_registry: event_registry)
8
+ end
9
+
10
+ let(:event_registry) { Jace::Registry.new }
11
+ let(:model_class) { User }
12
+ let(:keys) { :email }
13
+ let(:email) { SecureRandom.hex(10) }
14
+
15
+ describe '#find' do
16
+ let(:attributes) do
17
+ {
18
+ name: 'Some Name',
19
+ email: email,
20
+ password: 'SomePassword'
21
+ }
22
+ end
23
+
24
+ context 'when there is no entry in the database' do
25
+ it do
26
+ expect(finder.find(attributes)).to be_nil
27
+ end
28
+
29
+ context 'when a block is given' do
30
+ it do
31
+ user = finder.find(attributes) { |u| u.name = 'other' }
32
+ expect(user).to be_nil
33
+ end
34
+ end
35
+ end
36
+
37
+ context 'when the model is found and a block is given' do
38
+ let!(:user) { create(:user, **attributes) }
39
+
40
+ it 'runs the block' do
41
+ expect { finder.find(attributes) { |u| u.update(name: 'other') } }
42
+ .to change { user.reload.name }
43
+ .to('other')
44
+ end
45
+ end
46
+
47
+ context 'when the entry is there with the same attributes' do
48
+ let!(:user) { create(:user, **attributes) }
49
+
50
+ it 'returns the user' do
51
+ expect(finder.find(attributes)).to eq(user)
52
+ end
53
+ end
54
+
55
+ context 'when the entry is there with other attributes' do
56
+ let!(:user) { create(:user, email: email) }
57
+
58
+ it 'returns the user' do
59
+ expect(finder.find(attributes)).to eq(user)
60
+ end
61
+ end
62
+
63
+ context 'when there is another entry' do
64
+ before { create(:user) }
65
+
66
+ it 'returns the user' do
67
+ expect(finder.find(attributes)).to be_nil
68
+ end
69
+ end
70
+
71
+ context 'when the keys is set as string' do
72
+ let(:keys) { 'email' }
73
+ let!(:user) { create(:user, **attributes) }
74
+
75
+ it 'finds the user the same way' do
76
+ expect(finder.find(attributes)).to eq(user)
77
+ end
78
+ end
79
+
80
+ context 'when the attributes have string keys' do
81
+ let(:attributes) { { 'email' => email } }
82
+ let!(:user) { create(:user, **attributes) }
83
+
84
+ it 'finds the user the same way' do
85
+ expect(finder.find(attributes)).to eq(user)
86
+ end
87
+ end
88
+
89
+ context 'when there is an event handler' do
90
+ let(:name) { 'new_name' }
91
+
92
+ before do
93
+ new_name = name
94
+
95
+ event_registry.register(:found) do |model|
96
+ model.update(name: new_name)
97
+ end
98
+ end
99
+
100
+ context 'when the model is found' do
101
+ let!(:user) { create(:user, **attributes) }
102
+
103
+ it 'runs the event after the model was found' do
104
+ expect { finder.find(attributes) }
105
+ .to change { user.reload.name }
106
+ .to(name)
107
+ end
108
+ end
109
+
110
+ context 'when the model is not found' do
111
+ it do
112
+ expect(finder.find(attributes)).to be_nil
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Zyra::Registry do
6
+ let(:registry) { described_class.new }
7
+
8
+ describe '#register' do
9
+ it_behaves_like 'a method that registers a finder creator'
10
+ end
11
+
12
+ describe '#on' do
13
+ it_behaves_like 'a method that registers an event handler'
14
+ end
15
+
16
+ describe '#find_or_create' do
17
+ it_behaves_like 'a method that returns or create a model'
18
+ end
19
+ end
@@ -3,6 +3,19 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe Zyra do
6
- it 'does something' do
6
+ let(:registry) { described_class }
7
+
8
+ before { described_class.reset }
9
+
10
+ describe '.register' do
11
+ it_behaves_like 'a method that registers a finder creator'
12
+ end
13
+
14
+ describe '.on' do
15
+ it_behaves_like 'a method that registers an event handler'
16
+ end
17
+
18
+ describe '.find_or_create' do
19
+ it_behaves_like 'a method that returns or create a model'
7
20
  end
8
21
  end
data/spec/spec_helper.rb CHANGED
@@ -10,6 +10,13 @@ SimpleCov.start 'gem'
10
10
 
11
11
  require 'zyra'
12
12
  require 'pry-nav'
13
+ require 'factory_bot'
14
+ require 'database_cleaner'
15
+
16
+ require 'active_record'
17
+ ActiveRecord::Base.establish_connection(
18
+ adapter: 'sqlite3', database: ':memory:'
19
+ )
13
20
 
14
21
  support_files = File.expand_path('spec/support/**/*.rb')
15
22
 
@@ -21,6 +28,17 @@ RSpec.configure do |config|
21
28
  config.filter_run_excluding :integration unless ENV['ALL']
22
29
 
23
30
  config.order = 'random'
31
+
32
+ config.before(:suite) do
33
+ DatabaseCleaner.strategy = :transaction
34
+ DatabaseCleaner.clean_with(:truncation)
35
+ end
36
+
37
+ config.around do |example|
38
+ DatabaseCleaner.cleaning do
39
+ example.run
40
+ end
41
+ end
24
42
  end
25
43
 
26
44
  RSpec::Matchers.define_negated_matcher :not_change, :change
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :user, class: '::User' do
5
+ sequence(:name) { |n| "Name-#{n}" }
6
+ sequence(:email) { |n| "user-#{n}@email.com" }
7
+ password { SecureRandom.hex(10) }
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.configure do |config|
4
+ config.include FactoryBot::Syntax::Methods
5
+ end
6
+
7
+ FactoryBot.find_definitions
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Post < ActiveRecord::Base
4
+ belongs_to :user
5
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class User < ActiveRecord::Base
4
+ has_many :posts
5
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ ActiveRecord::Schema.define do
4
+ self.verbose = false
5
+
6
+ create_table :users, force: true do |t|
7
+ t.string :name
8
+ t.string :email
9
+ t.string :password
10
+ t.string :reference
11
+ end
12
+
13
+ create_table :posts, force: true do |t|
14
+ t.integer :user_id
15
+ t.string :name
16
+ t.text :content
17
+ end
18
+ end