sequel_bitemporal 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "sequel_bitemporal"
6
- s.version = "0.1.6"
6
+ s.version = "0.1.7"
7
7
  s.authors = ["Joseph HALTER"]
8
8
  s.email = ["joseph.halter@thetalentbox.com"]
9
9
  s.homepage = "https://github.com/TalentBox/sequel_bitemporal"
@@ -67,7 +67,7 @@ describe "Sequel::Plugins::Bitemporal" do
67
67
  master.should_not be_new
68
68
  master.should have_versions %Q{
69
69
  | name | price | created_at | expired_at | valid_from | valid_to | current |
70
- | Single Standard | 98 | 2009-11-28 | | 2009-11-28 | | true |
70
+ | Single Standard | 98 | 2009-11-28 | | 2009-11-28 | MAX DATE | true |
71
71
  }
72
72
  end
73
73
  it "allows creating a new version in the past" do
@@ -75,7 +75,7 @@ describe "Sequel::Plugins::Bitemporal" do
75
75
  master.update_attributes name: "Single Standard", price: 98, valid_from: Date.today-1
76
76
  master.should have_versions %Q{
77
77
  | name | price | created_at | expired_at | valid_from | valid_to | current |
78
- | Single Standard | 98 | 2009-11-28 | | 2009-11-27 | | true |
78
+ | Single Standard | 98 | 2009-11-28 | | 2009-11-27 | MAX DATE | true |
79
79
  }
80
80
  end
81
81
  it "allows creating a new version in the future" do
@@ -83,7 +83,7 @@ describe "Sequel::Plugins::Bitemporal" do
83
83
  master.update_attributes name: "Single Standard", price: 98, valid_from: Date.today+1
84
84
  master.should have_versions %Q{
85
85
  | name | price | created_at | expired_at | valid_from | valid_to | current |
86
- | Single Standard | 98 | 2009-11-28 | | 2009-11-29 | | |
86
+ | Single Standard | 98 | 2009-11-28 | | 2009-11-29 | MAX DATE | |
87
87
  }
88
88
  end
89
89
  it "doesn't loose previous version in same-day update" do
@@ -92,8 +92,8 @@ describe "Sequel::Plugins::Bitemporal" do
92
92
  master.update_attributes name: "Single Standard", price: 94
93
93
  master.should have_versions %Q{
94
94
  | name | price | created_at | expired_at | valid_from | valid_to | current |
95
- | Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | | |
96
- | Single Standard | 94 | 2009-11-28 | | 2009-11-28 | | true |
95
+ | Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
96
+ | Single Standard | 94 | 2009-11-28 | | 2009-11-28 | MAX DATE | true |
97
97
  }
98
98
  end
99
99
  it "allows partial updating based on current version" do
@@ -103,9 +103,9 @@ describe "Sequel::Plugins::Bitemporal" do
103
103
  master.update_attributes name: "King Size", partial_update: true
104
104
  master.should have_versions %Q{
105
105
  | name | price | created_at | expired_at | valid_from | valid_to | current |
106
- | Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | | |
107
- | Single Standard | 94 | 2009-11-28 | 2009-11-28 | 2009-11-28 | | |
108
- | King Size | 94 | 2009-11-28 | | 2009-11-28 | | true |
106
+ | Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
107
+ | Single Standard | 94 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
108
+ | King Size | 94 | 2009-11-28 | | 2009-11-28 | MAX DATE | true |
109
109
  }
110
110
  end
111
111
  it "expires previous version but keep it in history" do
@@ -115,9 +115,9 @@ describe "Sequel::Plugins::Bitemporal" do
115
115
  master.update_attributes price: 94, partial_update: true
116
116
  master.should have_versions %Q{
117
117
  | name | price | created_at | expired_at | valid_from | valid_to | current |
118
- | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | | |
118
+ | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | MAX DATE | |
119
119
  | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
120
- | Single Standard | 94 | 2009-11-29 | | 2009-11-29 | | true |
120
+ | Single Standard | 94 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
121
121
  }
122
122
  end
