39 lines
1.8 KiB
Python
39 lines
1.8 KiB
Python
from datetime import date
|
|
from decimal import Decimal as D
|
|
|
|
from app.services.pl_quota_allocation import SourceDemand, PermitCandidate
|
|
|
|
|
|
def permit(id, qty, products, unit='吨', refs=frozenset()):
|
|
return PermitCandidate(id, D(qty), unit, date.max, frozenset(products), refs)
|
|
|
|
|
|
def test_shared_capacity_is_counted_once_per_kind_and_unit():
|
|
from app.services.pl_quota_diagnostics import allocation_diagnostics
|
|
sources = [SourceDemand('a', 'a', D('20'), '吨'), SourceDemand('b', 'b', D('10'), '吨')]
|
|
rows = allocation_diagnostics(sources, [permit('p', '25', ['a', 'b'])], [])
|
|
purchase = rows[0]
|
|
assert purchase['demand'] == '30' and purchase['availableUpperBound'] == '25'
|
|
assert purchase['gapLowerBound'] == '5' and purchase['unit'] == '吨'
|
|
assert rows[1]['gapLowerBound'] == '30'
|
|
|
|
|
|
def test_foreign_unit_is_not_summed_or_implicitly_converted():
|
|
from app.services.pl_quota_diagnostics import allocation_diagnostics
|
|
rows = allocation_diagnostics([SourceDemand('a', 'a', D('30'), '吨')], [permit('p', '1000', ['a'], '千克')], [])
|
|
assert rows[0]['availableUpperBound'] is None and rows[0]['gapLowerBound'] is None
|
|
assert '人工' in rows[0]['reason']
|
|
|
|
|
|
def test_sufficient_totals_do_not_claim_joint_feasibility():
|
|
from app.services.pl_quota_diagnostics import allocation_diagnostics
|
|
rows = allocation_diagnostics([SourceDemand('a', 'a', D('30'), '吨')], [permit('p', '40', ['a'])], [permit('t', '40', ['a'])])
|
|
assert rows[0]['gapLowerBound'] == '0'
|
|
assert all('引用' in row['reason'] for row in rows)
|
|
|
|
|
|
def test_out_of_scope_balance_does_not_inflate_available():
|
|
from app.services.pl_quota_diagnostics import allocation_diagnostics
|
|
rows = allocation_diagnostics([SourceDemand('a', 'a', D('30'), '吨')], [permit('p', '100', ['b'])], [])
|
|
assert rows[0]['availableUpperBound'] == '0'
|