Passed
Push — master ( ea3f04...21da4e )
by Joschi
02:21
created

SourceSizeListTest::testSourceSizeList()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 12
nc 1
nop 0
dl 0
loc 18
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * responsive-images-css
5
 *
6
 * @category   Jkphl
7
 * @package    Jkphl\Respimgcss
8
 * @subpackage Jkphl\Respimgcss\Tests\Infrastructure
9
 * @author     Joschi Kuphal <[email protected]> / @jkphl
10
 * @copyright  Copyright © 2018 Joschi Kuphal <[email protected]> / @jkphl
11
 * @license    http://opensource.org/licenses/MIT The MIT License (MIT)
12
 */
13
14
/***********************************************************************************
15
 *  The MIT License (MIT)
16
 *
17
 *  Copyright © 2018 Joschi Kuphal <[email protected]> / @jkphl
18
 *
19
 *  Permission is hereby granted, free of charge, to any person obtaining a copy of
20
 *  this software and associated documentation files (the "Software"), to deal in
21
 *  the Software without restriction, including without limitation the rights to
22
 *  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
23
 *  the Software, and to permit persons to whom the Software is furnished to do so,
24
 *  subject to the following conditions:
25
 *
26
 *  The above copyright notice and this permission notice shall be included in all
27
 *  copies or substantial portions of the Software.
28
 *
29
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
31
 *  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
32
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
33
 *  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34
 *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
 ***********************************************************************************/
36
37
namespace Jkphl\Respimgcss\Tests\Infrastructure;
38
39
use Jkphl\Respimgcss\Application\Contract\CalculatorServiceFactoryInterface;
40
use Jkphl\Respimgcss\Application\Factory\LengthFactory;
41
use Jkphl\Respimgcss\Application\Factory\SourceSizeFactory;
42
use Jkphl\Respimgcss\Application\Model\ImageCandidateSet;
43
use Jkphl\Respimgcss\Application\Model\SourceSize;
44
use Jkphl\Respimgcss\Domain\Contract\AbsoluteLengthInterface;
45
use Jkphl\Respimgcss\Domain\Model\ImageCandidateMatch;
46
use Jkphl\Respimgcss\Domain\Model\WidthImageCandidate;
47
use Jkphl\Respimgcss\Infrastructure\SourceSizeList;
48
use Jkphl\Respimgcss\Infrastructure\ViewportCalculatorServiceFactory;
49
use Jkphl\Respimgcss\Tests\AbstractTestBase;
50
51
/**
52
 * Source size list test
53
 *
54
 * @package    Jkphl\Respimgcss
55
 * @subpackage Jkphl\Respimgcss\Tests\Infrastructure
56
 */
