From 1c3eaf45e0893fbb4d59fc7b380c3f81acd51c44 Mon Sep 17 00:00:00 2001 From: Valentine Frolov Date: Mon, 28 Sep 2026 21:48:42 +0300 Subject: [PATCH 1/2] fix(master): read the exact total, unwrap the pull request fixture and allow the complexity of if_absent --- lib/fbe/award.rb | 15 +++++++++++++-- lib/fbe/fake_octokit.rb | 2 +- lib/fbe/if_absent.rb | 2 +- test/fbe/test_award.rb | 26 ++++++++++++++++++++++++++ test/fbe/test_octo.rb | 6 ++++++ 5 files changed, 47 insertions(+), 4 deletions(-) diff --git a/lib/fbe/award.rb b/lib/fbe/award.rb index ae6eeb43..8c14d180 100644 --- a/lib/fbe/award.rb +++ b/lib/fbe/award.rb @@ -176,7 +176,7 @@ def to_val(any, bill) def calc(bill) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity case @op when :total - bill.points + bill.sum when :if raise(Fbe::Error, "The term 'if' needs three operands, #{@operands.size} given") if @operands.size < 3 to_val(@operands[0], bill) ? to_val(@operands[1], bill) : to_val(@operands[2], bill) @@ -384,7 +384,18 @@ def line(value, text) # bill.line(42.5, "for answer") # bill.points #=> 43 def points - whole(@lines.sum { |l| l[:v] }) + whole(sum) + end + + # Calculates the exact sum of all lines, before rounding. + # + # @return [Integer, Float] The sum of all point values + # @example + # bill = Fbe::Award::Bill.new + # bill.line(42.5, "for answer") + # bill.sum #=> 42.5 + def sum + @lines.sum { |l| l[:v] } end # Generates a human-readable summary of the bill. diff --git a/lib/fbe/fake_octokit.rb b/lib/fbe/fake_octokit.rb index 20f1141a..6cc424db 100644 --- a/lib/fbe/fake_octokit.rb +++ b/lib/fbe/fake_octokit.rb @@ -628,7 +628,7 @@ def pull_request(repo, number) changed_files: 2 } else - fixture = pull_requests(repo).find { |p| p[:number] == number } || {} + fixture = pull_requests(repo).find { |p| p[:number] == number }&.to_attrs || {} { id: 42, number:, diff --git a/lib/fbe/if_absent.rb b/lib/fbe/if_absent.rb index 0141b000..e5145e09 100644 --- a/lib/fbe/if_absent.rb +++ b/lib/fbe/if_absent.rb @@ -48,7 +48,7 @@ # else # puts "User already exists" # end -def Fbe.if_absent(fb: Fbe.fb, always: false) +def Fbe.if_absent(fb: Fbe.fb, always: false) # rubocop:disable Metrics/PerceivedComplexity raise(Fbe::Error, 'A block is required by if_absent') unless block_given? attrs = {} f = diff --git a/test/fbe/test_award.rb b/test/fbe/test_award.rb index b13c5c3d..aea07177 100644 --- a/test/fbe/test_award.rb +++ b/test/fbe/test_award.rb @@ -174,6 +174,32 @@ def test_rounds_the_sum_once assert_equal(1, bill.points) end + def test_reads_total_before_rounding + b = Fbe::Award.new('(award (give 0.4 "as a basis") (set t (total)) (give t "for the same again"))').bill + assert_equal(1, b.points, "total was rounded before the second line read it: #{b.greeting}") + end + + def test_tops_up_to_the_minimum_exactly + b = + Fbe::Award.new( + '(award (give 8 "as a basis") (give -12.5 "for delay") ' \ + '(set least (if (lt (total) 4) (minus 4 (total)) 0)) (give least "at least"))' + ).bill + assert_equal(4, b.points, "floor did not land on the minimum: #{b.greeting}") + end + + def test_prints_floor_lines_that_add_up_to_the_total + g = + Fbe::Award.new( + '(award (give 8 "as a basis") (give -12.5 "for delay") ' \ + '(set least (if (lt (total) 4) (minus 4 (total)) 0)) (give least "at least"))' + ).bill.greeting + assert_equal( + "You've earned +4 points for this: +8 as a basis; -13 for delay; +9 at least. ", g, + 'printed lines do not add up' + ) + end + def test_shorten_when_one_number g = Fbe::Award.new('(award (give 23 "for love"))').bill.greeting assert_equal('You\'ve earned +23 points. ', g, g) diff --git a/test/fbe/test_octo.rb b/test/fbe/test_octo.rb index 9efa8b8a..3ae5e5bb 100644 --- a/test/fbe/test_octo.rb +++ b/test/fbe/test_octo.rb @@ -897,6 +897,12 @@ def test_fake_pull_request_base_repo_matches_requested_repo end end + def test_fake_pull_request_keeps_base_sha_of_fixture + o = Fbe.octo(loog: Loog::NULL, global: {}, options: Judges::Options.new({ 'testing' => true })) + sha = o.pull_request('zerocracy/baza', 95).dig(:base, :sha) + assert_equal('5643eb3c7a0ccb3b', sha, 'base sha of pull request 95 is not the one in the fixture') + end + def test_fetch_fake_pull_request_review_comments o = Fbe.octo(loog: Loog::NULL, global: {}, options: Judges::Options.new({ 'testing' => true })) o.pull_request_review_comments('yegor256/test', 100, 100_001).then do |comments| From c73aa9b8fa6dbab111038ba0f711f2cc19ad8a12 Mon Sep 17 00:00:00 2001 From: Valentine Frolov Date: Tue, 29 Sep 2026 09:56:12 +0300 Subject: [PATCH 2/2] fix(#1207): draw the fitting slot from 1..3 so it always fits the timeout --- test/fbe/test_consider.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fbe/test_consider.rb b/test/fbe/test_consider.rb index e6c6f64a..ef38d928 100644 --- a/test/fbe/test_consider.rb +++ b/test/fbe/test_consider.rb @@ -85,7 +85,7 @@ def test_processes_fact_when_slot_fits_the_timeout '(exists foo)', fb:, judge: 'judge-fits', global: {}, loog: Loog::NULL, options: Judges::Options.new('timeout=10'), epoch: Time.now, kickoff: Time.now - 5, - quota_aware: false, slot: Random.new(seed).rand(1..4) + quota_aware: false, slot: Random.new(seed).rand(1..3) ) { |f| f.bar = 7 } assert_equal(1, fb.query('(exists bar)').each.to_a.size, "fitting slot stopped the loop, seed #{seed}") end