From a016bb7b67b99ca025209cbab50296a6aceffd83 Mon Sep 17 00:00:00 2001 From: Luke Kuzmish <42181698+cosmastech@users.noreply.github.com> Date: Tue, 9 Jul 2024 08:35:20 -0400 Subject: [PATCH] Add PHPStan (#8) * add phpstan * make phpstan happy --- .github/workflows/php.yml | 3 + composer.json | 8 ++- phpstan.neon | 5 ++ src/Adapters/Concerns/HasDefaultTagsTrait.php | 7 ++- .../Concerns/TagNormalizerAwareTrait.php | 4 ++ .../Datadog/DatadogStatsDClientAdapter.php | 6 +- .../InMemory/InMemoryClientAdapter.php | 15 ++++- .../InMemory/Models/InMemoryCountRecord.php | 7 +++ .../Models/InMemoryDistributionRecord.php | 7 +++ .../InMemory/Models/InMemoryGaugeRecord.php | 7 +++ .../Models/InMemoryHistogramRecord.php | 7 +++ .../InMemory/Models/InMemorySetRecord.php | 9 ++- .../InMemory/Models/InMemoryTimingRecord.php | 7 +++ .../League/LeagueStatsDClientAdapter.php | 30 ++++++++- src/Adapters/StatsDClientAdapter.php | 62 ++++++++++++++++++- src/Clients/Datadog/DatadogLoggingClient.php | 9 +++ src/TagNormalizers/ConvertEnumNormalizer.php | 4 ++ src/TagNormalizers/NoopTagNormalizer.php | 4 ++ src/TagNormalizers/TagNormalizer.php | 4 ++ .../League/LeagueStatsDClientTest.php | 2 + .../Datadog/DatadogLoggingClientTest.php | 5 +- tests/Doubles/ClockStub.php | 5 +- tests/Doubles/TagNormalizerSpy.php | 8 +++ .../ConvertEnumNormalizerTest.php | 2 +- .../SampleRateSendDeciderTest.php | 8 +-- 25 files changed, 216 insertions(+), 19 deletions(-) create mode 100644 phpstan.neon diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index db74d6b..d410319 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -42,3 +42,6 @@ jobs: - name: Style check run: composer php-cs-fixer-check + + - name: Static Analysis + run: composer static-analysis diff --git a/composer.json b/composer.json index 2c17043..0ba92bf 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,8 @@ "friendsofphp/php-cs-fixer": "^3.59", "league/statsd": "^2.0.0", "cosmastech/psr-logger-spy": "^0.0.2", - "datadog/php-datadogstatsd": "^1.6.1" + "datadog/php-datadogstatsd": "^1.6.1", + "phpstan/phpstan": "^1.11" }, "suggest": { "datadog/php-datadogstatsd": "For DataDog stats", @@ -40,6 +41,9 @@ "scripts": { "test": "phpunit tests", "php-cs-fixer": "./vendor/bin/php-cs-fixer fix ./", - "php-cs-fixer-check": "./vendor/bin/php-cs-fixer check ./" + "php-cs-fixer-check": "./vendor/bin/php-cs-fixer check ./", + "static-analysis": [ + "@php vendor/bin/phpstan analyse -c phpstan.neon" + ] } } diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..3a1f859 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,5 @@ +parameters: + level: 7 + paths: + - src + - tests diff --git a/src/Adapters/Concerns/HasDefaultTagsTrait.php b/src/Adapters/Concerns/HasDefaultTagsTrait.php index d607a61..5ccb91f 100644 --- a/src/Adapters/Concerns/HasDefaultTagsTrait.php +++ b/src/Adapters/Concerns/HasDefaultTagsTrait.php @@ -4,6 +4,9 @@ trait HasDefaultTagsTrait { + /** + * @var array + */ protected array $defaultTags = []; /** @@ -23,8 +26,8 @@ public function setDefaultTags(array $defaultTags = []): void } /** - * @param array $tags - * @return array + * @param array $tags + * @return array */ protected function mergeTags(array $tags): array { diff --git a/src/Adapters/Concerns/TagNormalizerAwareTrait.php b/src/Adapters/Concerns/TagNormalizerAwareTrait.php index a731a44..b316197 100644 --- a/src/Adapters/Concerns/TagNormalizerAwareTrait.php +++ b/src/Adapters/Concerns/TagNormalizerAwareTrait.php @@ -13,6 +13,10 @@ public function setTagNormalizer(TagNormalizer $tagNormalizer): void $this->tagNormalizer = $tagNormalizer; } + /** + * @param array $tags + * @return array + */ protected function normalizeTags(array $tags): array { return $this->tagNormalizer->normalize($tags); diff --git a/src/Adapters/Datadog/DatadogStatsDClientAdapter.php b/src/Adapters/Datadog/DatadogStatsDClientAdapter.php index 03cd4bb..a014a2e 100644 --- a/src/Adapters/Datadog/DatadogStatsDClientAdapter.php +++ b/src/Adapters/Datadog/DatadogStatsDClientAdapter.php @@ -14,6 +14,10 @@ class DatadogStatsDClientAdapter implements StatsDClientAdapter, TagNormalizerAw use HasDefaultTagsTrait; use TagNormalizerAwareTrait; + /** + * @param DogStatsd $datadogClient + * @param array $defaultTags + */ public function __construct(protected readonly DogStatsd $datadogClient, array $defaultTags = []) { $this->tagNormalizer = new NoopTagNormalizer(); @@ -90,7 +94,7 @@ public function decrement(array|string $stats, float $sampleRate = 1.0, array $t ); } - public function updateStats(array|string $stats, int $delta = 1, $sampleRate = 1.0, $tags = null): void + public function updateStats(array|string $stats, int $delta = 1, $sampleRate = 1.0, array $tags = null): void { $this->datadogClient->updateStats( $stats, diff --git a/src/Adapters/InMemory/InMemoryClientAdapter.php b/src/Adapters/InMemory/InMemoryClientAdapter.php index f7595f2..2a1fc44 100644 --- a/src/Adapters/InMemory/InMemoryClientAdapter.php +++ b/src/Adapters/InMemory/InMemoryClientAdapter.php @@ -25,6 +25,10 @@ class InMemoryClientAdapter implements StatsDClientAdapter, TagNormalizerAware protected InMemoryStatsRecord $stats; protected readonly ClockInterface $clock; + /** + * @param ClockInterface $clock + * @param array $defaultTags + */ public function __construct(ClockInterface $clock = new Clock(), array $defaultTags = []) { $this->clock = $clock; @@ -34,6 +38,9 @@ public function __construct(ClockInterface $clock = new Clock(), array $defaultT $this->setDefaultTags($defaultTags); } + /** + * @inheritDoc + */ public function timing(string $stat, float $durationMs, float $sampleRate = 1.0, array $tags = []): void { $this->stats->timing[] = new InMemoryTimingRecord( @@ -45,6 +52,9 @@ public function timing(string $stat, float $durationMs, float $sampleRate = 1.0, ); } + /** + * @inheritDoc + */ public function gauge(string $stat, float $value, float $sampleRate = 1.0, array $tags = []): void { $this->stats->gauge[] = new InMemoryGaugeRecord( @@ -103,7 +113,10 @@ public function decrement(array|string $stats, float $sampleRate = 1.0, array $t $this->updateStats($stats, $value, $sampleRate, $tags); } - public function updateStats(array|string $stats, int $delta = 1, $sampleRate = 1.0, $tags = null): void + /** + * @inheritDoc + */ + public function updateStats(array|string $stats, int $delta = 1, float $sampleRate = 1.0, array $tags = []): void { $stats = (array) $stats; $now = $this->clock->now(); diff --git a/src/Adapters/InMemory/Models/InMemoryCountRecord.php b/src/Adapters/InMemory/Models/InMemoryCountRecord.php index 9f26865..76f9868 100644 --- a/src/Adapters/InMemory/Models/InMemoryCountRecord.php +++ b/src/Adapters/InMemory/Models/InMemoryCountRecord.php @@ -6,6 +6,13 @@ class InMemoryCountRecord { + /** + * @param string $stat + * @param int $count + * @param float $sampleRate + * @param array $tags + * @param DateTimeImmutable $recordedAt + */ public function __construct( public string $stat, public int $count, diff --git a/src/Adapters/InMemory/Models/InMemoryDistributionRecord.php b/src/Adapters/InMemory/Models/InMemoryDistributionRecord.php index 416d930..738ddf4 100644 --- a/src/Adapters/InMemory/Models/InMemoryDistributionRecord.php +++ b/src/Adapters/InMemory/Models/InMemoryDistributionRecord.php @@ -6,6 +6,13 @@ readonly class InMemoryDistributionRecord { + /** + * @param string $stat + * @param float $value + * @param float $sampleRate + * @param array $tags + * @param DateTimeImmutable $recordedAt + */ public function __construct( public string $stat, public float $value, diff --git a/src/Adapters/InMemory/Models/InMemoryGaugeRecord.php b/src/Adapters/InMemory/Models/InMemoryGaugeRecord.php index 8e9b324..33cc966 100644 --- a/src/Adapters/InMemory/Models/InMemoryGaugeRecord.php +++ b/src/Adapters/InMemory/Models/InMemoryGaugeRecord.php @@ -6,6 +6,13 @@ readonly class InMemoryGaugeRecord { + /** + * @param string $stat + * @param float $value + * @param float $sampleRate + * @param array $tags + * @param DateTimeImmutable $recordedAt + */ public function __construct( public string $stat, public float $value, diff --git a/src/Adapters/InMemory/Models/InMemoryHistogramRecord.php b/src/Adapters/InMemory/Models/InMemoryHistogramRecord.php index 167ea5f..bcdff61 100644 --- a/src/Adapters/InMemory/Models/InMemoryHistogramRecord.php +++ b/src/Adapters/InMemory/Models/InMemoryHistogramRecord.php @@ -6,6 +6,13 @@ readonly class InMemoryHistogramRecord { + /** + * @param string $stat + * @param float $value + * @param float $sampleRate + * @param array $tags + * @param DateTimeImmutable $recordedAt + */ public function __construct( public string $stat, public float $value, diff --git a/src/Adapters/InMemory/Models/InMemorySetRecord.php b/src/Adapters/InMemory/Models/InMemorySetRecord.php index 864493b..549d647 100644 --- a/src/Adapters/InMemory/Models/InMemorySetRecord.php +++ b/src/Adapters/InMemory/Models/InMemorySetRecord.php @@ -6,9 +6,16 @@ readonly class InMemorySetRecord { + /** + * @param string $stat + * @param float|string $value + * @param float $sampleRate + * @param array $tags + * @param DateTimeImmutable $recordedAt + */ public function __construct( public string $stat, - public float $value, + public float|string $value, public float $sampleRate, public array $tags, public DateTimeImmutable $recordedAt, diff --git a/src/Adapters/InMemory/Models/InMemoryTimingRecord.php b/src/Adapters/InMemory/Models/InMemoryTimingRecord.php index 1c1b9b7..84c56ad 100644 --- a/src/Adapters/InMemory/Models/InMemoryTimingRecord.php +++ b/src/Adapters/InMemory/Models/InMemoryTimingRecord.php @@ -6,6 +6,13 @@ readonly class InMemoryTimingRecord { + /** + * @param string $stat + * @param float $durationMilliseconds + * @param float $sampleRate + * @param array $tags + * @param DateTimeImmutable $recordedAt + */ public function __construct( public string $stat, public float $durationMilliseconds, diff --git a/src/Adapters/League/LeagueStatsDClientAdapter.php b/src/Adapters/League/LeagueStatsDClientAdapter.php index 54631f6..5485f21 100644 --- a/src/Adapters/League/LeagueStatsDClientAdapter.php +++ b/src/Adapters/League/LeagueStatsDClientAdapter.php @@ -26,6 +26,12 @@ class LeagueStatsDClientAdapter implements StatsDClientAdapter, TagNormalizerAwa */ protected Closure $unavailableStatHandler; + /** + * @param LeagueStatsDClientInterface $leagueStatsDClient + * @param SampleRateSendDeciderInterface $sampleRateSendDecider + * @param array $defaultTags + * @param TagNormalizer $tagNormalizer + */ public function __construct( protected readonly LeagueStatsDClientInterface $leagueStatsDClient, protected readonly SampleRateSendDeciderInterface $sampleRateSendDecider = new SampleRateSendDecider(), @@ -37,6 +43,12 @@ public function __construct( } /** + * @param array $config + * @param string $instanceName + * @param SampleRateSendDeciderInterface|null $sampleRateSendDecider + * @param array $defaultTags + * @return self + * * @throws ConfigurationException */ public static function fromConfig( @@ -44,7 +56,8 @@ public static function fromConfig( string $instanceName = 'default', ?SampleRateSendDeciderInterface $sampleRateSendDecider = null, array $defaultTags = [] - ): static { + ): self { + /** @var Client $instance */ $instance = Client::instance($instanceName); $instance->configure($config); @@ -66,6 +79,13 @@ public function setUnavailableStatHandler(Closure $closure): self return $this; } + /** + * @param string $stat + * @param float $value + * @param float $sampleRate + * @param array $tags + * @return void + */ protected function handleUnavailableStat( string $stat, float $value, @@ -85,6 +105,12 @@ protected function getUnavailableStatHandler(): Closure /** + * @param string $stat + * @param float $durationMs + * @param float $sampleRate + * @param array $tags + * @return void + * * @throws ConnectionException */ public function timing(string $stat, float $durationMs, float $sampleRate = 1.0, array $tags = []): void @@ -171,7 +197,7 @@ public function decrement(array|string $stats, float $sampleRate = 1.0, array $t /** * @throws ConnectionException */ - public function updateStats(array|string $stats, int $delta = 1, $sampleRate = 1.0, $tags = null): void + public function updateStats(array|string $stats, int $delta = 1, float $sampleRate = 1.0, array $tags = []): void { $this->increment( $stats, diff --git a/src/Adapters/StatsDClientAdapter.php b/src/Adapters/StatsDClientAdapter.php index ccf5328..5ae97d9 100644 --- a/src/Adapters/StatsDClientAdapter.php +++ b/src/Adapters/StatsDClientAdapter.php @@ -4,32 +4,88 @@ interface StatsDClientAdapter { + /** + * @param string $stat + * @param float $durationMs + * @param float $sampleRate + * @param array $tags + * @return void + */ public function timing(string $stat, float $durationMs, float $sampleRate = 1.0, array $tags = []): void; + /** + * @param string $stat + * @param float $value + * @param float $sampleRate + * @param array $tags + * @return void + */ public function gauge(string $stat, float $value, float $sampleRate = 1.0, array $tags = []): void; + /** + * @param string $stat + * @param float $value + * @param float $sampleRate + * @param array $tags + * @return void + */ public function histogram(string $stat, float $value, float $sampleRate = 1.0, array $tags = []): void; + /** + * @param string $stat + * @param float $value + * @param float $sampleRate + * @param array $tags + * @return void + */ public function distribution(string $stat, float $value, float $sampleRate = 1.0, array $tags = []): void; + /** + * @param string $stat + * @param float|string $value + * @param float $sampleRate + * @param array $tags + * @return void + */ public function set(string $stat, float|string $value, float $sampleRate = 1.0, array $tags = []): void; + /** + * @param array|string $stats + * @param float $sampleRate + * @param array $tags + * @param int $value + * @return void + */ public function increment(array|string $stats, float $sampleRate = 1.0, array $tags = [], int $value = 1): void; + /** + * @param array|string $stats + * @param float $sampleRate + * @param array $tags + * @param int $value + * @return void + */ public function decrement(array|string $stats, float $sampleRate = 1.0, array $tags = [], int $value = 1): void; - public function updateStats(array|string $stats, int $delta = 1, $sampleRate = 1.0, $tags = null): void; + /** + * @param array|string $stats + * @param int $delta + * @param float $sampleRate + * @param array $tags + * @return void + */ + public function updateStats(array|string $stats, int $delta = 1, float $sampleRate = 1.0, array $tags = []): void; public function getClient(): mixed; /** - * @param array $tags + * @param array $defaultTags * @return void */ public function setDefaultTags(array $defaultTags = []): void; /** - * @return array + * @return array */ public function getDefaultTags(): array; } diff --git a/src/Clients/Datadog/DatadogLoggingClient.php b/src/Clients/Datadog/DatadogLoggingClient.php index 15f467e..dca953b 100644 --- a/src/Clients/Datadog/DatadogLoggingClient.php +++ b/src/Clients/Datadog/DatadogLoggingClient.php @@ -8,6 +8,11 @@ class DatadogLoggingClient extends DogStatsd { + /** + * @param LoggerInterface $logger + * @param string $logLevel + * @param array $datadogConfig + */ public function __construct( protected readonly LoggerInterface $logger, protected readonly string $logLevel = LogLevel::DEBUG, @@ -16,6 +21,10 @@ public function __construct( parent::__construct($datadogConfig); } + /** + * @param mixed $message + * @return void + */ public function flush($message) { $this->logger->log($this->logLevel, $message); diff --git a/src/TagNormalizers/ConvertEnumNormalizer.php b/src/TagNormalizers/ConvertEnumNormalizer.php index bf2b2da..6419630 100644 --- a/src/TagNormalizers/ConvertEnumNormalizer.php +++ b/src/TagNormalizers/ConvertEnumNormalizer.php @@ -7,6 +7,10 @@ class ConvertEnumNormalizer implements TagNormalizer { + /** + * @param array $tags + * @return array + */ public function normalize(array $tags): array { $toReturn = []; diff --git a/src/TagNormalizers/NoopTagNormalizer.php b/src/TagNormalizers/NoopTagNormalizer.php index 46e8fa3..74c71e4 100644 --- a/src/TagNormalizers/NoopTagNormalizer.php +++ b/src/TagNormalizers/NoopTagNormalizer.php @@ -4,6 +4,10 @@ class NoopTagNormalizer implements TagNormalizer { + /** + * @param array $tags + * @return array + */ public function normalize(array $tags): array { return $tags; diff --git a/src/TagNormalizers/TagNormalizer.php b/src/TagNormalizers/TagNormalizer.php index ab26f91..28dbad2 100644 --- a/src/TagNormalizers/TagNormalizer.php +++ b/src/TagNormalizers/TagNormalizer.php @@ -4,5 +4,9 @@ interface TagNormalizer { + /** + * @param array $tags + * @return array + */ public function normalize(array $tags): array; } diff --git a/tests/Adapters/League/LeagueStatsDClientTest.php b/tests/Adapters/League/LeagueStatsDClientTest.php index afd6332..db4298e 100644 --- a/tests/Adapters/League/LeagueStatsDClientTest.php +++ b/tests/Adapters/League/LeagueStatsDClientTest.php @@ -9,7 +9,9 @@ class LeagueStatsDClientTest extends BaseTestCase { + /** @var array */ protected array $args; + protected function setUp(): void { parent::setUp(); diff --git a/tests/Clients/Datadog/DatadogLoggingClientTest.php b/tests/Clients/Datadog/DatadogLoggingClientTest.php index c9afd36..5802d9d 100644 --- a/tests/Clients/Datadog/DatadogLoggingClientTest.php +++ b/tests/Clients/Datadog/DatadogLoggingClientTest.php @@ -21,7 +21,7 @@ public function setUp(): void #[Test] #[DataProvider("logLevelsDataProvider")] - public function respectsLogLevel(string $logLevel) + public function respectsLogLevel(string $logLevel): void { // Given $datadogLoggingClient = new DatadogLoggingClient($this->loggerSpy, $logLevel); @@ -36,6 +36,9 @@ public function respectsLogLevel(string $logLevel) self::assertEquals($logLevel, $logs[0]->getLevel()->value); } + /** + * @return array> + */ public static function logLevelsDataProvider(): array { return [ diff --git a/tests/Doubles/ClockStub.php b/tests/Doubles/ClockStub.php index 93ae395..b31dc88 100644 --- a/tests/Doubles/ClockStub.php +++ b/tests/Doubles/ClockStub.php @@ -8,11 +8,14 @@ class ClockStub implements ClockInterface { - /** @var array */ + /** @var array */ private readonly array $time; private int $currentIndex = 0; + /** + * @param array|DateTimeImmutable $now + */ public function __construct(array|DateTimeImmutable $now) { $time = is_array($now) ? $now : [$now]; diff --git a/tests/Doubles/TagNormalizerSpy.php b/tests/Doubles/TagNormalizerSpy.php index 093c663..87f87ef 100644 --- a/tests/Doubles/TagNormalizerSpy.php +++ b/tests/Doubles/TagNormalizerSpy.php @@ -6,8 +6,13 @@ class TagNormalizerSpy implements TagNormalizer { + /** @var array */ private array $normalizeCalls = []; + /** + * @param array $tags + * @return array + */ public function normalize(array $tags): array { $this->normalizeCalls[] = $tags; @@ -15,6 +20,9 @@ public function normalize(array $tags): array return $tags; } + /** + * @return array + */ public function getNormalizeCalls(): array { return $this->normalizeCalls; diff --git a/tests/TagNormalizers/ConvertEnumNormalizerTest.php b/tests/TagNormalizers/ConvertEnumNormalizerTest.php index 378b24f..b731563 100644 --- a/tests/TagNormalizers/ConvertEnumNormalizerTest.php +++ b/tests/TagNormalizers/ConvertEnumNormalizerTest.php @@ -12,7 +12,7 @@ class ConvertEnumNormalizerTest extends TestCase { #[Test] - public function normalize_convertsBackedEnumInValue() + public function normalize_convertsBackedEnumInValue(): void { // Given $convertEnumNormalizer = new ConvertEnumNormalizer(); diff --git a/tests/Utility/SampleRateDecider/SampleRateSendDeciderTest.php b/tests/Utility/SampleRateDecider/SampleRateSendDeciderTest.php index 1f1cb8b..b40d9cc 100644 --- a/tests/Utility/SampleRateDecider/SampleRateSendDeciderTest.php +++ b/tests/Utility/SampleRateDecider/SampleRateSendDeciderTest.php @@ -9,7 +9,7 @@ class SampleRateSendDeciderTest extends BaseTestCase { #[Test] - public function decide_sampleRateEquals1_returnsTrue() + public function decide_sampleRateEquals1_returnsTrue(): void { // Given $sampleRate = 1; @@ -22,7 +22,7 @@ public function decide_sampleRateEquals1_returnsTrue() } #[Test] - public function decide_sampleRateAbove1_returnsTrue() + public function decide_sampleRateAbove1_returnsTrue(): void { // Given $sampleRate = 1.01; @@ -35,7 +35,7 @@ public function decide_sampleRateAbove1_returnsTrue() } #[Test] - public function decide_sampleRateEquals0_returnsFalse() + public function decide_sampleRateEquals0_returnsFalse(): void { // Given $sampleRate = 0.0; @@ -48,7 +48,7 @@ public function decide_sampleRateEquals0_returnsFalse() } #[Test] - public function decide_sampleRateBelow0_returnsFalse() + public function decide_sampleRateBelow0_returnsFalse(): void { // Given $sampleRate = -110.0;