[
{ "name": "100 good units at 95% need 105.26, so 106 starts and 6 allowed as scrap", "args": [100, 9500], "expect": { "input": 106, "scrap": 6 } },
{ "name": "95 good units at 95% need exactly 100 starts", "args": [95, 9500], "expect": { "input": 100, "scrap": 5 } },
{ "name": "563 good units at 56.3% need exactly 1000 starts; 563 / 0.563 in floating point is 1000.0000000000001, whose ceiling is 1001", "args": [563, 5630], "expect": { "input": 1000, "scrap": 437 } },
{ "name": "57 at 90% need 63.33, so 64", "args": [57, 9000], "expect": { "input": 64, "scrap": 7 } },
{ "name": "a 100% yield needs no allowance", "args": [250, 10000], "expect": { "input": 250, "scrap": 0 } },
{ "name": "a tiny shortfall still costs a whole start: 1000 at 99.99% need 1000.1, so 1001", "args": [1000, 9999], "expect": { "input": 1001, "scrap": 1 } },
{ "name": "one good unit at 30% needs 3.33, so 4 starts", "args": [1, 3000], "expect": { "input": 4, "scrap": 3 } },
{ "name": "the lowest yield, 0.01%: one good unit needs 10000 starts", "args": [1, 1], "expect": { "input": 10000, "scrap": 9999 } },
{ "name": "zero output needs no input", "args": [0, 8000], "expect": { "input": 0, "scrap": 0 } },
{ "name": "a 50% yield doubles the input exactly", "args": [37, 5000], "expect": { "input": 74, "scrap": 37 } },
{ "name": "a zero yield is an error: nothing good ever comes out", "args": [100, 0], "expectError": "yieldBasisPoints must be a whole number from 1 to 10000" },
{ "name": "a yield over 100% is an error", "args": [100, 10001], "expectError": "yieldBasisPoints must be a whole number from 1 to 10000" },
{ "name": "a negative output is an error", "args": [-5, 9500], "expectError": "requiredOutput must be a whole number of units" },
{ "name": "a fractional output is an error", "args": [10.5, 9500], "expectError": "requiredOutput must be a whole number of units" },
{ "name": "a fractional yield is an error", "args": [100, 9500.5], "expectError": "yieldBasisPoints must be a whole number from 1 to 10000" }
]