Skip to content

Releases: FireMidge/value-objects

Version 2.7: Generic classes (& more). PHP 8.4-tested

Choose a tag to compare

@FireMidge FireMidge released this 24 Dec 12:53

Breaking changes

  1. next() and previous() on IsCollectionType no longer return a value.
    • This is because of \Iterator requiring next to return void, and it makes sense for next and previous to function in the same way.
  2. ConversionError now extends from \ValueError (previously \RuntimeException)

Features

  1. Added default classes to be able to use some of the traits instantly without having to create an empty new class each time. The classes added are:

    • \FireMidge\ValueObject\Generic\AnyCollection
    • \FireMidge\ValueObject\Generic\AnyFloat
    • \FireMidge\ValueObject\Generic\AnyInteger
    • \FireMidge\ValueObject\Generic\AnyString
    • All of the above classes implement \JsonSerializable, and AnyCollection also implements the \Iterator interface.
  2. Added default Percentage and Email classes

    • \FireMidge\ValueObject\Generic\Percentage
    • \FireMidge\ValueObject\Generic\Email
  3. New methods on IsCollectionType:

    • merge
    • withMerged
    • pop
    • popMultiple
    • split
    • shuffle
    • withReversedOrder
  4. jsonSerialize has been implemented for all types, to aid easy serialisation.

    • In order for automatic serialisation to happen when json_encode is called, the class using these traits has to implement the JsonSerializable interface.
    • The new generic classes all implement it already.

Improvements

  1. Added Psalm annotations in the collection type.
    • This allows for better IDE-internal type hints for methods like toArray(), first(), last() etc.
    • Usage is showcased in README.md
  2. More specific error messages for adding or subtracting a value from a float or integer type beyond allowed min/max values.
  3. Option to return $reasons from a ConversionError
  4. InvalidValue renders different types better, e.g. non-strings are no longer wrapped in double quotes
  5. Library is tested against PHP 8.4. Worked without changes to the code.
  6. Upgraded from PhpUnit 9 to 11.5 and upgraded Infection to 29.0.
    • Changed all docblock annotations to attributes
    • Infection's output is vastly improved, removing the vast majority of false positives. MSI has changed from 97% to 99%, Mutation Code Coverage from 98% to 99% and Covered Code MSI from 98% to 100%.

Version 2.6: New 'IsClassArrayEnumType'

Choose a tag to compare

@FireMidge FireMidge released this 25 Nov 23:23
6dcdba3

Feature: Added new type IsClassArrayEnumType, which is a convenience type between ArrayEnumType and ClassCollectionType.
It's used for collections of instances which in turn are enum types, i.e. there is a finite list of valid values. It also offers an easy way to create a new collection holding all valid variations of the underlying enum type (withAll()).

Feature: Added methods to navigate through the values of IsCollectionType with current, previous, next, first and last. This is, by extension, also available to instances using the IsClassCollectionType, IsArrayEnumType, IsClassArrayEnumType and all other related traits. Unlike the equivalent built-in PHP methods, these new methods return null for non-existing elements instead of false.

Dev: Improved @covers annotations and re-imported certain traits to improve accuracy of code coverage reports. Added tests for all new functionality as well as addressed all true positives in the Infection log. MSI improved from 94% to 97% and CCM from 95% to 98%.

Version 2.5: New convenience methods

Choose a tag to compare

@FireMidge FireMidge released this 21 Aug 17:56

B/C-Breaking Change: isClassCollectionType::className() is now a static abstract method. This means all existing classes using this trait will need to change it from protected to protected static. No further changes should be necessary.
As a static, it can be used for a wider range of useful convenience methods, like the new fromRawArray.

Feature: IsClassCollectionType now has a fromRawArray method, which allows creating a new array not from instances of the required class, but from raw values which are then automatically converted into the required class. A custom conversion callback can be provided. In order to globally (for that particular class) override the conversion of raw values into target class instances, you can override the protected static method convertFromRaw(mixed $value) : object.

Feature: IsCollectionType now has find and findIndex methods, which allows returning a specific element (or index, respectively) based on a custom callback. This means it's no longer needed to convert the class back to an array for the sake of finding a specific element.

Feature: isEqualTo and isNotEqualTo have been added to IsStringEnumType, IsStringType, IsIntType, IsIntEnumType and IsFloatType, to be consistent with other traits. ConversionError has been introduced, which is thrown when attempting to perform a loose comparison with a value that cannot be converted to the target type.

