Skip to content

Commit b556472

Browse files
authored
Merge pull request #11 from mathiasgrimm/feat/psnr-field
Surface the psnr field on ImageResult
2 parents 5eca864 + c9d3714 commit b556472

3 files changed

Lines changed: 45 additions & 4 deletions

File tree

src/ImageResult.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,38 @@
44

55
final readonly class ImageResult
66
{
7+
/**
8+
* @param float|null $psnr Peak signal-to-noise ratio in decibels between the
9+
* input and the output, returned by optimize and convert.
10+
* Higher means closer to the input. Null when the API
11+
* does not send the field (resize, thumbnail) or when
12+
* the loss cannot be measured.
13+
*/
714
public function __construct(
815
public string $bytes,
916
public string $format,
1017
public string $mimeType,
1118
public int $size,
1219
public int $width,
1320
public int $height,
21+
public ?float $psnr = null,
1422
) {}
1523

1624
/**
1725
* @param array<string, mixed> $data
1826
*/
1927
public static function fromResponse(array $data): self
2028
{
29+
$psnr = data_get($data, 'psnr');
30+
2131
return new self(
2232
bytes: (string) base64_decode((string) data_get($data, 'output.data'), true),
2333
format: (string) data_get($data, 'format'),
2434
mimeType: (string) data_get($data, 'mime_type'),
2535
size: (int) data_get($data, 'size'),
2636
width: (int) data_get($data, 'width'),
2737
height: (int) data_get($data, 'height'),
38+
psnr: $psnr === null ? null : (float) $psnr,
2839
);
2940
}
3041
}

tests/ClientTest.php

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use MathiasGrimm\GlimpsePhp\ForbiddenException;
99
use MathiasGrimm\GlimpsePhp\ImageFormat;
1010
use MathiasGrimm\GlimpsePhp\ImageInfo;
11+
use MathiasGrimm\GlimpsePhp\ImageResult;
1112
use MathiasGrimm\GlimpsePhp\RateLimitException;
1213
use MathiasGrimm\GlimpsePhp\SizeEstimate;
1314
use MathiasGrimm\GlimpsePhp\Tests\Fixtures\Images;
@@ -30,15 +31,16 @@ function client(Factory $http, Closure|string|null $token = 'test-token', string
3031
}
3132

3233
test('convert posts the base64 envelope and returns a decoded ImageResult', function () {
33-
$http = fakeHttp(['*/v1/convert' => Factory::response(fakeTransformResponse())]);
34+
$http = fakeHttp(['*/v1/convert' => Factory::response(fakeTransformResponse(overrides: ['psnr' => 41.27]))]);
3435

3536
$result = client($http)->convert(Images::png(), ImageFormat::Jpg);
3637

3738
expect($result->bytes)->toBe(Images::jpg())
3839
->and($result->format)->toBe(ImageFormat::Jpg->value)
3940
->and($result->mimeType)->toBe('image/jpeg')
4041
->and($result->width)->toBe(1280)
41-
->and($result->height)->toBe(720);
42+
->and($result->height)->toBe(720)
43+
->and($result->psnr)->toBe(41.27);
4244

4345
$http->assertSent(function (Request $request) {
4446
return $request->url() === 'https://glimpseimg.com/api/v1/convert'
@@ -49,6 +51,33 @@ function client(Factory $http, Closure|string|null $token = 'test-token', string
4951
});
5052
});
5153

54+
test('a null psnr in the response stays null', function () {
55+
$http = fakeHttp(['*/v1/optimize' => Factory::response(fakeTransformResponse(overrides: ['psnr' => null]))]);
56+
57+
expect(client($http)->optimize(Images::png())->psnr)->toBeNull();
58+
});
59+
60+
test('a response without a psnr field maps to a null psnr', function () {
61+
// Resize and thumbnail responses do not carry the field at all.
62+
$http = fakeHttp(['*/v1/resize' => Factory::response(fakeTransformResponse())]);
63+
64+
expect(client($http)->resize(Images::png(), width: 800)->psnr)->toBeNull();
65+
});
66+
67+
test('an integer psnr in the response is cast to float', function () {
68+
$http = fakeHttp(['*/v1/optimize' => Factory::response(fakeTransformResponse(overrides: ['psnr' => 42]))]);
69+
70+
expect(client($http)->optimize(Images::png())->psnr)->toBe(42.0);
71+
});
72+
73+
test('the six-argument constructor stays valid and defaults psnr to null', function () {
74+
// Locks backward compatibility: callers built against pre-3.1 must keep
75+
// working without passing psnr.
76+
$result = new ImageResult('bytes', 'jpg', 'image/jpeg', 100, 20, 10);
77+
78+
expect($result->psnr)->toBeNull();
79+
});
80+
5281
test('convert sends optimize and quality when given', function () {
5382
$http = fakeHttp(['*/v1/convert' => Factory::response(fakeTransformResponse())]);
5483

tests/Pest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,12 @@ function fakeInfoResponse(array $overrides = []): array
6868
/**
6969
* A canned successful transform-endpoint response envelope.
7070
*
71+
* @param array<string, mixed> $overrides
7172
* @return array{data: array<string, mixed>}
7273
*/
73-
function fakeTransformResponse(string $format = 'jpg', string $mimeType = 'image/jpeg'): array
74+
function fakeTransformResponse(string $format = 'jpg', string $mimeType = 'image/jpeg', array $overrides = []): array
7475
{
75-
return ['data' => [
76+
return ['data' => $overrides + [
7677
'output' => ['type' => 'BASE64', 'data' => Images::JPG_BASE64],
7778
'format' => $format,
7879
'mime_type' => $mimeType,

0 commit comments

Comments
 (0)