57
class SourceSizeListTest extends AbstractTestBase
58
{
59
    /**
60
     * Source size widths
61
     *
62
     * @var array
63
     */
64
    const SOURCE_SIZE_WIDTHS = [
65
        '((min-width: 200px) and (min-resolution: 2)) 80vw',
66
        '(min-width: 800px) 50vw',
67
        '100vw',
68
        '(min-width: 400px) 80vw',
69
        '((min-width: 800px) and (max-width: 1200px)) 50vw'
70
    ];
71
    /**
72
     * Source size resolutions
73
     *
74
     * @var array
75
     */
76
    const SOURCE_SIZE_RESOLUTIONS = [
77
        '((min-resolution: 1) and (max-resolution: 3)) 100vw',
78
        '(resolution: 1) 100vw',
79
        '((min-resolution: 1) and (max-resolution: 2)) 100vw',
80
        '(min-resolution: 1) 100vw',
81
        '((min-resolution: 2) and (max-resolution: 3)) 100vw',
82
        '(resolution: 1) 100vw'
83
    ];
84
85
    /**
86
     * Test the source size list
87
     */
88
    public function testSourceSizeList()
89
    {
90
        $sourceSizeFactory = new SourceSizeFactory(new ViewportCalculatorServiceFactory(), 16);
91
        $sourceSizes       = array_map(
92
            function ($sourceSize) use ($sourceSizeFactory) {
93
                return $sourceSizeFactory->createFromSourceSizeStr($sourceSize);
94
            },
95
            self::SOURCE_SIZE_WIDTHS
96
        );
97
        $sourceSizeList    = new SourceSizeList($sourceSizes, $sourceSizeFactory);
98
        $this->runSourceSizeListAssertions($sourceSizes, $sourceSizeList);
99
100
        $this->matchImageCandidates(
101
            $sourceSizeList,
102
            [
103
                $sourceSizeFactory->createAbsoluteLength(0),
104
                $sourceSizeFactory->createAbsoluteLength(400),
105
                $sourceSizeFactory->createAbsoluteLength(800),
106
            ]
107
        );
108
    }
109
110
    /**
111
     * Run source size list assertions
112
     *
113
     * @param SourceSize[] $sourceSizes      List of source sizes
114
     * @param SourceSizeList $sourceSizeList Source size list
115
     */
116
    protected function runSourceSizeListAssertions(array $sourceSizes, $sourceSizeList)
117
    {
118
        $this->assertInstanceOf(SourceSizeList::class, $sourceSizeList);
119
        $this->assertEquals(5, count($sourceSizeList));
120
        $this->assertEquals($sourceSizes[1], $sourceSizeList[0]);
121
        $this->assertEquals($sourceSizes[4], $sourceSizeList[1]);
122
        $this->assertEquals($sourceSizes[3], $sourceSizeList[2]);
123
        $this->assertEquals($sourceSizes[0], $sourceSizeList[3]);
124
        $this->assertEquals($sourceSizes[2], $sourceSizeList[4]);
125
    }
126
127
    /**
128
     * Find image candidates for breakpoints
129
     *
130
     * @param SourceSizeList $sourceSizeList         Source sizes list
131
     * @param AbsoluteLengthInterface[] $breakpoints Breakpoints
132
     */
133
    protected function matchImageCandidates(SourceSizeList $sourceSizeList, array $breakpoints)
134
    {
135
        $imageCandidateSet = new ImageCandidateSet(new WidthImageCandidate('small.jpg', 400));
136
        $this->assertInstanceOf(ImageCandidateSet::class, $imageCandidateSet);
137
138
        $imageCandidateSet[] = new WidthImageCandidate('medium.jpg', 800);
139
        $imageCandidateSet[] = new WidthImageCandidate('large.jpg', 1200);
140
        $imageCandidateSet[] = new WidthImageCandidate('extralarge.jpg', 1600);
141
142
        $imageCandidateResultFiles = ['small.jpg', 'medium.jpg', 'extralarge.jpg'];
143
144
        foreach ([1] as $density) {
145
            /** @var AbsoluteLengthInterface $breakpoint */
146
            foreach ($breakpoints as $breakpoint) {
147
                $imageCandidateMatch = $sourceSizeList->findImageCandidate($imageCandidateSet, $breakpoint, $density);
148
                $this->assertInstanceOf(ImageCandidateMatch::class, $imageCandidateMatch);
149
                $this->assertEquals(
150
                    $imageCandidateMatch->getImageCandidate()->getFile(),
151
                    array_shift($imageCandidateResultFiles)
152
                );
153
            }
154
        }
155
    }
156
157
    /**
158
     * Test the source size list with invalid source size
159
     *
160
     * @expectedException \Jkphl\Respimgcss\Ports\InvalidArgumentException
161
     * @expectedExceptionCode 1523047851
162
     */
163
    public function testSourceSizeListInvalid()
164
    {
165
        $lengthFactory = new LengthFactory($this->createMock(CalculatorServiceFactoryInterface::class), 16);
166
        new SourceSizeList(['test'], $lengthFactory);
167
    }
168
169
    /**
170
     * Test empty source size list
171
     */
172
    public function testEmptySourceSizeList()
173
    {
174
        $imageCandidateSet = new ImageCandidateSet(new WidthImageCandidate('small.jpg', 400));
175
        $this->assertInstanceOf(ImageCandidateSet::class, $imageCandidateSet);
176
177
        $imageCandidateSet[] = new WidthImageCandidate('medium.jpg', 800);
178
        $imageCandidateSet[] = new WidthImageCandidate('large.jpg', 1200);
179
        $imageCandidateSet[] = new WidthImageCandidate('extralarge.jpg', 1600);
180
181
        $sourceSizeFactory = new SourceSizeFactory(new ViewportCalculatorServiceFactory(), 16);
182
        $sourceSizeList    = new SourceSizeList([], $sourceSizeFactory);
183
        $this->assertInstanceOf(SourceSizeList::class, $sourceSizeList);
184
        $this->assertEquals(0, count($sourceSizeList));
185
        $this->assertNull(
186
            $sourceSizeList->findImageCandidate(
187
                $imageCandidateSet,
188
                $sourceSizeFactory->createAbsoluteLength(0),
189
                1
190
            )
191
        );
192
    }
193
194
    /**
195
     * Test a non matching set of image candidates
196
     */
197
    public function testNonMatchingImageCandidates()
198
    {
199
        $imageCandidateSet = new ImageCandidateSet(new WidthImageCandidate('small.jpg', 400));
200
        $sourceSizeFactory = new SourceSizeFactory(new ViewportCalculatorServiceFactory(), 16);
201
        $sourceSize        = $sourceSizeFactory->createFromSourceSizeStr(
202
            '((min-width: 1000px) and (max-width: 2000px)) 100vw'
203
        );
204
        $sourceSizeList    = new SourceSizeList([$sourceSize], $sourceSizeFactory);
205
        $this->assertInstanceOf(SourceSizeList::class, $sourceSizeList);
206
        $this->assertEquals(1, count($sourceSizeList));
207
        $this->assertNull(
208
            $sourceSizeList->findImageCandidate(
209
                $imageCandidateSet,
210
                $sourceSizeFactory->createAbsoluteLength(1500),
211
                1
212
            )
213
        );
214
    }
215
216
    /**
217
     * Test empty image candidate set
218
     */
219
    public function testEmptyImageCandidateSet()
220
    {
221
        $imageCandidateSet = $this->createMock(ImageCandidateSet::class);
222
        $sourceSizeFactory = new SourceSizeFactory(new ViewportCalculatorServiceFactory(), 16);
223
        $sourceSize        = $sourceSizeFactory->createFromSourceSizeStr('(min-width: 1px) 100vw');
224
        $sourceSizeList    = new SourceSizeList([$sourceSize], $sourceSizeFactory);
225
        $this->assertInstanceOf(SourceSizeList::class, $sourceSizeList);
226
        $this->assertEquals(1, count($sourceSizeList));
227
        $this->assertNull(
228
            $sourceSizeList->findImageCandidate(
229
                $imageCandidateSet,
230
                $sourceSizeFactory->createAbsoluteLength(100),
231
                1
232
            )
233
        );
234
    }
235
236
    /**
237
     * Test the sorting of the source sizes list
238
     */
239
    public function testSourceSizeListSorting()
240
    {
241
        $sourceSizeFactory = new SourceSizeFactory(new ViewportCalculatorServiceFactory(), 16);
242
        $sourceSizes       = array_map(
243
            function ($sourceSize) use ($sourceSizeFactory) {
244
                return $sourceSizeFactory->createFromSourceSizeStr($sourceSize);
245
            },
246
            self::SOURCE_SIZE_RESOLUTIONS
247
        );
248
        $sourceSizeList    = new SourceSizeList($sourceSizes, $sourceSizeFactory);
249
        $this->assertInstanceOf(SourceSizeList::class, $sourceSizeList);
250
        $this->assertEquals(6, count($sourceSizeList));
251
        $this->assertEquals($sourceSizes[4], $sourceSizeList[0]);
252
        $this->assertEquals($sourceSizes[3], $sourceSizeList[1]);
253
        $this->assertEquals($sourceSizes[0], $sourceSizeList[2]);
254
        $this->assertEquals($sourceSizes[2], $sourceSizeList[3]);
255
        $this->assertEquals($sourceSizes[1], $sourceSizeList[4]);
256
        $this->assertEquals($sourceSizes[5], $sourceSizeList[5]);
257
    }
258
}
259