Feature: Methods for mathematical operations (add, subtract) and comparisons (isGreaterThan, isGreaterThanOrEqualTo, isLessThan, isLessThanOrEqualTo have been added to IsFloatType and IsIntType.

Feature: IsFloatType now has fromString, fromStringOrNull, fromNumber, fromNumberOrNull.

Feature: IsIntEnumType now has a fromString, fromStringOrNull

Feature: isIntType now has fromStringOrNull (besides the pre-existing fromString) in order to make it consistent with other traits.

Feature: IsIntEnumType now implements the magic __toString method, which aids with comparisons and rendering.

Dev: Tests to cover all of the above have been added. Some additional tests to improve pre-existing ones have been added.

Dev: Every single mutant in the infection.log has been checked - they are all false positives. Several came back as escaped when in fact, the same manual mutation causes tests to fail. The @Covers annotation is correct. It may be a bug in how multi-layer trait inheritance is perceived as covered by Infection. MSI has fallen from 95% to 94% and Covered Code MSI has fallen from 97% to 95% - however, there is nothing that can be done to improve it.

Version 2.4: Strict checks

Choose a tag to compare

@FireMidge FireMidge released this 20 Jul 11:13
404f4ea

What's changed?

Change: isEqualTo and isNotEqualTo on IsIntStringMapType default to using a strict check, which means the item to compare it to must be of the same class. If you do not want a strict check to happen, you can continue to pass false for the $strictCheck parameter.

Change: isEqualTo and isNotEqualTo on IsCollectionType (which affects all array types) have a new $strictCheck parameter, defaulting to true. When it is true, the item to compare to must be of the same class. If you do not want a strict check to happen, you can pass false for the $strictCheck parameter.

It is best practice to be as strict as possible with checks to avoid comparing values you did not mean to compare, and encounter unexpected behaviour as a result.

Version 2.3: New methods

Choose a tag to compare

@FireMidge FireMidge released this 19 Jul 22:08
f80fa49

What's new?

Feature: Added isEqualTo and isNotEqualTo to IsIntStringMapType.
Overall Mutation Code Coverage has risen from 97% to 98%. No value has decreased.

Feature: Added withValues, withoutValues and tryWithoutValues to IsCollectionType, allowing to add/remove multiple values with a single method call. MSI has risen from 94% to 95% and Covered Code MSI from 96% to 97%.

Version 2.2

Choose a tag to compare

@FireMidge FireMidge released this 18 Jul 21:51

What's New?

Feature: It is now possible to also transform values in IsStringEnumType before validating.

Feature: There is a new fromString method on IsIntType.

Other

Code coverage has been improved and is now at 100% for methods, lines and classes/traits. Mutation score has also been improved from an official 28% (which was not accurate) to 94% MSI, 97% Mutation Code Coverage and 96% Covered Code MSI, containing false positives.
image

Dev: Instead of using method-based @Covers annotations, we now have class-based @Covers annotations, which is working SO much better. Now the Infection log and coverage reports are far more accurate.

Dev: Added more tests, to bring unit test coverage up to 100%.

Dev: Throwing LogicException when trying to validate the length of a string but passing a higher $minNumber than $maxNumber.

Version 2.1: Added IsClassCollectionType and more

Choose a tag to compare

@FireMidge FireMidge released this 16 Jul 00:02
1cf9066

What's new?

Feature: Added the following methods to all the array types (IsArrayEnumType, IsCollectionType, IsIntArrayEnumType, IsStringArrayEnumType, IsClassCollectionType):

  • count: Returns the number of elements inside the array value object.
  • isEmpty: Whether the value object contains any elements.
  • isNotEmpty: The opposite of isEmpty.
  • isEqualTo: Whether the value object's elements are equal to the argument. The argument can be another class (with a toArray method), an array, or an object with public properties.
  • isNotEqualTo: The opposite of isEqualTo.
  • empty: A factory method to create a new instance with no elements.

Feature: Added a new value type: IsClassCollectionType.
This adds on to IsCollectionType and makes it easier to create a collection holding an array of objects. It validates whether the items are of a specific class. By default, it does not allow duplicate values, however this can be overridden.

Feature: Added a small helper trait CanBeConvertedToStringArray, which can convert an array type into an array of scalar string values. Useful when using IsClassCollectionType with a class implementing the __toString method.

What's changed?

Feature: Adding duplicate values can now be ignored, by overriding the protected static function ignoreDuplicateValues() : bool method and returning true. To be backwards-compatible, it returns false by default.
When this method returns true, then any duplicate values will be ignored and simply not added to the collection; without throwing an exception.

Dev: Separate exception for duplicate values: DuplicateValue.
It is backwards compatible as it extends from InvalidValue, but it does now allow developers to catch this exception separately.

Version 2.0: Upgrade to PHP 8.1

Choose a tag to compare

@FireMidge FireMidge released this 08 Jul 23:12
0b8f225

What's new?

Only the PHP 8.1 upgrade. If you don't yet have PHP 8.1, you can continue to use v1.1.

The upgrade means that return types could be changed from self to static, and type hints for different types of numeric values, e.g. float|int $value.

Version 1.1

Choose a tag to compare

@FireMidge FireMidge released this 08 Jul 22:44
c5c6124

What's new?

These following types have been added:

  • IsArrayEnumType
  • IsFloatType
  • IsIntArrayEnumType
  • IsIntStringMapType
  • IsIntType
  • IsStringArrayEnumType
  • IsStringType
  • IsEmailType
  • IsCollectionType

What's changed?

There is now a fromStringOrNull method on IsStringEnumType, which allows passing a null value. This does not create a new instance but simply returns null back. This is useful for when you don't know whether a value is null but consider it valid.
Likewise, there is a fromIntOrNull method on IsIntEnumType.

The abstract all() method is now static.

Other

All types have been thoroughly covered by unit tests, which can now be run using the provided Docker image.
Infection (a mutation testing tool) has also been installed, been run, and the log checked for any true positives.

Version 1.0

Choose a tag to compare

@FireMidge FireMidge released this 08 Jul 22:39

Feature: Basic IsIntEnumType and IsStringEnumType

Provides basic value objects:
IsIntEnumType represents a single integer value, which must be one of a list of allowed values.
IsStringEnumType represents a single string value, which must be one of a list of allowed values.