From f54c3fae89c618b9135ad23b5f974e10bd7e3243 Mon Sep 17 00:00:00 2001 From: Kim Pepper Date: Sat, 13 Jan 2024 10:53:32 +1100 Subject: [PATCH] Modernise codebase (#8) * Replace hard-coded Guzzle with PSR implementation * Strict types * Replace GitHub action workflow * Add PHPStan baseline --- .github/workflows/build.yml | 43 ++++ .github/workflows/continuous-integration.yml | 34 --- .gitignore | 3 +- README.md | 6 +- composer.json | 30 ++- phpcs.xml | 26 +-- phpstan-baseline.neon | 31 +++ phpstan.neon | 11 + phpunit.xml | 64 ++---- src/BomClient.php | 91 +++----- src/Forecast/Area.php | 24 +- src/Forecast/Forecast.php | 34 +-- src/Forecast/ForecastPeriod.php | 210 +++--------------- src/Forecast/Serializer/AreaNormalizer.php | 9 +- .../Serializer/ForecastNormalizer.php | 9 +- .../Serializer/ForecastPeriodNormalizer.php | 18 +- .../Serializer/ForecastSerializerFactory.php | 9 +- src/Observation/Observation.php | 102 ++------- src/Observation/ObservationList.php | 30 +-- src/Observation/Pressure.php | 34 +-- .../Serializer/ObservationListNormalizer.php | 7 +- .../Serializer/ObservationNormalizer.php | 11 +- .../ObservationSerializerFactory.php | 7 +- src/Observation/Station.php | 74 ++---- src/Observation/Temperature.php | 98 ++------ src/Observation/Wind.php | 79 ++----- src/Util/BaseNormalizer.php | 20 +- src/Util/ClassNameSupportNormalizerTrait.php | 42 ++-- tests/Functional/BomClientTest.php | 64 ------ tests/bootstrap.php | 2 - tests/src/Functional/BomClientTest.php | 88 ++++++++ .../Serializer/ForecastSerializerTest.php | 36 +-- .../Serializer/ObservationSerializerTest.php | 9 +- 33 files changed, 483 insertions(+), 872 deletions(-) create mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/continuous-integration.yml create mode 100644 phpstan-baseline.neon create mode 100644 phpstan.neon delete mode 100644 tests/Functional/BomClientTest.php create mode 100644 tests/src/Functional/BomClientTest.php rename tests/{ => src}/Unit/Forecast/Serializer/ForecastSerializerTest.php (87%) rename tests/{ => src}/Unit/Observation/Serializer/ObservationSerializerTest.php (90%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..27f9284 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,43 @@ +name: ๐Ÿ— Build + +on: + pull_request: + types: [ synchronize, opened, reopened, ready_for_review ] + push: + branches: [ main ] + +permissions: + checks: write + pull-requests: write + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + prefer_lowest: ["", "--prefer-lowest"] + php: ["8.1", "8.2", "8.3"] + container: + image: skpr/php-cli:${{ matrix.php }}-dev-v2-edge + options: + --pull always + --user 1001:1001 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + show-progress: false + - name: ๐Ÿ“ฆ Composer Update + run: composer update --with-all-dependencies --prefer-dist --no-progress --no-interaction ${{ matrix.prefer_lowest }} + - name: ๐Ÿงน PHPCS + run: ./bin/phpcs --report=checkstyle -q | ./bin/cs2pr + - name: ๐Ÿงน PHPStan + run: ./bin/phpstan --error-format=github analyse + - name: โšก Run Tests + run: ./bin/phpunit --log-junit phpunit-results.xml + - name: ๐Ÿ“ Publish Test Results + uses: EnricoMi/publish-unit-test-result-action@v2 + if: always() + with: + files: phpunit-results.xml + check_name: Test Results ${{ matrix.php }} ${{ matrix.prefer_lowest }} diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml deleted file mode 100644 index fa809a0..0000000 --- a/.github/workflows/continuous-integration.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: "Continuous Integration" - -on: - pull_request: - push: - branches: - - '[0-9]+.[0-9]+.x' - - 'refs/pull/*' - tags: - - '[0-9]+.[0-9]+.x' - -jobs: - matrix: - name: Generate job matrix - runs-on: ubuntu-latest - outputs: - matrix: ${{ steps.matrix.outputs.matrix }} - steps: - - name: Gather CI configuration - id: matrix - uses: laminas/laminas-ci-matrix-action@v1 - - qa: - name: QA Checks - needs: [matrix] - runs-on: ${{ matrix.operatingSystem }} - strategy: - fail-fast: false - matrix: ${{ fromJSON(needs.matrix.outputs.matrix) }} - steps: - - name: ${{ matrix.name }} - uses: laminas/laminas-continuous-integration-action@v1 - with: - job: ${{ matrix.job }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9902d7b..55b5178 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/composer.lock +/.phpunit.cache /bin /vendor -/composer.lock diff --git a/README.md b/README.md index da4db89..a4a603a 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,7 @@ composer require previousnext/bom-weather ### Forecasts ```php -$logger = new NullLogger(); -$client = new BomClient($logger); +$client = new BomClient(new Client(), new RequestFactory(), new NullLogger()); $forecast = $client->getForecast('IDN10031'); $issueTime = $forecast->getIssueTime(); @@ -46,8 +45,7 @@ foreach ($locations as $location) { ### Observations ```php -$logger = new NullLogger(); -$client = new BomClient($logger); +$client = new BomClient(new Client(), new RequestFactory(), new NullLogger()); $observationList = $client->getObservationList('IDN60901', '95757'); $refreshMessage = $observationList->getRefreshMessage(); diff --git a/composer.json b/composer.json index 11d566c..ef93c23 100644 --- a/composer.json +++ b/composer.json @@ -9,29 +9,39 @@ } ], "require": { - "php": "^7.1", - "ext-curl": "*", + "php": "^8.1", "ext-xml": "*", - "guzzlehttp/guzzle": "~6.3", - "psr/log": "~1.0", - "symfony/serializer": "~3.4" + "psr/http-client-implementation": "^1.0", + "psr/http-factory-implementation": "^1.0", + "psr/http-message-implementation": "^1.0", + "psr/log": "^3.0", + "symfony/serializer": "^6.4" }, "require-dev": { - "drupal/coder": ">=8.2.12", - "phpunit/phpunit": "~6.5", - "symfony/phpunit-bridge": "~3.4" + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "guzzlehttp/psr7": "^2.6", + "http-interop/http-factory-guzzle": "^1.2", + "php-http/mock-client": "^1.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.6", + "previousnext/coding-standard": "^0.1.3", + "staabm/annotate-pull-request-from-checkstyle": "^1.8" }, "autoload": { "psr-4": {"BomWeather\\": "src/"} }, "autoload-dev": { - "psr-4": {"BomWeather\\Tests\\": "tests/"} + "psr-4": {"BomWeather\\Tests\\": "tests/src"} }, "config": { "bin-dir": "bin/", "preferred-install": { "*": "dist" }, - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true, + "php-http/discovery": true + } } } diff --git a/phpcs.xml b/phpcs.xml index 2eb97a7..0253d5a 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -1,26 +1,8 @@ - - PHP CodeSniffer configuration for BOM Weather - + ./src - ./tests - - - + ./tests/src + + - - - - - - diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..3313301 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,31 @@ +parameters: + ignoreErrors: + - + message: "#^Method BomWeather\\\\Util\\\\BaseNormalizer\\:\\:normalize\\(\\) return type with generic class ArrayObject does not specify its types\\: TKey, TValue$#" + count: 1 + path: src/Util/BaseNormalizer.php + + - + message: "#^Call to method getEndTime\\(\\) on an unknown class BomWeather\\\\Forecast\\\\RegionForecastPeriod\\.$#" + count: 1 + path: tests/src/Unit/Forecast/Serializer/ForecastSerializerTest.php + + - + message: "#^Call to method getForecast\\(\\) on an unknown class BomWeather\\\\Forecast\\\\RegionForecastPeriod\\.$#" + count: 1 + path: tests/src/Unit/Forecast/Serializer/ForecastSerializerTest.php + + - + message: "#^Call to method getStartTime\\(\\) on an unknown class BomWeather\\\\Forecast\\\\RegionForecastPeriod\\.$#" + count: 1 + path: tests/src/Unit/Forecast/Serializer/ForecastSerializerTest.php + + - + message: "#^Parameter \\#1 \\$periods of method BomWeather\\\\Tests\\\\Unit\\\\Forecast\\\\Serializer\\\\ForecastSerializerTest\\:\\:assertRegionPeriods\\(\\) expects array\\, array\\ given\\.$#" + count: 1 + path: tests/src/Unit/Forecast/Serializer/ForecastSerializerTest.php + + - + message: "#^Parameter \\$periods of method BomWeather\\\\Tests\\\\Unit\\\\Forecast\\\\Serializer\\\\ForecastSerializerTest\\:\\:assertRegionPeriods\\(\\) has invalid type BomWeather\\\\Forecast\\\\RegionForecastPeriod\\.$#" + count: 1 + path: tests/src/Unit/Forecast/Serializer/ForecastSerializerTest.php diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..c488226 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,11 @@ +includes: + - phpstan-baseline.neon + +parameters: + level: 6 + paths: + - src + - tests/src + checkMissingIterableValueType: false + ignoreErrors: + - "#^Call to an undefined method Symfony\\\\Component\\\\Serializer\\\\SerializerInterface\\:\\:denormalize\\(\\)\\.$#" diff --git a/phpunit.xml b/phpunit.xml index 2cf0a05..e63b442 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,43 +1,27 @@ - - - - - - - - - - - - - - ./tests/Unit - - - ./tests/Functional - - - - - - - - - - ./src - - - ./ - ./ - - - + beStrictAboutTodoAnnotatedTests="true" + convertDeprecationsToExceptions="true" + failOnRisky="true" + failOnWarning="true" + verbose="true"> + + + tests/src + + + + + + src + + diff --git a/src/BomClient.php b/src/BomClient.php index 3d2d6fe..a704b2a 100644 --- a/src/BomClient.php +++ b/src/BomClient.php @@ -1,14 +1,16 @@ logger = $logger; - if ($httpClient == NULL) { - $httpClient = new Client([ - 'headers' => ['Accept-Encoding' => 'gzip'], - ]); - } - $this->httpClient = $httpClient; - if ($forecastSerializer == NULL) { $forecastSerializer = ForecastSerializerFactory::create(); } @@ -90,22 +48,23 @@ public function __construct( * * @return \BomWeather\Forecast\Forecast|null * The forecast, or NULL if not found. - * - * @throws \GuzzleHttp\Exception\GuzzleException */ public function getForecast(string $productId): ?Forecast { try { - $response = $this->httpClient->request('GET', "http://www.bom.gov.au/fwo/$productId.xml"); + $request = $this->requestFactory->createRequest('GET', "http://www.bom.gov.au/fwo/$productId.xml") + ->withHeader('Accept-Encoding', 'gzip'); + $response = $this->httpClient->sendRequest($request); /** @var \BomWeather\Forecast\Forecast $forecast */ $forecast = $this->forecastSerializer->deserialize($response->getBody(), Forecast::class, 'xml'); return $forecast; } - catch (ClientException $e) { - $this->logger->error("Failed to fetch forecast for ID $productId"); + catch (ClientExceptionInterface $e) { + $this->logger->error("Failed to fetch forecast for ID $productId", [ + 'exception' => $e, + ]); return NULL; } - } /** @@ -118,17 +77,21 @@ public function getForecast(string $productId): ?Forecast { * * @return \BomWeather\Observation\ObservationList|null * The observation, or null if not found. - * - * @throws \GuzzleHttp\Exception\GuzzleException */ public function getObservationList(string $productId, string $wmo): ?ObservationList { try { - $response = $this->httpClient->request('GET', "http://reg.bom.gov.au/fwo/$productId/$productId.$wmo.json"); + $request = $this->requestFactory->createRequest('GET', "http://reg.bom.gov.au/fwo/$productId/$productId.$wmo.json") + ->withHeader('Accept-Encoding', 'gzip'); + $response = $this->httpClient->sendRequest($request); + + /** @var \BomWeather\Observation\ObservationList $observationList */ $observationList = $this->observationSerializer->deserialize($response->getBody(), ObservationList::class, 'json'); return $observationList; } - catch (ClientException $e) { - $this->logger->error("Failed to fetch observation list for product $productId and WMO $wmo"); + catch (ClientExceptionInterface $e) { + $this->logger->error("Failed to fetch observation list for product $productId and WMO $wmo", [ + 'exception' => $e, + ]); return NULL; } } diff --git a/src/Forecast/Area.php b/src/Forecast/Area.php index b9f85a7..cea835c 100644 --- a/src/Forecast/Area.php +++ b/src/Forecast/Area.php @@ -1,11 +1,13 @@ issueTime; } /** * Sets the issue time. - * - * @param \DateTime $issueTime - * The issue time. - * - * @return $this */ - public function setIssueTime(\DateTime $issueTime): Forecast { + public function setIssueTime(\DateTimeImmutable $issueTime): Forecast { $this->issueTime = $issueTime; return $this; } diff --git a/src/Forecast/ForecastPeriod.php b/src/Forecast/ForecastPeriod.php index 824f621..22f9918 100644 --- a/src/Forecast/ForecastPeriod.php +++ b/src/Forecast/ForecastPeriod.php @@ -1,177 +1,130 @@ startTime; } /** * Sets the start time. - * - * @param \DateTime $startTime - * The start time. - * - * @return $this */ - public function setStartTime(\DateTime $startTime): ForecastPeriod { + public function setStartTime(\DateTimeImmutable $startTime): ForecastPeriod { $this->startTime = $startTime; return $this; } /** * Gets the end time. - * - * @return \DateTime - * The end time. */ - public function getEndTime(): \DateTime { + public function getEndTime(): ?\DateTimeImmutable { return $this->endTime; } /** * Sets the end time. - * - * @param \DateTime $endTime - * The end time. - * - * @return $this */ - public function setEndTime(\DateTime $endTime): ForecastPeriod { + public function setEndTime(\DateTimeImmutable $endTime): ForecastPeriod { $this->endTime = $endTime; return $this; } /** * Gets the icon code. - * - * @return string - * The icon code. */ public function getIconCode(): ?string { return $this->iconCode; @@ -179,11 +132,6 @@ public function getIconCode(): ?string { /** * Sets the icon code. - * - * @param string $iconCode - * The icon code. - * - * @return $this */ public function setIconCode(string $iconCode): ForecastPeriod { $this->iconCode = $iconCode; @@ -192,9 +140,6 @@ public function setIconCode(string $iconCode): ForecastPeriod { /** * Gets the precipitation range. - * - * @return string - * The precipitation range. */ public function getPrecipitationRange(): ?string { return $this->precipitationRange; @@ -202,23 +147,14 @@ public function getPrecipitationRange(): ?string { /** * Sets the precipitation range. - * - * @param string $precipitationRange - * The precipitation range. - * - * @return $this */ - public function setPrecipitationRange(string $precipitationRange - ): ForecastPeriod { + public function setPrecipitationRange(string $precipitationRange): ForecastPeriod { $this->precipitationRange = $precipitationRange; return $this; } /** * Gets the air temp minimum. - * - * @return int - * The air temp minimum. */ public function getAirTempMinimum(): ?int { return $this->airTempMinimum; @@ -226,11 +162,6 @@ public function getAirTempMinimum(): ?int { /** * Sets the air temp minimum. - * - * @param int $airTempMinimum - * The air temp minimum. - * - * @return $this */ public function setAirTempMinimum(int $airTempMinimum): ForecastPeriod { $this->airTempMinimum = $airTempMinimum; @@ -239,9 +170,6 @@ public function setAirTempMinimum(int $airTempMinimum): ForecastPeriod { /** * Gets the air temp maximum. - * - * @return int - * The air temp maximum. */ public function getAirTempMaximum(): ?int { return $this->airTempMaximum; @@ -249,23 +177,14 @@ public function getAirTempMaximum(): ?int { /** * Sets the air temp maximum. - * - * @param int $airTempMaximum - * The air temp maximum. - * - * @return $this */ - public function setAirTempMaximum(int $airTempMaximum - ): ForecastPeriod { + public function setAirTempMaximum(int $airTempMaximum): ForecastPeriod { $this->airTempMaximum = $airTempMaximum; return $this; } /** * Gets the precis. - * - * @return string - * The precis. */ public function getPrecis(): ?string { return $this->precis; @@ -273,11 +192,6 @@ public function getPrecis(): ?string { /** * Sets the precis. - * - * @param string $precis - * The precis. - * - * @return $this */ public function setPrecis(string $precis): ForecastPeriod { $this->precis = $precis; @@ -286,9 +200,6 @@ public function setPrecis(string $precis): ForecastPeriod { /** * Gets the probability of precipitation. - * - * @return string - * The probability of precipitation. */ public function getProbabilityOfPrecipitation(): ?string { return $this->probabilityOfPrecipitation; @@ -296,11 +207,6 @@ public function getProbabilityOfPrecipitation(): ?string { /** * Sets the probability of precipitation. - * - * @param string $probabilityOfPrecipitation - * The probability of precipitation. - * - * @return $this */ public function setProbabilityOfPrecipitation( string $probabilityOfPrecipitation @@ -311,9 +217,6 @@ public function setProbabilityOfPrecipitation( /** * Gets the forecast. - * - * @return string - * The forecast. */ public function getForecast(): ?string { return $this->forecast; @@ -321,11 +224,6 @@ public function getForecast(): ?string { /** * Sets the forecast. - * - * @param string $forecast - * The forecast. - * - * @return $this */ public function setForecast(string $forecast): ForecastPeriod { $this->forecast = $forecast; @@ -334,9 +232,6 @@ public function setForecast(string $forecast): ForecastPeriod { /** * Gets the UV alert. - * - * @return string - * The UV alert. */ public function getUvAlert(): ?string { return $this->uvAlert; @@ -344,11 +239,6 @@ public function getUvAlert(): ?string { /** * Sets the UV alert. - * - * @param string $uvAlert - * The UV alert. - * - * @return $this */ public function setUvAlert(string $uvAlert): ForecastPeriod { $this->uvAlert = $uvAlert; @@ -357,21 +247,13 @@ public function setUvAlert(string $uvAlert): ForecastPeriod { /** * Gets the synoptic. - * - * @return string - * The synoptic. */ - public function getSynoptic(): string { + public function getSynoptic(): ?string { return $this->synoptic; } /** * Sets the synoptic. - * - * @param string $synoptic - * The synoptic. - * - * @return $this */ public function setSynoptic(string $synoptic): ForecastPeriod { $this->synoptic = $synoptic; @@ -380,21 +262,13 @@ public function setSynoptic(string $synoptic): ForecastPeriod { /** * Gets the seas. - * - * @return string - * The seas. */ - public function getSeas(): string { + public function getSeas(): ?string { return $this->seas; } /** * Sets the seas. - * - * @param string $seas - * The seas. - * - * @return $this */ public function setSeas(string $seas): ForecastPeriod { $this->seas = $seas; @@ -403,21 +277,13 @@ public function setSeas(string $seas): ForecastPeriod { /** * Gets the swell. - * - * @return string - * The swell. */ - public function getSwell(): string { + public function getSwell(): ?string { return $this->swell; } /** * Sets the swell. - * - * @param string $swell - * The swell. - * - * @return $this */ public function setSwell(string $swell): ForecastPeriod { $this->swell = $swell; @@ -426,21 +292,13 @@ public function setSwell(string $swell): ForecastPeriod { /** * Gets the weather. - * - * @return string - * The weather. */ - public function getWeather(): string { + public function getWeather(): ?string { return $this->weather; } /** * Sets the weather. - * - * @param string $weather - * The weather. - * - * @return $this */ public function setWeather(string $weather): ForecastPeriod { $this->weather = $weather; @@ -449,21 +307,13 @@ public function setWeather(string $weather): ForecastPeriod { /** * Gets the winds. - * - * @return string - * The winds. */ - public function getWinds(): string { + public function getWinds(): ?string { return $this->winds; } /** * Sets the winds. - * - * @param string $winds - * The winds. - * - * @return $this */ public function setWinds(string $winds): ForecastPeriod { $this->winds = $winds; diff --git a/src/Forecast/Serializer/AreaNormalizer.php b/src/Forecast/Serializer/AreaNormalizer.php index 14d9b2b..ee15051 100644 --- a/src/Forecast/Serializer/AreaNormalizer.php +++ b/src/Forecast/Serializer/AreaNormalizer.php @@ -1,5 +1,7 @@ serializer instanceof DenormalizerInterface) { throw new \RuntimeException('The serializer must implement the DenormalizerInterface.'); } @@ -38,7 +39,7 @@ public function denormalize($data, $class, $format = NULL, array $context = []) $area->addForecastPeriod($this->serializer->denormalize($period, ForecastPeriod::class)); } else { - array_map(function ($period) use ($area) { + \array_map(function ($period) use ($area): void { $area->addForecastPeriod($this->serializer->denormalize($period, ForecastPeriod::class)); }, $data['forecast-period'], [$area]); diff --git a/src/Forecast/Serializer/ForecastNormalizer.php b/src/Forecast/Serializer/ForecastNormalizer.php index 189e414..5b9c7df 100644 --- a/src/Forecast/Serializer/ForecastNormalizer.php +++ b/src/Forecast/Serializer/ForecastNormalizer.php @@ -1,5 +1,7 @@ setIssueTime($this->serializer->denormalize($data['amoc']['issue-time-utc'], \DateTime::class)); + ->setIssueTime($this->serializer->denormalize($data['amoc']['issue-time-utc'], \DateTimeImmutable::class)); if ($this->isAssoc($data['forecast']['area'])) { $area = $data['forecast']['area']; $this->setValue($area, $forecast); } else { - array_map(function ($area) use ($forecast) { - + \array_map(function ($area) use ($forecast): void { $this->setValue($area, $forecast); }, $data['forecast']['area'], [$forecast]); } diff --git a/src/Forecast/Serializer/ForecastPeriodNormalizer.php b/src/Forecast/Serializer/ForecastPeriodNormalizer.php index 1cd695c..eb52a5e 100644 --- a/src/Forecast/Serializer/ForecastPeriodNormalizer.php +++ b/src/Forecast/Serializer/ForecastPeriodNormalizer.php @@ -1,5 +1,7 @@ setStartTime($this->serializer->denormalize($data['@start-time-utc'], \DateTime::class)) - ->setEndTime($this->serializer->denormalize($data['@end-time-utc'], \DateTime::class)); + ->setStartTime($this->serializer->denormalize($data['@start-time-utc'], \DateTimeImmutable::class)) + ->setEndTime($this->serializer->denormalize($data['@end-time-utc'], \DateTimeImmutable::class)); if (isset($data['text'])) { if ($this->isAssoc($data['text'])) { @@ -26,7 +28,7 @@ public function denormalize($data, $class, $format = NULL, array $context = []) $this->setTextValue($text, $period); } else { - array_map(function ($text) use ($period) { + \array_map(function ($text) use ($period): void { $this->setTextValue($text, $period); }, $data['text'], [$period]); } @@ -38,7 +40,7 @@ public function denormalize($data, $class, $format = NULL, array $context = []) $this->setElementValue($element, $period); } else { - array_map(function ($element) use ($period) { + \array_map(function ($element) use ($period): void { $this->setElementValue($element, $period); }, $data['element'], [$period]); } @@ -54,18 +56,18 @@ public function denormalize($data, $class, $format = NULL, array $context = []) * @param \BomWeather\Forecast\ForecastPeriod $period * The period. */ - protected function setElementValue(array $element, ForecastPeriod $period) { + protected function setElementValue(array $element, ForecastPeriod $period): void { switch ($element['@type']) { case 'forecast_icon_code': $period->setIconCode($element['#']); break; case 'air_temperature_minimum': - $period->setAirTempMinimum($element['#']); + $period->setAirTempMinimum((int) $element['#']); break; case 'air_temperature_maximum': - $period->setAirTempMaximum($element['#']); + $period->setAirTempMaximum((int) $element['#']); break; case 'precipitation_range': diff --git a/src/Forecast/Serializer/ForecastSerializerFactory.php b/src/Forecast/Serializer/ForecastSerializerFactory.php index 48a1c30..8d79ef2 100644 --- a/src/Forecast/Serializer/ForecastSerializerFactory.php +++ b/src/Forecast/Serializer/ForecastSerializerFactory.php @@ -1,5 +1,7 @@ $rootNode])]; $normalizers = [ - new DateTimeNormalizer(\DateTime::RFC3339, new \DateTimeZone('UTC')), + new DateTimeNormalizer([DateTimeNormalizer::TIMEZONE_KEY => 'UTC']), new ForecastNormalizer(), new AreaNormalizer(), new ForecastPeriodNormalizer(), diff --git a/src/Observation/Observation.php b/src/Observation/Observation.php index 8692dfc..acc17c9 100644 --- a/src/Observation/Observation.php +++ b/src/Observation/Observation.php @@ -1,91 +1,68 @@ dateTime; } /** * Sets the DateTime. - * - * @param \DateTime $dateTime - * The DateTime. - * - * @return $this */ - public function setDateTime(\DateTime $dateTime): Observation { + public function setDateTime(\DateTimeImmutable $dateTime): self { $this->dateTime = $dateTime; return $this; } /** * Gets the Station. - * - * @return \BomWeather\Observation\Station - * The Station. */ public function getStation(): Station { return $this->station; @@ -93,105 +70,68 @@ public function getStation(): Station { /** * Sets the Station. - * - * @param \BomWeather\Observation\Station $station - * The Station. - * - * @return $this */ - public function setStation(Station $station): Observation { + public function setStation(Station $station): self { $this->station = $station; return $this; } /** * Gets the Temperature. - * - * @return \BomWeather\Observation\Temperature - * The Temperature. */ - public function getTemperature(): Temperature { + public function getTemperature(): ?Temperature { return $this->temperature; } /** * Sets the Temperature. - * - * @param \BomWeather\Observation\Temperature $temperature - * The Temperature. - * - * @return $this */ - public function setTemperature(Temperature $temperature): Observation { + public function setTemperature(Temperature $temperature): ?Observation { $this->temperature = $temperature; return $this; } /** * Gets the Wind. - * - * @return \BomWeather\Observation\Wind - * The Wind. */ - public function getWind(): Wind { + public function getWind(): ?Wind { return $this->wind; } /** * Sets the Wind. - * - * @param \BomWeather\Observation\Wind $wind - * The Wind. - * - * @return $this */ - public function setWind(Wind $wind): Observation { + public function setWind(Wind $wind): self { $this->wind = $wind; return $this; } /** * Gets the Pressure. - * - * @return \BomWeather\Observation\Pressure - * The Pressure. */ - public function getPressure(): Pressure { + public function getPressure(): ?Pressure { return $this->pressure; } /** * Sets the Pressure. - * - * @param \BomWeather\Observation\Pressure $pressure - * The Pressure. - * - * @return $this */ - public function setPressure(Pressure $pressure): Observation { + public function setPressure(Pressure $pressure): self { $this->pressure = $pressure; return $this; } /** * Gets the RainSince9am. - * - * @return int - * The RainSince9am. */ - public function getRainSince9am(): int { + public function getRainSince9am(): ?string { return $this->rainSince9am; } /** * Sets the RainSince9am. - * - * @param int $rainSince9am - * The RainSince9am. - * - * @return $this */ - public function setRainSince9am(int $rainSince9am): Observation { + public function setRainSince9am(string $rainSince9am): self { $this->rainSince9am = $rainSince9am; return $this; } diff --git a/src/Observation/ObservationList.php b/src/Observation/ObservationList.php index 4db2244..5dfd9c0 100644 --- a/src/Observation/ObservationList.php +++ b/src/Observation/ObservationList.php @@ -1,25 +1,25 @@ observations = $observations; return $this; } @@ -49,10 +47,8 @@ public function setObservations(array $observations): ObservationList { * * @param \BomWeather\Observation\Observation $observation * The observation. - * - * @return $this */ - public function addObservation(Observation $observation): ObservationList { + public function addObservation(Observation $observation): self { $this->observations[] = $observation; return $this; } @@ -72,23 +68,15 @@ public function getLatest(): ?Observation { /** * Gets the Refresh Message. - * - * @return string - * The RefreshMessage. */ - public function getRefreshMessage(): string { + public function getRefreshMessage(): ?string { return $this->refreshMessage; } /** * Sets the Refresh Message. - * - * @param string $refreshMessage - * The RefreshMessage. - * - * @return $this */ - public function setRefreshMessage(string $refreshMessage): ObservationList { + public function setRefreshMessage(string $refreshMessage): self { $this->refreshMessage = $refreshMessage; return $this; } diff --git a/src/Observation/Pressure.php b/src/Observation/Pressure.php index fe70acd..5d85cd9 100644 --- a/src/Observation/Pressure.php +++ b/src/Observation/Pressure.php @@ -1,40 +1,33 @@ qnh; @@ -42,11 +35,6 @@ public function getQnh(): ?int { /** * Sets the PressureQnh. - * - * @param int $qnh - * The PressureQnh. - * - * @return $this */ public function setQnh(int $qnh): Pressure { $this->qnh = $qnh; @@ -55,9 +43,6 @@ public function setQnh(int $qnh): Pressure { /** * Gets the PressureMsl. - * - * @return int|null - * The PressureMsl. */ public function getMeanSeaLevel(): ?int { return $this->meanSeaLevel; @@ -65,11 +50,6 @@ public function getMeanSeaLevel(): ?int { /** * Sets the PressureMsl. - * - * @param int $meanSeaLevel - * The PressureMsl. - * - * @return $this */ public function setMeanSeaLevel(int $meanSeaLevel): Pressure { $this->meanSeaLevel = $meanSeaLevel; diff --git a/src/Observation/Serializer/ObservationListNormalizer.php b/src/Observation/Serializer/ObservationListNormalizer.php index 0750964..89257aa 100644 --- a/src/Observation/Serializer/ObservationListNormalizer.php +++ b/src/Observation/Serializer/ObservationListNormalizer.php @@ -1,5 +1,7 @@ serializer instanceof DenormalizerInterface) { throw new \RuntimeException('The serializer must implement the DenormalizerInterface.'); } @@ -26,7 +27,7 @@ public function denormalize($data, $class, $format = NULL, array $context = []) $observationList = new ObservationList(); $observationList->setRefreshMessage($data['observations']['header'][0]['refresh_message']); - array_map(function ($observationData) use ($observationList) { + \array_map(function ($observationData) use ($observationList): void { $observationList->addObservation($this->serializer->denormalize($observationData, Observation::class)); }, $data['observations']['data'], [$observationList]); diff --git a/src/Observation/Serializer/ObservationNormalizer.php b/src/Observation/Serializer/ObservationNormalizer.php index 3ca33d8..4803354 100644 --- a/src/Observation/Serializer/ObservationNormalizer.php +++ b/src/Observation/Serializer/ObservationNormalizer.php @@ -1,5 +1,7 @@ setId($data['wmo']) ->setLatitude($data['lat']) @@ -32,7 +33,7 @@ public function denormalize($data, $class, $format = NULL, array $context = []) ->setApparentTemp($data['apparent_t']) ->setDeltaT($data['delta_t']) ->setDewPoint($data['dewpt']) - ->setRealtiveHumidity($data['rel_hum']); + ->setRelativeHumidity($data['rel_hum']); $wind = Wind::create() ->setDirection($data['wind_dir']) @@ -50,7 +51,7 @@ public function denormalize($data, $class, $format = NULL, array $context = []) } $observation = Observation::create() - ->setDateTime($this->serializer->denormalize($data['aifstime_utc'], \DateTime::class)) + ->setDateTime($this->serializer->denormalize($data['aifstime_utc'], \DateTimeImmutable::class)) ->setRainSince9am($data['rain_trace']) ->setPressure($pressure) ->setTemperature($temperature) diff --git a/src/Observation/Serializer/ObservationSerializerFactory.php b/src/Observation/Serializer/ObservationSerializerFactory.php index b3e4cb7..e310f47 100644 --- a/src/Observation/Serializer/ObservationSerializerFactory.php +++ b/src/Observation/Serializer/ObservationSerializerFactory.php @@ -1,5 +1,7 @@ 'UTC']), new GetSetMethodNormalizer(), ]; return new Serializer($normalizers, $encoders); diff --git a/src/Observation/Station.php b/src/Observation/Station.php index 8257e33..d964fcc 100644 --- a/src/Observation/Station.php +++ b/src/Observation/Station.php @@ -1,137 +1,97 @@ name; } /** * Sets the Name. - * - * @param string $name - * The Name. - * - * @return $this */ - public function setName(string $name): Station { + public function setName(string $name): self { $this->name = $name; return $this; } /** * Gets the Latitude. - * - * @return float - * The Latitude. */ - public function getLatitude(): float { + public function getLatitude(): ?float { return $this->latitude; } /** * Sets the Latitude. - * - * @param float $latitude - * The Latitude. - * - * @return $this */ - public function setLatitude(float $latitude): Station { + public function setLatitude(float $latitude): self { $this->latitude = $latitude; return $this; } /** * Gets the Longitude. - * - * @return float - * The Longitude. */ - public function getLongitude(): float { + public function getLongitude(): ?float { return $this->longitude; } /** * Sets the Longitude. - * - * @param float $longitude - * The Longitude. - * - * @return $this */ - public function setLongitude(float $longitude): Station { + public function setLongitude(float $longitude): self { $this->longitude = $longitude; return $this; } /** * Gets the Id. - * - * @return string - * The Id. */ - public function getId(): string { + public function getId(): ?int { return $this->id; } /** * Sets the Id. - * - * @param string $id - * The Id. - * - * @return $this */ - public function setId(string $id): Station { + public function setId(int $id): self { $this->id = $id; return $this; } diff --git a/src/Observation/Temperature.php b/src/Observation/Temperature.php index 077521d..2d622ae 100644 --- a/src/Observation/Temperature.php +++ b/src/Observation/Temperature.php @@ -1,73 +1,55 @@ airTemp; } /** * Sets the AirTemp. - * - * @param float $airTemp - * The AirTemp. - * - * @return $this */ public function setAirTemp(float $airTemp): Temperature { $this->airTemp = $airTemp; @@ -76,21 +58,13 @@ public function setAirTemp(float $airTemp): Temperature { /** * Gets the ApparentTemp. - * - * @return float - * The ApparentTemp. */ - public function getApparentTemp(): float { + public function getApparentTemp(): ?float { return $this->apparentTemp; } /** * Sets the ApparentTemp. - * - * @param float $apparentTemp - * The ApparentTemp. - * - * @return $this */ public function setApparentTemp(float $apparentTemp): Temperature { $this->apparentTemp = $apparentTemp; @@ -99,21 +73,13 @@ public function setApparentTemp(float $apparentTemp): Temperature { /** * Gets the DewPoint. - * - * @return float - * The DewPoint. */ - public function getDewPoint(): float { + public function getDewPoint(): ?float { return $this->dewPoint; } /** * Sets the DewPoint. - * - * @param float $dewPoint - * The DewPoint. - * - * @return $this */ public function setDewPoint(float $dewPoint): Temperature { $this->dewPoint = $dewPoint; @@ -121,45 +87,29 @@ public function setDewPoint(float $dewPoint): Temperature { } /** - * Gets the RealtiveHumidity. - * - * @return int - * The RealtiveHumidity. + * Gets the RelativeHumidity. */ - public function getRealtiveHumidity(): int { - return $this->realtiveHumidity; + public function getRelativeHumidity(): ?int { + return $this->relativeHumidity; } /** - * Sets the RealtiveHumidity. - * - * @param int $realtiveHumidity - * The RealtiveHumidity. - * - * @return $this + * Sets the RelativeHumidity. */ - public function setRealtiveHumidity(int $realtiveHumidity): Temperature { - $this->realtiveHumidity = $realtiveHumidity; + public function setRelativeHumidity(int $relativeHumidity): Temperature { + $this->relativeHumidity = $relativeHumidity; return $this; } /** * Gets the DeltaT. - * - * @return float - * The DeltaT. */ - public function getDeltaT(): float { + public function getDeltaT(): ?float { return $this->deltaT; } /** * Sets the DeltaT. - * - * @param float $deltaT - * The DeltaT. - * - * @return $this */ public function setDeltaT(float $deltaT): Temperature { $this->deltaT = $deltaT; diff --git a/src/Observation/Wind.php b/src/Observation/Wind.php index ece15ac..d10f8d4 100644 --- a/src/Observation/Wind.php +++ b/src/Observation/Wind.php @@ -1,74 +1,57 @@ direction; } /** * Sets the Direction. - * - * @param string $direction - * The Direction. - * - * @return $this */ public function setDirection(string $direction): Wind { $this->direction = $direction; @@ -77,21 +60,13 @@ public function setDirection(string $direction): Wind { /** * Gets the Speed, in kilometres per hour. - * - * @return int - * The SpeedKmh. */ - public function getSpeedKmh(): int { + public function getSpeedKmh(): ?int { return $this->speedKmh; } /** * Sets the Speed, in kilometres per hour. - * - * @param int $speedKmh - * The SpeedKmh. - * - * @return $this */ public function setSpeedKmh(int $speedKmh): Wind { $this->speedKmh = $speedKmh; @@ -100,21 +75,13 @@ public function setSpeedKmh(int $speedKmh): Wind { /** * Gets the Gust, in kilometres per hour. - * - * @return int - * The GustKmh. */ - public function getGustKmh(): int { + public function getGustKmh(): ?int { return $this->gustKmh; } /** * Sets the Gust, in kilometres per hour. - * - * @param int $gustKmh - * The GustKmh. - * - * @return $this */ public function setGustKmh(int $gustKmh): Wind { $this->gustKmh = $gustKmh; @@ -123,21 +90,13 @@ public function setGustKmh(int $gustKmh): Wind { /** * Gets the Speed, in knots. - * - * @return int - * The SpeedKnots. */ - public function getSpeedKnots(): int { + public function getSpeedKnots(): ?int { return $this->speedKnots; } /** * Sets the Speed, in knots. - * - * @param int $speedKnots - * The SpeedKnots. - * - * @return $this */ public function setSpeedKnots(int $speedKnots): Wind { $this->speedKnots = $speedKnots; @@ -146,21 +105,13 @@ public function setSpeedKnots(int $speedKnots): Wind { /** * Gets the Gust, in knots. - * - * @return int - * The GustsKnots. */ - public function getGustKnots(): int { + public function getGustKnots(): ?int { return $this->gustKnots; } /** * Sets the Gust, in knots. - * - * @param int $gustKnots - * The GustsKnots. - * - * @return $this */ public function setGustKnots(int $gustKnots): Wind { $this->gustKnots = $gustKnots; diff --git a/src/Util/BaseNormalizer.php b/src/Util/BaseNormalizer.php index 2ed9ba1..f1cc270 100644 --- a/src/Util/BaseNormalizer.php +++ b/src/Util/BaseNormalizer.php @@ -1,5 +1,7 @@ supportedInterfaceOrClass; } /** * Sets the string or array of supported classes. - * - * @param array|string $supported_interface_or_class - * The string or array of supported classes. - * - * @return $this - * The current object. */ - public function setSupportedInterfaceOrClass($supported_interface_or_class) { + public function setSupportedInterfaceOrClass(string|array $supported_interface_or_class): self { $this->supportedInterfaceOrClass = $supported_interface_or_class; return $this; } @@ -48,16 +37,16 @@ public function setSupportedInterfaceOrClass($supported_interface_or_class) { /** * {@inheritdoc} */ - public function supportsNormalization($data, $format = NULL) { + public function supportsNormalization(mixed $data, string $format = NULL /* , array $context = [] */): bool { // If we aren't dealing with an object or the format is not supported return // now. - if (!is_object($data) || !$this->checkFormat($format)) { + if (!\is_object($data) || !$this->checkFormat($format)) { return FALSE; } $supported = (array) $this->supportedInterfaceOrClass; - return (bool) array_filter($supported, function ($name) use ($data) { + return (bool) \array_filter($supported, function ($name) use ($data) { return $data instanceof $name; }); } @@ -65,7 +54,7 @@ public function supportsNormalization($data, $format = NULL) { /** * {@inheritdoc} */ - public function supportsDenormalization($data, $type, $format = NULL) { + public function supportsDenormalization(mixed $data, string $type, string $format = NULL /* , array $context = [] */): bool { // If the format is not supported return now. if (!$this->checkFormat($format)) { return FALSE; @@ -74,30 +63,27 @@ public function supportsDenormalization($data, $type, $format = NULL) { $supported = (array) $this->supportedInterfaceOrClass; $subclass_check = function ($name) use ($type) { - return (class_exists($name) || interface_exists($name)) && is_subclass_of($type, + return (\class_exists($name) || \interface_exists($name)) && \is_subclass_of($type, $name, TRUE); }; - return in_array($type, $supported) || array_filter($supported, + return \in_array($type, $supported) || \array_filter($supported, $subclass_check); } /** * Checks if the provided format is supported by this serializer. * - * @param string $format - * The format to check. - * * @return bool * TRUE if the format is supported, FALSE otherwise. If no format is * specified this will return TRUE. */ - protected function checkFormat($format = NULL) { + protected function checkFormat(string $format = NULL): bool { if (!isset($format) || !isset($this->format)) { return TRUE; } - return in_array($format, (array) $this->format); + return \in_array($format, (array) $this->format); } } diff --git a/tests/Functional/BomClientTest.php b/tests/Functional/BomClientTest.php deleted file mode 100644 index 803d6b8..0000000 --- a/tests/Functional/BomClientTest.php +++ /dev/null @@ -1,64 +0,0 @@ -getForecast('IDN10064'); - - $this->assertNotNull($forecast); - } - - /** - * @covers ::__construct() - * @covers ::getObservationList() - */ - public function testGetObservation() { - - $logger = new NullLogger(); - $client = new BomClient($logger); - $observationList = $client->getObservationList('IDN60901', '95757'); - - $this->assertNotNull($observationList); - - $refreshMessage = $observationList->getRefreshMessage(); - - // Get the latest observation. - $observation = $observationList->getLatest(); - $rain = $observation->getRainSince9am(); - - $station = $observation->getStation(); - $name = $station->getName(); - - $temperature = $observation->getTemperature(); - $airTemp = $temperature->getAirTemp(); - $apparentTemp = $temperature->getApparentTemp(); - $relativeHumidity = $temperature->getRealtiveHumidity(); - - $wind = $observation->getWind(); - $direction = $wind->getDirection(); - $speedKmh = $wind->getSpeedKmh(); - $gustKmh = $wind->getGustKmh(); - - $pressure = $observation->getPressure(); - $qnh = $pressure->getQnh(); - $meanSeaLevel = $pressure->getMeanSeaLevel(); - - } - -} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 7ddf755..2117040 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -5,8 +5,6 @@ * Boostrap for PHPUnit. */ -assert_options(ASSERT_ACTIVE, FALSE); - $autoloader = __DIR__ . '/../vendor/autoload.php'; $loader = require $autoloader; diff --git a/tests/src/Functional/BomClientTest.php b/tests/src/Functional/BomClientTest.php new file mode 100644 index 0000000..427cefb --- /dev/null +++ b/tests/src/Functional/BomClientTest.php @@ -0,0 +1,88 @@ +createMock(ResponseInterface::class); + $response->method('getBody') + ->willReturn(new Stream(\fopen(__DIR__ . '/../../fixtures/IDN10064.xml', 'r'))); + $httpClient->addResponse($response); + $requestFactory = $this->createMock(RequestFactoryInterface::class); + $request = $this->createMock(RequestInterface::class); + $requestFactory->method('createRequest') + ->willReturn($request); + $request->method('withHeader')->willReturn($request); + $client = new BomClient($httpClient, $requestFactory, $logger); + $forecast = $client->getForecast('IDN10064'); + + $this->assertNotNull($forecast); + } + + /** + * @covers ::__construct() + * @covers ::getObservationList() + */ + public function testGetObservation(): void { + $logger = new NullLogger(); + $httpClient = new Client(); + $response = $this->createMock(ResponseInterface::class); + $response->method('getBody') + ->willReturn(new Stream(\fopen(__DIR__ . '/../../fixtures/IDN60901.94759.json', 'r'))); + $httpClient->addResponse($response); + $requestFactory = $this->createMock(RequestFactoryInterface::class); + $request = $this->createMock(RequestInterface::class); + $requestFactory->method('createRequest') + ->willReturn($request); + $request->method('withHeader')->willReturn($request); + $client = new BomClient($httpClient, $requestFactory, $logger); + $observationList = $client->getObservationList('IDN60901', '95757'); + + $this->assertNotNull($observationList); + + $refreshMessage = $observationList->getRefreshMessage(); + + // Get the latest observation. + $observation = $observationList->getLatest(); + $rain = $observation->getRainSince9am(); + + $station = $observation->getStation(); + $name = $station->getName(); + + $temperature = $observation->getTemperature(); + $airTemp = $temperature->getAirTemp(); + $apparentTemp = $temperature->getApparentTemp(); + $relativeHumidity = $temperature->getRelativeHumidity(); + + $wind = $observation->getWind(); + $direction = $wind->getDirection(); + $speedKmh = $wind->getSpeedKmh(); + $gustKmh = $wind->getGustKmh(); + + $pressure = $observation->getPressure(); + $qnh = $pressure->getQnh(); + $meanSeaLevel = $pressure->getMeanSeaLevel(); + } + +} diff --git a/tests/Unit/Forecast/Serializer/ForecastSerializerTest.php b/tests/src/Unit/Forecast/Serializer/ForecastSerializerTest.php similarity index 87% rename from tests/Unit/Forecast/Serializer/ForecastSerializerTest.php rename to tests/src/Unit/Forecast/Serializer/ForecastSerializerTest.php index 05d9827..9adc823 100644 --- a/tests/Unit/Forecast/Serializer/ForecastSerializerTest.php +++ b/tests/src/Unit/Forecast/Serializer/ForecastSerializerTest.php @@ -1,5 +1,7 @@ create(); - $xml = file_get_contents(__DIR__ . '/../../../fixtures/IDN10064.xml'); + $xml = \file_get_contents(__DIR__ . '/../../../../fixtures/IDN10064.xml'); /** @var \BomWeather\Forecast\Forecast $forecast */ $forecast = $serializer->deserialize($xml, Forecast::class, 'xml'); @@ -30,7 +32,7 @@ public function testDeserializeSydney() { $regions = $forecast->getRegions(); $this->assertCount(1, $regions); - $region = array_shift($regions); + $region = \array_shift($regions); $this->assertEquals('NSW_FA001', $region->getAac()); $this->assertEquals('New South Wales', $region->getDescription()); @@ -40,7 +42,7 @@ public function testDeserializeSydney() { $metros = $forecast->getMetropolitanAreas(); $this->assertCount(1, $metros); - $metro = array_shift($metros); + $metro = \array_shift($metros); $this->assertEquals('NSW_ME001', $metro->getAac()); $this->assertEquals('Sydney', $metro->getDescription()); $this->assertEquals('metropolitan', $metro->getType()); @@ -52,7 +54,7 @@ public function testDeserializeSydney() { $locations = $forecast->getLocations(); $this->assertCount(8, $locations); - $location = array_shift($locations); + $location = \array_shift($locations); $this->assertEquals('NSW_PT131', $location->getAac()); $this->assertEquals('Sydney', $location->getDescription()); @@ -61,12 +63,11 @@ public function testDeserializeSydney() { $this->assertSydneyPeriods($location->getForecastPeriods()); - $location = end($locations); + $location = \end($locations); $this->assertEquals('NSW_PT237', $location->getAac()); $this->assertEquals('Bondi', $location->getDescription()); $this->assertBondiPeriods($location->getForecastPeriods()); - } /** @@ -75,9 +76,9 @@ public function testDeserializeSydney() { * @param \BomWeather\Forecast\RegionForecastPeriod[] $periods * The regions. */ - protected function assertRegionPeriods(array $periods) { + protected function assertRegionPeriods(array $periods): void { $this->assertCount(1, $periods); - $period = array_shift($periods); + $period = \array_shift($periods); $this->assertEquals('2018-06-20T21:41:56+00:00', $period->getStartTime()->format(DATE_RFC3339)); $this->assertEquals('2018-06-20T21:41:56+00:00', $period->getEndTime()->format(DATE_RFC3339)); @@ -90,22 +91,21 @@ protected function assertRegionPeriods(array $periods) { * @param \BomWeather\Forecast\ForecastPeriod[] $metroPeriods * The periods. */ - protected function assertMetroPeriods(array $metroPeriods) { + protected function assertMetroPeriods(array $metroPeriods): void { $this->assertCount(7, $metroPeriods); - $period = array_shift($metroPeriods); + $period = \array_shift($metroPeriods); $this->assertEquals('2018-06-20T14:00:00+00:00', $period->getStartTime()->format(DATE_RFC3339)); $this->assertEquals('2018-06-21T14:00:00+00:00', $period->getEndTime()->format(DATE_RFC3339)); $this->assertEquals('Cloudy. High (70%) chance of showers along the coastal fringe, slight (30%) chance elsewhere, becoming less likely in the late afternoon and evening. Light winds.', $period->getForecast()); $this->assertEquals('Sun protection not recommended, UV Index predicted to reach 2 [Low]', $period->getUvAlert()); - $period = array_shift($metroPeriods); + $period = \array_shift($metroPeriods); $this->assertEquals('2018-06-21T14:00:00+00:00', $period->getStartTime()->format(DATE_RFC3339)); $this->assertEquals('2018-06-22T14:00:00+00:00', $period->getEndTime()->format(DATE_RFC3339)); $this->assertEquals('Mostly sunny. Fog and patches of light frost in the west in the early morning. Light winds.', $period->getForecast()); $this->assertNull($period->getUvAlert()); - } /** @@ -114,9 +114,9 @@ protected function assertMetroPeriods(array $metroPeriods) { * @param \BomWeather\Forecast\ForecastPeriod[] $locationPeriods * The location periods. */ - protected function assertSydneyPeriods(array $locationPeriods) { + protected function assertSydneyPeriods(array $locationPeriods): void { $this->assertCount(7, $locationPeriods); - $period = array_shift($locationPeriods); + $period = \array_shift($locationPeriods); $this->assertEquals('2018-06-20T21:37:12+00:00', $period->getStartTime()->format(DATE_RFC3339)); $this->assertEquals('2018-06-21T14:00:00+00:00', $period->getEndTime()->format(DATE_RFC3339)); @@ -128,7 +128,7 @@ protected function assertSydneyPeriods(array $locationPeriods) { $this->assertEquals(16, $period->getAirTempMaximum()); $this->assertNull($period->getPrecipitationRange()); - $period = array_shift($locationPeriods); + $period = \array_shift($locationPeriods); $this->assertEquals('2018-06-21T14:00:00+00:00', $period->getStartTime()->format(DATE_RFC3339)); $this->assertEquals('2018-06-22T14:00:00+00:00', $period->getEndTime()->format(DATE_RFC3339)); @@ -147,10 +147,10 @@ protected function assertSydneyPeriods(array $locationPeriods) { * @param \BomWeather\Forecast\ForecastPeriod[] $locationPeriods * The location periods. */ - protected function assertBondiPeriods(array $locationPeriods) { + protected function assertBondiPeriods(array $locationPeriods): void { $this->assertCount(1, $locationPeriods); - $period = array_shift($locationPeriods); + $period = \array_shift($locationPeriods); $this->assertEquals('2018-06-20T21:37:12+00:00', $period->getStartTime()->format(DATE_RFC3339)); $this->assertEquals('2018-06-21T14:00:00+00:00', $period->getEndTime()->format(DATE_RFC3339)); $this->assertEquals(16, $period->getAirTempMaximum()); diff --git a/tests/Unit/Observation/Serializer/ObservationSerializerTest.php b/tests/src/Unit/Observation/Serializer/ObservationSerializerTest.php similarity index 90% rename from tests/Unit/Observation/Serializer/ObservationSerializerTest.php rename to tests/src/Unit/Observation/Serializer/ObservationSerializerTest.php index 94e6659..401f51f 100644 --- a/tests/Unit/Observation/Serializer/ObservationSerializerTest.php +++ b/tests/src/Unit/Observation/Serializer/ObservationSerializerTest.php @@ -1,5 +1,7 @@ deserialize($json, ObservationList::class, 'json'); @@ -41,7 +43,7 @@ public function testDeserialize() { $this->assertEquals(7.8, $temperature->getApparentTemp()); $this->assertEquals(1.1, $temperature->getDeltaT()); $this->assertEquals(7.5, $temperature->getDewPoint()); - $this->assertEquals(86, $temperature->getRealtiveHumidity()); + $this->assertEquals(86, $temperature->getRelativeHumidity()); $wind = $observation->getWind(); $this->assertEquals('W', $wind->getDirection()); @@ -55,7 +57,6 @@ public function testDeserialize() { $this->assertEquals('Terrey Hills', $station->getName()); $this->assertEquals(-33.7, $station->getLatitude()); $this->assertEquals(151.2, $station->getLongitude()); - } }