123
123
  it "doesn't expire no longer valid versions" do
@@ -129,7 +129,7 @@ describe "Sequel::Plugins::Bitemporal" do
129
129
  master.should have_versions %Q{
130
130
  | name | price | created_at | expired_at | valid_from | valid_to | current |
131
131
  | Single Standard | 98 | 2009-11-28 | | 2009-11-28 | 2009-11-29 | |
132
- | Single Standard | 94 | 2009-11-29 | | 2009-11-29 | | true |
132
+ | Single Standard | 94 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
133
133
  }
134
134
  end
135
135
  it "allows shortening validity (SEE COMMENTS FOR IMPROVEMENTS)" do
@@ -139,7 +139,7 @@ describe "Sequel::Plugins::Bitemporal" do
139
139
  master.update_attributes valid_to: Date.today+10, partial_update: true
140
140
  master.should have_versions %Q{
141
141
  | name | price | created_at | expired_at | valid_from | valid_to | current |
142
- | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | | |
142
+ | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | MAX DATE | |
143
143
  | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
144
144
  | Single Standard | 98 | 2009-11-29 | | 2009-11-29 | 2009-12-09 | true |
145
145
  }
@@ -161,12 +161,12 @@ describe "Sequel::Plugins::Bitemporal" do
161
161
  | name | price | created_at | expired_at | valid_from | valid_to | current |
162
162
  | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
163
163
  | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
164
- | Single Standard | 98 | 2009-11-29 | | 2009-11-29 | | true |
164
+ | Single Standard | 98 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
165
165
  }
166
166
  # would be even better if it could be:
167
167
  # | name | price | created_at | expired_at | valid_from | valid_to | current |
168
168
  # | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
169
- # | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | | true |
169
+ # | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | MAX DATE | true |
170
170
  end
171
171
  xit "doesn't do anything if unchanged" do
172
172
  end
@@ -216,7 +216,7 @@ describe "Sequel::Plugins::Bitemporal" do
216
216
  | Single Standard | 94 | 2009-11-28 | 2009-11-29 | 2009-11-30 | 2009-12-02 | |
217
217
  | Single Standard | 95 | 2009-11-28 | 2009-11-29 | 2009-12-02 | 2009-12-04 | |
218
218
  | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
219
- | King Size | 98 | 2009-11-29 | | 2009-11-29 | | true |
219
+ | King Size | 98 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
220
220
  }
221
221
  end
222
222
  it "allows deleting current version" do
@@ -227,9 +227,9 @@ describe "Sequel::Plugins::Bitemporal" do
227
227
  master.current_version.destroy.should be_true
228
228
  master.should have_versions %Q{
229
229
  | name | price | created_at | expired_at | valid_from | valid_to | current |
230
- | Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | | |
230
+ | Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
231
231
  | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
232
- | Single Standard | 94 | 2009-11-28 | | 2009-11-30 | | |
232
+ | Single Standard | 94 | 2009-11-28 | | 2009-11-30 | MAX DATE | |
233
233
  | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
234
234
  }
235
235
  end
@@ -241,10 +241,10 @@ describe "Sequel::Plugins::Bitemporal" do
241
241
  master.versions.last.destroy.should be_true
242
242
  master.should have_versions %Q{
243
243
  | name | price | created_at | expired_at | valid_from | valid_to | current |
244
- | Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | | |
244
+ | Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
245
245
  | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
246
- | Single Standard | 94 | 2009-11-28 | 2009-11-29 | 2009-11-30 | | |
247
- | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | | true |
246
+ | Single Standard | 94 | 2009-11-28 | 2009-11-29 | 2009-11-30 | MAX DATE | |
247
+ | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | MAX DATE | true |
248
248
  }
249
249
  end
250
250
  it "allows deleting all versions" do
@@ -255,9 +255,9 @@ describe "Sequel::Plugins::Bitemporal" do
255
255
  master.destroy.should be_true
