Skip to content

Commit

Permalink
Backport Rotation "enum", help keep tests sane
Browse files Browse the repository at this point in the history
  • Loading branch information
dvdoug committed Jul 26, 2023
1 parent 2a29a27 commit d589cfd
Show file tree
Hide file tree
Showing 14 changed files with 658 additions and 638 deletions.
20 changes: 20 additions & 0 deletions src/Rotation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
/**
* Box packing (3D bin packing, knapsack problem).
*
* @author Doug Wright
*/
declare(strict_types=1);

namespace DVDoug\BoxPacker;

/*
* Rotation permutations
*/
class Rotation
{
/* Can be turned sideways 90°, but cannot be placed *on* it's side e.g. fragile "↑this way up" items */
public const KeepFlat = 2;
/* No handling restrictions, item can be placed in any orientation */
public const BestFit = 6;
}
4 changes: 2 additions & 2 deletions tests/EfficiencyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public function testCanPackRepresentativeLargerSamples(
$item['length'],
$item['depth'],
$item['weight'],
true
Rotation::KeepFlat
),
(int) $item['qty']
);
Expand All @@ -66,7 +66,7 @@ public function testCanPackRepresentativeLargerSamples(
$item['length'],
$item['depth'],
$item['weight'],
false
Rotation::BestFit
),
(int) $item['qty']
);
Expand Down
848 changes: 424 additions & 424 deletions tests/InfalliblePackerTest.php

Large diffs are not rendered by default.

