You could add a method to determine source trails. Potential
extensions:
- a filter for which original sources to include
def _source_trails(trails=[], &block)
case @source
when Audit
@source._source_trails(trails, &block)
when Array
@source.collect do |audit|
trails.concat audit._source_trails(&block)
end
when nil
trails << []
end
trails.each do |trail|
trail.push(block_given? ? block.call(self) : self)
end
trails
end
Tests:
#
# _source_trails test
#
def test__source_trails_with_sequence
a = Audit.new(:a, 'one')
b = Audit.new(:b, 'two', a)
c = Audit.new(:c, 'three', b)
assert_equal [[a, b, c]], c._source_trails
end
def test__source_trails_collects_block_return
a = Audit.new(:a, 'one')
b = Audit.new(:b, 'two', a)
c = Audit.new(:c, 'three', b)
assert_equal [[:a, :b, :c]], c._source_trails {|audit| audit.key }
end
def test__source_trails_with_fork_and_merge
a = Audit.new(:a, 'one')
b = Audit.new(:b, 'two', a)
c = Audit.new(:c, 'three', a)
d = Audit.new(:d, 'four')
e = Audit.new(:e, 'five', [c,d])
f = Audit.new(:f, 'six')
g = Audit.new(:g, 'seven', [b,e,f])
assert_equal [
[:a, :b, :g],
[:a, :c, :e, :g],
[:d, :e, :g],
[:f, :g]
], g._source_trails {|audit| audit.key }
end