Functional Weave
Code in TypeScript

construction.timber-length@1.0.0

vectors.json

5,894 bytes · view raw

[
  {
    "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"
  }
]