32 changes: 16 additions & 16 deletions tests/ItemListTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ class ItemListTest extends TestCase
*/
public function testDimensionalSorting(): void
{
$item1 = new TestItem('Small', 20, 20, 2, 100, true);
$item2 = new TestItem('Large', 200, 200, 20, 1000, true);
$item3 = new TestItem('Medium', 100, 100, 10, 500, true);
$item4 = new TestItem('Medium Heavy', 100, 100, 10, 501, true);
$item1 = new TestItem('Small', 20, 20, 2, 100, Rotation::BestFit);
$item2 = new TestItem('Large', 200, 200, 20, 1000, Rotation::BestFit);
$item3 = new TestItem('Medium', 100, 100, 10, 500, Rotation::BestFit);
$item4 = new TestItem('Medium Heavy', 100, 100, 10, 501, Rotation::BestFit);

$list = new ItemList();
$list->insert($item1);
Expand All @@ -46,10 +46,10 @@ public function testDimensionalSorting(): void
*/
public function testKeepingItemsOfSameTypeTogether(): void
{
$item1 = new TestItem('Item A', 20, 20, 2, 100, true);
$item2 = new TestItem('Item B', 20, 20, 2, 100, true);
$item3 = new TestItem('Item A', 20, 20, 2, 100, true);
$item4 = new TestItem('Item B', 20, 20, 2, 100, true);
$item1 = new TestItem('Item A', 20, 20, 2, 100, Rotation::BestFit);
$item2 = new TestItem('Item B', 20, 20, 2, 100, Rotation::BestFit);
$item3 = new TestItem('Item A', 20, 20, 2, 100, Rotation::BestFit);
$item4 = new TestItem('Item B', 20, 20, 2, 100, Rotation::BestFit);

$list = new ItemList();
$list->insert($item1);
Expand All @@ -69,15 +69,15 @@ public function testCount(): void
$itemList = new ItemList();
self::assertCount(0, $itemList);

$item1 = new TestItem('Item A', 20, 20, 2, 100, true);
$item1 = new TestItem('Item A', 20, 20, 2, 100, Rotation::BestFit);
$itemList->insert($item1);
self::assertCount(1, $itemList);

$item2 = new TestItem('Item B', 20, 20, 2, 100, true);
$item2 = new TestItem('Item B', 20, 20, 2, 100, Rotation::BestFit);
$itemList->insert($item2);
self::assertCount(2, $itemList);

$item3 = new TestItem('Item C', 20, 20, 2, 100, true);
$item3 = new TestItem('Item C', 20, 20, 2, 100, Rotation::BestFit);
$itemList->insert($item3);
self::assertCount(3, $itemList);

Expand All @@ -91,7 +91,7 @@ public function testCount(): void
public function testTop(): void
{
$itemList = new ItemList();
$item1 = new TestItem('Item A', 20, 20, 2, 100, true);
$item1 = new TestItem('Item A', 20, 20, 2, 100, Rotation::BestFit);
$itemList->insert($item1);

self::assertEquals($item1, $itemList->top());
Expand All @@ -105,13 +105,13 @@ public function testTopN(): void
{
$itemList = new ItemList();

$item1 = new TestItem('Item A', 20, 20, 2, 100, true);
$item1 = new TestItem('Item A', 20, 20, 2, 100, Rotation::BestFit);
$itemList->insert($item1);

$item2 = new TestItem('Item B', 20, 20, 2, 100, true);
$item2 = new TestItem('Item B', 20, 20, 2, 100, Rotation::BestFit);
$itemList->insert($item2);

$item3 = new TestItem('Item C', 20, 20, 2, 100, true);
$item3 = new TestItem('Item C', 20, 20, 2, 100, Rotation::BestFit);
$itemList->insert($item3);

$top2 = $itemList->topN(2);
Expand All @@ -127,7 +127,7 @@ public function testTopN(): void
public function testExtract(): void
{
$itemList = new ItemList();
$item1 = new TestItem('Item A', 20, 20, 2, 100, true);
$item1 = new TestItem('Item A', 20, 20, 2, 100, Rotation::BestFit);
$itemList->insert($item1);

self::assertEquals($item1, $itemList->extract());
Expand Down
2 changes: 1 addition & 1 deletion tests/NoBoxesAvailableExceptionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class NoBoxesAvailableExceptionTest extends TestCase
*/
public function testCanGetItem(): void
{
$item = new TestItem('Item 1', 2500, 2500, 20, 2000, true);
$item = new TestItem('Item 1', 2500, 2500, 20, 2000, Rotation::BestFit);

$exception = new NoBoxesAvailableException('Just testing...', $item);
self::assertEquals($item, $exception->getItem());
Expand Down
2 changes: 1 addition & 1 deletion tests/OrientatedItemTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class OrientatedItemTest extends TestCase
{
public function testSerialize(): void
{
$item = new OrientatedItem(new TestItem('Test', 1, 2, 3, 4, false), 1, 2, 3);
$item = new OrientatedItem(new TestItem('Test', 1, 2, 3, 4, Rotation::BestFit), 1, 2, 3);

$serializedDataKeys = json_decode(json_encode($item), true);
self::assertArrayHasKey('item', $serializedDataKeys);
Expand Down
24 changes: 12 additions & 12 deletions tests/PackedBoxListTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class PackedBoxListTest extends TestCase
public function testInsertAndCount(): void
{
$box = new TestBox('Box', 10, 10, 10, 0, 10, 10, 10, 100);
$itemA = new TestItem('Item A', 5, 10, 10, 10, true);
$itemB = new TestItem('Item B', 5, 10, 10, 20, true);
$itemA = new TestItem('Item A', 5, 10, 10, 10, Rotation::BestFit);
$itemB = new TestItem('Item B', 5, 10, 10, 20, Rotation::BestFit);

$packedItemA = new PackedItem($itemA, 0, 0, 0, 5, 10, 10);
$packedItemB = new PackedItem($itemB, 0, 0, 0, 5, 10, 10);
Expand All @@ -52,8 +52,8 @@ public function testInsertAndCount(): void
public function testInsertFromArrayAndCount(): void
{
$box = new TestBox('Box', 10, 10, 10, 0, 10, 10, 10, 100);
$itemA = new TestItem('Item A', 5, 10, 10, 10, true);
$itemB = new TestItem('Item B', 5, 10, 10, 20, true);
$itemA = new TestItem('Item A', 5, 10, 10, 10, Rotation::BestFit);
$itemB = new TestItem('Item B', 5, 10, 10, 20, Rotation::BestFit);

$packedItemA = new PackedItem($itemA, 0, 0, 0, 5, 10, 10);
$packedItemB = new PackedItem($itemB, 0, 0, 0, 5, 10, 10);
Expand All @@ -78,8 +78,8 @@ public function testInsertFromArrayAndCount(): void
public function testTop(): void
{
$box = new TestBox('Box', 10, 10, 10, 0, 10, 10, 10, 100);
$itemA = new TestItem('Item A', 5, 10, 10, 10, true);
$itemB = new TestItem('Item B', 5, 10, 10, 20, true);
$itemA = new TestItem('Item A', 5, 10, 10, 10, Rotation::BestFit);
$itemB = new TestItem('Item B', 5, 10, 10, 20, Rotation::BestFit);

$packedItemA = new PackedItem($itemA, 0, 0, 0, 5, 10, 10);
$packedItemB = new PackedItem($itemB, 0, 0, 0, 5, 10, 10);
Expand All @@ -105,7 +105,7 @@ public function testTop(): void
public function testVolumeUtilisation(): void
{
$box = new TestBox('Box', 10, 10, 10, 0, 10, 10, 10, 10);
$item = new TestItem('Item', 5, 10, 10, 10, true);
$item = new TestItem('Item', 5, 10, 10, 10, Rotation::BestFit);

$packedItem = new PackedItem($item, 0, 0, 0, 5, 10, 10);

Expand All @@ -126,8 +126,8 @@ public function testVolumeUtilisation(): void
public function testWeightVariance(): void
{
$box = new TestBox('Box', 10, 10, 10, 0, 10, 10, 10, 100);
$itemA = new TestItem('Item A', 5, 10, 10, 10, true);
$itemB = new TestItem('Item B', 5, 10, 10, 20, true);
$itemA = new TestItem('Item A', 5, 10, 10, 10, Rotation::BestFit);
$itemB = new TestItem('Item B', 5, 10, 10, 20, Rotation::BestFit);

$packedItemA = new PackedItem($itemA, 0, 0, 0, 5, 10, 10);
$packedItemB = new PackedItem($itemB, 0, 0, 0, 5, 10, 10);
Expand All @@ -153,8 +153,8 @@ public function testWeightVariance(): void
public function testMeanWeight(): void
{
$box = new TestBox('Box', 10, 10, 10, 0, 10, 10, 10, 100);
$itemA = new TestItem('Item A', 5, 10, 10, 10, true);
$itemB = new TestItem('Item B', 5, 10, 10, 20, true);
$itemA = new TestItem('Item A', 5, 10, 10, 10, Rotation::BestFit);
$itemB = new TestItem('Item B', 5, 10, 10, 20, Rotation::BestFit);

$packedItemA = new PackedItem($itemA, 0, 0, 0, 5, 10, 10);
$packedItemB = new PackedItem($itemB, 0, 0, 0, 5, 10, 10);
Expand All @@ -180,7 +180,7 @@ public function testMeanWeight(): void
public function testJsonSerialize(): void
{
$box = new TestBox('Box', 10, 10, 20, 10, 10, 10, 20, 10);
$item = new OrientatedItem(new TestItem('Item', 4, 10, 10, 10, true), 4, 10, 10);
$item = new OrientatedItem(new TestItem('Item', 4, 10, 10, 10, Rotation::KeepFlat), 4, 10, 10);

$boxItems = new PackedItemList();
$boxItems->insert(PackedItem::fromOrientatedItem($item, 0, 0, 0));
Expand Down
8 changes: 4 additions & 4 deletions tests/PackedBoxTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class PackedBoxTest extends TestCase
public function testGetters(): void
{
$box = new TestBox('Box', 370, 375, 60, 140, 364, 374, 40, 3000);
$item = new OrientatedItem(new TestItem('Item', 230, 330, 6, 320, true), 230, 330, 6);
$item = new OrientatedItem(new TestItem('Item', 230, 330, 6, 320, Rotation::BestFit), 230, 330, 6);

$packedItemList = new PackedItemList();
$packedItemList->insert(PackedItem::fromOrientatedItem($item, 0, 0, 0));
Expand All @@ -49,7 +49,7 @@ public function testGetters(): void
public function testVolumeUtilisation(): void
{
$box = new TestBox('Box', 10, 10, 20, 10, 10, 10, 20, 10);
$item = new OrientatedItem(new TestItem('Item', 4, 10, 10, 10, true), 4, 10, 10);
$item = new OrientatedItem(new TestItem('Item', 4, 10, 10, 10, Rotation::BestFit), 4, 10, 10);

$boxItems = new PackedItemList();
$boxItems->insert(PackedItem::fromOrientatedItem($item, 0, 0, 0));
Expand All @@ -67,7 +67,7 @@ public function testVolumeUtilisation(): void
public function testWeightCalcCaching(): void
{
$box = new TestBox('Box', 10, 10, 20, 10, 10, 10, 20, 10);
$item = new OrientatedItem(new TestItem('Item', 4, 10, 10, 10, true), 4, 10, 10);
$item = new OrientatedItem(new TestItem('Item', 4, 10, 10, 10, Rotation::BestFit), 4, 10, 10);

$boxItems = new PackedItemList();
$boxItems->insert(PackedItem::fromOrientatedItem($item, 0, 0, 0));
Expand All @@ -91,7 +91,7 @@ public function testWeightCalcCaching(): void
public function testJsonSerialize(): void
{
$box = new TestBox('Box', 10, 10, 20, 10, 10, 10, 20, 10);
$item = new OrientatedItem(new TestItem('Item', 4, 10, 10, 10, true), 4, 10, 10);
$item = new OrientatedItem(new TestItem('Item', 4, 10, 10, 10, Rotation::KeepFlat), 4, 10, 10);

$boxItems = new PackedItemList();
$boxItems->insert(PackedItem::fromOrientatedItem($item, 0, 0, 0));
Expand Down
4 changes: 2 additions & 2 deletions tests/PackedItemTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class PackedItemTest extends TestCase
*/
public function testVolumeCalculation(): void
{
$packedItem = new PackedItem(new TestItem('Item', 1, 1, 0, 0, false), 0, 0, 0, 3, 5, 7);
$packedItem = new PackedItem(new TestItem('Item', 1, 1, 0, 0, Rotation::BestFit), 0, 0, 0, 3, 5, 7);
self::assertSame(105, $packedItem->getVolume());
}

Expand All @@ -32,7 +32,7 @@ public function testVolumeCalculation(): void
*/
public function testJsonSerialize(): void
{
$packedItem = new PackedItem(new TestItem('Item', 1, 2, 3, 10, false), 100, 20, 300, 3, 5, 7);
$packedItem = new PackedItem(new TestItem('Item', 1, 2, 3, 10, Rotation::BestFit), 100, 20, 300, 3, 5, 7);
self::assertJsonStringEqualsJsonString('{"x":100,"y":20,"z":300,"width":3,"length":5,"depth":7,"item":{"description":"Item","width":1,"length":2,"depth":3,"keepFlat":false, "weight":10}}', json_encode($packedItem));
}
}
2 changes: 1 addition & 1 deletion tests/PackedLayerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class PackedLayerTest extends TestCase
{
public function testGetters(): void
{
$packedItem = new PackedItem(new TestItem('Item', 11, 22, 33, 43, false), 4, 5, 6, 33, 11, 22);
$packedItem = new PackedItem(new TestItem('Item', 11, 22, 33, 43, Rotation::BestFit), 4, 5, 6, 33, 11, 22);
$packedLayer = new PackedLayer();
$packedLayer->insert($packedItem);
self::assertSame(4, $packedLayer->getStartX());
Expand Down
Loading

0 comments on commit d589cfd

Please sign in to comment.