coverJpeg(srcJpeg(2000, 2000), 300, 250); $info = getimagesizefromstring($out); expect($info)->not->toBeFalse() ->and($info[0])->toBe(300) ->and($info[1])->toBe(250) ->and($info['mime'])->toBe('image/jpeg') ->and(strlen($out))->toBeLessThanOrEqual(512000); }); it('работает для широкого и высокого форматов (cover, точные пиксели)', function () { $gen = new BannerGenerator; $wide = getimagesizefromstring($gen->coverJpeg(srcJpeg(1200, 1200), 728, 90)); expect($wide[0])->toBe(728)->and($wide[1])->toBe(90); $tall = getimagesizefromstring($gen->coverJpeg(srcJpeg(1200, 1200), 240, 600)); expect($tall[0])->toBe(240)->and($tall[1])->toBe(600); }); /** Хелпер: «шумная» картинка — такую JPEG не ужимает почти никак, вес остаётся большим. */ function noisyJpeg(int $w, int $h): string { $img = imagecreatetruecolor($w, $h); for ($x = 0; $x < $w; $x += 2) { for ($y = 0; $y < $h; $y += 2) { imagesetpixel($img, $x, $y, imagecolorallocate($img, ($x * 7) % 255, ($y * 13) % 255, ($x * $y) % 255)); } } ob_start(); imagejpeg($img, null, 95); $bin = (string) ob_get_clean(); imagedestroy($img); return $bin; } /** * Подбор качества упирается в пол 40 и дальше жать не может. Раньше в этом случае наружу * молча уходил файл любого веса — а кабинет Яндекса тяжелее предела его не примет, и узнали * бы мы об этом уже роботом, стоящим перед окном загрузки на боевом. Лучше честно сказать, * что картинка не ужимается, чем отдать заведомо негодный файл. */ it('не отдаёт молча файл тяжелее предела, а честно отказывается', function () { expect(fn () => (new BannerGenerator)->coverJpeg(noisyJpeg(1200, 1200), 970, 250, 2000)) ->toThrow(RuntimeException::class); }); it('бросает исключение на нечитаемой картинке', function () { expect(fn () => (new BannerGenerator)->coverJpeg('не картинка', 300, 250)) ->toThrow(RuntimeException::class); });