[ { "name": "three 1200s need two 3600 lengths once the kerf is counted", "args": [ [ 1200, 1200, 1200 ], 3600, 3 ], "expect": { "bars": [ { "cuts": [ 1200, 1200 ], "offcut": 1194 }, { "cuts": [ 1200 ], "offcut": 2397 } ], "barCount": 2, "waste": 3600 } }, { "name": "with no kerf three 1200s fill one 3600 exactly", "args": [ [ 1200, 1200, 1200 ], 3600, 0 ], "expect": { "bars": [ { "cuts": [ 1200, 1200, 1200 ], "offcut": 0 } ], "barCount": 1, "waste": 0 } }, { "name": "first-fit decreasing fills earlier bars before opening a new one", "args": [ [ 600, 1800, 1200, 1200, 600 ], 2400, 0 ], "expect": { "bars": [ { "cuts": [ 1800, 600 ], "offcut": 0 }, { "cuts": [ 1200, 1200 ], "offcut": 0 }, { "cuts": [ 600 ], "offcut": 1800 } ], "barCount": 3, "waste": 1800 } }, { "name": "the last piece may end at the end of the bar without a final cut", "args": [ [ 1197, 1200 ], 2400, 3 ], "expect": { "bars": [ { "cuts": [ 1200, 1197 ], "offcut": 0 } ], "barCount": 1, "waste": 3 } }, { "name": "less than a kerf left over is dust, not an offcut", "args": [ [ 1198, 1198 ], 2400, 3 ], "expect": { "bars": [ { "cuts": [ 1198, 1198 ], "offcut": 0 } ], "barCount": 1, "waste": 4 } }, { "name": "a piece as long as the stock takes the whole bar", "args": [ [ 2400 ], 2400, 3 ], "expect": { "bars": [ { "cuts": [ 2400 ], "offcut": 0 } ], "barCount": 1, "waste": 0 } }, { "name": "a mixed stud and nogging list from 4800 lengths", "args": [ [ 2400, 2400, 1500, 1500, 1500, 900, 900, 300 ], 4800, 4 ], "expect": { "bars": [ { "cuts": [ 2400, 1500, 300 ], "offcut": 588 }, { "cuts": [ 2400, 1500 ], "offcut": 892 }, { "cuts": [ 1500, 900, 900 ], "offcut": 1488 } ], "barCount": 3, "waste": 3000 } }, { "name": "input order does not change the plan", "args": [ [ 300, 900, 1500, 2400, 900, 1500, 2400, 1500 ], 4800, 4 ], "expect": { "bars": [ { "cuts": [ 2400, 1500, 300 ], "offcut": 588 }, { "cuts": [ 2400, 1500 ], "offcut": 892 }, { "cuts": [ 1500, 900, 900 ], "offcut": 1488 } ], "barCount": 3, "waste": 3000 } }, { "name": "a single short piece leaves the rest of the bar as offcut", "args": [ [ 450 ], 3000, 5 ], "expect": { "bars": [ { "cuts": [ 450 ], "offcut": 2545 } ], "barCount": 1, "waste": 2550 } }, { "name": "nothing to cut buys nothing", "args": [ [], 4800, 3 ], "expect": { "bars": [], "barCount": 0, "waste": 0 } }, { "name": "a wide kerf pushes a piece onto a new bar", "args": [ [ 1000, 1000 ], 2020, 25 ], "expect": { "bars": [ { "cuts": [ 1000 ], "offcut": 995 }, { "cuts": [ 1000 ], "offcut": 995 } ], "barCount": 2, "waste": 2040 } }, { "name": "a cut longer than the stock is an error", "args": [ [ 2000, 4000 ], 3600, 3 ], "expectError": "cut 2 (4000 mm) is longer than the stock length (3600 mm)" }, { "name": "a zero-length cut is an error", "args": [ [ 0 ], 3600, 3 ], "expectError": "cut 1 must be a whole number of millimetres greater than 0" }, { "name": "a fractional cut is an error", "args": [ [ 1.5 ], 3600, 3 ], "expectError": "cut 1 must be a whole number of millimetres greater than 0" }, { "name": "a negative kerf is an error", "args": [ [ 100 ], 3600, -1 ], "expectError": "kerf must be a whole number of millimetres, 0 or more" }, { "name": "a zero stock length is an error", "args": [ [ 100 ], 0, 3 ], "expectError": "stockLength must be a whole number of millimetres greater than 0" } ]