From 8dad7bd5ca9480ba342c6860d30ef54500b1e768 Mon Sep 17 00:00:00 2001 From: Oliver Klee Date: Tue, 11 Jun 2024 11:56:20 +0200 Subject: [PATCH] [TASK] Document our approach to assertions and type checks (#1339) Fixes #1330 --- Documentation/Assertions.rst | 72 ++++++++++++++++++++++++++++++++++++ Documentation/Index.rst | 1 + 2 files changed, 73 insertions(+) create mode 100644 Documentation/Assertions.rst diff --git a/Documentation/Assertions.rst b/Documentation/Assertions.rst new file mode 100644 index 0000000..fef6b38 --- /dev/null +++ b/Documentation/Assertions.rst @@ -0,0 +1,72 @@ +.. include:: /Includes.rst.txt + +.. _assertions-and-type-checks: + +========================================== +Our approach to assertions and type checks +========================================== + +In general, we use assertions and type checks to catch bad input, to help debug +problems, and to help static type analysis tools like PHPStan or Psalm to +determine the type and range of a variable where it cannot detect it +automatically. + +In production code +------------------ + +To catch bad input that actually is possible, we throw an exception. This allows +developers and users to see what is wrong and to fix it. + +.. code-block:: php + + if (!$model instanceof Tea) { + throw new \RuntimeException('No model found.', 1687363745); + } + + +To help PHPStan and Psalm with variables where we (as developers) know the type +and range for sure, but the tool cannot determine it automatically, we use +assertions. + +This makes the type and range obvious both to PHPStan as well as the human +reader. + +.. code-block:: php + + /** + * @return int<0, max> + */ + private function getUidOfLoggedInUser(): int + { + $userUid = $this->context->getPropertyFromAspect('frontend.user', 'id'); + \assert(\is_int($userUid) && $userUid >= 0); + + return $userUid; + } + +In tests +-------- + +In tests, we use PHPUnit's assertions to check the expected outcome of a test, +and also to test preconditions. + +This allows us to have test failure messages that help debugging as well as +allow PHPStan to determine types. + +.. code-block:: php + + /** + * @test + */ + public function findByUidForExistingRecordMapsAllScalarData(): void + { + $this->importCSVDataSet(__DIR__ . '/Fixtures/TeaWithAllScalarData.csv'); + + $model = $this->subject->findByUid(1); + self::assertInstanceOf(Tea::class, $model); + + self::assertSame('Earl Grey', $model->getTitle()); + self::assertSame('Fresh and hot.', $model->getDescription()); + self::assertSame(2, $model->getOwnerUid()); + } + diff --git a/Documentation/Index.rst b/Documentation/Index.rst index 42be3dd..a53417b 100644 --- a/Documentation/Index.rst +++ b/Documentation/Index.rst @@ -51,6 +51,7 @@ continuous integration. ContinuousIntegration Documentation Security + Assertions DivergencesToTypo3Core .. Meta Menu