Skip to content

Commit

Permalink
Added isAnyOf(), isNoneOf() and doesNotEqualTo() methods
Browse files Browse the repository at this point in the history
  • Loading branch information
fulopattila122 committed Feb 29, 2024
1 parent 29453c2 commit 1e7dc3d
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 10 deletions.
5 changes: 5 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## 4.x

## Unreleased
###### 2024-XX-YY

- Added the `isAnyOf()`, `isNoneOf()` and `doesNotEqualTo()` comparison methods

## 4.1.0
###### 2023-06-07

Expand Down
46 changes: 44 additions & 2 deletions docs/compare.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ var_dump(
// bool(true)
```

Many developers prefer to avoid using negative conditions in their code
like:
### Does Not Equal To

Many developers prefer to avoid using negative conditions in their code like:

```php
if (!$one->equals($two)) //...
Expand All @@ -41,6 +42,9 @@ if (!$one->equals($two)) //...
thus the `notEquals()` method is available (since v2.2) for improved
code readability. It's simply just the negation of `equals()`.

In v4.2, the `doesNotEqualTo(EnumInterface $enum): bool` method has been added, which is equivalent to the `notEquals()` method,
but it only accepts `EnumInterface` as argument.

### Type Check

The `equals()` method does a type check so two different types of the same value won't be equal:
Expand Down Expand Up @@ -141,6 +145,44 @@ const ONE = 1 ==> isOne()
const LUCKY_LUKE = 'll' ==> isLuckyLuke()
```

## The `isAnyOf()` and `isNoneOf()` Methods

> This is a v4.2+ feature
It is possible to check whether an enum "is any of" or "is none of" multiple enum instances:

```php
class Status extends \Konekt\Enum\Enum
{
public const NEW = 'new';
public const PENDING = 'pending';
public const COMPLETE = 'complete';
public const CANCELED = 'canceled';
}

$new = Status::NEW();
$new->isAnyOf(Status::PENDING(), Status::NEW());
// => true

$complete = Status::COMPLETE();
$complete->isNoneOf(Status::PENDING(), Status::NEW());
// => true

$canceled = Status::CANCELED();
$canceled->isAnyOf(Status::NEW(), Status::PENDING());
// => false

$pending = Status::PENDING();
$pending->isNoneOf(Status::PENDING(), Status::COMPLETE());
// => false
```

You can pass any number of arguments to the `isNoneOf()` and `isAnyOf()` methods,
but all of them have to be `EnumInterface` instances.

The methods will use the `equals()` method under the hood to compare the enums, so the same rules described above apply
here as well.

---

**Next**: [Labels »](labels.md)
23 changes: 15 additions & 8 deletions src/Enum.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,6 @@ public function label(): string
/**
* Checks if two enums are equal. Value and class are both matched.
* Value check is not type strict.
*
* @param mixed $object
*
* @return bool True if enums are equal
*/
public function equals(object $object): bool
{
Expand All @@ -179,16 +175,27 @@ public function equals(object $object): bool
/**
* Checks if two enums are NOT equal. Value and class are both matched.
* Value check is not type strict.
*
* @param mixed $object
*
* @return bool True if enums do not equal
*/
public function notEquals(object $object): bool
{
return !$this->equals($object);
}

public function doesNotEqualTo(EnumInterface $enum): bool
{
return $this->notEquals($enum);
}

public function isAnyOf(EnumInterface ...$enums): bool
{
return !$this->isNoneOf(...$enums);
}

public function isNoneOf(EnumInterface ...$enums): bool
{
return empty(array_filter($enums, fn (Enum $enum) => $this->equals($enum)));
}

/**
* Returns the default value of the class. Equals to the __DEFAULT constant.
*/
Expand Down
70 changes: 70 additions & 0 deletions tests/IsAnyOfTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

declare(strict_types=1);

/**
* Contains the IsAnyOfTest class.
*
* @copyright Copyright (c) 2024 Attila Fulop
* @author Attila Fulop
* @license MIT
* @since 2024-02-29
*
*/

namespace Konekt\Enum\Tests;

use Konekt\Enum\Tests\Fixture\Another123;
use Konekt\Enum\Tests\Fixture\Sample123;
use PHPUnit\Framework\TestCase;

class IsAnyOfTest extends TestCase
{
/** @test */
public function is_any_of_returns_true_when_passing_the_same_instance()
{
$one = Sample123::create(1);

$this->assertTrue($one->isAnyOf($one));
}

/** @test */
public function is_any_of_returns_true_when_passing_the_same_value_but_separate_instances()
{
$one = Sample123::create(1);

$this->assertTrue($one->isAnyOf(Sample123::create(1)));
}

/** @test */
public function is_any_of_returns_true_when_passing_multiple_values_of_which_one_equals_the()
{
$one = Sample123::create(1);

$this->assertTrue($one->isAnyOf(Sample123::ONE(), Sample123::TWO()));
}

/** @test */
public function is_none_of_returns_true_when_passing_nothing()
{
$one = Sample123::create(1);

$this->assertTrue($one->isNoneOf());
}

/** @test */
public function is_none_of_returns_true_when_passing_enums_of_which_none_equals_the_base_enum()
{
$three = Sample123::create(3);

$this->assertTrue($three->isNoneOf(Sample123::ONE(), Sample123::TWO()));
}

/** @test */
public function mixing_separate_enums_with_same_underlying_values_will_not_match()
{
$two = Sample123::TWO();

$this->assertTrue($two->isNoneOf(Another123::TWO()));
}
}

0 comments on commit 1e7dc3d

Please sign in to comment.