Skip to content

Commit

Permalink
Add Safe As Of feature
Browse files Browse the repository at this point in the history
  • Loading branch information
tagliala committed Jun 2, 2022
1 parent 536c7bf commit 876e765
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 7 deletions.
1 change: 1 addition & 0 deletions lib/chrono_model/time_gate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module TimeGate
include ChronoModel::Patches::AsOfTimeHolder

module ClassMethods
include ChronoModel::TimeMachine::SafeAsOf
include ChronoModel::TimeMachine::Timeline

def as_of(time)
Expand Down
3 changes: 3 additions & 0 deletions lib/chrono_model/time_machine.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'chrono_model/time_machine/safe_as_of'
require 'chrono_model/time_machine/time_query'
require 'chrono_model/time_machine/timeline'
require 'chrono_model/time_machine/history_model'
Expand Down Expand Up @@ -63,6 +64,8 @@ def self.define_history_model_for(model)
end

module ClassMethods
include ChronoModel::TimeMachine::SafeAsOf

# Identify this class as the parent, non-history, class.
#
def history?
Expand Down
15 changes: 15 additions & 0 deletions lib/chrono_model/time_machine/safe_as_of.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

module ChronoModel
module TimeMachine
module SafeAsOf
def safe_as_of(time)
if time.present?
as_of(time)
else
all
end
end
end
end
end
2 changes: 1 addition & 1 deletion spec/chrono_model/time_machine/as_of_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

it { expect(Foo.as_of($t.foos[0].ts[0])).to eq [$t.foo, $t.foos[0]] }
it { expect(Foo.as_of($t.foos[1].ts[0])).to eq [$t.foo, $t.foos[0], $t.foos[1]] }
it { expect(Foo.as_of(Time.now)).to eq [$t.foo, $t.foos[0], $t.foos[1]] }
it { expect(Foo.as_of(Time.now)).to eq [$t.foo, $t.foos[0], $t.foos[1], $t.goo_foos[0], $t.goo_foos[1]] }

it { expect(Bar.as_of($t.foos[1].ts[0])).to eq [$t.bar] }

Expand Down
2 changes: 1 addition & 1 deletion spec/chrono_model/time_machine/history_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

describe '.history' do
let(:foo_history) {
['foo', 'foo bar', 'new foo', 'foo 0', 'foo 1']
['foo', 'foo bar', 'new foo', 'foo 0', 'foo 1', 'goo foo 0', 'goo foo 1']
}

let(:bar_history) {
Expand Down
2 changes: 1 addition & 1 deletion spec/chrono_model/time_machine/keep_cool_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
include ChronoTest::TimeMachine::Helpers

describe 'does not interfere with AR standard behaviour' do
let(:all_foos) { [$t.foo] + $t.foos }
let(:all_foos) { [$t.foo] + $t.foos + $t.goo_foos }
let(:all_bars) { [$t.bar] + $t.bars }

it { expect(Foo.count).to eq all_foos.size }
Expand Down
14 changes: 14 additions & 0 deletions spec/chrono_model/time_machine/safe_as_of_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require 'spec_helper'
require 'support/time_machine/structure'

describe ChronoModel::TimeMachine do
include ChronoTest::TimeMachine::Helpers

describe '.safe_as_of' do
it { expect(Foo.safe_as_of($t.foos[0].ts[0])).to eq Foo.as_of($t.foos[0].ts[0]) }
it { expect(Foo.safe_as_of(nil)).to eq Foo.all }

it { expect(FooGoo.safe_as_of($t.goo_foos[0].ts[0]).first.foos).to eq $t.goo.as_of($t.goo_foos[0].ts[0]).foos }
it { expect(FooGoo.safe_as_of(nil).first.foos).to eq $t.goo.foos }
end
end
4 changes: 2 additions & 2 deletions spec/chrono_model/time_machine/time_query_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ class ::Event < ActiveRecord::Base

# Main timeline quick test
#
it { expect(Foo.history.time_query(:after, :now, inclusive: true).count).to eq 3 }
it { expect(Foo.history.time_query(:after, :now, inclusive: true).count).to eq 5 }
it { expect(Foo.history.time_query(:after, :now, inclusive: false).count).to eq 0 }
it { expect(Foo.history.time_query(:before, :now, inclusive: true).count).to eq 5 }
it { expect(Foo.history.time_query(:before, :now, inclusive: true).count).to eq 7 }
it { expect(Foo.history.time_query(:before, :now, inclusive: false).count).to eq 2 }

it { expect(Foo.history.past.size).to eq 2 }
Expand Down
7 changes: 5 additions & 2 deletions spec/support/time_machine/structure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class ::Foo < ActiveRecord::Base
class ::FooGoo < ActiveRecord::Base
include ChronoModel::TimeGate

has_many :foos, inverse_of: :goo
has_many :foos, inverse_of: :goo, foreign_key: :goo_id
end

class ::Moo < ActiveRecord::Base
Expand All @@ -126,7 +126,7 @@ class ::SubSubBar < ActiveRecord::Base
# Master timeline, used in multiple specs. It is defined here
# as a global variable to be able to be shared across specs.
#
$t = Struct.new(:foo, :bar, :baz, :subbar, :foos, :bars, :boos, :moos).new
$t = Struct.new(:foo, :bar, :baz, :subbar, :foos, :bars, :boos, :moos, :goo, :goo_foos).new

# Set up associated records, with intertwined updates
#
Expand Down Expand Up @@ -155,4 +155,7 @@ class ::SubSubBar < ActiveRecord::Base
$t.moos = Array.new(2) { |i| ts_eval { Moo.create! name: "moo #{i}", boos: $t.boos } }

$t.baz = Baz.create! name: 'baz', bar: $t.bar

$t.goo = FooGoo.create! name: 'goo'
$t.goo_foos = Array.new(2) { |i| ts_eval { Foo.create! name: "goo foo #{i}", goo: $t.goo } }
end

0 comments on commit 876e765

Please sign in to comment.