HornsAndHooves-moribus 0.4.4 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,140 @@
1
+ require "spec_helper"
2
+
3
+ describe Moribus::Extensions::DelegateAssociated do
4
+ before do
5
+ class SpecStatus < MoribusSpecModel(name: :string, description: :string)
6
+ acts_as_enumerated
7
+
8
+ self.enumeration_model_updates_permitted = true
9
+ create!(name: "inactive", description: "Inactive")
10
+ create!(name: "active" , description: "Active")
11
+ end
12
+
13
+ class SpecType < MoribusSpecModel(name: :string, description: :string)
14
+ acts_as_enumerated
15
+
16
+ self.enumeration_model_updates_permitted = true
17
+ create!(name: "important" , description: "Important")
18
+ create!(name: "unimportant", description: "Unimportant")
19
+ end
20
+
21
+ class SpecSuffix < MoribusSpecModel(name: :string, description: :string)
22
+ acts_as_enumerated
23
+
24
+ self.enumeration_model_updates_permitted = true
25
+ create!(name: "none", description: "")
26
+ create!(name: "jr" , description: "Junior")
27
+ end
28
+
29
+ class SpecPersonName < MoribusSpecModel(first_name: :string,
30
+ middle_name: :string,
31
+ last_name: :string,
32
+ spec_suffix_id: :integer
33
+ )
34
+ acts_as_aggregated non_content_columns: :middle_name
35
+ has_enumerated :spec_suffix, default: ""
36
+
37
+ validates_presence_of :first_name, :last_name
38
+
39
+ # custom writer that additionally strips first name
40
+ def first_name=(value)
41
+ self[:first_name] = value.strip
42
+ end
43
+ end
44
+
45
+ class SpecCustomerInfo < MoribusSpecModel(
46
+ spec_customer_id: :integer!,
47
+ spec_person_name_id: :integer,
48
+ spec_status_id: :integer,
49
+ spec_type_id: :integer,
50
+ is_current: :boolean,
51
+ lock_version: :integer,
52
+ created_at: :datetime,
53
+ updated_at: :datetime,
54
+ previous_id: :integer
55
+ )
56
+ attr :custom_field
57
+
58
+ belongs_to :spec_customer, inverse_of: :spec_customer_info, touch: true
59
+ has_aggregated :spec_person_name
60
+ has_enumerated :spec_status
61
+ has_enumerated :spec_type
62
+
63
+ acts_as_tracked by: :spec_customer, preceding_key: :previous_id
64
+ end
65
+
66
+ class SpecCustomer < MoribusSpecModel(spec_status_id: :integer)
67
+ has_one_current :spec_customer_info, inverse_of: :spec_customer
68
+ has_one_current :spec_customer_info_with_type, inverse_of: :spec_customer
69
+ has_enumerated :spec_status, default: "inactive"
70
+
71
+ delegate_associated :spec_person_name, :custom_field, :spec_type, to: :spec_customer_info
72
+ end
73
+ end
74
+
75
+ after do
76
+ MoribusSpecModel.cleanup!
77
+ end
78
+
79
+ let!(:customer) do
80
+ SpecCustomer.create(
81
+ spec_customer_info_attributes: {
82
+ spec_person_name_attributes: { first_name: " John ", last_name: "Smith" }
83
+ }
84
+ )
85
+ end
86
+
87
+ let(:info) { customer.spec_customer_info }
88
+
89
+ describe "Delegations" do
90
+ it "has delegated column information" do
91
+ expect(customer.column_for_attribute(:first_name)).not_to be_nil
92
+ end
93
+
94
+ it "does not delegate special methods" do
95
+ expect(customer).not_to respond_to(:reset_first_name)
96
+ expect(customer).not_to respond_to(:first_name_was)
97
+ expect(customer).not_to respond_to(:first_name_before_type_cast)
98
+ expect(customer).not_to respond_to(:first_name_will_change!)
99
+ expect(customer).not_to respond_to(:first_name_changed?)
100
+ expect(customer).not_to respond_to(:lock_version)
101
+ end
102
+
103
+ it "delegates methods to aggregated parts" do
104
+ expect(info).to respond_to(:first_name)
105
+ expect(info).to respond_to(:first_name=)
106
+ expect(info).to respond_to(:spec_suffix)
107
+ expect(info.last_name).to eq "Smith"
108
+ end
109
+
110
+ it "delegates methods to representation" do
111
+ expect(customer).to respond_to(:first_name)
112
+ expect(customer).to respond_to(:first_name=)
113
+ expect(customer).to respond_to(:spec_suffix)
114
+ expect(customer.last_name).to eq "Smith"
115
+ expect(customer).to respond_to(:custom_field)
116
+ expect(customer).to respond_to(:custom_field=)
117
+ end
118
+
119
+ it "properly delegates enumerated attributes" do
120
+ expect(customer).to respond_to(:spec_type)
121
+ expect(customer).to respond_to(:spec_type=)
122
+ customer.spec_type = :important
123
+ expect(customer.spec_type === :important).to eq true
124
+ end
125
+
126
+ it "raises NoMethodError if unknown method is received" do
127
+ expect{ customer.impossibru }.to raise_error(NoMethodError)
128
+ end
129
+ end
130
+
131
+ describe "#column_for_attribute" do
132
+ it "returns class db column if it exists" do
133
+ expect(customer.column_for_attribute(:id)).not_to be_nil
134
+ end
135
+
136
+ it "returns class db column if it doesn't exist" do
137
+ expect(customer.column_for_attribute(:foobar)).to be_nil
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,40 @@
1
+ require "spec_helper"
2
+
3
+ describe Moribus::Extensions::HasCurrentExtension do
4
+ before do
5
+ class SpecCustomerInfo < MoribusSpecModel(
6
+ spec_customer_id: :integer!,
7
+ is_current: :boolean,
8
+ lock_version: :integer,
9
+ created_at: :datetime,
10
+ updated_at: :datetime,
11
+ previous_id: :integer
12
+ )
13
+
14
+ belongs_to :spec_customer, inverse_of: :spec_customer_info, touch: true
15
+ end
16
+
17
+ class SpecCustomer < MoribusSpecModel(spec_status_id: :integer)
18
+ has_one_current :spec_customer_info, inverse_of: :spec_customer, dependent: :destroy
19
+ end
20
+ end
21
+
22
+ after do
23
+ MoribusSpecModel.cleanup!
24
+ end
25
+
26
+ let(:customer) { SpecCustomer.create }
27
+ let!(:info) { SpecCustomerInfo.create(spec_customer: customer, is_current: true) }
28
+
29
+ describe ".remove_target!" do
30
+ before do
31
+ allow(customer.spec_customer_info).to receive(:new_record?).and_return(true)
32
+ end
33
+
34
+ it "sets 'is_current' flag of overridden record to false for new record" do
35
+ old_info = customer.spec_customer_info
36
+ customer.spec_customer_info = SpecCustomerInfo.new
37
+ expect(old_info.is_current).to be_falsey
38
+ end
39
+ end
40
+ end
@@ -1,7 +1,101 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  # Some of the Moribus::Macros methods are tested in
4
4
  # spec/lib/moribus_spec.rb.
