Skip to content

feat: process a specific message from the queue#106

Open
podoko wants to merge 1 commit into
zenstruck:1.xfrom
podoko:feat-process-specific-message
Open

feat: process a specific message from the queue#106
podoko wants to merge 1 commit into
zenstruck:1.xfrom
podoko:feat-process-specific-message

Conversation

@podoko

@podoko podoko commented Jun 27, 2026

Copy link
Copy Markdown

Hello, I needed the same feature as described in #72 so I tried to implement it.

This pr aims at allowing tests to process a specific message present in a queue when many are present but only the behavior of a specific one is being tested

Closes #72

Allow passing a callable or a message class-string to `process()` to handle a single matching message instead of the whole queue.

Closes zenstruck#72
zenstruck#72

@nikophil nikophil left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while I like the idea, I'm not sure about the implementation: we should not store the filter like any other configuration.

I think the right thing to do here is some kind of decorator:

final class TestTransport implements TransportInterface
{
  public function process(int|callable|string $numberOrFilter = -1): self
  {
      // ...

      if (\is_int($numberOrFilter)) {
          $number = $numberOrFilter;
          $receiver = $this;
      } else {
          $number = 1;
          $receiver = new FilteredReceiver($this, EnvelopeFilter::normalize($numberOrFilter));
      }

      $worker = new Worker([$this->name => $receiver], $this->bus, $this->dispatcher);

      // ...
  }

  public function get(): iterable
  {
      return $this->getMatching(null);
  }

   /** @internal */
  public function getMatching(?callable $filter): iterable
  {
     // ... basically everything which is currently in `TestTransport::get()`
  }
}

 /** @internal */
 final class FilteredReceiver implements ReceiverInterface
 {
     /** @param \Closure(Envelope):bool $filter */
     public function __construct(
        private readonly TestTransport $decorated, 
        private readonly \Closure $filter,
    ) {}

     public function get(): iterable
     {
         return $this->decorated->getMatching($this->filter); 
     }

     // ... other method from ReceiverInterface should defer to $decorated
}

Comment thread src/EnvelopeFilter.php
*
* @return callable(Envelope):bool
*/
public static function normalize(callable|string $filter): callable

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please, don't use a static method, but make this class concrete and invokable.

Then, then method TestTransport::getMatching() I am talking in the other comment will look like this:

 /** @internal */
public function getMatching(?EnvelopeFilter $filter): iterable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Process exact message

2 participants