HornsAndHooves-moribus 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.simplecov +1 -1
- data/Gemfile +5 -1
- data/HornsAndHooves-moribus.gemspec +1 -1
- data/lib/moribus/alias_association.rb +9 -3
- data/lib/moribus/macros.rb +4 -0
- data/lib/moribus/tracked_behavior.rb +9 -7
- data/lib/moribus/version.rb +2 -2
- data/spec/moribus/alias_association_spec.rb +19 -19
- data/spec/moribus_spec.rb +38 -38
- metadata +12 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff0aab79e8583ad02f5eeea9b364f1675d893399
|
4
|
+
data.tar.gz: 2c299a91b8eb26c99a91896b01100dcd04626409
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c66b62b01b54222d549dbd8e038d3b073cf850a9f394450dcde325bf32d644e796ce234720c53cbebd1c0f8cd156a5479571b5d59021798fc5b48f1a5ecdbbe8
|
7
|
+
data.tar.gz: 86c8695bd44971914bc00f5f60fd72a1a697a1625810cafd9575b2287ee3e2112b74b0c51e92411868609e5f3e3d48dba35e2bf81c032216efbf40fd9f1d2a16
|
data/.simplecov
CHANGED
@@ -12,7 +12,7 @@ SimpleCov.start do
|
|
12
12
|
# Fail the build when coverage is weak:
|
13
13
|
at_exit do
|
14
14
|
SimpleCov.result.format!
|
15
|
-
threshold, actual =
|
15
|
+
threshold, actual = 97.118, SimpleCov.result.covered_percent
|
16
16
|
if actual < threshold
|
17
17
|
msg = "\nLow coverage: "
|
18
18
|
msg << red("#{actual}%")
|
data/Gemfile
CHANGED
@@ -3,10 +3,14 @@ source "https://rubygems.org"
|
|
3
3
|
# Specify your gem's dependencies in moribus.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
+
group :development, :test do
|
7
|
+
gem "pry"
|
8
|
+
gem "pry-nav"
|
9
|
+
end
|
10
|
+
|
6
11
|
group :development do
|
7
12
|
gem "redcarpet"
|
8
13
|
gem "yard"
|
9
|
-
gem "pry"
|
10
14
|
end
|
11
15
|
|
12
16
|
group :test do
|
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
22
|
# specify any dependencies here; for example:
|
23
|
-
s.add_dependency "rails", "
|
23
|
+
s.add_dependency "rails", "> 4.0", "< 4.2"
|
24
24
|
s.add_dependency "power_enum", ">= 2.7.0"
|
25
25
|
s.add_dependency "yard", ">= 0"
|
26
26
|
|
@@ -19,11 +19,17 @@ module Moribus
|
|
19
19
|
|
20
20
|
# Class methods for ActiveRecord::Base
|
21
21
|
module ClassMethods
|
22
|
-
# Aliases association reflection in reflections hash and
|
23
|
-
# association-specific methods. See module description for example
|
22
|
+
# Aliases association reflection in ActiveRecord's (internal) reflections hash and
|
23
|
+
# association-specific methods. See module description for example.
|
24
24
|
def alias_association(alias_name, association_name)
|
25
25
|
if reflection = reflect_on_association(association_name)
|
26
|
-
|
26
|
+
# Use Rails 4.1.x+ behavior, if available:
|
27
|
+
if ActiveRecord::Reflection.respond_to? :add_reflection then
|
28
|
+
ActiveRecord::Reflection.add_reflection self, alias_name, reflection
|
29
|
+
else
|
30
|
+
# Rails 4.0.x behavior:
|
31
|
+
reflections[alias_name] = reflection
|
32
|
+
end
|
27
33
|
alias_association_methods(alias_name, reflection)
|
28
34
|
reflection
|
29
35
|
end
|
data/lib/moribus/macros.rb
CHANGED
@@ -92,6 +92,8 @@ module Moribus
|
|
92
92
|
end
|
93
93
|
|
94
94
|
reflection = has_one(name, scope, options)
|
95
|
+
# Rails 4.1 compatibility fix:
|
96
|
+
reflection = reflection[name] if reflection.respond_to? :[]
|
95
97
|
reflection.options[:is_current] = true
|
96
98
|
accepts_nested_attributes_for name
|
97
99
|
define_effective_reader_for name
|
@@ -106,6 +108,8 @@ module Moribus
|
|
106
108
|
# Extensions::HasAggregatedExtension)
|
107
109
|
def has_aggregated(name, options = {})
|
108
110
|
reflection = belongs_to(name, options)
|
111
|
+
# Rails 4.1 compatibility fix:
|
112
|
+
reflection = reflection[name] if reflection.respond_to? :[]
|
109
113
|
reflection.options[:aggregated] = true
|
110
114
|
accepts_nested_attributes_for name
|
111
115
|
define_effective_reader_for name
|
@@ -77,13 +77,15 @@ module Moribus
|
|
77
77
|
|
78
78
|
# Generate SQL statement to be used to update 'is_current' state of record to false.
|
79
79
|
def current_to_false_sql_statement
|
80
|
-
klass
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
sql << "
|
80
|
+
klass = self.class
|
81
|
+
is_current_col = klass.columns.detect{|c| c.name == "is_current" }
|
82
|
+
lock_col = klass.locking_column
|
83
|
+
lock_value = respond_to?(lock_col) && send(lock_col).to_i
|
84
|
+
quoted_lock_col = klass.connection.quote_column_name(lock_col)
|
85
|
+
"UPDATE #{klass.quoted_table_name} SET \"is_current\" = #{klass.quote_value(false, is_current_col)} ".tap do |sql|
|
86
|
+
sql << ", #{quoted_lock_col} = #{klass.quote_value(lock_value + 1, lock_col)} " if lock_value
|
87
|
+
sql << "WHERE #{klass.quoted_primary_key} = #{klass.quote_value(@_before_to_new_record_values[:id], "id")} "
|
88
|
+
sql << "AND #{quoted_lock_col} = #{klass.quote_value(lock_value, lock_col)}" if lock_value
|
87
89
|
end
|
88
90
|
end
|
89
91
|
private :current_to_false_sql_statement
|
data/lib/moribus/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Moribus # :nodoc:
|
2
|
-
VERSION = "0.
|
3
|
-
end
|
2
|
+
VERSION = "0.2.0" # :nodoc:
|
3
|
+
end
|
@@ -38,51 +38,51 @@ describe Moribus::AliasAssociation do
|
|
38
38
|
|
39
39
|
describe "reflection aliasing" do
|
40
40
|
it "alias association name in reflections" do
|
41
|
-
SpecPost.reflect_on_association(:author).
|
41
|
+
expect(SpecPost.reflect_on_association(:author)).not_to be_nil
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should not raise error when using aliased name in scopes" do
|
45
45
|
expect{
|
46
46
|
SpecPost.includes(:comments).first
|
47
|
-
}.
|
47
|
+
}.not_to raise_error
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
51
|
describe "association accessor alias methods" do
|
52
52
|
subject{ @post }
|
53
53
|
|
54
|
-
it{
|
55
|
-
it{
|
56
|
-
it{
|
57
|
-
it{
|
58
|
-
it{
|
59
|
-
it{
|
54
|
+
it{ is_expected.to respond_to :author }
|
55
|
+
it{ is_expected.to respond_to :author= }
|
56
|
+
it{ is_expected.to respond_to :comments }
|
57
|
+
it{ is_expected.to respond_to :comments= }
|
58
|
+
it{ is_expected.to respond_to :post_info }
|
59
|
+
it{ is_expected.to respond_to :post_info= }
|
60
60
|
end
|
61
61
|
|
62
62
|
describe "singular association alias method" do
|
63
63
|
subject{ @post }
|
64
64
|
|
65
|
-
it{
|
66
|
-
it{
|
67
|
-
it{
|
65
|
+
it{ is_expected.to respond_to :build_author }
|
66
|
+
it{ is_expected.to respond_to :create_author }
|
67
|
+
it{ is_expected.to respond_to :create_author! }
|
68
68
|
|
69
|
-
it{
|
70
|
-
it{
|
71
|
-
it{
|
69
|
+
it{ is_expected.to respond_to :build_post_info }
|
70
|
+
it{ is_expected.to respond_to :create_post_info }
|
71
|
+
it{ is_expected.to respond_to :create_post_info! }
|
72
72
|
end
|
73
73
|
|
74
74
|
describe "collection association alias method" do
|
75
75
|
subject{ @post }
|
76
76
|
|
77
|
-
it{
|
78
|
-
it{
|
77
|
+
it{ is_expected.to respond_to :comment_ids }
|
78
|
+
it{ is_expected.to respond_to :comment_ids= }
|
79
79
|
end
|
80
80
|
|
81
81
|
describe ":alias => alias_name shortcuts" do
|
82
82
|
subject{ @post }
|
83
83
|
|
84
|
-
it {
|
85
|
-
it {
|
86
|
-
it {
|
84
|
+
it { is_expected.to respond_to :creator }
|
85
|
+
it { is_expected.to respond_to :remarks }
|
86
|
+
it { is_expected.to respond_to :information }
|
87
87
|
end
|
88
88
|
end
|
data/spec/moribus_spec.rb
CHANGED
@@ -102,9 +102,9 @@ describe Moribus do
|
|
102
102
|
}.not_to change(SpecCustomerInfo, :count)
|
103
103
|
end
|
104
104
|
expect(@info.new_record?).to eq false
|
105
|
-
@info.id.
|
106
|
-
@info.updated_at.
|
107
|
-
@info.created_at.
|
105
|
+
expect(@info.id ).to eq old_id
|
106
|
+
expect(@info.updated_at ).to eq old_updated_at
|
107
|
+
expect(@info.created_at ).to eq old_created_at
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
@@ -140,7 +140,7 @@ describe Moribus do
|
|
140
140
|
it "should lookup self and replace id with existing on create" do
|
141
141
|
name = SpecPersonName.new :first_name => 'John', :last_name => 'Smith'
|
142
142
|
name.save
|
143
|
-
name.id.
|
143
|
+
expect(name.id).to eq @existing.id
|
144
144
|
end
|
145
145
|
|
146
146
|
it "should create a new record if lookup fails" do
|
@@ -152,7 +152,7 @@ describe Moribus do
|
|
152
152
|
it "should lookup self and replace id with existing on update" do
|
153
153
|
name = SpecPersonName.create :first_name => 'Alice', :last_name => 'Smith'
|
154
154
|
name.update_attributes :first_name => 'John'
|
155
|
-
name.id.
|
155
|
+
expect(name.id).to eq @existing.id
|
156
156
|
end
|
157
157
|
|
158
158
|
context "with caching" do
|
@@ -164,7 +164,7 @@ describe Moribus do
|
|
164
164
|
it "should lookup the existing value and add it to the cache" do
|
165
165
|
feature = SpecCustomerFeature.new :feature_name => @existing.feature_name
|
166
166
|
expect{ feature.save }.to change(SpecCustomerFeature.aggregated_records_cache, :length).by(1)
|
167
|
-
feature.id.
|
167
|
+
expect(feature.id).to eq @existing.id
|
168
168
|
end
|
169
169
|
|
170
170
|
it "should add the freshly-created record to the cache" do
|
@@ -173,12 +173,12 @@ describe Moribus do
|
|
173
173
|
|
174
174
|
it "should freeze the cached object" do
|
175
175
|
feature = SpecCustomerFeature.create(:feature_name => 'Cancelled')
|
176
|
-
SpecCustomerFeature.aggregated_records_cache[feature.feature_name].
|
176
|
+
expect(SpecCustomerFeature.aggregated_records_cache[feature.feature_name]).to be_frozen
|
177
177
|
end
|
178
178
|
|
179
179
|
it "should cache the clone of the record, not the record itself" do
|
180
180
|
feature = SpecCustomerFeature.create(:feature_name => 'Returned')
|
181
|
-
SpecCustomerFeature.aggregated_records_cache[feature.feature_name].object_id.
|
181
|
+
expect(SpecCustomerFeature.aggregated_records_cache[feature.feature_name].object_id).not_to eq feature.object_id
|
182
182
|
end
|
183
183
|
end
|
184
184
|
end
|
@@ -198,7 +198,7 @@ describe Moribus do
|
|
198
198
|
it "should replace itself with new id" do
|
199
199
|
old_id = @info.id
|
200
200
|
@info.update_attributes(:spec_person_name_id => 2)
|
201
|
-
@info.id.
|
201
|
+
expect(@info.id).not_to eq old_id
|
202
202
|
end
|
203
203
|
|
204
204
|
it "should set is_current record to false for superseded record" do
|
@@ -210,14 +210,14 @@ describe Moribus do
|
|
210
210
|
it "should set previous_id to the id of the previous record" do
|
211
211
|
old_id = @info.id
|
212
212
|
@info.update_attributes(:spec_person_name_id => 2)
|
213
|
-
@info.previous_id.
|
213
|
+
expect(@info.previous_id).to eq old_id
|
214
214
|
end
|
215
215
|
|
216
216
|
it "assigning a new current record should change is_current to false for previous one" do
|
217
217
|
new_info = SpecCustomerInfo.new :spec_person_name_id => 2, :is_current => true
|
218
218
|
@customer.spec_customer_info = new_info
|
219
|
-
new_info.spec_customer_id.
|
220
|
-
expect(@info.is_current).to eq false
|
219
|
+
expect(new_info.spec_customer_id).to eq @customer.id
|
220
|
+
expect(@info.is_current ).to eq false
|
221
221
|
end
|
222
222
|
|
223
223
|
it "should not crash on superseding with 'is_current' conditional constraint" do
|
@@ -234,14 +234,14 @@ describe Moribus do
|
|
234
234
|
|
235
235
|
it "should be updated on change" do
|
236
236
|
info = @customer.create_spec_customer_info :spec_person_name_id => 1
|
237
|
-
info.updated_at.
|
238
|
-
info.created_at.
|
237
|
+
expect(info.updated_at).to eq first_time
|
238
|
+
expect(info.created_at).to eq first_time
|
239
239
|
|
240
240
|
Timecop.freeze(second_time)
|
241
241
|
info.spec_person_name_id = 2
|
242
242
|
info.save!
|
243
|
-
info.updated_at.
|
244
|
-
info.created_at.
|
243
|
+
expect(info.updated_at).to eq second_time
|
244
|
+
expect(info.created_at).to eq second_time
|
245
245
|
end
|
246
246
|
end
|
247
247
|
|
@@ -274,8 +274,8 @@ describe Moribus do
|
|
274
274
|
old_id = @info.id
|
275
275
|
@customer.spec_customer_info.spec_person_name.first_name = 'Alice'
|
276
276
|
expect{ @customer.save }.to change(@info, :spec_person_name_id)
|
277
|
-
@info.id.
|
278
|
-
@info.is_current.
|
277
|
+
expect(@info.id).not_to eq old_id
|
278
|
+
expect(@info.is_current).to eq true
|
279
279
|
expect(SpecCustomerInfo.find(old_id).is_current).to eq false
|
280
280
|
end
|
281
281
|
end
|
@@ -290,39 +290,39 @@ describe Moribus do
|
|
290
290
|
end
|
291
291
|
|
292
292
|
it "should have delegated column information" do
|
293
|
-
@customer.column_for_attribute(:first_name).
|
293
|
+
expect(@customer.column_for_attribute(:first_name)).not_to be_nil
|
294
294
|
end
|
295
295
|
|
296
296
|
it "should not delegate special methods" do
|
297
|
-
@customer.
|
298
|
-
@customer.
|
299
|
-
@customer.
|
300
|
-
@customer.
|
301
|
-
@customer.
|
302
|
-
@customer.
|
297
|
+
expect(@customer).not_to respond_to(:reset_first_name)
|
298
|
+
expect(@customer).not_to respond_to(:first_name_was)
|
299
|
+
expect(@customer).not_to respond_to(:first_name_before_type_cast)
|
300
|
+
expect(@customer).not_to respond_to(:first_name_will_change!)
|
301
|
+
expect(@customer).not_to respond_to(:first_name_changed?)
|
302
|
+
expect(@customer).not_to respond_to(:lock_version)
|
303
303
|
end
|
304
304
|
|
305
305
|
it "should delegate methods to aggregated parts" do
|
306
|
-
@info.
|
307
|
-
@info.
|
308
|
-
@info.
|
309
|
-
@info.last_name.
|
306
|
+
expect(@info).to respond_to(:first_name)
|
307
|
+
expect(@info).to respond_to(:first_name=)
|
308
|
+
expect(@info).to respond_to(:spec_suffix)
|
309
|
+
expect(@info.last_name).to eq 'Smith'
|
310
310
|
end
|
311
311
|
|
312
312
|
it "should delegate methods to representation" do
|
313
|
-
@customer.
|
314
|
-
@customer.
|
315
|
-
@customer.
|
316
|
-
@customer.last_name.
|
317
|
-
@customer.
|
318
|
-
@customer.
|
313
|
+
expect(@customer).to respond_to(:first_name)
|
314
|
+
expect(@customer).to respond_to(:first_name=)
|
315
|
+
expect(@customer).to respond_to(:spec_suffix)
|
316
|
+
expect(@customer.last_name).to eq 'Smith'
|
317
|
+
expect(@customer).to respond_to(:custom_field)
|
318
|
+
expect(@customer).to respond_to(:custom_field=)
|
319
319
|
end
|
320
320
|
|
321
321
|
it 'should properly delegate enumerated attributes' do
|
322
|
-
@customer.
|
323
|
-
@customer.
|
322
|
+
expect(@customer).to respond_to(:spec_type)
|
323
|
+
expect(@customer).to respond_to(:spec_type=)
|
324
324
|
@customer.spec_type = :important
|
325
|
-
@customer.spec_type
|
325
|
+
expect(@customer.spec_type === :important).to eq true
|
326
326
|
end
|
327
327
|
|
328
328
|
it "should raise NoMethodError if unknown method received" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: HornsAndHooves-moribus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- HornsAndHooves
|
@@ -10,22 +10,28 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2015-01-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rails
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
18
|
requirements:
|
19
|
-
- - "
|
19
|
+
- - ">"
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 4.0
|
21
|
+
version: '4.0'
|
22
|
+
- - "<"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: '4.2'
|
22
25
|
type: :runtime
|
23
26
|
prerelease: false
|
24
27
|
version_requirements: !ruby/object:Gem::Requirement
|
25
28
|
requirements:
|
26
|
-
- - "
|
29
|
+
- - ">"
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: '4.0'
|
32
|
+
- - "<"
|
27
33
|
- !ruby/object:Gem::Version
|
28
|
-
version: 4.
|
34
|
+
version: '4.2'
|
29
35
|
- !ruby/object:Gem::Dependency
|
30
36
|
name: power_enum
|
31
37
|
requirement: !ruby/object:Gem::Requirement
|