256
256
  master.should have_versions %Q{
257
257
  | name | price | created_at | expired_at | valid_from | valid_to | current |
258
- | Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | | |
258
+ | Single Standard | 98 | 2009-11-28 | 2009-11-28 | 2009-11-28 | MAX DATE | |
259
259
  | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | 2009-11-30 | |
260
- | Single Standard | 94 | 2009-11-28 | 2009-11-29 | 2009-11-30 | | |
260
+ | Single Standard | 94 | 2009-11-28 | 2009-11-29 | 2009-11-30 | MAX DATE | |
261
261
  }
262
262
  end
263
263
  it "allows simultaneous updates without information loss" do
@@ -269,10 +269,10 @@ describe "Sequel::Plugins::Bitemporal" do
269
269
  master2.update_attributes name: "Single Standard", price: 95
270
270
  master.should have_versions %Q{
271
271
  | name | price | created_at | expired_at | valid_from | valid_to | current |
272
- | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | | |
272
+ | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | MAX DATE | |
273
273
  | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
274
- | Single Standard | 94 | 2009-11-29 | 2009-11-29 | 2009-11-29 | | |
275
- | Single Standard | 95 | 2009-11-29 | | 2009-11-29 | | true |
274
+ | Single Standard | 94 | 2009-11-29 | 2009-11-29 | 2009-11-29 | MAX DATE | |
275
+ | Single Standard | 95 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
276
276
  }
277
277
  end
278
278
  it "allows simultaneous cumulative updates" do
@@ -284,10 +284,10 @@ describe "Sequel::Plugins::Bitemporal" do
284
284
  master2.update_attributes name: "King Size", partial_update: true
285
285
  master.should have_versions %Q{
286
286
  | name | price | created_at | expired_at | valid_from | valid_to | current |
287
- | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | | |
287
+ | Single Standard | 98 | 2009-11-28 | 2009-11-29 | 2009-11-28 | MAX DATE | |
288
288
  | Single Standard | 98 | 2009-11-29 | | 2009-11-28 | 2009-11-29 | |
289
- | Single Standard | 94 | 2009-11-29 | 2009-11-29 | 2009-11-29 | | |
290
- | King Size | 94 | 2009-11-29 | | 2009-11-29 | | true |
289
+ | Single Standard | 94 | 2009-11-29 | 2009-11-29 | 2009-11-29 | MAX DATE | |
290
+ | King Size | 94 | 2009-11-29 | | 2009-11-29 | MAX DATE | true |
291
291
  }
292
292
  end
293
293
  it "allows eager loading with conditions on current version" do
