Completed
Push — 2.x-dev ( 5f5b4d...48a1b4 )
by Doug
61:10 queued 51:42
created

PackerTest::testPackFiveItemsTwoLargeOneSmallBox()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 39
Code Lines 29

Duplication

Lines 39
Ratio 100 %

Importance

Changes 0
Metric Value
dl 39
loc 39
c 0
b 0
f 0
rs 8.8571
cc 1
eloc 29
nc 1
nop 0
1
<?php
2
/**
3
 * Box packing (3D bin packing, knapsack problem).
4
 *
5
 * @author Doug Wright
6
 */
7
8
namespace DVDoug\BoxPacker;
9
10
use DVDoug\BoxPacker\Test\TestBox;
11
use DVDoug\BoxPacker\Test\TestItem;
12
use PHPUnit\Framework\TestCase;
13
14
/**
15
 * @covers \DVDoug\BoxPacker\Packer
16
 */
17
class PackerTest extends TestCase
18
{
19
    /**
20
     * @expectedException \DVDoug\BoxPacker\ItemTooLargeException
21
     */
22
    public function testPackThreeItemsOneDoesntFitInAnyBox()
23
    {
24
        $box1 = new TestBox('Le petite box', 300, 300, 10, 10, 296, 296, 8, 1000);
25
        $box2 = new TestBox('Le grande box', 3000, 3000, 100, 100, 2960, 2960, 80, 10000);
26
27
        $item1 = new TestItem('Item 1', 2500, 2500, 20, 2000, true);
28
        $item2 = new TestItem('Item 2', 25000, 2500, 20, 2000, true);
29
        $item3 = new TestItem('Item 3', 2500, 2500, 20, 2000, true);
30
31
        $packer = new Packer();
32
        $packer->addBox($box1);
33
        $packer->addBox($box2);
34
        $packer->addItem($item1);
35
        $packer->addItem($item2);
36
        $packer->addItem($item3);
37
        $packer->pack();
38
    }
39
40
    /**
41
     * @expectedException \DVDoug\BoxPacker\ItemTooLargeException
42
     */
43
    public function testPackWithoutBox()
44
    {
45
        $item1 = new TestItem('Item 1', 2500, 2500, 20, 2000, true);
46
        $item2 = new TestItem('Item 2', 25000, 2500, 20, 2000, true);
47
        $item3 = new TestItem('Item 3', 2500, 2500, 20, 2000, true);
48
49
        $packer = new Packer();
50
        $packer->addItem($item1);
51
        $packer->addItem($item2);
52
        $packer->addItem($item3);
53
        $packer->pack();
54
    }
55
56
    /**
57
     * Test weight distribution getter/setter.
58
     */
59
    public function testCanSetMaxBoxesToWeightBalance()
60
    {
61
        $packer = new Packer();
62
        $packer->setMaxBoxesToBalanceWeight(3);
63
        self::assertEquals(3, $packer->getMaxBoxesToBalanceWeight());
64
    }
65
66
    /**
67
     * Test that weight redistribution activates (or not) correctly based on the current limit.
68
     */
69
    public function testWeightRedistributionActivatesOrNot()
70
    {
71
        // first pack normally - expecting 2+2 after balancing
72
73
        $packer = new Packer();
74
        $packer->addBox(new TestBox('Box', 1, 1, 3, 0, 1, 1, 3, 3));
75
        $packer->addItem(new TestItem('Item', 1, 1, 1, 1, false), 4);
76
77
        /** @var PackedBox[] $packedBoxes */
78
        $packedBoxes = iterator_to_array($packer->pack(), false);
79
80
        self::assertEquals(2, $packedBoxes[0]->getItems()->count());
81
        self::assertEquals(2, $packedBoxes[1]->getItems()->count());
82
83
        // same items, but with redistribution turned off - expecting 3+1 based on pure fit
84
        $packer = new Packer();
85
        $packer->addBox(new TestBox('Box', 1, 1, 3, 0, 1, 1, 3, 3));
86
        $packer->addItem(new TestItem('Item', 1, 1, 1, 1, false), 4);
87
        $packer->setMaxBoxesToBalanceWeight(1);
88
89
        /** @var PackedBox[] $packedBoxes */
90
        $packedBoxes = iterator_to_array($packer->pack(), false);
91
92
        self::assertEquals(3, $packedBoxes[0]->getItems()->count());
93
        self::assertEquals(1, $packedBoxes[1]->getItems()->count());
94
    }
95
96
    /**
97
     * Test used width calculations on a case where it used to fail.
98
     */
99
    public function testIssue52A()
100
    {
101
        $packer = new Packer();
102
        $packer->addBox(new TestBox('Box', 100, 50, 50, 0, 100, 50, 50, 5000));
103
        $packer->addItem(new TestItem('Item', 15, 13, 8, 407, true), 2);
104
        $packedBoxes = $packer->pack();
105
106
        self::assertEquals(1, $packedBoxes->count());
107
        self::assertEquals(26, $packedBoxes->top()->getUsedWidth());
108
        self::assertEquals(15, $packedBoxes->top()->getUsedLength());
109
        self::assertEquals(8, $packedBoxes->top()->getUsedDepth());
110
    }
111
112
    /**
113
     * Test used width calculations on a case where it used to fail.
114
     */
115
    public function testIssue52B()
116
    {
117
        $packer = new Packer();
118
        $packer->addBox(new TestBox('Box', 370, 375, 60, 140, 364, 374, 40, 3000));
119
        $packer->addItem(new TestItem('Item 1', 220, 310, 12, 679, true));
120
        $packer->addItem(new TestItem('Item 2', 210, 297, 11, 648, true));
121
        $packer->addItem(new TestItem('Item 3', 210, 297, 5, 187, true));
122
        $packer->addItem(new TestItem('Item 4', 148, 210, 32, 880, true));
123
        $packedBoxes = $packer->pack();
124
125
        self::assertEquals(1, $packedBoxes->count());
126
        self::assertEquals(310, $packedBoxes->top()->getUsedWidth());
127
        self::assertEquals(368, $packedBoxes->top()->getUsedLength());
128
        self::assertEquals(32, $packedBoxes->top()->getUsedDepth());
129
    }
130
131
    /**
132
     * Test used width calculations on a case where it used to fail.
133
     */
134
    public function testIssue52C()
135
    {
136
        $packer = new Packer();
137
        $packer->addBox(new TestBox('Box', 230, 300, 240, 160, 230, 300, 240, 15000));
138
        $packer->addItem(new TestItem('Item 1', 210, 297, 4, 213, true));
139
        $packer->addItem(new TestItem('Item 2', 80, 285, 70, 199, true));
140
        $packer->addItem(new TestItem('Item 3', 80, 285, 70, 199, true));
141
142
        /** @var PackedBox[] $packedBoxes */
143
        $packedBoxes = iterator_to_array($packer->pack(), false);
144
145
        self::assertEquals(2, count($packedBoxes));
146
147
        self::assertEquals(160, $packedBoxes[0]->getUsedWidth());
148
        self::assertEquals(285, $packedBoxes[0]->getUsedLength());
149
        self::assertEquals(70, $packedBoxes[0]->getUsedDepth());
150
151
        self::assertEquals(210, $packedBoxes[1]->getUsedWidth());
152
        self::assertEquals(297, $packedBoxes[1]->getUsedLength());
153
        self::assertEquals(4, $packedBoxes[1]->getUsedDepth());
154
    }
155
}
156