yesterday 0.2 → 0.3
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.
- data/README.rdoc +1 -1
- data/lib/yesterday/model.rb +20 -8
- data/lib/yesterday/serializer.rb +2 -2
- data/lib/yesterday/version.rb +1 -1
- data/spec/models.rb +10 -2
- data/spec/schema.rb +13 -0
- data/spec/serializer_spec.rb +7 -5
- data/spec/yesterday_model_spec.rb +123 -79
- metadata +4 -4
data/README.rdoc
CHANGED
data/lib/yesterday/model.rb
CHANGED
@@ -46,7 +46,7 @@ module Yesterday
|
|
46
46
|
@tracked_attributes || []
|
47
47
|
end
|
48
48
|
|
49
|
-
def
|
49
|
+
def track_changes(options = {})
|
50
50
|
send :include, InstanceMethods
|
51
51
|
|
52
52
|
after_save :serialize_current_state
|
@@ -55,13 +55,13 @@ module Yesterday
|
|
55
55
|
|
56
56
|
def version(version_number)
|
57
57
|
if object = first
|
58
|
-
Versioning.versioned_object_for
|
58
|
+
Versioning.versioned_object_for version_number, object
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
62
|
def diff_version(from_version_number, to_version_number)
|
63
63
|
if object = first
|
64
|
-
Versioning.diff_for
|
64
|
+
Versioning.diff_for from_version_number, to_version_number, object
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
@@ -69,29 +69,41 @@ module Yesterday
|
|
69
69
|
|
70
70
|
module InstanceMethods
|
71
71
|
def changesets
|
72
|
-
Versioning.changesets_for(self)
|
72
|
+
@changesets ||= Versioning.changesets_for(self)
|
73
73
|
end
|
74
74
|
|
75
75
|
def version_number
|
76
|
-
Versioning.current_version_number_for(self)
|
76
|
+
@version_number ||= Versioning.current_version_number_for(self)
|
77
77
|
end
|
78
78
|
|
79
79
|
def previous_version_number
|
80
|
-
version_number > 1 ? version_number - 1 : version_number
|
80
|
+
@previous_version_number ||= (version_number > 1 ? version_number - 1 : version_number)
|
81
81
|
end
|
82
82
|
|
83
83
|
def version(version_number)
|
84
|
-
|
84
|
+
@version ||= {}
|
85
|
+
@version[version_number] ||= Versioning.versioned_object_for(version_number, self)
|
85
86
|
end
|
86
87
|
|
87
88
|
def diff_version(from_version_number, to_version_number)
|
88
|
-
|
89
|
+
@diff_version ||= {}
|
90
|
+
@diff_version[from_version_number] ||= {}
|
91
|
+
@diff_version[from_version_number][to_version_number] ||= Versioning.diff_for(from_version_number, to_version_number, self)
|
89
92
|
end
|
90
93
|
|
91
94
|
private
|
92
95
|
|
93
96
|
def serialize_current_state
|
94
97
|
Versioning.create_changeset_for self
|
98
|
+
invalidate_cached_versioning
|
99
|
+
end
|
100
|
+
|
101
|
+
def invalidate_cached_versioning
|
102
|
+
cached_versioned_items.each { |item| instance_variable_set(:"@#{item}", nil) }
|
103
|
+
end
|
104
|
+
|
105
|
+
def cached_versioned_items
|
106
|
+
%w(changesets version_number previous_version_number version diff_version)
|
95
107
|
end
|
96
108
|
|
97
109
|
end
|
data/lib/yesterday/serializer.rb
CHANGED
@@ -14,7 +14,7 @@ module Yesterday
|
|
14
14
|
each_association_collection(object) do |association, association_name, item|
|
15
15
|
path << object
|
16
16
|
|
17
|
-
if
|
17
|
+
if association_has_collection?(association)
|
18
18
|
hash[association_name] ||= []
|
19
19
|
hash[association_name] << hash_object(item)
|
20
20
|
else
|
@@ -27,7 +27,7 @@ module Yesterday
|
|
27
27
|
hash
|
28
28
|
end
|
29
29
|
|
30
|
-
def
|
30
|
+
def association_has_collection?(association)
|
31
31
|
[:has_many, :has_and_belongs_to_many].include? association.macro
|
32
32
|
end
|
33
33
|
|
data/lib/yesterday/version.rb
CHANGED
data/spec/models.rb
CHANGED
@@ -1,12 +1,20 @@
|
|
1
|
+
class Report < ActiveRecord::Base
|
2
|
+
has_many :contacts
|
3
|
+
has_many :companies
|
4
|
+
|
5
|
+
track_changes
|
6
|
+
end
|
7
|
+
|
1
8
|
class Contact < ActiveRecord::Base
|
2
9
|
has_and_belongs_to_many :addresses
|
3
|
-
tracks_changes
|
4
10
|
end
|
5
11
|
|
6
12
|
class Address < ActiveRecord::Base
|
7
13
|
end
|
8
14
|
|
9
15
|
class Company < ActiveRecord::Base
|
10
|
-
|
16
|
+
has_and_belongs_to_many :addresses
|
17
|
+
|
18
|
+
track_changes
|
11
19
|
exclude_tracking_for :attributes => [:created_at, :updated_at]
|
12
20
|
end
|
data/spec/schema.rb
CHANGED
@@ -1,11 +1,18 @@
|
|
1
1
|
ActiveRecord::Schema.define(:version => 1) do
|
2
2
|
|
3
|
+
create_table 'reports', :force => true do |t|
|
4
|
+
t.string 'description'
|
5
|
+
t.datetime 'created_at'
|
6
|
+
t.datetime 'updated_at'
|
7
|
+
end
|
8
|
+
|
3
9
|
create_table 'contacts', :force => true do |t|
|
4
10
|
t.string 'first_name'
|
5
11
|
t.string 'middle_name'
|
6
12
|
t.string 'last_name'
|
7
13
|
t.datetime 'created_at'
|
8
14
|
t.datetime 'updated_at'
|
15
|
+
t.integer 'report_id'
|
9
16
|
end
|
10
17
|
|
11
18
|
create_table 'addresses', :force => true do |t|
|
@@ -23,6 +30,11 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
23
30
|
t.integer 'address_id'
|
24
31
|
end
|
25
32
|
|
33
|
+
create_table 'addresses_companies', :id => false, :force => true do |t|
|
34
|
+
t.integer 'company_id'
|
35
|
+
t.integer 'address_id'
|
36
|
+
end
|
37
|
+
|
26
38
|
create_table 'changesets', :force => true do |t|
|
27
39
|
t.integer 'changed_object_id'
|
28
40
|
t.string 'changed_object_type'
|
@@ -36,6 +48,7 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
36
48
|
t.string 'name'
|
37
49
|
t.datetime 'created_at'
|
38
50
|
t.datetime 'updated_at'
|
51
|
+
t.integer 'report_id'
|
39
52
|
end
|
40
53
|
|
41
54
|
end
|
data/spec/serializer_spec.rb
CHANGED
@@ -6,7 +6,7 @@ describe Yesterday::Serializer do
|
|
6
6
|
|
7
7
|
address1 = Address.create(
|
8
8
|
:street => 'street',
|
9
|
-
:house_number => 1,
|
9
|
+
:house_number => '1',
|
10
10
|
:zipcode => '1234AA',
|
11
11
|
:city => 'Armadillo',
|
12
12
|
:country => 'FooCountry'
|
@@ -14,7 +14,7 @@ describe Yesterday::Serializer do
|
|
14
14
|
|
15
15
|
address2 = Address.create(
|
16
16
|
:street => 'lane',
|
17
|
-
:house_number => 1337,
|
17
|
+
:house_number => '1337',
|
18
18
|
:zipcode => '2211AB',
|
19
19
|
:city => 'Cougar town',
|
20
20
|
:country => 'BarCountry'
|
@@ -24,6 +24,7 @@ describe Yesterday::Serializer do
|
|
24
24
|
contact.addresses << address2
|
25
25
|
|
26
26
|
Yesterday::Serializer.new(contact).to_hash.should == {
|
27
|
+
'report_id' => nil,
|
27
28
|
'id' => contact.id,
|
28
29
|
'first_name' => 'foo',
|
29
30
|
'middle_name' => nil,
|
@@ -34,7 +35,7 @@ describe Yesterday::Serializer do
|
|
34
35
|
{
|
35
36
|
'id' => address1.id,
|
36
37
|
'street' => 'street',
|
37
|
-
'house_number' => 1,
|
38
|
+
'house_number' => '1',
|
38
39
|
'zipcode' => '1234AA',
|
39
40
|
'city' => 'Armadillo',
|
40
41
|
'country' => 'FooCountry',
|
@@ -44,7 +45,7 @@ describe Yesterday::Serializer do
|
|
44
45
|
{
|
45
46
|
'id' => address2.id,
|
46
47
|
'street' => 'lane',
|
47
|
-
'house_number' => 1337,
|
48
|
+
'house_number' => '1337',
|
48
49
|
'zipcode' => '2211AB',
|
49
50
|
'city' => 'Cougar town',
|
50
51
|
'country' => 'BarCountry',
|
@@ -60,7 +61,8 @@ describe Yesterday::Serializer do
|
|
60
61
|
|
61
62
|
Yesterday::Serializer.new(company).to_hash.should == {
|
62
63
|
'id' => company.id,
|
63
|
-
'name' => 'foobar'
|
64
|
+
'name' => 'foobar',
|
65
|
+
'report_id' => nil
|
64
66
|
}
|
65
67
|
end
|
66
68
|
end
|
@@ -5,117 +5,126 @@ require 'models'
|
|
5
5
|
describe Yesterday::Model do
|
6
6
|
|
7
7
|
it 'should have mixed in yesterday::model' do
|
8
|
-
|
8
|
+
Report.new.should respond_to :version_number
|
9
9
|
Address.new.should_not respond_to :version_number
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'should create a new changeset when saved' do
|
13
13
|
Yesterday::Changeset.count.should == 0
|
14
|
-
|
14
|
+
Report.create :description => 'bar'
|
15
15
|
Yesterday::Changeset.count.should == 1
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'should return all related changesets' do
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
report = Report.create(:description => 'foo bar')
|
20
|
+
report.changesets.size.should == 1
|
21
|
+
report.changesets.first.changed_object_type.should == 'Report'
|
22
22
|
end
|
23
23
|
|
24
24
|
describe 'returning version numbers' do
|
25
25
|
it 'should return version number when new record' do
|
26
|
-
|
27
|
-
|
26
|
+
report = Report.new(:description => 'foo bar')
|
27
|
+
report.version_number.should == 0
|
28
28
|
end
|
29
29
|
|
30
30
|
it 'should return version number after first save' do
|
31
|
-
|
32
|
-
|
31
|
+
report = Report.create(:description => 'foo bar')
|
32
|
+
report.version_number.should == 1
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'should return version number after update' do
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
report = Report.create(:description => 'foo bar')
|
37
|
+
report.description = 'foo bar baz'
|
38
|
+
report.save!
|
39
39
|
|
40
|
-
|
40
|
+
report.version_number.should == 2
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
44
|
describe' returning older versions' do
|
45
45
|
it 'should not return and old version when there is no history' do
|
46
|
-
|
47
|
-
|
46
|
+
Report.new
|
47
|
+
Report.version(0).should == nil
|
48
48
|
end
|
49
49
|
|
50
50
|
it 'should return a historical item' do
|
51
|
-
|
52
|
-
|
53
|
-
|
51
|
+
report = Report.create!(:description => 'bar')
|
52
|
+
Report.where(:id => report.id).version(0).should == nil
|
53
|
+
Report.where(:id => report.id).version(1).should be_a(Yesterday::VersionedObject)
|
54
54
|
end
|
55
55
|
|
56
56
|
describe 'return a historical view of a version' do
|
57
57
|
before do
|
58
|
-
@
|
59
|
-
@
|
60
|
-
@
|
58
|
+
@report = Report.create!(:description => 'foo')
|
59
|
+
@report.update_attributes :description => 'bar'
|
60
|
+
@report.update_attributes :description => 'baz'
|
61
61
|
end
|
62
62
|
|
63
63
|
it 'using scopes' do
|
64
|
-
@
|
64
|
+
@report.version_number.should == 3
|
65
65
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
Contact.where(:id => @contact.id).version(1).first_name.should == 'foo'
|
70
|
-
Contact.where(:id => @contact.id).version(1).last_name.should == 'bar'
|
66
|
+
Report.where(:id => @report.id).version(3).description.should == 'baz'
|
67
|
+
Report.where(:id => @report.id).version(2).description.should == 'bar'
|
68
|
+
Report.where(:id => @report.id).version(1).description.should == 'foo'
|
71
69
|
end
|
72
70
|
|
73
71
|
it 'using instance method' do
|
74
|
-
@
|
75
|
-
@
|
76
|
-
|
77
|
-
@contact.version(1).first_name.should == 'foo'
|
78
|
-
@contact.version(1).last_name.should == 'bar'
|
72
|
+
@report.version(3).description.should == 'baz'
|
73
|
+
@report.version(2).description.should == 'bar'
|
74
|
+
@report.version(1).description.should == 'foo'
|
79
75
|
end
|
80
76
|
end
|
81
77
|
end
|
82
78
|
|
83
79
|
describe 'diffing two versions' do
|
84
80
|
it 'should diff version 1 with version 2' do
|
85
|
-
|
86
|
-
|
81
|
+
report = Report.create(:description => 'foo bar')
|
82
|
+
report.update_attributes :description => 'foo bar baz'
|
87
83
|
|
88
|
-
diff =
|
84
|
+
diff = report.diff_version(1, 2)
|
89
85
|
diff.should be_a(Yesterday::VersionedObject)
|
90
86
|
|
91
|
-
diff.
|
92
|
-
diff.
|
93
|
-
|
94
|
-
diff.last_name.current.should == 'do'
|
95
|
-
diff.last_name.previous.should == 'bar'
|
87
|
+
diff.description.current.should == 'foo bar baz'
|
88
|
+
diff.description.previous.should == 'foo bar'
|
96
89
|
end
|
97
90
|
|
98
91
|
it 'should diff version 1 with version 3' do
|
99
|
-
|
100
|
-
|
101
|
-
|
92
|
+
report = Report.create(:description => 'foo')
|
93
|
+
report.update_attributes :description => 'bar'
|
94
|
+
report.update_attributes :description => 'baz'
|
102
95
|
|
103
|
-
diff =
|
96
|
+
diff = report.diff_version(1, 3)
|
104
97
|
diff.should be_a(Yesterday::VersionedObject)
|
105
98
|
|
106
|
-
diff.
|
107
|
-
diff.
|
108
|
-
|
109
|
-
diff.last_name.current.should == 'foo'
|
110
|
-
diff.last_name.previous.should == 'bar'
|
99
|
+
diff.description.current.should == 'baz'
|
100
|
+
diff.description.previous.should == 'foo'
|
111
101
|
end
|
112
102
|
|
113
103
|
it 'should detect that new associations are created' do
|
114
|
-
|
104
|
+
address1 = Address.new(
|
105
|
+
:street => 'street',
|
106
|
+
:house_number => 1,
|
107
|
+
:zipcode => '1234AA',
|
108
|
+
:city => 'ElectricCity',
|
109
|
+
:country => 'Netherlands'
|
110
|
+
)
|
111
|
+
|
112
|
+
report = Report.create(
|
113
|
+
:description => 'foo bar baz',
|
114
|
+
:contacts => [
|
115
|
+
Contact.create(
|
116
|
+
:first_name => 'John',
|
117
|
+
:last_name => 'Doe',
|
118
|
+
:addresses => [
|
119
|
+
address1
|
120
|
+
]
|
121
|
+
)
|
122
|
+
]
|
123
|
+
)
|
115
124
|
|
116
|
-
|
125
|
+
report.version_number.should == 1
|
117
126
|
|
118
|
-
|
127
|
+
address2 = Address.new(
|
119
128
|
:street => 'street',
|
120
129
|
:house_number => 1,
|
121
130
|
:zipcode => '1234AA',
|
@@ -123,7 +132,7 @@ describe Yesterday::Model do
|
|
123
132
|
:country => 'FooCountry'
|
124
133
|
)
|
125
134
|
|
126
|
-
|
135
|
+
address3 = Address.new(
|
127
136
|
:street => 'lane',
|
128
137
|
:house_number => 1337,
|
129
138
|
:zipcode => '2211AB',
|
@@ -131,22 +140,52 @@ describe Yesterday::Model do
|
|
131
140
|
:country => 'BarCountry'
|
132
141
|
)
|
133
142
|
|
134
|
-
|
135
|
-
contact.save!
|
143
|
+
report.contacts.first.addresses = [address1, address2, address3]
|
136
144
|
|
137
|
-
|
145
|
+
report.save!
|
138
146
|
|
139
|
-
|
140
|
-
|
141
|
-
diff
|
142
|
-
|
147
|
+
report.version_number.should == 2
|
148
|
+
|
149
|
+
diff = report.diff_version(1, 2)
|
150
|
+
|
151
|
+
diff.contacts.count.should == 1
|
152
|
+
diff.contacts.first.addresses.count.should == 1
|
153
|
+
diff.contacts.first.addresses.first.id.should == address1.id
|
154
|
+
|
155
|
+
diff.contacts.first.created_addresses.count.should == 2
|
156
|
+
diff.contacts.first.created_addresses.first.id.should == address2.id
|
157
|
+
diff.contacts.first.created_addresses.last.id.should == address3.id
|
143
158
|
end
|
144
159
|
|
145
160
|
describe 'association removal' do
|
146
161
|
before do
|
147
|
-
@
|
162
|
+
@report = Report.create(
|
163
|
+
:description => 'foo bar baz',
|
164
|
+
:contacts => [
|
165
|
+
Contact.create(
|
166
|
+
:first_name => 'John',
|
167
|
+
:last_name => 'Doe',
|
168
|
+
:addresses => [
|
169
|
+
Address.create(
|
170
|
+
:street => 'street',
|
171
|
+
:house_number => 1,
|
172
|
+
:zipcode => '1234AA',
|
173
|
+
:city => 'ElectricCity',
|
174
|
+
:country => 'Netherlands'
|
175
|
+
)
|
176
|
+
]
|
177
|
+
)
|
178
|
+
],
|
179
|
+
:companies => [
|
180
|
+
Company.create(
|
181
|
+
:name => 'Test company'
|
182
|
+
)
|
183
|
+
]
|
184
|
+
)
|
185
|
+
|
186
|
+
@report.version_number.should == 1
|
148
187
|
|
149
|
-
@address1 = Address.
|
188
|
+
@address1 = Address.new(
|
150
189
|
:street => 'street',
|
151
190
|
:house_number => 1,
|
152
191
|
:zipcode => '1234AA',
|
@@ -154,7 +193,7 @@ describe Yesterday::Model do
|
|
154
193
|
:country => 'FooCountry'
|
155
194
|
)
|
156
195
|
|
157
|
-
@address2 = Address.
|
196
|
+
@address2 = Address.new(
|
158
197
|
:street => 'lane',
|
159
198
|
:house_number => 1337,
|
160
199
|
:zipcode => '2211AB',
|
@@ -162,32 +201,37 @@ describe Yesterday::Model do
|
|
162
201
|
:country => 'BarCountry'
|
163
202
|
)
|
164
203
|
|
165
|
-
@
|
166
|
-
@
|
204
|
+
@report.contacts.first.addresses = [@address1, @address2]
|
205
|
+
@report.save!
|
167
206
|
|
168
|
-
@
|
169
|
-
@
|
207
|
+
@report.contacts.first.addresses = [@address1]
|
208
|
+
@report.companies.first.addresses = [@address1]
|
209
|
+
@report.save!
|
170
210
|
|
171
|
-
@
|
172
|
-
|
173
|
-
@contact.version_number.should == 3
|
211
|
+
@report.version_number.should == 3
|
174
212
|
end
|
175
213
|
|
176
214
|
it 'should detect that associations are destroyed when diffing version 2 with 3' do
|
215
|
+
diff = @report.diff_version(2, 3)
|
216
|
+
diff.contacts.count.should == 1
|
217
|
+
|
218
|
+
diff.contacts.first.addresses.count.should == 1
|
219
|
+
diff.contacts.first.destroyed_addresses.count.should == 1
|
177
220
|
|
178
|
-
diff
|
179
|
-
diff.addresses.
|
180
|
-
diff.destroyed_addresses.count.should == 1
|
221
|
+
diff.contacts.first.destroyed_addresses.first.id.should == @address2.id
|
222
|
+
diff.contacts.first.addresses.first.id.should == @address1.id
|
181
223
|
|
182
|
-
diff.
|
183
|
-
diff.addresses.first.id.should == @address1.id
|
224
|
+
diff.companies.first.created_addresses.count.should == 1
|
184
225
|
end
|
185
226
|
|
186
227
|
it 'should detect that associations are created when diffing version 1 with 3' do
|
187
|
-
diff = @
|
188
|
-
diff.should_not respond_to(:addresses)
|
189
|
-
|
190
|
-
diff.
|
228
|
+
diff = @report.diff_version(1, 3)
|
229
|
+
diff.contacts.first.should_not respond_to(:addresses)
|
230
|
+
|
231
|
+
diff.contacts.first.created_addresses.count.should == 1
|
232
|
+
diff.contacts.first.created_addresses.first.id.should == @address1.id
|
233
|
+
|
234
|
+
diff.companies.first.created_addresses.count.should == 1
|
191
235
|
end
|
192
236
|
end
|
193
237
|
end
|
metadata
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yesterday
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 13
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: "0.
|
8
|
+
- 3
|
9
|
+
version: "0.3"
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Diederick Lawson
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-
|
17
|
+
date: 2011-04-01 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|