fix: maintain FIFO queue even if outgoing_rate is not found (#30560)

This commit is contained in:
Ankush Menat 2022-04-04 15:22:15 +05:30 committed by GitHub
parent 52eb0a93bb
commit 12c01e2975
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 19 deletions

View File

@ -60,9 +60,9 @@ class TestFIFOValuation(unittest.TestCase):
self.queue.remove_stock(1, 5)
self.assertEqual(self.queue, [[-1, 5]])
# XXX
self.queue.remove_stock(1, 10)
self.queue.remove_stock(1)
self.assertTotalQty(-2)
self.assertEqual(self.queue, [[-2, 5]])
self.queue.add_stock(2, 10)
self.assertTotalQty(0)
@ -93,7 +93,7 @@ class TestFIFOValuation(unittest.TestCase):
self.queue.remove_stock(3, 20)
self.assertEqual(self.queue, [[1, 10], [5, 20]])
def test_collapsing_of_queue(self):
def test_queue_with_unknown_rate(self):
self.queue.add_stock(1, 1)
self.queue.add_stock(1, 2)
self.queue.add_stock(1, 3)
@ -102,8 +102,7 @@ class TestFIFOValuation(unittest.TestCase):
self.assertTotalValue(10)
self.queue.remove_stock(3, 1)
# XXX
self.assertEqual(self.queue, [[1, 7]])
self.assertEqual(self.queue, [[1, 4]])
def test_rounding_off(self):
self.queue.add_stock(1.0, 1.0)
@ -172,6 +171,32 @@ class TestFIFOValuation(unittest.TestCase):
self.assertTotalQty(total_qty)
self.assertTotalValue(total_value)
@given(stock_queue_generator, st.floats(min_value=0.1, max_value=1e6))
def test_fifo_qty_value_nonneg_hypothesis_with_outgoing_rate(self, stock_queue, outgoing_rate):
self.queue = FIFOValuation([])
total_qty = 0.0
total_value = 0.0
for qty, rate in stock_queue:
# don't allow negative stock
if qty == 0 or total_qty + qty < 0 or abs(qty) < 0.1:
continue
if qty > 0:
self.queue.add_stock(qty, rate)
total_qty += qty
total_value += qty * rate
else:
qty = abs(qty)
consumed = self.queue.remove_stock(qty, outgoing_rate)
self.assertAlmostEqual(
qty, sum(q for q, _ in consumed), msg=f"incorrect consumption {consumed}"
)
total_qty -= qty
total_value -= sum(q * r for q, r in consumed)
self.assertTotalQty(total_qty)
self.assertTotalValue(total_value)
self.assertGreaterEqual(total_value, 0)
class TestLIFOValuation(unittest.TestCase):
def setUp(self):

View File

@ -60,9 +60,7 @@ class FIFOValuation(BinWiseValuation):
# specifying the attributes to save resources
# ref: https://docs.python.org/3/reference/datamodel.html#slots
__slots__ = [
"queue",
]
__slots__ = ["queue"]
def __init__(self, state: Optional[List[StockBin]]):
self.queue: List[StockBin] = state if state is not None else []
@ -123,15 +121,9 @@ class FIFOValuation(BinWiseValuation):
index = idx
break
# If no entry found with outgoing rate, collapse queue
# If no entry found with outgoing rate, consume as per FIFO
if index is None: # nosemgrep
new_stock_value = sum(d[QTY] * d[RATE] for d in self.queue) - qty * outgoing_rate
new_stock_qty = sum(d[QTY] for d in self.queue) - qty
self.queue = [
[new_stock_qty, new_stock_value / new_stock_qty if new_stock_qty > 0 else outgoing_rate]
]
consumed_bins.append([qty, outgoing_rate])
break
index = 0
else:
index = 0
@ -172,9 +164,7 @@ class LIFOValuation(BinWiseValuation):
# specifying the attributes to save resources
# ref: https://docs.python.org/3/reference/datamodel.html#slots
__slots__ = [
"stack",
]
__slots__ = ["stack"]
def __init__(self, state: Optional[List[StockBin]]):
self.stack: List[StockBin] = state if state is not None else []