Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions lib/fbe/overwrite.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,19 @@ def Fbe.overwrite(fact, property_or_hash, values = nil, fb: Fbe.fb, fid: '_id')
end
return unless modified
unless overwrites
property_or_hash.each do |k, vv|
sk = k.to_s
next unless fact[sk].nil?
vv = [vv] unless vv.is_a?(Array)
vv.each do |v|
fact.public_send(:"#{sk}=", v)
add =
lambda do |target|
property_or_hash.each do |k, vv|
next unless target[k.to_s].nil?
(vv.is_a?(Array) ? vv : [vv]).each { |v| target.public_send(:"#{k}=", v) }
end
end
id = fact[fid]&.first
if id.nil?
add.call(fact)
else
fb.txn do |fbt|
add.call(fbt.query("(eq #{fid} #{id})").each.first || raise(Fbe::Error, "No facts by #{fid} = #{id}"))
end
end
return
Expand Down
47 changes: 47 additions & 0 deletions test/fbe/test_overwrite.rb
Original file line number Diff line number Diff line change
Expand Up @@ -467,4 +467,51 @@ def test_returns_nil_when_something_changes
f = fb.query('(always)').each.first
assert_nil(Fbe.overwrite(f, { 'foo' => 'q' }, fb:))
end

def test_adds_pair_of_properties_that_rules_accept_only_together
seed = Random.new_seed
repo = Random.new(seed).rand(1..1_000_000)
fbx = Fbe.fb(fb: Factbase.new, global: {}, options: Judges::Options.new, loog: Loog::NULL)
f = fbx.insert
f.what = 'foo-bar'
Fbe.overwrite(f, { repository: repo, where: 'github' }, fb: fbx)
assert_equal([repo], fbx.query('(always)').each.first['repository'], "pair is not added, seed #{seed}")
end

def test_leaves_fact_untouched_when_added_properties_break_rules
seed = Random.new_seed
repo = Random.new(seed).rand(1..1_000_000)
fbx = Fbe.fb(fb: Factbase.new, global: {}, options: Judges::Options.new, loog: Loog::NULL)
f = fbx.insert
f.what = 'foo-bar'
begin
Fbe.overwrite(f, { repository: repo, where: 'bitbucket' }, fb: fbx)
rescue StandardError
nil
end
assert_nil(fbx.query('(always)').each.first['repository'], "half of a broken pair is kept, seed #{seed}")
end

def test_adds_properties_in_place_to_fact_without_id
seed = Random.new_seed
count = Random.new(seed).rand(1..1_000_000)
fb = Factbase.new
f = fb.insert
f.what = 'ñame'
Fbe.overwrite(f, { count:, tag: 'ü' }, fb:)
assert_equal([count], fb.query('(always)').each.first['count'], "property is not added, seed #{seed}")
end

def test_cannot_add_properties_to_fact_that_is_gone
seed = Random.new_seed
id = Random.new(seed).rand(1..1_000_000)
fb = Factbase.new
f = fb.insert
f._id = id
f.what = 'gõne'
fb.query("(eq _id #{id})").delete!
assert_raises(Fbe::Error, "a deleted fact got new properties, seed #{seed}") do
Fbe.overwrite(f, { tag: 'ü' }, fb:)
end
end
end
Loading