5
5
  describe Moribus::Macros do
6
+ before do
7
+ class SpecCustomer < MoribusSpecModel(spec_status_id: :integer)
8
+ has_one_current :spec_customer_info,
9
+ -> { where(spec_customer_id: 3) }, inverse_of: :spec_customer
10
+ end
6
11
 
12
+ class SpecCustomerInfo < MoribusSpecModel(
13
+ spec_customer_id: :integer!,
14
+ is_current: :boolean,
15
+ lock_version: :integer,
16
+ created_at: :datetime,
17
+ updated_at: :datetime,
18
+ previous_id: :integer
19
+ )
20
+
21
+ belongs_to :spec_customer, inverse_of: :spec_customer_info, touch: true
22
+ end
23
+
24
+ class SpecCustomerOrder < MoribusSpecModel(:spec_status_id => :integer)
25
+ has_one_current :spec_customer_info_order,
26
+ -> { order(:created_at) }, :inverse_of => :spec_customer_order
27
+ end
28
+
29
+ class SpecCustomerInfoOrder < MoribusSpecModel(
30
+ spec_customer_order_id: :integer!,
31
+ is_current: :boolean,
32
+ lock_version: :integer,
33
+ created_at: :datetime,
34
+ updated_at: :datetime,
35
+ previous_id: :integer
36
+ )
37
+
38
+ belongs_to :spec_customer_order, inverse_of: :spec_customer_info_order, touch: true
39
+ end
40
+ end
41
+
42
+ after do
43
+ MoribusSpecModel.cleanup!
44
+ end
45
+
46
+ describe ".has_one_current" do
47
+ let!(:customer) { SpecCustomer.create(id: 3, spec_status_id: 2) }
48
+ let!(:customer_order) { SpecCustomerOrder.create(id: 9, spec_status_id: 1) }
49
+
50
+ let!(:info1) do
51
+ SpecCustomerInfo.create(
52
+ spec_customer_id: 1,
53
+ is_current: true,
54
+ created_at: 5.days.ago,
55
+ updated_at: 5.days.ago
56
+ )
57
+ end
58
+
59
+ let!(:info2) do
60
+ SpecCustomerInfo.create(
61
+ spec_customer_id: 3,
62
+ is_current: true,
63
+ created_at: 5.days.ago,
64
+ updated_at: 5.days.ago
65
+ )
66
+ end
67
+
68
+ let!(:info_order1) do
69
+ SpecCustomerInfoOrder.create(
70
+ spec_customer_order_id: 9,
71
+ is_current: true,
72
+ created_at: 5.days.ago,
73
+ updated_at: 5.days.ago
74
+ )
75
+ end
76
+
77
+ let!(:info_order2) do
78
+ SpecCustomerInfoOrder.create(
79
+ spec_customer_order_id: 11,
80
+ is_current: true,
81
+ created_at: 5.days.ago,
82
+ updated_at: 5.days.ago
83
+ )
84
+ end
85
+
86
+ it "merges has_one_current scope with has_one if given" do
87
+ expect(customer.spec_customer_info ).to eq(info2)
88
+ expect(customer_order.spec_customer_info_order).to eq(info_order1)
89
+ end
90
+ end
91
+
92
+ describe ".normalize_reflection" do
93
+ subject do
94
+ SpecCustomer.send(:normalize_reflection, { spec_customer_info: :key_value }, :spec_customer_info)
95
+ end
96
+
97
+ it "returns reflection with symbol key for rails 4.1" do
98
+ is_expected.to eq(:key_value)
99
+ end
100
+ end
7
101
  end
