mirror of
https://github.com/php-flasher/php-flasher.git
synced 2026-03-31 15:07:47 +01:00
Update filter criteria and CHANGELOG
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
- [Notyf] Dispatch events: `flasher:notyf:click`, `flasher:notyf:dismiss`
|
||||
- [Themes] Dispatch events: `flasher:theme:click` (generic) and `flasher:theme:{name}:click` (specific)
|
||||
- [Laravel] Add LivewireListener classes for all adapters and themes to enable Livewire event handling
|
||||
* fix [Flasher] Fix FilterCriteria uninitialized property error when constructed with empty array
|
||||
* fix [Flasher] Fix null comparison issues in PriorityCriteria, HopsCriteria, and DelayCriteria that relied on PHP's implicit null-to-0 coercion
|
||||
|
||||
## [v2.1.3](https://github.com/php-flasher/php-flasher/compare/v2.1.2...v2.1.3) - 2025-01-25
|
||||
|
||||
|
||||
@@ -46,14 +46,9 @@ final readonly class DelayCriteria implements CriteriaInterface
|
||||
|
||||
$delay = $stamp->getDelay();
|
||||
|
||||
if (null === $this->maxDelay) {
|
||||
return $delay >= $this->minDelay;
|
||||
}
|
||||
$meetsMin = null === $this->minDelay || $delay >= $this->minDelay;
|
||||
$meetsMax = null === $this->maxDelay || $delay <= $this->maxDelay;
|
||||
|
||||
if ($delay <= $this->maxDelay) {
|
||||
return $delay >= $this->minDelay;
|
||||
}
|
||||
|
||||
return false;
|
||||
return $meetsMin && $meetsMax;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ final class FilterCriteria implements CriteriaInterface
|
||||
/**
|
||||
* @var \Closure[]
|
||||
*/
|
||||
private array $callbacks;
|
||||
private array $callbacks = [];
|
||||
|
||||
/**
|
||||
* @throws \InvalidArgumentException
|
||||
|
||||
@@ -11,9 +11,9 @@ final readonly class HopsCriteria implements CriteriaInterface
|
||||
{
|
||||
use RangeExtractor;
|
||||
|
||||
private readonly ?int $minAmount;
|
||||
private ?int $minAmount;
|
||||
|
||||
private readonly ?int $maxAmount;
|
||||
private ?int $maxAmount;
|
||||
|
||||
/**
|
||||
* @throws \InvalidArgumentException
|
||||
@@ -44,14 +44,11 @@ final readonly class HopsCriteria implements CriteriaInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
if (null === $this->maxAmount) {
|
||||
return $stamp->getAmount() >= $this->minAmount;
|
||||
}
|
||||
$amount = $stamp->getAmount();
|
||||
|
||||
if ($stamp->getAmount() <= $this->maxAmount) {
|
||||
return $stamp->getAmount() >= $this->minAmount;
|
||||
}
|
||||
$meetsMin = null === $this->minAmount || $amount >= $this->minAmount;
|
||||
$meetsMax = null === $this->maxAmount || $amount <= $this->maxAmount;
|
||||
|
||||
return false;
|
||||
return $meetsMin && $meetsMax;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,14 +46,9 @@ final readonly class PriorityCriteria implements CriteriaInterface
|
||||
|
||||
$priority = $stamp->getPriority();
|
||||
|
||||
if (null === $this->maxPriority) {
|
||||
return $priority >= $this->minPriority;
|
||||
}
|
||||
$meetsMin = null === $this->minPriority || $priority >= $this->minPriority;
|
||||
$meetsMax = null === $this->maxPriority || $priority <= $this->maxPriority;
|
||||
|
||||
if ($priority <= $this->maxPriority) {
|
||||
return $priority >= $this->minPriority;
|
||||
}
|
||||
|
||||
return false;
|
||||
return $meetsMin && $meetsMax;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,4 +248,52 @@ final class DelayCriteriaTest extends TestCase
|
||||
|
||||
$this->assertCount(3, $result);
|
||||
}
|
||||
|
||||
public function testMatchWithOnlyMaxAndNullMin(): void
|
||||
{
|
||||
// This test verifies explicit null handling for min
|
||||
// Previously relied on PHP's implicit null-to-0 coercion
|
||||
$envelope = new Envelope(new Notification(), [new DelayStamp(3)]);
|
||||
|
||||
$criteria = new DelayCriteria(['max' => 5]);
|
||||
|
||||
// With min=null and max=5, delay=3 should match
|
||||
$this->assertTrue($criteria->match($envelope));
|
||||
}
|
||||
|
||||
public function testMatchWithOnlyMaxRejectsHigherDelay(): void
|
||||
{
|
||||
$envelope = new Envelope(new Notification(), [new DelayStamp(10)]);
|
||||
|
||||
$criteria = new DelayCriteria(['max' => 5]);
|
||||
|
||||
// With min=null and max=5, delay=10 should NOT match
|
||||
$this->assertFalse($criteria->match($envelope));
|
||||
}
|
||||
|
||||
public function testMatchWithBothNullMinAndMax(): void
|
||||
{
|
||||
// When both min and max are null, all envelopes with delay stamp should match
|
||||
$envelope = new Envelope(new Notification(), [new DelayStamp(100)]);
|
||||
|
||||
$criteria = new DelayCriteria([]);
|
||||
|
||||
$this->assertTrue($criteria->match($envelope));
|
||||
}
|
||||
|
||||
public function testApplyWithNullMinAndMaxMatchesAll(): void
|
||||
{
|
||||
$envelopes = [
|
||||
new Envelope(new Notification(), [new DelayStamp(0)]),
|
||||
new Envelope(new Notification(), [new DelayStamp(50)]),
|
||||
new Envelope(new Notification(), [new DelayStamp(100)]),
|
||||
];
|
||||
|
||||
$criteria = new DelayCriteria([]);
|
||||
|
||||
$result = $criteria->apply($envelopes);
|
||||
|
||||
// All envelopes with delay stamp should match when no constraints
|
||||
$this->assertCount(3, $result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,4 +166,32 @@ final class FilterCriteriaTest extends TestCase
|
||||
$this->assertSame(['first', 'second'], $order);
|
||||
$this->assertCount(2, $result);
|
||||
}
|
||||
|
||||
public function testConstructorWithEmptyArrayDoesNotThrow(): void
|
||||
{
|
||||
// This test verifies the fix for uninitialized $callbacks property
|
||||
// Previously, new FilterCriteria([]) would leave $callbacks uninitialized
|
||||
// causing "must not be accessed before initialization" error on apply()
|
||||
$criteria = new FilterCriteria([]);
|
||||
|
||||
$envelopes = [new Envelope(new Notification())];
|
||||
$result = $criteria->apply($envelopes);
|
||||
|
||||
// With no callbacks, envelopes should pass through unchanged
|
||||
$this->assertSame($envelopes, $result);
|
||||
}
|
||||
|
||||
public function testApplyWithEmptyCallbacksReturnsEnvelopesUnchanged(): void
|
||||
{
|
||||
$criteria = new FilterCriteria([]);
|
||||
|
||||
$notification = new Notification();
|
||||
$notification->setMessage('test');
|
||||
$envelopes = [new Envelope($notification)];
|
||||
|
||||
$result = $criteria->apply($envelopes);
|
||||
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertSame('test', $result[0]->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,4 +229,52 @@ final class HopsCriteriaTest extends TestCase
|
||||
|
||||
$this->assertCount(1, $result);
|
||||
}
|
||||
|
||||
public function testMatchWithOnlyMaxAndNullMin(): void
|
||||
{
|
||||
// This test verifies explicit null handling for min
|
||||
// Previously relied on PHP's implicit null-to-0 coercion
|
||||
$envelope = new Envelope(new Notification(), [new HopsStamp(2)]);
|
||||
|
||||
$criteria = new HopsCriteria(['max' => 5]);
|
||||
|
||||
// With min=null and max=5, hops=2 should match
|
||||
$this->assertTrue($criteria->match($envelope));
|
||||
}
|
||||
|
||||
public function testMatchWithOnlyMaxRejectsHigherHops(): void
|
||||
{
|
||||
$envelope = new Envelope(new Notification(), [new HopsStamp(10)]);
|
||||
|
||||
$criteria = new HopsCriteria(['max' => 5]);
|
||||
|
||||
// With min=null and max=5, hops=10 should NOT match
|
||||
$this->assertFalse($criteria->match($envelope));
|
||||
}
|
||||
|
||||
public function testMatchWithBothNullMinAndMax(): void
|
||||
{
|
||||
// When both min and max are null, all envelopes with hops stamp should match
|
||||
$envelope = new Envelope(new Notification(), [new HopsStamp(100)]);
|
||||
|
||||
$criteria = new HopsCriteria([]);
|
||||
|
||||
$this->assertTrue($criteria->match($envelope));
|
||||
}
|
||||
|
||||
public function testApplyWithNullMinAndMaxMatchesAll(): void
|
||||
{
|
||||
$envelopes = [
|
||||
new Envelope(new Notification(), [new HopsStamp(1)]),
|
||||
new Envelope(new Notification(), [new HopsStamp(50)]),
|
||||
new Envelope(new Notification(), [new HopsStamp(100)]),
|
||||
];
|
||||
|
||||
$criteria = new HopsCriteria([]);
|
||||
|
||||
$result = $criteria->apply($envelopes);
|
||||
|
||||
// All envelopes with hops stamp should match when no constraints
|
||||
$this->assertCount(3, $result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,4 +245,52 @@ final class PriorityCriteriaTest extends TestCase
|
||||
|
||||
$this->assertCount(1, $result);
|
||||
}
|
||||
|
||||
public function testMatchWithOnlyMaxAndNullMin(): void
|
||||
{
|
||||
// This test verifies explicit null handling for min
|
||||
// Previously relied on PHP's implicit null-to-0 coercion
|
||||
$envelope = new Envelope(new Notification(), [new PriorityStamp(3)]);
|
||||
|
||||
$criteria = new PriorityCriteria(['max' => 5]);
|
||||
|
||||
// With min=null and max=5, priority 3 should match
|
||||
$this->assertTrue($criteria->match($envelope));
|
||||
}
|
||||
|
||||
public function testMatchWithOnlyMaxRejectsHigherPriority(): void
|
||||
{
|
||||
$envelope = new Envelope(new Notification(), [new PriorityStamp(10)]);
|
||||
|
||||
$criteria = new PriorityCriteria(['max' => 5]);
|
||||
|
||||
// With min=null and max=5, priority 10 should NOT match
|
||||
$this->assertFalse($criteria->match($envelope));
|
||||
}
|
||||
|
||||
public function testMatchWithBothNullMinAndMax(): void
|
||||
{
|
||||
// When both min and max are null, all envelopes with priority stamp should match
|
||||
$envelope = new Envelope(new Notification(), [new PriorityStamp(100)]);
|
||||
|
||||
$criteria = new PriorityCriteria([]);
|
||||
|
||||
$this->assertTrue($criteria->match($envelope));
|
||||
}
|
||||
|
||||
public function testApplyWithNullMinAndMaxMatchesAll(): void
|
||||
{
|
||||
$envelopes = [
|
||||
new Envelope(new Notification(), [new PriorityStamp(-100)]),
|
||||
new Envelope(new Notification(), [new PriorityStamp(0)]),
|
||||
new Envelope(new Notification(), [new PriorityStamp(100)]),
|
||||
];
|
||||
|
||||
$criteria = new PriorityCriteria([]);
|
||||
|
||||
$result = $criteria->apply($envelopes);
|
||||
|
||||
// All envelopes with priority stamp should match when no constraints
|
||||
$this->assertCount(3, $result);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user