getNormalizer()->normalize($this->provideNotNullObject(), 'docgen', [ AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => $this->provideDocGenExpectClass(), ]); $nullNormalizedObject = $this->getNormalizer()->normalize(null, 'docgen', [ AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => $this->provideDocGenExpectClass(), ]); self::assertEqualsCanonicalizing(array_keys($normalizedObject), array_keys($nullNormalizedObject)); self::assertArrayHasKey('isNull', $nullNormalizedObject, 'each object must have an "isNull" key'); self::assertTrue($nullNormalizedObject['isNull'], 'isNull key must be true for null objects'); self::assertFalse($normalizedObject['isNull'], 'isNull key must be false for null objects'); foreach ($normalizedObject as $key => $value) { if (in_array($key, ['isNull', 'type'])) { continue; } if (is_array($value)) { if (array_is_list($value)) { self::assertEquals([], $nullNormalizedObject[$key], "list must be serialized as an empty array, in {$key}"); } else { self::assertEqualsCanonicalizing(array_keys($value), array_keys($nullNormalizedObject[$key]), "sub-object must have the same keys, in {$key}"); } } elseif (is_string($value)) { self::assertEquals('', $nullNormalizedObject[$key], 'strings must be '); } } } /** * @return T */ abstract public function provideNotNullObject(): object; /** * @return class-string */ abstract public function provideDocGenExpectClass(): string; abstract public function getNormalizer(): NormalizerInterface; }