data/spec/moribus_spec.rb CHANGED
@@ -2,36 +2,37 @@ require "spec_helper"
2
2
 
3
3
  describe Moribus do
4
4
  before do
5
- class SpecStatus < MoribusSpecModel(:name => :string, :description => :string)
5
+ class SpecStatus < MoribusSpecModel(name: :string, description: :string)
6
6
  acts_as_enumerated
7
7
 
8
8
  self.enumeration_model_updates_permitted = true
9
- create!(:name => "inactive", :description => "Inactive")
10
- create!(:name => "active" , :description => "Active")
9
+ create!(name: "inactive", description: "Inactive")
10
+ create!(name: "active" , description: "Active")
11
11
  end
12
12
 
13
- class SpecType < MoribusSpecModel(:name => :string, :description => :string)
13
+ class SpecType < MoribusSpecModel(name: :string, description: :string)
14
14
  acts_as_enumerated
15
15
 
16
16
  self.enumeration_model_updates_permitted = true
17
- create!(:name => "important" , :description => "Important")
18
- create!(:name => "unimportant", :description => "Unimportant")
17
+ create!(name: "important" , description: "Important")
18
+ create!(name: "unimportant", description: "Unimportant")
19
19
  end
20
20
 
21
- class SpecSuffix < MoribusSpecModel(:name => :string, :description => :string)
21
+ class SpecSuffix < MoribusSpecModel(name: :string, description: :string)
22
22
  acts_as_enumerated
23
23
 
24
24
  self.enumeration_model_updates_permitted = true
25
- create!(:name => "none", :description => "")
26
- create!(:name => "jr" , :description => "Junior")
25
+ create!(name: "none", description: "")
26
+ create!(name: "jr" , description: "Junior")
27
27
  end
28
28
 