@@ -0,0 +1,317 @@
1
+ require "spec_helper"
2
+
3
+ describe "Sequel::Plugins::Bitemporal" do
4
+ let(:hour){ 3600 }
5
+ before :all do
6
+ DB.create_table! :rooms do
7
+ primary_key :id
8
+ end
9
+ DB.create_table! :room_versions do
10
+ primary_key :id
11
+ foreign_key :master_id, :rooms
12
+ String :name
13
+ Fixnum :price
14
+ Time :created_at
15
+ Time :expired_at
16
+ Time :valid_from
17
+ Time :valid_to
18
+ end
19
+ @version_class = Class.new Sequel::Model do
20
+ set_dataset :room_versions
21
+ def validate
22
+ super
23
+ errors.add(:name, "is required") unless name
24
+ errors.add(:price, "is required") unless price
25
+ end
26
+ end
27
+ closure = @version_class
28
+ @master_class = Class.new Sequel::Model do
29
+ set_dataset :rooms
30
+ plugin :bitemporal, version_class: closure
31
+ end
32
+ end
33
+ before do
34
+ Timecop.freeze 2009, 11, 28, 10
35
+ end
36
+ after do
37
+ Timecop.return
38
+ @master_class.truncate
39
+ @version_class.truncate
40
+ end
41
+ it "checks version class is given" do
42
+ lambda{
43
+ @version_class.plugin :bitemporal
44
+ }.should raise_error Sequel::Error, "please specify version class to use for bitemporal plugin"
45
+ end
46
+ it "checks required columns are present" do
47
+ lambda{
48
+ @version_class.plugin :bitemporal, :version_class => @master_class
49
+ }.should raise_error Sequel::Error, "bitemporal plugin requires the following missing columns on version class: master_id, valid_from, valid_to, created_at, expired_at"
50
+ end
51
+ it "propagates errors from version to master" do
52
+ master = @master_class.new
53
+ master.should be_valid
54
+ master.attributes = {name: "Single Standard"}
55
+ master.should_not be_valid
56
+ master.errors.should == {price: ["is required"]}
57
+ end
58
+ it "#update_attributes returns false instead of raising errors" do
59
+ master = @master_class.new
60
+ master.update_attributes(name: "Single Standard").should be_false
61
+ master.should be_new
62
+ master.errors.should == {price: ["is required"]}
63
+ master.update_attributes(price: 98).should be_true
64
+ end
65
+ it "allows creating a master and its first version in one step" do
66
+ master = @master_class.new
67
+ master.update_attributes(name: "Single Standard", price: 98).should be_true
68
+ master.should_not be_new
69
+ master.should have_versions %Q{
70
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
71
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | MAX TIME | true |
72
+ }
73
+ end
74
+ it "allows creating a new version in the past" do
75
+ master = @master_class.new
76
+ master.update_attributes name: "Single Standard", price: 98, valid_from: Time.now-hour
77
+ master.should have_versions %Q{
78
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
79
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 09:00:00 +0100 | MAX TIME | true |
80
+ }
81
+ end
82
+ it "allows creating a new version in the future" do
83
+ master = @master_class.new
84
+ master.update_attributes name: "Single Standard", price: 98, valid_from: Time.now+hour
85
+ master.should have_versions %Q{
86
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
87
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | MAX TIME | |
88
+ }
89
+ end
90
+ it "doesn't loose previous version in same-day update" do
91
+ master = @master_class.new
92
+ master.update_attributes name: "Single Standard", price: 98
93
+ master.update_attributes name: "Single Standard", price: 94
94
+ master.should have_versions %Q{
95
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
96
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
97
+ | Single Standard | 94 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | MAX TIME | true |
98
+ }
99
+ end
100
+ it "allows partial updating based on current version" do
101
+ master = @master_class.new
102
+ master.update_attributes name: "Single Standard", price: 98
103
+ master.update_attributes price: 94, partial_update: true
104
+ master.update_attributes name: "King Size", partial_update: true
105
+ master.should have_versions %Q{
106
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
107
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
108
+ | Single Standard | 94 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
109
+ | King Size | 94 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | MAX TIME | true |
110
+ }
111
+ end
112
+ it "expires previous version but keep it in history" do
113
+ master = @master_class.new
114
+ master.update_attributes name: "Single Standard", price: 98
115
+ Timecop.freeze Time.now+hour
116
+ master.update_attributes price: 94, partial_update: true
117
+ master.should have_versions %Q{
118
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
119
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
120
+ | Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
121
+ | Single Standard | 94 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | MAX TIME | true |
122
+ }
123
+ end
124
+ it "doesn't expire no longer valid versions" do
125
+ master = @master_class.new
126
+ master.update_attributes name: "Single Standard", price: 98, valid_to: Time.now+hour
127
+ Timecop.freeze Time.now+hour
128
+ master.update_attributes(price: 94, partial_update: true).should be_false
129
+ master.update_attributes name: "Single Standard", price: 94
130
+ master.should have_versions %Q{
131
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
132
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
133
+ | Single Standard | 94 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | MAX TIME | true |
134
+ }
135
+ end
136
+ it "allows shortening validity (SEE COMMENTS FOR IMPROVEMENTS)" do
137
+ master = @master_class.new
138
+ master.update_attributes name: "Single Standard", price: 98
139
+ Timecop.freeze Time.now+hour
140
+ master.update_attributes valid_to: Time.now+10*hour, partial_update: true
141
+ master.should have_versions %Q{
142
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
143
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
144
+ | Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
145
+ | Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | 2009-11-28 21:00:00 +0100 | true |
146
+ }
147
+ # would be even better if it could be:
148
+ # | name | price | created_at | expired_at | valid_from | valid_to | current |
149
+ # | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
150
+ # | Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 21:00:00 +0100 | true |
151
+ end
152
+ it "allows extending validity (SEE COMMENTS FOR IMPROVEMENTS)" do
153
+ master = @master_class.new
154
+ master.update_attributes name: "Single Standard", price: 98, valid_to: Time.now+2*hour
155
+ Timecop.freeze Time.now+hour
156
+ master.should have_versions %Q{
157
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
158
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | true |
159
+ }
160
+ master.update_attributes valid_to: nil, partial_update: true
161
+ master.should have_versions %Q{
162
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
163
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | |
164
+ | Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
165
+ | Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | MAX TIME | true |
166
+ }
167
+ # would be even better if it could be:
168
+ # | name | price | created_at | expired_at | valid_from | valid_to | current |
169
+ # | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | |
170
+ # | Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | MAX TIME | true |
171
+ end
172
+ xit "doesn't do anything if unchanged" do
173
+ end
174
+ it "overrides no future versions" do
175
+ master = @master_class.new
176
+ master.update_attributes name: "Single Standard", price: 98, valid_to: Time.now+2*hour
177
+ master.update_attributes name: "Single Standard", price: 94, valid_from: Time.now+2*hour, valid_to: Time.now+4*hour
178
+ master.update_attributes name: "Single Standard", price: 95, valid_from: Time.now+4*hour, valid_to: Time.now+6*hour
179
+ Timecop.freeze Time.now+hour
180
+ master.update_attributes name: "King Size", valid_to: nil, partial_update: true
181
+ master.should have_versions %Q{
182
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
183
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | |
184
+ | Single Standard | 94 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 12:00:00 +0100 | 2009-11-28 14:00:00 +0100 | |
185
+ | Single Standard | 95 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 14:00:00 +0100 | 2009-11-28 16:00:00 +0100 | |
186
+ | Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
187
+ | King Size | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | 2009-11-28 12:00:00 +0100 | true |
188
+ }
189
+ end
190
+ it "overrides multiple future versions" do
191
+ master = @master_class.new
192
+ master.update_attributes name: "Single Standard", price: 98, valid_to: Time.now+2*hour
193
+ master.update_attributes name: "Single Standard", price: 94, valid_from: Time.now+2*hour, valid_to: Time.now+4*hour
194
+ master.update_attributes name: "Single Standard", price: 95, valid_from: Time.now+4*hour, valid_to: Time.now+6*hour
195
+ Timecop.freeze Time.now+hour
196
+ master.update_attributes name: "King Size", valid_to: Time.now+4*hour, partial_update: true
197
+ master.should have_versions %Q{
198
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
199
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | |
200
+ | Single Standard | 94 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 12:00:00 +0100 | 2009-11-28 14:00:00 +0100 | |
201
+ | Single Standard | 95 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 14:00:00 +0100 | 2009-11-28 16:00:00 +0100 | |
202
+ | Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
203
+ | Single Standard | 95 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 15:00:00 +0100 | 2009-11-28 16:00:00 +0100 | |
204
+ | King Size | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | 2009-11-28 15:00:00 +0100 | true |
205
+ }
206
+ end
207
+ it "overrides all future versions" do
208
+ master = @master_class.new
209
+ master.update_attributes name: "Single Standard", price: 98, valid_to: Time.now+2*hour
210
+ master.update_attributes name: "Single Standard", price: 94, valid_from: Time.now+2*hour, valid_to: Time.now+4*hour
211
+ master.update_attributes name: "Single Standard", price: 95, valid_from: Time.now+4*hour, valid_to: Time.now+6*hour
212
+ Timecop.freeze Time.now+hour
213
+ master.update_attributes name: "King Size", valid_to: Time.utc(9999), partial_update: true
214
+ master.should have_versions %Q{
215
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
216
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | |
217
+ | Single Standard | 94 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 12:00:00 +0100 | 2009-11-28 14:00:00 +0100 | |
218
+ | Single Standard | 95 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 14:00:00 +0100 | 2009-11-28 16:00:00 +0100 | |
219
+ | Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
220
+ | King Size | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | MAX TIME | true |
221
+ }
222
+ end
223
+ it "allows deleting current version" do
224
+ master = @master_class.new
225
+ master.update_attributes name: "Single Standard", price: 98
226
+ master.update_attributes name: "Single Standard", price: 94, valid_from: Time.now+2*hour
227
+ Timecop.freeze Time.now+hour
228
+ master.current_version.destroy.should be_true
229
+ master.should have_versions %Q{
230
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
231
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
232
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | |
233
+ | Single Standard | 94 | 2009-11-28 10:00:00 +0100 | | 2009-11-28 12:00:00 +0100 | MAX TIME | |
234
+ | Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
235
+ }
236
+ end
237
+ it "allows deleting a future version" do
238
+ master = @master_class.new
239
+ master.update_attributes name: "Single Standard", price: 98
240
+ master.update_attributes name: "Single Standard", price: 94, valid_from: Time.now+2*hour
241
+ Timecop.freeze Time.now+hour
242
+ master.versions.last.destroy.should be_true
243
+ master.should have_versions %Q{
244
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
245
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
246
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | |
247
+ | Single Standard | 94 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 12:00:00 +0100 | MAX TIME | |
248
+ | Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | MAX TIME | true |
249
+ }
250
+ end
251
+ it "allows deleting all versions" do
252
+ master = @master_class.new
253
+ master.update_attributes name: "Single Standard", price: 98
254
+ master.update_attributes name: "Single Standard", price: 94, valid_from: Time.now+2*hour
255
+ Timecop.freeze Time.now+hour
256
+ master.destroy.should be_true
257
+ master.should have_versions %Q{
258
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
259
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
260
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | 2009-11-28 12:00:00 +0100 | |
261
+ | Single Standard | 94 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 12:00:00 +0100 | MAX TIME | |
262
+ }
263
+ end
264
+ it "allows simultaneous updates without information loss" do
265
+ master = @master_class.new
266
+ master.update_attributes name: "Single Standard", price: 98
267
+ Timecop.freeze Time.now+hour
268
+ master2 = @master_class.find id: master.id
269
+ master.update_attributes name: "Single Standard", price: 94
270
+ master2.update_attributes name: "Single Standard", price: 95
271
+ master.should have_versions %Q{
272
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
273
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
274
+ | Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
275
+ | Single Standard | 94 | 2009-11-28 11:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 11:00:00 +0100 | MAX TIME | |
276
+ | Single Standard | 95 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | MAX TIME | true |
277
+ }
278
+ end
279
+ it "allows simultaneous cumulative updates" do
280
+ master = @master_class.new
281
+ master.update_attributes name: "Single Standard", price: 98
282
+ Timecop.freeze Time.now+hour
283
+ master2 = @master_class.find id: master.id
284
+ master.update_attributes price: 94, partial_update: true
285
+ master2.update_attributes name: "King Size", partial_update: true
286
+ master.should have_versions %Q{
287
+ | name | price | created_at | expired_at | valid_from | valid_to | current |
288
+ | Single Standard | 98 | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 10:00:00 +0100 | MAX TIME | |
289
+ | Single Standard | 98 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 10:00:00 +0100 | 2009-11-28 11:00:00 +0100 | |
290
+ | Single Standard | 94 | 2009-11-28 11:00:00 +0100 | 2009-11-28 11:00:00 +0100 | 2009-11-28 11:00:00 +0100 | MAX TIME | |
291
+ | King Size | 94 | 2009-11-28 11:00:00 +0100 | | 2009-11-28 11:00:00 +0100 | MAX TIME | true |
292
+ }
293
+ end
294
+ it "allows eager loading with conditions on current version" do
295
+ master = @master_class.new
296
+ master.update_attributes name: "Single Standard", price: 98
297
+ master.update_attributes name: "Single Standard", price: 94, valid_from: Time.now+2*hour
298
+ @master_class.eager_graph(:current_version).where("current_version.id IS NOT NULL").first.should be
299
+ Timecop.freeze Time.now+hour
300
+ master.destroy
301
+ @master_class.eager_graph(:current_version).where("current_version.id IS NOT NULL").first.should be_nil
302
+ end
303
+ it "gets pending or current version attributes" do
304
+ master = @master_class.new
305
+ master.attributes.should == {}
306
+ master.pending_version.should be_nil
307
+ master.pending_or_current_version.should be_nil
308
+ master.update_attributes name: "Single Standard", price: 98
309
+ master.attributes[:name].should == "Single Standard"
310
+ master.pending_version.should be_nil
311
+ master.pending_or_current_version.name.should == "Single Standard"
312
+ master.attributes = {name: "King Size"}
313
+ master.attributes[:name].should == "King Size"
314
+ master.pending_version.should be
315
+ master.pending_or_current_version.name.should == "King Size"
316
+ end
317
+ end
@@ -9,15 +9,20 @@ RSpec::Matchers.define :have_versions do |versions_str|
9
9
  @last_version = version
