sequel_bitemporal 0.1.6 → 0.1.7

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.
@@ -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