29
- class SpecPersonName < MoribusSpecModel(:first_name => :string,
30
- :last_name => :string,
31
- :spec_suffix_id => :integer
29
+ class SpecPersonName < MoribusSpecModel(first_name: :string,
30
+ middle_name: :string,
31
+ last_name: :string,
32
+ spec_suffix_id: :integer
32
33
  )
33
- acts_as_aggregated
34
- has_enumerated :spec_suffix, :default => ""
34
+ acts_as_aggregated non_content_columns: :middle_name
35
+ has_enumerated :spec_suffix, default: ""
35
36
 
36
37
  validates_presence_of :first_name, :last_name
37
38
 
@@ -41,63 +42,63 @@ describe Moribus do
41
42
  end
42
43
  end
43
44
 
44
- class SpecCustomerFeature < MoribusSpecModel(:feature_name => :string)
45
- acts_as_aggregated :cache_by => :feature_name
45
+ class SpecCustomerFeature < MoribusSpecModel(feature_name: :string)
46
+ acts_as_aggregated cache_by: :feature_name
46
47
  end
47
48
 
48
49
  class SpecCustomerInfo < MoribusSpecModel(
49
- :spec_customer_id => :integer!,
50
- :spec_person_name_id => :integer,
51
- :spec_status_id => :integer,
52
- :spec_type_id => :integer,
53
- :is_current => :boolean,
54
- :lock_version => :integer,
55
- :created_at => :datetime,
56
- :updated_at => :datetime,
57
- :previous_id => :integer
50
+ spec_customer_id: :integer!,
51
+ spec_person_name_id: :integer,
52
+ spec_status_id: :integer,
53
+ spec_type_id: :integer,
54
+ is_current: :boolean,
55
+ lock_version: :integer,
56
+ created_at: :datetime,
57
+ updated_at: :datetime,
58
+ previous_id: :integer
58
59
  )
59
60
  attr :custom_field
60
61
 
61
- belongs_to :spec_customer, :inverse_of => :spec_customer_info, :touch => true
62
+ belongs_to :spec_customer, inverse_of: :spec_customer_info, touch: true
62
63
  has_aggregated :spec_person_name
63
64
  has_enumerated :spec_status
64
65
  has_enumerated :spec_type
65
66
 
66
- acts_as_tracked :by => :spec_customer, :preceding_key => :previous_id
67
+ acts_as_tracked by: :spec_customer, preceding_key: :previous_id
67
68
  end
68
69
 
69
70
  class SpecCustomerInfoWithType < MoribusSpecModel(
70
- :spec_customer_id => :integer!,
71
- :spec_status_id => :integer,
72
- :spec_type_id => :integer,
73
- :is_current => :boolean,
74
- :lock_version => :integer,
75
- :created_at => :datetime,
76
- :updated_at => :datetime
71
+ spec_customer_id: :integer!,
72
+ spec_status_id: :integer,
73
+ spec_type_id: :integer,
74
+ is_current: :boolean,
75
+ lock_version: :integer,
76
+ created_at: :datetime,
77
+ updated_at: :datetime
77
78
  )
78
79
  attr :custom_field
79
80
 
80
- belongs_to :spec_customer, :inverse_of => :spec_customer_info_with_type, :touch => true
81
+ belongs_to :spec_customer, inverse_of: :spec_customer_info_with_type, touch: true
81
82
  has_enumerated :spec_status
82
83
  has_enumerated :spec_type
83
84
 
84
85
  acts_as_tracked :by => [:spec_customer, :spec_type]
85
86
  end
86
87
 
87
- class SpecCustomer < MoribusSpecModel(:spec_status_id => :integer)
88
- has_one_current :spec_customer_info, :inverse_of => :spec_customer
89
- has_one_current :spec_customer_info_with_type, :inverse_of => :spec_customer
90
- has_enumerated :spec_status, :default => "inactive"
88
+ class SpecCustomer < MoribusSpecModel(spec_status_id: :integer)
89
+ has_one_current :spec_customer_info, inverse_of: :spec_customer
90
+ has_one_current :spec_customer_info_with_type, inverse_of: :spec_customer
91
+ has_enumerated :spec_status, default: "inactive"
91
92
 
92
- delegate_associated :spec_person_name, :custom_field, :spec_type, :to => :spec_customer_info
93
+ delegate_associated :spec_person_name, :custom_field, :spec_type, to: :spec_customer_info
93
94
  end
94
95
 
95
- class SpecCustomerEmail < MoribusSpecModel(:spec_customer_id => :integer,
96
- :email => :string,
97
- :is_current => :boolean,
98
- :status => :string
96
+ class SpecCustomerEmail < MoribusSpecModel(spec_customer_id: :integer,
97
+ email: :string,
98
+ is_current: :boolean,
99
+ status: :string
99
100
  )
100
- connection.add_index table_name, [:email, :is_current], :unique => true
101
+ connection.add_index table_name, [:email, :is_current], unique: true
101
102
 
102
103
  belongs_to :spec_customer
103
104
 
@@ -112,22 +113,22 @@ describe Moribus do
112
113
  describe "common behavior" do
113
114
  before do
114
115
  @info = SpecCustomerInfo.create(
115
- :spec_customer_id => 1,
116
- :spec_person_name_id => 1,
117
- :is_current => true,
118
- :created_at => 5.days.ago,
119
- :updated_at => 5.days.ago
116
+ spec_customer_id: 1,
117
+ spec_person_name_id: 1,
118
+ is_current: true,
119
+ created_at: 5.days.ago,
120
+ updated_at: 5.days.ago
120
121
  )
121
122
  end
122
123
 
123
- it "should revert changes if exception is raised" do
124
+ it "reverts changes if exception is raised" do
124
125
  old_id = @info.id
125
126
  old_updated_at = @info.updated_at
126
127
  old_created_at = @info.created_at
127
128
 
128
129
  suppress(Exception) do
129
130
  expect {
130
- @info.update_attributes :spec_customer_id => nil, :spec_person_name_id => 2
131
+ @info.update_attributes spec_customer_id: nil, spec_person_name_id: 2
131
132
  }.not_to change(SpecCustomerInfo, :count)
132
133
  end
133
134
 
@@ -138,130 +139,46 @@ describe Moribus do
138
139
 
139
140
  expect(@info.changed_attributes[:updated_at]).to eq(nil)
140
141
  expect(@info.changed_attributes[:created_at]).to eq(nil)
141
-
142
- end
143
- end
144
-
145
- describe "Aggregated" do
146
- context "definition" do
147
- it "should raise an error on an unknown option" do
148
- expect{
149
- Class.new(ActiveRecord::Base).class_eval do
150
- acts_as_aggregated :invalid_key => :error
151
- end
152
- }.to raise_error(ArgumentError)
153
- end
154
-
155
- it "should raise an error when including AggregatedCacheBehavior without AggregatedBehavior" do
156
- expect{
157
- Class.new(ActiveRecord::Base).class_eval do
158
- include Moribus::AggregatedCacheBehavior
159
- end
160
- }.to raise_error(Moribus::AggregatedCacheBehavior::NotAggregatedError)
161
- end
162
- end
163
-
164
- before do
165
- @existing = SpecPersonName.create! :first_name => "John", :last_name => "Smith"
166
- end
167
-
168
- it "doesn't duplicate records" do
169
- expect {
170
- SpecPersonName.create :first_name => " John ", :last_name => "Smith"
171
- }.not_to change(SpecPersonName, :count)
172
- end
173
-
174
- it "looks up self and replaces id with existing on create" do
175
- name = SpecPersonName.new :first_name => "John", :last_name => "Smith"
176
- name.save
177
- expect(name.id).to eq @existing.id
178
142
  end
179
143
 
180
- it "creates a new record if lookup fails" do
181
- expect {
182
- SpecPersonName.create :first_name => "Alice", :last_name => "Smith"
183
- }.to change(SpecPersonName, :count).by(1)
184
- end
185
-
186
- it "looks up self and replaces id with existing on update" do
187
- name = SpecPersonName.create :first_name => "Alice", :last_name => "Smith"
188
- name.update_attributes :first_name => "John"
189
- expect(name.id).to eq @existing.id
190
- end
191
-
192
- it "raises the expected error when 'save!' fails" do
193
- name = SpecPersonName.create :first_name => "Alice", :last_name => "Smith"
194
- name.last_name = nil
195
- expect {
196
- name.save!
197
- }.to raise_error(ActiveRecord::RecordNotSaved)
198
- end
199
-
200
- context "with caching" do
201
- before do
202
- @existing = SpecCustomerFeature.create(:feature_name => "Pays")
203
- SpecCustomerFeature.clear_cache
204
- end
205
-
206
- it "looks up the existing value and adds it to the cache" do
207
- feature = SpecCustomerFeature.new :feature_name => @existing.feature_name
208
-
209
- expect{ feature.save }.
210
- to change(SpecCustomerFeature.aggregated_records_cache, :length).by(1)
211
-
212
- expect(feature.id).to eq @existing.id
213
- end
214
-
215
- it "adds the freshly-created record to the cache" do
216
- expect{ SpecCustomerFeature.create(:feature_name => "Fraud") }.
217
- to change(SpecCustomerFeature.aggregated_records_cache, :length).by(1)
218
- end
219
-
220
- it "freezes the cached object" do
221
- feature = SpecCustomerFeature.create(:feature_name => "Cancelled")
222
- expect(SpecCustomerFeature.aggregated_records_cache[feature.feature_name]).to be_frozen
223
- end
224
-
225
- it "caches the clone of the record, not the record itself" do
226
- feature = SpecCustomerFeature.create(:feature_name => "Returned")
227
- expect(SpecCustomerFeature.aggregated_records_cache[feature.feature_name].object_id).
228
- not_to eq feature.object_id
229
- end
144
+ it "has module included class check methods" do
145
+ expect(SpecCustomerFeature.acts_as_aggregated?).to be_truthy
146
+ expect(SpecCustomerEmail.acts_as_tracked?).to be_truthy
230
147
  end
231
148
  end
232
149
 
233
150
  describe "Tracked" do
234
151
  before do
235
152
  @customer = SpecCustomer.create
236
- @info = @customer.create_spec_customer_info :spec_person_name_id => 1
153
+ @info = @customer.create_spec_customer_info spec_person_name_id: 1
237
154
  end
238
155
 
239
156
  it "creates a new current record if updated" do
240
157
  expect {
241
- @info.update_attributes(:spec_person_name_id => 2)
158
+ @info.update_attributes(spec_person_name_id: 2)
242
159
  }.to change(SpecCustomerInfo, :count).by(1)
243
160
  end
244
161
 
245
162
  it "replaces itself with new id" do
246
163
  old_id = @info.id
247
- @info.update_attributes(:spec_person_name_id => 2)
164
+ @info.update_attributes(spec_person_name_id: 2)
248
165
  expect(@info.id).not_to eq old_id
249
166
  end
250
167
 
251
168
  it "sets is_current record to false for superseded record" do
252
169
  old_id = @info.id
253
- @info.update_attributes(:spec_person_name_id => 2)
170
+ @info.update_attributes(spec_person_name_id: 2)
254
171
  expect(SpecCustomerInfo.find(old_id).is_current).to eq false
255
172
  end
256
173
 
257
174
  it "sets previous_id to the id of the previous record" do
258
175
  old_id = @info.id
259
- @info.update_attributes(:spec_person_name_id => 2)
176
+ @info.update_attributes(spec_person_name_id: 2)
260
177
  expect(@info.previous_id).to eq old_id
261
178
  end
262
179
 
263
180
  it "changes is_current to false for previous one when assigning a new current record" do
264
- new_info = SpecCustomerInfo.new :spec_person_name_id => 2, :is_current => true
181
+ new_info = SpecCustomerInfo.new spec_person_name_id: 2, is_current: true
265
182
  @customer.spec_customer_info = new_info
266
183
  expect(new_info.spec_customer_id).to eq @customer.id
267
184
  @info.reload
@@ -269,12 +186,12 @@ describe Moribus do
269
186
  end
270
187
 
271
188
  it "does not crash on superseding with 'is_current' conditional constraint" do
272
- email = SpecCustomerEmail.create( :spec_customer => @customer,
273
- :email => "foo@bar.com",
274
- :status => "unverified",
275
- :is_current => true
189
+ email = SpecCustomerEmail.create( spec_customer: @customer,
190
+ email: "foo@bar.com",
191
+ status: "unverified",
192
+ is_current: true
276
193
  )
277
- expect{ email.update_attributes(:status => "verified") }.not_to raise_error
194
+ expect{ email.update_attributes(status: "verified") }.not_to raise_error
278
195
  end
279
196
 
280
197
  describe "updated_at and created_at" do
@@ -285,7 +202,7 @@ describe Moribus do
285
202
  after { Timecop.return }
286
203
 
287
204
  it "is updated on change" do
288
- info = @customer.create_spec_customer_info :spec_person_name_id => 1
205
+ info = @customer.create_spec_customer_info spec_person_name_id: 1
289
206
  expect(info.updated_at).to eq first_time
290
207
  expect(info.created_at).to eq first_time
291
208
 
@@ -304,28 +221,41 @@ describe Moribus do
304
221
  end
305
222
 
306
223
  it "raises a stale object error" do
307
- @info1.update_attributes(:spec_person_name_id => 3)
224
+ @info1.update_attributes(spec_person_name_id: 3)
308
225
 
309
- expect{ @info2.update_attributes(:spec_person_name_id => 4) }.
226
+ expect{ @info2.update_attributes(spec_person_name_id: 4) }.
310
227
  to raise_error(ActiveRecord::StaleObjectError,
311
- "Attempted to update_current (version #{@info2.lock_version}) a stale object: SpecCustomerInfo")
228
+ /Attempted to update_current \(version #{@info2.lock_version}\) a stale object: SpecCustomerInfo\./)
312
229
  end
313
230
 
314
231
  it "updates lock_version incrementally for each new record" do
315
232
  spec_customer_info = @customer.spec_customer_info
316
233
 
317
234
  expect {
318
- spec_customer_info.update_attributes(:spec_person_name_id => 3)
235
+ spec_customer_info.update_attributes(spec_person_name_id: 3)
319
236
  }.to change { spec_customer_info.lock_version }.from(0).to(1)
320
237
 
321
238
  expect {
322
- spec_customer_info.update_attributes(:spec_person_name_id => 4)
239
+ spec_customer_info.update_attributes(spec_person_name_id: 4)
323
240
  }.to change { spec_customer_info.lock_version }.from(1).to(2)
324
241
  end
325
242
 
243
+ it "does not fail to update if a lock version growth is for any reason not monotonic" do
244
+ spec_customer_info = @customer.spec_customer_info
245
+
246
+ spec_customer_info.update_attributes(spec_person_name_id: 3)
247
+ spec_customer_info.update_attributes(spec_person_name_id: 4)
248
+
249
+ SpecCustomerInfo.where(spec_customer_id: @customer.id, lock_version: 1).delete_all
250
+
251
+ expect {
252
+ spec_customer_info.update_attributes(spec_person_name_id: 5)
253
+ }.to change { spec_customer_info.lock_version }.from(2).to(3)
254
+ end
255
+
326
256
  it "does not fail if no locking_column is present" do
327
- email = SpecCustomerEmail.create(:spec_customer_id => 1, :email => "foo@bar.com")
328
- expect{ email.update_attributes(:email => "foo2@bar.com") }.not_to raise_error
257
+ email = SpecCustomerEmail.create(spec_customer_id: 1, email: "foo@bar.com")
258
+ expect{ email.update_attributes(email: "foo2@bar.com") }.not_to raise_error
329
259
  end
330
260
 
331
261
  it "updates lock_version column based on parent relation" do
@@ -333,29 +263,29 @@ describe Moribus do
333
263
  spec_customer_info = @customer.spec_customer_info
334
264
 
335
265
  expect {
336
- spec_customer_info.update_attributes(:spec_person_name_id => 3)
266
+ spec_customer_info.update_attributes(spec_person_name_id: 3)
337
267
  }.to change { spec_customer_info.lock_version }.from(0).to(1)
338
268
 
339
269
  expect {
340
- spec_customer_info.update_attributes(:spec_customer => @other_customer)
270
+ spec_customer_info.update_attributes(spec_customer: @other_customer)
341
271
  }.to change { spec_customer_info.lock_version }.from(1).to(0)
342
272
  end
343
273
 
344
274
  it "updates lock_version column base on relation list from 'by' option" do
345
275
  info_with_type =
346
- @customer.reload.create_spec_customer_info_with_type(:spec_type => :important)
276
+ @customer.reload.create_spec_customer_info_with_type(spec_type: :important)
347
277
 
348
278
  expect( info_with_type.lock_version ).to eq 0
349
279
 
350
280
  other_info_with_type =
351
- @customer.reload.create_spec_customer_info_with_type(:spec_type => :unimportant)
281
+ @customer.reload.create_spec_customer_info_with_type(spec_type: :unimportant)
352
282
 
353
283
  expect( other_info_with_type.lock_version ).to eq 0
354
284
 
355
- info_with_type.update_attributes(:spec_status => :active)
285
+ info_with_type.update_attributes(spec_status: :active)
356
286
  expect( info_with_type.lock_version ).to eq 1
357
287
 
358
- info_with_type.update_attributes(:spec_status => :inactive)
288
+ info_with_type.update_attributes(spec_status: :inactive)
359
289
  expect( info_with_type.lock_version ).to eq 2
360
290
 
361
291
  expect( other_info_with_type.lock_version ).to eq 0
@@ -365,7 +295,7 @@ describe Moribus do
365
295
  describe "with Aggregated" do
366
296
  before do
367
297
  @info.spec_person_name =
368
- SpecPersonName.create(:first_name => "John", :last_name => "Smith")
298
+ SpecPersonName.create(first_name: "John", last_name: "Smith")
369
299
  @info.save
370
300
  @info.reload
371
301
  end
@@ -374,59 +304,12 @@ describe Moribus do
374
304
  old_id = @info.id
375
305
  @customer.spec_customer_info.spec_person_name.first_name = "Alice"
376
306
  expect{ @customer.save }.to change(@info, :spec_person_name_id)
377
- expect(@info.id).not_to eq old_id
378
- expect(@info.is_current).to eq true
379
- expect(SpecCustomerInfo.find(old_id).is_current).to eq false
380
- end
381
- end
382
- end
383
-
384
- describe "Delegations" do
385
- before do
386
- @customer = SpecCustomer.create(
387
- :spec_customer_info_attributes => {
388
- :spec_person_name_attributes => {:first_name => " John ", :last_name => "Smith"} } )
389
- @info = @customer.spec_customer_info
390
- end
391
307
 
392
- it "has delegated column information" do
393
- expect(@customer.column_for_attribute(:first_name)).not_to be_nil
394
- end
395
-
396
- it "does not delegate special methods" do
397
- expect(@customer).not_to respond_to(:reset_first_name)
398
- expect(@customer).not_to respond_to(:first_name_was)
399
- expect(@customer).not_to respond_to(:first_name_before_type_cast)
400
- expect(@customer).not_to respond_to(:first_name_will_change!)
401
- expect(@customer).not_to respond_to(:first_name_changed?)
402
- expect(@customer).not_to respond_to(:lock_version)
403
- end
308
+ expect(@info.id ).not_to eq old_id
309
+ expect(@info.is_current).to eq true
404
310
 
405
- it "delegates methods to aggregated parts" do
406
- expect(@info).to respond_to(:first_name)
407
- expect(@info).to respond_to(:first_name=)
408
- expect(@info).to respond_to(:spec_suffix)
409
- expect(@info.last_name).to eq "Smith"
410
- end
411
-
412
- it "delegates methods to representation" do
413
- expect(@customer).to respond_to(:first_name)
414
- expect(@customer).to respond_to(:first_name=)
415
- expect(@customer).to respond_to(:spec_suffix)
416
- expect(@customer.last_name).to eq "Smith"
417
- expect(@customer).to respond_to(:custom_field)
418
- expect(@customer).to respond_to(:custom_field=)
419
- end
420
-
421
- it "properly delegates enumerated attributes" do
422
- expect(@customer).to respond_to(:spec_type)
423
- expect(@customer).to respond_to(:spec_type=)
424
- @customer.spec_type = :important
425
- expect(@customer.spec_type === :important).to eq true
426
- end
427
-
428
- it "raises NoMethodError if unknown method is received" do
429
- expect{ @customer.impossibru }.to raise_error(NoMethodError)
311
+ expect(SpecCustomerInfo.find(old_id).is_current).to eq false
312
+ end
430
313
  end
431
314
  end
432
315
  end