10
10
  master_version = versions[index]
11
11
  [:name, :price, :valid_from, :valid_to, :created_at, :expired_at, :current].all? do |column|
12
- expected = version[column.to_s]
13
- case column
14
- when :valid_to
15
- expected = "9999-01-01"
16
- when :current
17
- expected = "false"
18
- end if expected==""
19
- found = master_version.send(column == :current ? "current?" : column).to_s
20
- equal = found == expected
12
+ if column==:current
13
+ found = master_version.current?
14
+ expected = (version[column.to_s]=="true").to_s
15
+ else
16
+ found = master_version.send column
17
+ expected = version[column.to_s]
18
+ case expected
19
+ when "MAX DATE"
20
+ expected = "9999-01-01"
21
+ when "MAX TIME"
22
+ expected = "9999-01-01 01:00:00 +0100"
23
+ end
24
+ end
25
+ equal = found.to_s == expected
21
26
  puts "#{column}: #{found} != #{expected}" unless equal
22
27
  equal
23
28
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel_bitemporal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-04 00:00:00.000000000Z
12
+ date: 2011-11-07 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sqlite3
16
- requirement: &2158074720 !ruby/object:Gem::Requirement
16
+ requirement: &2157615300 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *2158074720
24
+ version_requirements: *2157615300
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &2158074280 !ruby/object:Gem::Requirement
27
+ requirement: &2157614860 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2158074280
35
+ version_requirements: *2157614860
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: timecop
38
- requirement: &2158073860 !ruby/object:Gem::Requirement
38
+ requirement: &2157614440 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2158073860
46
+ version_requirements: *2157614440
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: sequel
49
- requirement: &2158073440 !ruby/object:Gem::Requirement
49
+ requirement: &2157614020 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *2158073440
57
+ version_requirements: *2157614020
58
58
  description: Bitemporal versioning for sequel, fully tested.
59
59
  email:
60
60
  - joseph.halter@thetalentbox.com
@@ -69,7 +69,8 @@ files:
69
69
  - lib/sequel/plugins/bitemporal.rb
70
70
  - lib/sequel_bitemporal.rb
71
71
  - sequel_bitemporal.gemspec
72
- - spec/bitemporal_spec.rb
72
+ - spec/bitemporal_date_spec.rb
73
+ - spec/bitemporal_time_spec.rb
73
74
  - spec/spec_helper.rb
74
75
  - spec/support/bitemporal_matchers.rb
75
76
  homepage: https://github.com/TalentBox/sequel_bitemporal
@@ -97,6 +98,7 @@ signing_key:
97
98
  specification_version: 3
98
99
  summary: Bitemporal versioning for sequel.
99
100
  test_files:
100
- - spec/bitemporal_spec.rb
101
+ - spec/bitemporal_date_spec.rb
102
+ - spec/bitemporal_time_spec.rb
101
103
  - spec/spec_helper.rb
102
104
  - spec/support/bitemporal_matchers.rb