From 3071c677fd424f6ad55691823bb723e296d46517 Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Fri, 10 Jul 2026 09:56:33 +1000 Subject: [PATCH 1/2] feat: deprecate non-int values in Counter::set() Passing a non-int value to Counter::set() now triggers an E_USER_DEPRECATED notice before the existing InvalidArgumentException is thrown. The parameter type will be narrowed to int in the next major release. Documents the value as int<0, max>. Closes #16 --- src/Counter.php | 9 +++++++-- tests/Unit/CounterTest.php | 39 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/Counter.php b/src/Counter.php index 9c59841..5c0f938 100644 --- a/src/Counter.php +++ b/src/Counter.php @@ -24,8 +24,8 @@ public function getType(): string { /** * Adds a value for this metric. * - * @param mixed $value - * The value. + * @param int<0, max> $value + * The value. Non-int values are deprecated. * @param array $labels * The list of key value label pairs. * @@ -33,6 +33,11 @@ public function getType(): string { * If the value is not a non-negative integer. */ public function set(mixed $value, array $labels = []): void { + // @phpstan-ignore function.alreadyNarrowedType + if (!is_int($value)) { + // phpcs:ignore Drupal.Semantics.FunctionTriggerError.TriggerErrorSeeUrlFormat + @trigger_error(sprintf('Passing a non-int value to %s() is deprecated in php_prometheus:1.1.0 and will throw a \TypeError in php_prometheus:2.0.0. See https://github.com/previousnext/php-prometheus/issues/16', __METHOD__), E_USER_DEPRECATED); + } if (!$this->isValidValue($value)) { throw new \InvalidArgumentException("A count value must be a positive integer."); } diff --git a/tests/Unit/CounterTest.php b/tests/Unit/CounterTest.php index 405c762..d60cfac 100644 --- a/tests/Unit/CounterTest.php +++ b/tests/Unit/CounterTest.php @@ -5,6 +5,7 @@ namespace PNX\Prometheus\Tests\Unit; use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\IgnoreDeprecations; use PHPUnit\Framework\TestCase; use PNX\Prometheus\Counter; @@ -18,18 +19,52 @@ class CounterTest extends TestCase { * Tests setting counter values. */ public function testCounter(): void { - $counter = new Counter('foo', 'bar', 'Example counter help'); $counter->set(89, ['baz' => 'wiz']); $this->assertEquals("foo_bar", $counter->getName()); $this->assertEquals("counter", $counter->getType()); + $values = $counter->getLabelledValues(); + $this->assertCount(1, $values); + $this->assertEquals(89, $values[0]->getValue()); + } + + /** + * Tests that a negative value throws an exception. + */ + public function testNegativeValueThrows(): void { + $counter = new Counter('foo', 'bar', 'Example counter help'); $this->expectException(\InvalidArgumentException::class); + // @phpstan-ignore argument.type $counter->set(-1, ['baz' => 'wiz']); + } + + /** + * Tests that a non-int value triggers a deprecation notice. + */ + public function testNonIntValueIsDeprecated(): void { + $counter = new Counter('foo', 'bar', 'Example counter help'); + $this->expectUserDeprecationMessage('Passing a non-int value to PNX\Prometheus\Counter::set() is deprecated in php_prometheus:1.1.0 and will throw a \TypeError in php_prometheus:2.0.0. See https://github.com/previousnext/php-prometheus/issues/16'); + + try { + // @phpstan-ignore argument.type + $counter->set('bing', ['baz' => 'wiz']); + } + catch (\InvalidArgumentException) { + // The deprecation is triggered before the exception is thrown. + } + } + /** + * Tests that a non-int value still throws an exception. + */ + #[IgnoreDeprecations] + public function testNonIntValueThrows(): void { + $counter = new Counter('foo', 'bar', 'Example counter help'); $this->expectException(\InvalidArgumentException::class); - $counter->set('bing', ['baz' => 'wiz']); + // @phpstan-ignore argument.type + @$counter->set('bing', ['baz' => 'wiz']); } /** From a84657b492f3835fab1f1fa28085628020c32b71 Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Fri, 10 Jul 2026 11:50:20 +1000 Subject: [PATCH 2/2] refactor: remove redundant inline phpcs ignore in Counter::set() The TriggerErrorSeeUrlFormat sniff is now excluded globally in phpcs.xml, so the inline phpcs:ignore is no longer needed. --- src/Counter.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Counter.php b/src/Counter.php index 5c0f938..5f25ba6 100644 --- a/src/Counter.php +++ b/src/Counter.php @@ -35,7 +35,6 @@ public function getType(): string { public function set(mixed $value, array $labels = []): void { // @phpstan-ignore function.alreadyNarrowedType if (!is_int($value)) { - // phpcs:ignore Drupal.Semantics.FunctionTriggerError.TriggerErrorSeeUrlFormat @trigger_error(sprintf('Passing a non-int value to %s() is deprecated in php_prometheus:1.1.0 and will throw a \TypeError in php_prometheus:2.0.0. See https://github.com/previousnext/php-prometheus/issues/16', __METHOD__), E_USER_DEPRECATED); } if (!$this->isValidValue($value)) {