code: function property(string $name, $value = null): self {
      $isArray = is_array($this->target) || $this->target instanceof \ArrayAccess;
      if (!$isArray && !is_object($this->target)) throw new \BadMethodCallException('The target is not an array nor an object.');
  
      $hasProperty = $isArray ? array_key_exists($name, $this->target) : property_exists($this->target, $name);
      $hasPropertyConstraint = $isArray ? arrayHasKey($name) : objectHasAttribute($name);
      $property = $isArray ? ($this->target[$name] ?? null) : ($this->target->$name ?? null);
  
      if (!$hasProperty || $value === null) $this->expect($this->target, $hasPropertyConstraint);
      else {
        assertThat($this->target, $hasPropertyConstraint);
        $this->expect($property, equalTo($value));
      }
  
      $this->target = $property;
      return $this;
    }
docs: Reports an error if the target has not a given property or key.
  
  Optionally asserts that the value of that property or key is equal to the specified value.
  Changes the subject of the assertion to be the value of that property from the original object.
  
  @param string $name The property name.
  @param mixed $value The property value.
  @return self This instance.
  @throws \BadMethodCallException The target is not an array nor an object.