diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6af830d85..b6eb50b38 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,12 +5,24 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+- Add Lazy Collection and bring Collection/Enumerable Values trait up-to-date with Laravel.
+
## Unreleased
📢 Minimum PHP version is now 8.2. The framework supports 8.2 - 8.4.
### Added
+- ✨ Experimental feature ✨: Use the home URL as the base URL for testing rather
+ than `WP_TESTS_DOMAIN`. This can be enabled by calling the
+ `with_experimental_testing_url_host()` method of the installation manager or
+ by setting the `MANTLE_EXPERIMENTAL_TESTING_USE_HOME_URL_HOST` environment
+ variable.
+
+ Once enabled, the home URL will be used as the base URL for testing rather
+ the hard-coded `WP_TESTS_DOMAIN`. It will also infer the HTTPS status from
+ the home URL.
+- Added `with_option()`/`with_home_url()`/`with_site_url()` methods to the installation manager.
- Add a `without_local_object_cache()` method to prevent the `object-cache.php` drop-in from being loaded locally.
- Added a better `dump()` method to the response object when testing HTTP
requests that will dump the request/response to the console.
@@ -42,6 +54,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Allow `Filter`/`Action` attributes to be used multiple times on the same method.
+>>>>>>> @{-1}
## v1.3.2 - 2024-12-17
diff --git a/phpcs.xml b/phpcs.xml
index a3fbf02ed..124ea0d45 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -29,6 +29,8 @@
+
+
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
new file mode 100644
index 000000000..bd18aff36
--- /dev/null
+++ b/phpstan-baseline.neon
@@ -0,0 +1,691 @@
+parameters:
+ ignoreErrors:
+ -
+ message: "#^PHPDoc tag @param has invalid value \\(callable\\(\\.\\.\\.mixed\\)\\: mixed \\$callback\\)\\: Unexpected token \"\\(\", expected variable at offset 84$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Parameter \\#1 \\$callback of method Mantle\\\\Support\\\\Collection\\\\:\\:when_empty\\(\\) expects callable\\(Mantle\\\\Support\\\\Collection\\\\)\\: TUnlessNotEmptyReturnType, callable\\(\\$this\\)\\: TUnlessNotEmptyReturnType given\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Parameter \\#1 \\$callback of method Mantle\\\\Support\\\\Collection\\\\:\\:when_not_empty\\(\\) expects callable\\(Mantle\\\\Support\\\\Collection\\\\)\\: TUnlessEmptyReturnType, callable\\(\\$this\\)\\: TUnlessEmptyReturnType given\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Parameter \\#2 \\$callback of method Mantle\\\\Support\\\\Collection\\\\:\\:when\\(\\) expects \\(callable\\(Mantle\\\\Support\\\\Collection\\, bool\\)\\: TWhenEmptyReturnType\\)\\|null, callable\\(\\$this\\)\\: TWhenEmptyReturnType given\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Parameter \\#2 \\$callback of method Mantle\\\\Support\\\\Collection\\\\:\\:when\\(\\) expects \\(callable\\(Mantle\\\\Support\\\\Collection\\, bool\\)\\: TWhenNotEmptyReturnType\\)\\|null, callable\\(\\$this\\)\\: TWhenNotEmptyReturnType given\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Parameter \\#2 \\$default of method Mantle\\\\Support\\\\Collection\\\\:\\:when_empty\\(\\) expects \\(callable\\(Mantle\\\\Support\\\\Collection\\\\)\\: TUnlessNotEmptyReturnType\\)\\|null, \\(callable\\(\\$this\\)\\: TUnlessNotEmptyReturnType\\)\\|null given\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Parameter \\#2 \\$default of method Mantle\\\\Support\\\\Collection\\\\:\\:when_not_empty\\(\\) expects \\(callable\\(Mantle\\\\Support\\\\Collection\\\\)\\: TUnlessEmptyReturnType\\)\\|null, \\(callable\\(\\$this\\)\\: TUnlessEmptyReturnType\\)\\|null given\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Parameter \\#2 \\$flags of class CachingIterator constructor expects 0\\|1\\|2\\|3\\|4\\|5\\|6\\|7\\|8\\|9\\|10\\|11\\|12\\|13\\|14\\|15\\|16\\|17\\|18\\|19\\|20\\|21\\|22\\|23\\|24\\|25\\|26\\|27\\|28\\|29\\|30\\|31\\|256\\|257\\|258\\|259\\|260\\|261\\|262\\|263\\|264\\|265\\|266\\|267\\|268\\|269\\|270\\|271\\|272\\|273\\|274\\|275\\|276\\|277\\|278\\|279\\|280\\|281\\|282\\|283\\|284\\|285\\|286\\|287, int given\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Parameter \\#3 \\$default of method Mantle\\\\Support\\\\Collection\\\\:\\:when\\(\\) expects \\(callable\\(Mantle\\\\Support\\\\Collection\\, bool\\)\\: TWhenEmptyReturnType\\)\\|null, \\(callable\\(\\$this\\)\\: TWhenEmptyReturnType\\)\\|null given\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Parameter \\#3 \\$default of method Mantle\\\\Support\\\\Collection\\\\:\\:when\\(\\) expects \\(callable\\(Mantle\\\\Support\\\\Collection\\, bool\\)\\: TWhenNotEmptyReturnType\\)\\|null, \\(callable\\(\\$this\\)\\: TWhenNotEmptyReturnType\\)\\|null given\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter callback of method Mantle\\\\Support\\\\Collection\\:\\:reject\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter callback of method Mantle\\\\Support\\\\Collection\\:\\:transform\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter item of method Mantle\\\\Support\\\\Collection\\:\\:add\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:diff\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:diff_assoc\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:diff_assoc_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:diff_keys\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:diff_keys_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:diff_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:intersect\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:intersect_assoc\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:intersect_assoc_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:intersect_by_keys\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:merge\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:replace\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:replace_recursive\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:union\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter key of method Mantle\\\\Support\\\\Collection\\:\\:contains\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter key of method Mantle\\\\Support\\\\Collection\\:\\:contains_strict\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter key of method Mantle\\\\Support\\\\Collection\\:\\:every\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter key of method Mantle\\\\Support\\\\Collection\\:\\:partition\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter key of method Mantle\\\\Support\\\\Collection\\:\\:some\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter operator of method Mantle\\\\Support\\\\Collection\\:\\:partition\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter replacement of method Mantle\\\\Support\\\\Collection\\:\\:splice\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter source of method Mantle\\\\Support\\\\Collection\\:\\:concat\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter value of method Mantle\\\\Support\\\\Collection\\:\\:contains_strict\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter value of method Mantle\\\\Support\\\\Collection\\:\\:partition\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter value of method Mantle\\\\Support\\\\Collection\\:\\:put\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter value of method Mantle\\\\Support\\\\Collection\\:\\:search\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter value of method Mantle\\\\Support\\\\Collection\\:\\:skip_until\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter value of method Mantle\\\\Support\\\\Collection\\:\\:skip_while\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter value of method Mantle\\\\Support\\\\Collection\\:\\:take_until\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter value of method Mantle\\\\Support\\\\Collection\\:\\:take_while\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter values of method Mantle\\\\Support\\\\Collection\\:\\:push\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in return type of method Mantle\\\\Support\\\\Collection\\:\\:duplicate_comparator\\(\\)\\.$#"
+ count: 2
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in implemented type ArrayAccess\\ of class Mantle\\\\Support\\\\Collection\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in implemented type Mantle\\\\Support\\\\Enumerable\\ of class Mantle\\\\Support\\\\Collection\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:diff\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:diff_assoc\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:diff_assoc_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:diff_keys\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:diff_keys_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:diff_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:intersect\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:intersect_assoc\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:intersect_assoc_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:intersect_by_keys\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:merge\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:replace\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:replace_recursive\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Collection\\:\\:union\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in return type of method Mantle\\\\Support\\\\Collection\\:\\:combine\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-collection.php
+
+ -
+ message: "#^Call to an undefined method Mantle\\\\Support\\\\Higher_Order_Collection_Proxy\\:\\:current\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Call to an undefined method Mantle\\\\Support\\\\Higher_Order_Collection_Proxy\\:\\:next\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Call to an undefined method Mantle\\\\Support\\\\Higher_Order_Collection_Proxy\\:\\:valid\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Call to an undefined method Traversable\\<\\(int\\|string\\), TCombineValue\\>\\:\\:current\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Call to an undefined method Traversable\\<\\(int\\|string\\), TCombineValue\\>\\:\\:next\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Call to an undefined method Traversable\\<\\(int\\|string\\), TCombineValue\\>\\:\\:valid\\(\\)\\.$#"
+ count: 2
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Call to an undefined method Traversable\\\\:\\:current\\(\\)\\.$#"
+ count: 11
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Call to an undefined method Traversable\\\\:\\:key\\(\\)\\.$#"
+ count: 10
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Call to an undefined method Traversable\\\\:\\:next\\(\\)\\.$#"
+ count: 12
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Call to an undefined method Traversable\\\\:\\:valid\\(\\)\\.$#"
+ count: 14
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Call to function is_null\\(\\) with array will always evaluate to false\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Call to function is_null\\(\\) with array\\\\|string will always evaluate to false\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Callable callable\\(TValue\\)\\: bool invoked with 2 parameters, 1 required\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Default value of the parameter \\#1 \\$depth \\(float\\) of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:flatten\\(\\) is incompatible with type int\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^PHPDoc tag @param has invalid value \\(callable\\(\\.\\.\\.mixed\\)\\: mixed \\$callback\\)\\: Unexpected token \"\\(\", expected variable at offset 84$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^PHPDoc tag @throws with type Mantle\\\\Support\\\\ItemNotFoundException is not subtype of Throwable$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^PHPDoc tag @throws with type Mantle\\\\Support\\\\ItemNotFoundException\\|Mantle\\\\Support\\\\MultipleItemsFoundException is not subtype of Throwable$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Parameter \\#1 \\$callback of method Mantle\\\\Support\\\\Lazy_Collection\\\\:\\:when_empty\\(\\) expects callable\\(Mantle\\\\Support\\\\Lazy_Collection\\\\)\\: TUnlessNotEmptyReturnType, callable\\(\\$this\\)\\: TUnlessNotEmptyReturnType given\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Parameter \\#1 \\$callback of method Mantle\\\\Support\\\\Lazy_Collection\\\\:\\:when_not_empty\\(\\) expects callable\\(Mantle\\\\Support\\\\Lazy_Collection\\\\)\\: TUnlessEmptyReturnType, callable\\(\\$this\\)\\: TUnlessEmptyReturnType given\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Parameter \\#1 \\$size of method Mantle\\\\Support\\\\Lazy_Collection\\\\:\\:chunk\\(\\) expects int, float given\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Parameter \\#2 \\$callback of method Mantle\\\\Support\\\\Lazy_Collection\\\\:\\:when\\(\\) expects \\(callable\\(Mantle\\\\Support\\\\Lazy_Collection\\, bool\\)\\: TWhenEmptyReturnType\\)\\|null, callable\\(\\$this\\)\\: TWhenEmptyReturnType given\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Parameter \\#2 \\$callback of method Mantle\\\\Support\\\\Lazy_Collection\\\\:\\:when\\(\\) expects \\(callable\\(Mantle\\\\Support\\\\Lazy_Collection\\, bool\\)\\: TWhenNotEmptyReturnType\\)\\|null, callable\\(\\$this\\)\\: TWhenNotEmptyReturnType given\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Parameter \\#2 \\$default of method Mantle\\\\Support\\\\Lazy_Collection\\\\:\\:when_empty\\(\\) expects \\(callable\\(Mantle\\\\Support\\\\Lazy_Collection\\\\)\\: TUnlessNotEmptyReturnType\\)\\|null, \\(callable\\(\\$this\\)\\: TUnlessNotEmptyReturnType\\)\\|null given\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Parameter \\#2 \\$default of method Mantle\\\\Support\\\\Lazy_Collection\\\\:\\:when_not_empty\\(\\) expects \\(callable\\(Mantle\\\\Support\\\\Lazy_Collection\\\\)\\: TUnlessEmptyReturnType\\)\\|null, \\(callable\\(\\$this\\)\\: TUnlessEmptyReturnType\\)\\|null given\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Parameter \\#2 \\$flags of class CachingIterator constructor expects 0\\|1\\|2\\|3\\|4\\|5\\|6\\|7\\|8\\|9\\|10\\|11\\|12\\|13\\|14\\|15\\|16\\|17\\|18\\|19\\|20\\|21\\|22\\|23\\|24\\|25\\|26\\|27\\|28\\|29\\|30\\|31\\|256\\|257\\|258\\|259\\|260\\|261\\|262\\|263\\|264\\|265\\|266\\|267\\|268\\|269\\|270\\|271\\|272\\|273\\|274\\|275\\|276\\|277\\|278\\|279\\|280\\|281\\|282\\|283\\|284\\|285\\|286\\|287, int given\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Parameter \\#3 \\$default of method Mantle\\\\Support\\\\Lazy_Collection\\\\:\\:when\\(\\) expects \\(callable\\(Mantle\\\\Support\\\\Lazy_Collection\\, bool\\)\\: TWhenEmptyReturnType\\)\\|null, \\(callable\\(\\$this\\)\\: TWhenEmptyReturnType\\)\\|null given\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Parameter \\#3 \\$default of method Mantle\\\\Support\\\\Lazy_Collection\\\\:\\:when\\(\\) expects \\(callable\\(Mantle\\\\Support\\\\Lazy_Collection\\, bool\\)\\: TWhenNotEmptyReturnType\\)\\|null, \\(callable\\(\\$this\\)\\: TWhenNotEmptyReturnType\\)\\|null given\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter callback of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:reject\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:diff\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:diff_assoc\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:diff_assoc_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:diff_keys\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:diff_keys_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:diff_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:intersect\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:intersect_assoc\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:intersect_assoc_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:intersect_by_keys\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:intersect_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:merge\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:replace\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:replace_recursive\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:union\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter key of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:contains\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter key of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:contains_strict\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter key of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:every\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter key of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:partition\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter key of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:some\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter operator of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:partition\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter value of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:contains_strict\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter value of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:partition\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter value of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:search\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter value of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:skip_until\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter value of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:skip_while\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter value of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:take_until\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in contravariant position in parameter value of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:take_while\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in implemented type Mantle\\\\Support\\\\Enumerable\\ of class Mantle\\\\Support\\\\Lazy_Collection\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:diff\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:diff_assoc\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:diff_assoc_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:diff_keys\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:diff_keys_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:diff_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:intersect\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:intersect_assoc\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:intersect_assoc_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:intersect_by_keys\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:intersect_using\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:merge\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:replace\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:replace_recursive\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in parameter items of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:union\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in return type of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:combine\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Template type TValue is declared as covariant, but occurs in invariant position in return type of method Mantle\\\\Support\\\\Lazy_Collection\\:\\:flip\\(\\)\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
+
+ -
+ message: "#^Unreachable statement \\- code above always terminates\\.$#"
+ count: 1
+ path: src/mantle/support/class-lazy-collection.php
diff --git a/src/mantle/support/class-collection.php b/src/mantle/support/class-collection.php
index ef6786d33..198617c54 100644
--- a/src/mantle/support/class-collection.php
+++ b/src/mantle/support/class-collection.php
@@ -24,7 +24,8 @@
* Collection
*
* @template TKey of array-key
- * @template TValue
+ *
+ * @template-covariant TValue
*
* @implements \ArrayAccess
* @implements \Mantle\Support\Enumerable
@@ -65,7 +66,7 @@ public function __construct( $items = [] ) {
* @param iterable|\WP_Query $value
* @return static
*/
- public static function from( $value ) {
+ public static function from( mixed $value ) {
global $post;
if ( $value instanceof \WP_Query ) {
$items = [];
@@ -109,6 +110,15 @@ public function all() {
return $this->items;
}
+ /**
+ * Get a lazy collection for the items in this collection.
+ *
+ * @return Lazy_Collection
+ */
+ public function lazy(): Lazy_Collection {
+ return new Lazy_Collection( $this->items );
+ }
+
/**
* Get the average value of a given key.
*
@@ -221,7 +231,7 @@ public function contains( $key, $operator = null, $value = null ) {
return $this->first( $key, $placeholder ) !== $placeholder;
}
- return in_array( $key, $this->items ); // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
+ return in_array( $key, $this->items, false ); // phpcs:ignore WordPress.PHP.StrictInArray.FoundNonStrictFalse
}
return $this->contains( $this->operator_for_where( ...func_get_args() ) );
@@ -243,7 +253,7 @@ public function contains_strict( $key, $value = null ) {
return ! is_null( $this->first( $key ) );
}
- return in_array( $key, $this->items, true );
+ return in_array( $key, $this->items, true );
}
/**
@@ -255,7 +265,7 @@ public function contains_strict( $key, $value = null ) {
* @return bool
*/
public function doesnt_contain( $key, $operator = null, $value = null ) {
- return ! $this->contains( ...func_get_args() );
+ return ! $this->contains( ...func_get_args() );
}
/**
@@ -522,7 +532,7 @@ public function group_by( $group_by, $preserve_keys = false ) {
$result = new static( $results );
if ( ! empty( $next_groups ) ) {
- return $result->map->groupBy( $next_groups, $preserve_keys ); // @phpstan-ignore-line undefined method
+ return $result->map->group_by( $next_groups, $preserve_keys );
}
return $result;
@@ -1104,6 +1114,26 @@ public function skip( $count ) {
return $this->slice( $count );
}
+ /**
+ * Skip items in the collection until the given condition is met.
+ *
+ * @param TValue|callable(TValue,TKey): bool $value
+ * @return static
+ */
+ public function skip_until( $value ) {
+ return new static( $this->lazy()->skip_until( $value )->all() );
+ }
+
+ /**
+ * Skip items in the collection while the given condition is met.
+ *
+ * @param TValue|callable(TValue,TKey): bool $value
+ * @return static
+ */
+ public function skip_while( $value ) {
+ return new static( $this->lazy()->skip_while( $value )->all() );
+ }
+
/**
* Slice the underlying collection array.
*
@@ -1289,7 +1319,7 @@ public function splice( $offset, $length = null, $replacement = [] ) {
/**
* Take the first or last {$limit} items.
*
- * @param int $limit
+ * @param int $limit
* @return static
*/
public function take( $limit ) {
@@ -1300,13 +1330,32 @@ public function take( $limit ) {
return $this->slice( 0, $limit );
}
+ /**
+ * Take items in the collection until the given condition is met.
+ *
+ * @param TValue|callable(TValue,TKey): bool $value
+ * @return static
+ */
+ public function take_until( $value ) {
+ return new static( $this->lazy()->take_until( $value )->all() );
+ }
+
+ /**
+ * Take items in the collection while the given condition is met.
+ *
+ * @param TValue|callable(TValue,TKey): bool $value
+ * @return static
+ */
+ public function take_while( $value ) {
+ return new static( $this->lazy()->take_while( $value )->all() );
+ }
+
/**
* Transform each item in the collection using a callback.
*
* @param callable(TValue, TKey): TValue $callback
- * @return $this
*/
- public function transform( callable $callback ) {
+ public function transform( callable $callback ): static {
$this->items = $this->map( $callback )->all();
return $this;
@@ -1388,6 +1437,16 @@ public function count(): int {
return count( $this->items );
}
+ /**
+ * Count the number of items in the collection by a field or using a callback.
+ *
+ * @param (callable(TValue, TKey): array-key)|string|null $count_by
+ * @return static
+ */
+ public function count_by( $count_by = null ) {
+ return new static( $this->lazy()->count_by( $count_by )->all() );
+ }
+
/**
* Add an item to the collection.
*
diff --git a/src/mantle/support/class-lazy-collection.php b/src/mantle/support/class-lazy-collection.php
new file mode 100644
index 000000000..09e453e57
--- /dev/null
+++ b/src/mantle/support/class-lazy-collection.php
@@ -0,0 +1,1737 @@
+
+ */
+class Lazy_Collection implements Enumerable {
+ /**
+ * @use \Mantle\Support\Traits\Enumerates_Values
+ */
+ use Enumerates_Values;
+ use Macroable;
+
+ /**
+ * The source from which to generate items.
+ *
+ * @var (Closure(): \Generator)|static|array
+ */
+ public $source;
+
+ /**
+ * Create a new lazy collection instance.
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable|(Closure(): \Generator)|self|array|null $source
+ * @return void
+ */
+ public function __construct( $source = null ) {
+ if ( $source instanceof Closure || $source instanceof self ) {
+ $this->source = $source;
+ } elseif ( is_null( $source ) ) {
+ $this->source = static::empty();
+ } elseif ( $source instanceof Generator ) {
+ throw new InvalidArgumentException(
+ 'Generators should not be passed directly to Lazy_Collection. Instead, pass a generator function.'
+ );
+ } else {
+ $this->source = $this->get_arrayable_items( $source );
+ }
+ }
+
+ /**
+ * Create a new collection instance if the value isn't one already.
+ *
+ * @template TMakeKey of array-key
+ * @template TMakeValue
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable|(Closure(): \Generator)|self|array|null $items
+ * @return static
+ */
+ public static function make( $items = [] ) {
+ return new static( $items );
+ }
+
+ /**
+ * Create a collection with the given range.
+ *
+ * @param int $from
+ * @param int $to
+ * @return static
+ */
+ public static function range( $from, $to ) {
+ return new static( function () use ( $from, $to ) {
+ if ( $from <= $to ) {
+ for ( ; $from <= $to; $from++ ) {
+ yield $from;
+ }
+ } else {
+ for ( ; $from >= $to; $from-- ) {
+ yield $from;
+ }
+ }
+ } );
+ }
+
+ /**
+ * Get all items in the enumerable.
+ *
+ * @return array
+ */
+ public function all() {
+ if ( is_array( $this->source ) ) {
+ return $this->source;
+ }
+
+ return iterator_to_array( $this->getIterator() );
+ }
+
+ /**
+ * Eager load all items into a new lazy collection backed by an array.
+ *
+ * @return static
+ */
+ public function eager() {
+ return new static( $this->all() );
+ }
+
+ /**
+ * Cache values as they're enumerated.
+ *
+ * @return static
+ */
+ public function remember() {
+ $iterator = $this->getIterator();
+
+ $iteratorIndex = 0;
+
+ $cache = [];
+
+ return new static( function () use ( $iterator, &$iteratorIndex, &$cache ) {
+ for ( $index = 0; true; $index++ ) {
+ if ( array_key_exists( $index, $cache ) ) {
+ yield $cache[ $index ][0] => $cache[ $index ][1];
+
+ continue;
+ }
+
+ if ( $iteratorIndex < $index ) {
+ $iterator->next();
+
+ $iteratorIndex++;
+ }
+
+ if ( ! $iterator->valid() ) {
+ break;
+ }
+
+ $cache[ $index ] = [ $iterator->key(), $iterator->current() ];
+
+ yield $cache[ $index ][0] => $cache[ $index ][1];
+ }
+ } );
+ }
+
+ /**
+ * Get the average value of a given key.
+ *
+ * @param (callable(TValue): float|int)|string|null $callback
+ * @return float|int|null
+ */
+ public function avg( $callback = null ) {
+ return $this->collect()->avg( $callback );
+ }
+
+ /**
+ * Get the median of a given key.
+ *
+ * @param string|array|null $key
+ * @return float|int|null
+ */
+ public function median( $key = null ) {
+ return $this->collect()->median( $key );
+ }
+
+ /**
+ * Get the mode of a given key.
+ *
+ * @param string|array|null $key
+ * @return array|null
+ */
+ public function mode( $key = null ) {
+ return $this->collect()->mode( $key );
+ }
+
+ /**
+ * Collapse the collection of items into a single array.
+ *
+ * @return static
+ */
+ public function collapse() {
+ return new static( function () {
+ foreach ( $this as $values ) {
+ if ( is_array( $values ) || $values instanceof Enumerable ) {
+ foreach ( $values as $value ) {
+ yield $value;
+ }
+ }
+ }
+ } );
+ }
+
+ /**
+ * Determine if an item exists in the enumerable.
+ *
+ * @param (callable(TValue, TKey): bool)|TValue|string $key
+ * @param mixed $operator
+ * @param mixed $value
+ * @return bool
+ */
+ public function contains( $key, $operator = null, $value = null ) {
+ if ( func_num_args() === 1 && $this->use_as_callable( $key ) ) {
+ $placeholder = new stdClass();
+
+ /** @var callable $key */
+ return $this->first( $key, $placeholder ) !== $placeholder;
+ }
+
+ if ( func_num_args() === 1 ) {
+ $needle = $key;
+
+ foreach ( $this as $value ) {
+ if ( $value == $needle ) { // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ return $this->contains( $this->operator_for_where( ...func_get_args() ) );
+ }
+
+ /**
+ * Determine if an item exists, using strict comparison.
+ *
+ * @param (callable(TValue): bool)|TValue|array-key $key
+ * @param TValue|null $value
+ * @return bool
+ */
+ public function contains_strict( $key, $value = null ) {
+ if ( func_num_args() === 2 ) {
+ return $this->contains( fn ( $item ) => data_get( $item, $key ) === $value );
+ }
+
+ if ( $this->use_as_callable( $key ) ) {
+ return ! is_null( $this->first( $key ) );
+ }
+
+ foreach ( $this as $item ) {
+ if ( $item === $key ) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Determine if an item is not contained in the enumerable.
+ *
+ * @param mixed $key
+ * @param mixed $operator
+ * @param mixed $value
+ * @return bool
+ */
+ public function doesnt_contain( $key, $operator = null, $value = null ) {
+ return ! $this->contains( ...func_get_args() );
+ }
+
+ /**
+ * Cross join the given iterables, returning all possible permutations.
+ *
+ * @template TCrossJoinKey of array-key
+ * @template TCrossJoinValue
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable ...$arrays
+ * @return static>
+ */
+ public function cross_join( ...$arrays ) {
+ return $this->passthru( 'cross_join', func_get_args() );
+ }
+
+ /**
+ * Count the number of items in the collection by a field or using a callback.
+ *
+ * @param (callable(TValue, TKey): array-key)|string|null $count_by
+ * @return static
+ */
+ public function count_by( $count_by = null ) {
+ $count_by = is_null( $count_by )
+ ? $this->identity()
+ : $this->value_retriever( $count_by );
+
+ return new static( function () use ( $count_by ) {
+ $counts = [];
+
+ foreach ( $this as $key => $value ) {
+ $group = $count_by( $value, $key );
+
+ if ( empty( $counts[ $group ] ) ) {
+ $counts[ $group ] = 0;
+ }
+
+ $counts[ $group ]++;
+ }
+
+ yield from $counts;
+ } );
+ }
+
+ /**
+ * Get the items that are not present in the given items.
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $items
+ * @return static
+ */
+ public function diff( $items ) {
+ return $this->passthru( 'diff', func_get_args() );
+ }
+
+ /**
+ * Get the items that are not present in the given items, using the callback.
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $items
+ * @param callable(TValue, TValue): int $callback
+ * @return static
+ */
+ public function diff_using( $items, callable $callback ) {
+ return $this->passthru( 'diff_using', func_get_args() );
+ }
+
+ /**
+ * Get the items whose keys and values are not present in the given items.
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $items
+ * @return static
+ */
+ public function diff_assoc( $items ) {
+ return $this->passthru( 'diff_assoc', func_get_args() );
+ }
+
+ /**
+ * Get the items whose keys and values are not present in the given items, using the callback.
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $items
+ * @param callable(TKey, TKey): int $callback
+ * @return static
+ */
+ public function diff_assoc_using( $items, callable $callback ) {
+ return $this->passthru( 'diff_assoc_using', func_get_args() );
+ }
+
+ /**
+ * Get the items whose keys are not present in the given items.
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $items
+ * @return static
+ */
+ public function diff_keys( $items ) {
+ return $this->passthru( 'diff_keys', func_get_args() );
+ }
+
+ /**
+ * Get the items whose keys are not present in the given items, using the callback.
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $items
+ * @param callable(TKey, TKey): int $callback
+ * @return static
+ */
+ public function diff_keys_using( $items, callable $callback ) {
+ return $this->passthru( 'diff_keys_using', func_get_args() );
+ }
+
+ /**
+ * Retrieve duplicate items.
+ *
+ * @param (callable(TValue): bool)|string|null $callback
+ * @param bool $strict
+ * @return static
+ */
+ public function duplicates( $callback = null, $strict = false ) {
+ return $this->passthru( 'duplicates', func_get_args() );
+ }
+
+ /**
+ * Retrieve duplicate items using strict comparison.
+ *
+ * @param (callable(TValue): bool)|string|null $callback
+ * @return static
+ */
+ public function duplicates_strict( $callback = null ) {
+ return $this->passthru( 'duplicates_strict', func_get_args() );
+ }
+
+ /**
+ * Get all items except for those with the specified keys.
+ *
+ * @param \Mantle\Support\Enumerable|array $keys
+ * @return static
+ */
+ public function except( $keys ) {
+ return $this->passthru( 'except', func_get_args() );
+ }
+
+ /**
+ * Run a filter over each of the items.
+ *
+ * @param (callable(TValue, TKey): bool)|null $callback
+ * @return static
+ */
+ public function filter( ?callable $callback = null ) {
+ if ( is_null( $callback ) ) {
+ $callback = fn ( $value ) => (bool) $value;
+ }
+
+ return new static( function () use ( $callback ) {
+ foreach ( $this as $key => $value ) {
+ if ( $callback( $value, $key ) ) {
+ yield $key => $value;
+ }
+ }
+ } );
+ }
+
+ /**
+ * Get the first item from the enumerable passing the given truth test.
+ *
+ * @template TFirstDefault
+ *
+ * @param (callable(TValue): bool)|null $callback
+ * @param TFirstDefault|(\Closure(): TFirstDefault) $default
+ * @return TValue|TFirstDefault
+ */
+ public function first( ?callable $callback = null, $default = null ) {
+ $iterator = $this->getIterator();
+
+ if ( is_null( $callback ) ) {
+ if ( ! $iterator->valid() ) {
+ return value( $default );
+ }
+
+ return $iterator->current();
+ }
+
+ foreach ( $iterator as $key => $value ) {
+ if ( $callback( $value, $key ) ) {
+ return $value;
+ }
+ }
+
+ return value( $default );
+ }
+
+ /**
+ * Get a flattened list of the items in the collection.
+ *
+ * @param int $depth
+ * @return static
+ */
+ public function flatten( $depth = INF ) {
+ $instance = new static( function () use ( $depth ) {
+ foreach ( $this as $item ) {
+ if ( ! is_array( $item ) && ! $item instanceof Enumerable ) {
+ yield $item;
+ } elseif ( $depth === 1 ) {
+ yield from $item;
+ } else {
+ yield from (new static( $item ))->flatten( $depth - 1 );
+ }
+ }
+ } );
+
+ return $instance->values();
+ }
+
+ /**
+ * Flip the items in the collection.
+ *
+ * @return static
+ */
+ public function flip() {
+ return new static( function () {
+ foreach ( $this as $key => $value ) {
+ yield $value => $key;
+ }
+ } );
+ }
+
+ /**
+ * Get an item by key.
+ *
+ * @template TGetDefault
+ *
+ * @param TKey|null $key
+ * @param TGetDefault|(\Closure(): TGetDefault) $default
+ * @return TValue|TGetDefault
+ */
+ public function get( $key, $default = null ) {
+ if ( is_null( $key ) ) {
+ return;
+ }
+
+ foreach ( $this as $outerKey => $outerValue ) {
+ if ( $outerKey === $key ) {
+ return $outerValue;
+ }
+ }
+
+ return value( $default );
+ }
+
+ /**
+ * Group an associative array by a field or using a callback.
+ *
+ * @param (callable(TValue, TKey): array-key)|array|string $groupBy
+ * @param bool $preserveKeys
+ * @return static>
+ */
+ public function group_by( $groupBy, $preserveKeys = false ) {
+ return $this->passthru( 'group_by', func_get_args() );
+ }
+
+ /**
+ * Key an associative array by a field or using a callback.
+ *
+ * @param (callable(TValue, TKey): array-key)|array|string $keyBy
+ * @return static
+ */
+ public function key_by( $keyBy ) {
+ return new static( function () use ( $keyBy ) {
+ $keyBy = $this->value_retriever( $keyBy );
+
+ foreach ( $this as $key => $item ) {
+ $resolvedKey = $keyBy( $item, $key );
+
+ if ( is_object( $resolvedKey ) ) {
+ $resolvedKey = (string) $resolvedKey;
+ }
+
+ yield $resolvedKey => $item;
+ }
+ } );
+ }
+
+ /**
+ * Determine if an item exists in the collection by key.
+ *
+ * @param mixed $key
+ */
+ public function has( $key ): bool {
+ $keys = array_flip( is_array( $key ) ? $key : func_get_args() );
+ $count = count( $keys );
+
+ foreach ( $this as $key => $value ) {
+ if ( array_key_exists( $key, $keys ) && --$count === 0 ) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Determine if any of the keys exist in the collection.
+ *
+ * @param mixed $key
+ */
+ public function hasAny( $key ): bool {
+ $keys = array_flip( is_array( $key ) ? $key : func_get_args() );
+
+ foreach ( $this as $key => $value ) {
+ if ( array_key_exists( $key, $keys ) ) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Concatenate values of a given key as a string.
+ *
+ * @param callable|string $value
+ * @param string|null $glue
+ * @return string
+ */
+ public function implode( $value, $glue = null ) {
+ return $this->collect()->implode( ...func_get_args() );
+ }
+
+ /**
+ * Concatenate values of a given key as a string and returns a stringable class.
+ *
+ * @param callable|string $value
+ * @param string|null $glue
+ * @return string
+ */
+ public function implode_str( $value, $glue = null ) {
+ return $this->collect()->implode_str( ...func_get_args() );
+ }
+
+ /**
+ * Intersect the collection with the given items.
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $items
+ * @return static
+ */
+ public function intersect( $items ) {
+ return $this->passthru( 'intersect', func_get_args() );
+ }
+
+ /**
+ * Intersect the collection with the given items, using the callback.
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $items
+ * @param callable(TValue, TValue): int $callback
+ * @return static
+ */
+ public function intersect_using( $items, callable $callback ) {
+ return $this->passthru( 'intersect_using', func_get_args() );
+ }
+
+ /**
+ * Intersect the collection with the given items with additional index check.
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $items
+ * @return static
+ */
+ public function intersect_assoc( $items ) {
+ return $this->passthru( 'intersect_assoc', func_get_args() );
+ }
+
+ /**
+ * Intersect the collection with the given items with additional index check, using the callback.
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $items
+ * @param callable(TValue, TValue): int $callback
+ * @return static
+ */
+ public function intersect_assoc_using( $items, callable $callback ) {
+ return $this->passthru( 'intersect_assoc_using', func_get_args() );
+ }
+
+ /**
+ * Intersect the collection with the given items by key.
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $items
+ * @return static
+ */
+ public function intersect_by_keys( $items ) {
+ return $this->passthru( 'intersect_by_keys', func_get_args() );
+ }
+
+ /**
+ * Determine if the items are empty or not.
+ *
+ * @return bool
+ */
+ public function is_empty() {
+ return ! $this->getIterator()->valid();
+ }
+
+ /**
+ * Determine if the collection contains a single item.
+ */
+ public function contains_one_item(): bool {
+ return $this->take( 2 )->count() === 1;
+ }
+
+ /**
+ * Join all items from the collection using a string. The final items can use a separate glue string.
+ *
+ * @param string $glue
+ * @param string $finalGlue
+ * @return string
+ */
+ public function join( $glue, $finalGlue = '' ) {
+ return $this->collect()->join( ...func_get_args() );
+ }
+
+ /**
+ * Get the keys of the collection items.
+ *
+ * @return static
+ */
+ public function keys() {
+ return new static( function () {
+ foreach ( $this as $key => $value ) {
+ yield $key;
+ }
+ } );
+ }
+
+ /**
+ * Get the last item from the collection.
+ *
+ * @template TLastDefault
+ *
+ * @param (callable(TValue, TKey): bool)|null $callback
+ * @param TLastDefault|(\Closure(): TLastDefault) $default
+ * @return TValue|TLastDefault
+ */
+ public function last( ?callable $callback = null, $default = null ) {
+ $needle = $placeholder = new stdClass();
+
+ foreach ( $this as $key => $value ) {
+ if ( is_null( $callback ) || $callback( $value, $key ) ) {
+ $needle = $value;
+ }
+ }
+
+ return $needle === $placeholder ? value( $default ) : $needle;
+ }
+
+ /**
+ * Get the values of a given key.
+ *
+ * @param string|array $value
+ * @param string|null $key
+ * @return static
+ */
+ public function pluck( $value, $key = null ) {
+ return new static( function () use ( $value, $key ) {
+ [$value, $key] = $this->explode_pluck_parameters( $value, $key );
+
+ foreach ( $this as $item ) {
+ $itemValue = data_get( $item, $value );
+
+ if ( is_null( $key ) ) {
+ yield $itemValue;
+ } else {
+ $itemKey = data_get( $item, $key );
+
+ if ( is_object( $itemKey ) && method_exists( $itemKey, '__toString' ) ) {
+ $itemKey = (string) $itemKey;
+ }
+
+ yield $itemKey => $itemValue;
+ }
+ }
+ } );
+ }
+
+ /**
+ * Run a map over each of the items.
+ *
+ * @template TMapValue
+ *
+ * @param callable(TValue, TKey): TMapValue $callback
+ * @return static
+ */
+ public function map( callable $callback ) {
+ return new static( function () use ( $callback ) {
+ foreach ( $this as $key => $value ) {
+ yield $key => $callback( $value, $key );
+ }
+ } );
+ }
+
+ /**
+ * Run a dictionary map over the items.
+ *
+ * The callback should return an associative array with a single key/value pair.
+ *
+ * @template TMapToDictionaryKey of array-key
+ * @template TMapToDictionaryValue
+ *
+ * @param callable(TValue, TKey): array $callback
+ * @return static>
+ */
+ public function map_to_dictionary( callable $callback ) {
+ return $this->passthru( 'map_to_dictionary', func_get_args() );
+ }
+
+ /**
+ * Run an associative map over each of the items.
+ *
+ * The callback should return an associative array with a single key/value pair.
+ *
+ * @template TMapWithKeysKey of array-key
+ * @template TMapWithKeysValue
+ *
+ * @param callable(TValue, TKey): array $callback
+ * @return static
+ */
+ public function map_with_keys( callable $callback ) {
+ return new static( function () use ( $callback ) {
+ foreach ( $this as $key => $value ) {
+ yield from $callback( $value, $key );
+ }
+ } );
+ }
+
+ /**
+ * Merge the collection with the given items.
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $items
+ * @return static
+ */
+ public function merge( $items ) {
+ return $this->passthru( 'merge', func_get_args() );
+ }
+
+ /**
+ * Recursively merge the collection with the given items.
+ *
+ * @template TMergeRecursiveValue
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $items
+ * @return static
+ */
+ public function merge_recursive( $items ) {
+ return $this->passthru( 'merge_recursive', func_get_args() );
+ }
+
+ /**
+ * Create a collection by using this collection for keys and another for its values.
+ *
+ * @template TCombineValue
+ *
+ * @param \IteratorAggregate|array|(callable(): \Generator) $values
+ * @return static
+ */
+ public function combine( $values ) {
+ return new static( function () use ( $values ) {
+ $values = $this->make_iterator( $values );
+
+ $error_message = 'Both parameters should have an equal number of elements';
+
+ foreach ( $this as $key ) {
+ if ( ! $values->valid() ) {
+ trigger_error( esc_html( $error_message ), E_USER_WARNING ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
+
+ break;
+ }
+
+ yield $key => $values->current();
+
+ $values->next();
+ }
+
+ if ( $values->valid() ) {
+ trigger_error( esc_html( $error_message ), E_USER_WARNING ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
+ }
+ } );
+ }
+
+ /**
+ * Union the collection with the given items.
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $items
+ * @return static
+ */
+ public function union( $items ) {
+ return $this->passthru( 'union', func_get_args() );
+ }
+
+ /**
+ * Create a new collection consisting of every n-th element.
+ *
+ * @param int $step
+ * @param int $offset
+ * @return static
+ */
+ public function nth( $step, $offset = 0 ) {
+ return new static( function () use ( $step, $offset ) {
+ $position = 0;
+
+ foreach ( $this->slice( $offset ) as $item ) {
+ if ( $position % $step === 0 ) {
+ yield $item;
+ }
+
+ $position++;
+ }
+ } );
+ }
+
+ /**
+ * Get the items with the specified keys.
+ *
+ * @param \Mantle\Support\Enumerable|array|string $keys
+ * @return static
+ */
+ public function only( $keys ) {
+ if ( $keys instanceof Enumerable ) {
+ $keys = $keys->all();
+ } elseif ( ! is_null( $keys ) ) { // @phpstan-ignore-line always evaluate to false
+ $keys = is_array( $keys ) ? $keys : func_get_args();
+ }
+
+ return new static( function () use ( $keys ) {
+ if ( is_null( $keys ) ) { // @phpstan-ignore-line always evaluate to false
+ yield from $this;
+ } else {
+ $keys = array_flip( $keys );
+
+ foreach ( $this as $key => $value ) {
+ if ( array_key_exists( $key, $keys ) ) {
+ yield $key => $value;
+
+ unset( $keys[ $key ] );
+
+ if ( empty( $keys ) ) {
+ break;
+ }
+ }
+ }
+ }
+ } );
+ }
+
+ /**
+ * Select specific values from the items within the collection.
+ *
+ * @param \Mantle\Support\Enumerable|array|string $keys
+ * @return static
+ */
+ public function select( $keys ) {
+ if ( $keys instanceof Enumerable ) {
+ $keys = $keys->all();
+ } elseif ( ! is_null( $keys ) ) {
+ $keys = is_array( $keys ) ? $keys : func_get_args();
+ }
+
+ return new static( function () use ( $keys ) {
+ if ( is_null( $keys ) ) {
+ yield from $this;
+ } else {
+ foreach ( $this as $item ) {
+ $result = [];
+
+ foreach ( $keys as $key ) {
+ if ( Arr::accessible( $item ) && Arr::exists( $item, $key ) ) {
+ $result[ $key ] = $item[ $key ];
+ } elseif ( is_object( $item ) && isset( $item->{$key} ) ) {
+ $result[ $key ] = $item->{$key};
+ }
+ }
+
+ yield $result;
+ }
+ }
+ } );
+ }
+
+ /**
+ * Push all of the given items onto the collection.
+ *
+ * @template TConcatKey of array-key
+ * @template TConcatValue
+ *
+ * @param iterable $source
+ * @return static
+ */
+ public function concat( $source ) {
+ return ( new static( function () use ( $source ) {
+ yield from $this;
+ yield from $source;
+ } ) )->values();
+ }
+
+ /**
+ * Get one or a specified number of items randomly from the collection.
+ *
+ * @param int|null $number
+ * @return static|TValue
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function random( $number = null ) {
+ $result = $this->collect()->random( ...func_get_args() );
+
+ return is_null( $number ) ? $result : new static( $result );
+ }
+
+ /**
+ * Replace the collection items with the given items.
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $items
+ * @return static
+ */
+ public function replace( $items ) {
+ return new static( function () use ( $items ) {
+ $items = $this->get_arrayable_items( $items );
+
+ foreach ( $this as $key => $value ) {
+ if ( array_key_exists( $key, $items ) ) {
+ yield $key => $items[ $key ];
+
+ unset( $items[ $key ] );
+ } else {
+ yield $key => $value;
+ }
+ }
+
+ foreach ( $items as $key => $value ) {
+ yield $key => $value;
+ }
+ } );
+ }
+
+ /**
+ * Recursively replace the collection items with the given items.
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $items
+ * @return static
+ */
+ public function replace_recursive( $items ) {
+ return $this->passthru( 'replace_recursive', func_get_args() );
+ }
+
+ /**
+ * Reverse items order.
+ *
+ * @return static
+ */
+ public function reverse() {
+ return $this->passthru( 'reverse', func_get_args() );
+ }
+
+ /**
+ * Search the collection for a given value and return the corresponding key if successful.
+ *
+ * @param TValue|(callable(TValue,TKey): bool) $value
+ * @param bool $strict
+ * @return TKey|false
+ */
+ public function search( $value, $strict = false ) {
+ /** @var (callable(TValue,TKey): bool) $predicate */
+ $predicate = $this->use_as_callable( $value )
+ ? $value
+ : ( fn ( $item ) => $strict ? $item === $value : $item == $value ); // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual
+
+ foreach ( $this as $key => $item ) {
+ if ( $predicate( $item, $key ) ) {
+ return $key;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Shuffle the items in the collection.
+ *
+ * @return static
+ */
+ public function shuffle( $seed = null ) {
+ return $this->passthru( 'shuffle', [] );
+ }
+
+ /**
+ * Create chunks representing a "sliding window" view of the items in the collection.
+ *
+ * @param int $size
+ * @param int $step
+ * @return static
+ */
+ public function sliding( $size = 2, $step = 1 ) {
+ return new static( function () use ( $size, $step ) {
+ $iterator = $this->getIterator();
+
+ $chunk = [];
+
+ while ( $iterator->valid() ) {
+ $chunk[ $iterator->key() ] = $iterator->current();
+
+ if ( count( $chunk ) === $size ) {
+ yield (new static( $chunk ))->tap( function () use ( &$chunk, $step ): void {
+ $chunk = array_slice( $chunk, $step, null, true );
+ } );
+
+ // If the $step between chunks is bigger than each chunk's $size
+ // we will skip the extra items (which should never be in any
+ // chunk) before we continue to the next chunk in the loop.
+ if ( $step > $size ) {
+ $skip = $step - $size;
+
+ for ( $i = 0; $i < $skip && $iterator->valid(); $i++ ) { // phpcs:ignore Generic.CodeAnalysis.ForLoopWithTestFunctionCall.NotAllowed
+ $iterator->next();
+ }
+ }
+ }
+
+ $iterator->next();
+ }
+ } );
+ }
+
+ /**
+ * Skip the first {$count} items.
+ *
+ * @param int $count
+ * @return static
+ */
+ public function skip( $count ) {
+ return new static( function () use ( $count ) {
+ $iterator = $this->getIterator();
+
+ while ( $iterator->valid() && $count-- ) {
+ $iterator->next();
+ }
+
+ while ( $iterator->valid() ) {
+ yield $iterator->key() => $iterator->current();
+
+ $iterator->next();
+ }
+ } );
+ }
+
+ /**
+ * Skip items in the collection until the given condition is met.
+ *
+ * @param TValue|callable(TValue,TKey): bool $value
+ * @return static
+ */
+ public function skip_until( $value ) {
+ $callback = $this->use_as_callable( $value ) ? $value : $this->equality( $value );
+
+ return $this->skip_while( $this->negate( $callback ) );
+ }
+
+ /**
+ * Skip items in the collection while the given condition is met.
+ *
+ * @param TValue|callable(TValue,TKey): bool $value
+ * @return static
+ */
+ public function skip_while( $value ) {
+ $callback = $this->use_as_callable( $value ) ? $value : $this->equality( $value );
+
+ return new static( function () use ( $callback ) {
+ $iterator = $this->getIterator();
+
+ while ( $iterator->valid() && $callback( $iterator->current(), $iterator->key() ) ) {
+ $iterator->next();
+ }
+
+ while ( $iterator->valid() ) {
+ yield $iterator->key() => $iterator->current();
+
+ $iterator->next();
+ }
+ } );
+ }
+
+ /**
+ * Get a slice of items from the enumerable.
+ *
+ * @param int $offset
+ * @param int|null $length
+ * @return static
+ */
+ public function slice( $offset, $length = null ) {
+ if ( $offset < 0 || $length < 0 ) {
+ return $this->passthru( 'slice', func_get_args() );
+ }
+
+ $instance = $this->skip( $offset );
+
+ return is_null( $length ) ? $instance : $instance->take( $length );
+ }
+
+ /**
+ * Split a collection into a certain number of groups.
+ *
+ * @param int $numberOfGroups
+ * @return static
+ */
+ public function split( $numberOfGroups ) {
+ return $this->passthru( 'split', func_get_args() );
+ }
+
+ /**
+ * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception.
+ *
+ * @param (callable(TValue, TKey): bool)|string $key
+ * @param mixed $operator
+ * @param mixed $value
+ * @return TValue
+ *
+ * @throws \Mantle\Support\ItemNotFoundException
+ * @throws \Mantle\Support\MultipleItemsFoundException
+ */
+ public function sole( $key = null, $operator = null, $value = null ) {
+ $filter = func_num_args() > 1
+ ? $this->operator_for_where( ...func_get_args() )
+ : $key;
+
+ return $this
+ ->unless( $filter === null )
+ ->filter( $filter )
+ ->take( 2 )
+ ->collect()
+ ->sole();
+ }
+
+ /**
+ * Get the first item in the collection but throw an exception if no matching items exist.
+ *
+ * @param (callable(TValue, TKey): bool)|string $key
+ * @param mixed $operator
+ * @param mixed $value
+ * @return TValue
+ *
+ * @throws \Mantle\Support\ItemNotFoundException
+ */
+ public function first_or_fail( $key = null, $operator = null, $value = null ) {
+ $filter = func_num_args() > 1
+ ? $this->operator_for_where( ...func_get_args() )
+ : $key;
+
+ return $this
+ ->unless( $filter === null )
+ ->filter( $filter )
+ ->take( 1 )
+ ->collect()
+ ->firstOrFail();
+ }
+
+ /**
+ * Chunk the collection into chunks of the given size.
+ *
+ * @param int $size
+ * @return static
+ */
+ public function chunk( $size ) {
+ if ( $size <= 0 ) {
+ return static::empty();
+ }
+
+ return new static( function () use ( $size ) {
+ $iterator = $this->getIterator();
+
+ while ( $iterator->valid() ) {
+ $chunk = [];
+
+ while ( true ) {
+ $chunk[ $iterator->key() ] = $iterator->current();
+
+ if ( count( $chunk ) < $size ) {
+ $iterator->next();
+
+ if ( ! $iterator->valid() ) {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+ yield new static( $chunk );
+
+ $iterator->next();
+ }
+ } );
+ }
+
+ /**
+ * Split a collection into a certain number of groups, and fill the first groups completely.
+ *
+ * @param int $numberOfGroups
+ * @return static
+ */
+ public function split_in( $numberOfGroups ) {
+ return $this->chunk( ceil( $this->count() / $numberOfGroups ) );
+ }
+
+ /**
+ * Chunk the collection into chunks with a callback.
+ *
+ * @param callable(TValue, TKey, Collection): bool $callback
+ * @return static>
+ */
+ public function chunk_while( callable $callback ) {
+ return new static( function () use ( $callback ) {
+ $iterator = $this->getIterator();
+
+ $chunk = new Collection();
+
+ if ( $iterator->valid() ) {
+ $chunk[ $iterator->key() ] = $iterator->current();
+
+ $iterator->next();
+ }
+
+ while ( $iterator->valid() ) {
+ if ( ! $callback( $iterator->current(), $iterator->key(), $chunk ) ) {
+ yield new static( $chunk );
+
+ $chunk = new Collection();
+ }
+
+ $chunk[ $iterator->key() ] = $iterator->current();
+
+ $iterator->next();
+ }
+
+ if ( $chunk->is_not_empty() ) {
+ yield new static( $chunk );
+ }
+ } );
+ }
+
+ /**
+ * Sort through each item with a callback.
+ *
+ * @param (callable(TValue, TValue): int)|null|int $callback
+ * @return static
+ */
+ public function sort( $callback = null ) {
+ return $this->passthru( 'sort', func_get_args() );
+ }
+
+ /**
+ * Sort items in descending order.
+ *
+ * @param int $options
+ * @return static
+ */
+ public function sort_desc( $options = SORT_REGULAR ) {
+ return $this->passthru( 'sort_desc', func_get_args() );
+ }
+
+ /**
+ * Sort the collection using the given callback.
+ *
+ * @param array|(callable(TValue, TKey): mixed)|string $callback
+ * @param int $options
+ * @param bool $descending
+ * @return static
+ */
+ public function sort_by( $callback, $options = SORT_REGULAR, $descending = false ) {
+ return $this->passthru( 'sort_by', func_get_args() );
+ }
+
+ /**
+ * Sort the collection in descending order using the given callback.
+ *
+ * @param array|(callable(TValue, TKey): mixed)|string $callback
+ * @param int $options
+ * @return static
+ */
+ public function sort_by_desc( $callback, $options = SORT_REGULAR ) {
+ return $this->passthru( 'sort_by_desc', func_get_args() );
+ }
+
+ /**
+ * Sort the collection keys.
+ *
+ * @param int $options
+ * @param bool $descending
+ * @return static
+ */
+ public function sort_keys( $options = SORT_REGULAR, $descending = false ) {
+ return $this->passthru( 'sort_keys', func_get_args() );
+ }
+
+ /**
+ * Sort the collection keys in descending order.
+ *
+ * @param int $options
+ * @return static
+ */
+ public function sort_keys_desc( $options = SORT_REGULAR ) {
+ return $this->passthru( 'sort_keys_desc', func_get_args() );
+ }
+
+ /**
+ * Sort the collection keys using a callback.
+ *
+ * @param callable(TKey, TKey): int $callback
+ * @return static
+ */
+ public function sort_keys_using( callable $callback ) {
+ return $this->passthru( 'sort_keys_using', func_get_args() );
+ }
+
+ /**
+ * Take the first or last {$limit} items.
+ *
+ * @param int $limit
+ * @return static
+ */
+ public function take( $limit ) {
+ if ( $limit < 0 ) {
+ return new static( function () use ( $limit ) {
+ $limit = abs( $limit );
+ $ringBuffer = [];
+ $position = 0;
+
+ foreach ( $this as $key => $value ) {
+ $ringBuffer[ $position ] = [ $key, $value ];
+ $position = ( $position + 1 ) % $limit; // phpcs:ignore Squiz.Operators.IncrementDecrementUsage.Found
+ }
+
+ for ( $i = 0, $end = min( $limit, count( $ringBuffer ) ); $i < $end; $i++ ) {
+ $pointer = ( $position + $i ) % $limit;
+ yield $ringBuffer[ $pointer ][0] => $ringBuffer[ $pointer ][1];
+ }
+ } );
+ }
+
+ return new static( function () use ( $limit ) {
+ $iterator = $this->getIterator();
+
+ while ( $limit-- ) {
+ if ( ! $iterator->valid() ) {
+ break;
+ }
+
+ yield $iterator->key() => $iterator->current();
+
+ if ( $limit ) {
+ $iterator->next();
+ }
+ }
+ } );
+ }
+
+ /**
+ * Take items in the collection until the given condition is met.
+ *
+ * @param TValue|callable(TValue,TKey): bool $value
+ * @return static
+ */
+ public function take_until( $value ) {
+ /** @var callable(TValue, TKey): bool $callback */
+ $callback = $this->use_as_callable( $value ) ? $value : $this->equality( $value );
+
+ return new static( function () use ( $callback ) {
+ foreach ( $this as $key => $item ) {
+ if ( $callback( $item, $key ) ) {
+ break;
+ }
+
+ yield $key => $item;
+ }
+ } );
+ }
+
+ /**
+ * Take items in the collection until a given point in time.
+ *
+ * @param \DateTimeInterface $timeout
+ * @return static
+ */
+ public function take_until_timeout( DateTimeInterface $timeout ) {
+ $timeout = $timeout->getTimestamp();
+
+ return new static( function () use ( $timeout ) {
+ if ( $this->now() >= $timeout ) {
+ return;
+ }
+
+ foreach ( $this as $key => $value ) {
+ yield $key => $value;
+
+ if ( $this->now() >= $timeout ) {
+ break;
+ }
+ }
+ } );
+ }
+
+ /**
+ * Take items in the collection while the given condition is met.
+ *
+ * @param TValue|callable(TValue,TKey): bool $value
+ * @return static
+ */
+ public function take_while( $value ) {
+ /** @var callable(TValue, TKey): bool $callback */
+ $callback = $this->use_as_callable( $value ) ? $value : $this->equality( $value );
+
+ return $this->take_until( fn ( $item, $key ) => ! $callback( $item, $key ) );
+ }
+
+ /**
+ * Pass each item in the collection to the given callback, lazily.
+ *
+ * @param callable(TValue, TKey): mixed $callback
+ * @return static
+ */
+ public function tap_each( callable $callback ) {
+ return new static( function () use ( $callback ) {
+ foreach ( $this as $key => $value ) {
+ $callback( $value, $key );
+
+ yield $key => $value;
+ }
+ } );
+ }
+
+ /**
+ * Throttle the values, releasing them at most once per the given seconds.
+ *
+ * @return static
+ */
+ public function throttle( float $seconds ) {
+ return new static( function () use ( $seconds ) {
+ $microseconds = $seconds * 1_000_000;
+
+ foreach ( $this as $key => $value ) {
+ $fetchedAt = $this->precise_now();
+
+ yield $key => $value;
+
+ $sleep = $microseconds - ( $this->precise_now() - $fetchedAt );
+
+ $this->usleep( (int) $sleep );
+ }
+ } );
+ }
+
+ /**
+ * Flatten a multi-dimensional associative array with dots.
+ *
+ * @return static
+ */
+ public function dot() {
+ return $this->passthru( 'dot', [] );
+ }
+
+ /**
+ * Convert a flatten "dot" notation array into an expanded array.
+ *
+ * @return static
+ */
+ public function undot() {
+ return $this->passthru( 'undot', [] );
+ }
+
+ /**
+ * Return only unique items from the collection array.
+ *
+ * @param (callable(TValue, TKey): mixed)|string|null $key
+ * @param bool $strict
+ * @return static
+ */
+ public function unique( $key = null, $strict = false ) {
+ $callback = $this->value_retriever( $key );
+
+ return new static( function () use ( $callback, $strict ) {
+ $exists = [];
+
+ foreach ( $this as $key => $item ) {
+ if ( ! in_array( $id = $callback( $item, $key ), $exists, $strict ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
+ yield $key => $item;
+
+ $exists[] = $id;
+ }
+ }
+ } );
+ }
+
+ /**
+ * Reset the keys on the underlying array.
+ *
+ * @return static
+ */
+ public function values() {
+ return new static( function () {
+ foreach ( $this as $item ) {
+ yield $item;
+ }
+ } );
+ }
+
+ /**
+ * Zip the collection together with one or more arrays.
+ *
+ * Example:
+ *
+ * new Lazy_Collection([1, 2, 3])->zip([4, 5, 6]);
+ * => [[1, 4], [2, 5], [3, 6]]
+ *
+ * @template TZipValue
+ *
+ * @param \Mantle\Contracts\Support\Arrayable|iterable ...$items
+ * @return static>
+ */
+ public function zip( $items ) {
+ $iterables = func_get_args();
+
+ return new static( function () use ( $iterables ) {
+ $iterators = Collection::make( $iterables )->map( fn( $iterable ) => $this->make_iterator( $iterable ) )->prepend( $this->getIterator() );
+
+ while ( $iterators->contains->valid() ) {
+ yield new static( $iterators->map->current() );
+
+ $iterators->each->next();
+ }
+ } );
+ }
+
+ /**
+ * Pad collection to the specified length with a value.
+ *
+ * @template TPadValue
+ *
+ * @param int $size
+ * @param TPadValue $value
+ * @return static
+ */
+ public function pad( $size, $value ) {
+ if ( $size < 0 ) {
+ return $this->passthru( 'pad', func_get_args() );
+ }
+
+ return new static( function () use ( $size, $value ) {
+ $yielded = 0;
+
+ foreach ( $this as $index => $item ) {
+ yield $index => $item;
+
+ $yielded++;
+ }
+
+ while ( $yielded++ < $size ) {
+ yield $value;
+ }
+ } );
+ }
+
+ /**
+ * Get the values iterator.
+ *
+ * @return \Traversable
+ */
+ public function getIterator(): Traversable {
+ return $this->make_iterator( $this->source );
+ }
+
+ /**
+ * Count the number of items in the collection.
+ */
+ public function count(): int {
+ if ( is_array( $this->source ) ) {
+ return count( $this->source );
+ }
+
+ return iterator_count( $this->getIterator() );
+ }
+
+ /**
+ * Make an iterator from the given source.
+ *
+ * @template TIteratorKey of array-key
+ * @template TIteratorValue
+ *
+ * @param \IteratorAggregate|array|(callable(): \Generator) $source
+ * @return \Traversable
+ */
+ protected function make_iterator( $source ) {
+ if ( $source instanceof IteratorAggregate ) {
+ return $source->getIterator();
+ }
+
+ if ( is_array( $source ) ) {
+ return new ArrayIterator( $source );
+ }
+
+ if ( is_callable( $source ) ) {
+ $maybeTraversable = $source();
+
+ return $maybeTraversable instanceof Traversable
+ ? $maybeTraversable
+ : new ArrayIterator( Arr::wrap( $maybeTraversable ) );
+ }
+
+ return new ArrayIterator( (array) $source );
+ }
+
+ /**
+ * Explode the "value" and "key" arguments passed to "pluck".
+ *
+ * @param string|string[] $value
+ * @param string|string[]|null $key
+ * @return array{string[],string[]|null}
+ */
+ protected function explode_pluck_parameters( $value, $key ) {
+ $value = is_string( $value ) ? explode( '.', $value ) : $value;
+
+ $key = is_null( $key ) || is_array( $key ) ? $key : explode( '.', $key );
+
+ return [ $value, $key ];
+ }
+
+ /**
+ * Pass this lazy collection through a method on the collection class.
+ *
+ * @param string $method
+ * @param array $params
+ */
+ protected function passthru( $method, array $params ): static {
+ return new static( function () use ( $method, $params ) {
+ yield from $this->collect()->$method( ...$params );
+ } );
+ }
+
+ /**
+ * Get the current time.
+ */
+ protected function now(): int {
+ return class_exists( Carbon::class )
+ ? Carbon::now()->timestamp
+ : time();
+ }
+
+ /**
+ * Get the precise current time.
+ */
+ protected function precise_now(): float {
+ return class_exists( Carbon::class )
+ ? Carbon::now()->getPreciseTimestamp()
+ : microtime( true ) * 1_000_000;
+ }
+
+ /**
+ * Sleep for the given amount of microseconds.
+ */
+ protected function usleep( int $microseconds ): void {
+ if ( $microseconds <= 0 ) {
+ return;
+ }
+
+ usleep( $microseconds );
+ }
+}
diff --git a/src/mantle/support/interface-enumerable.php b/src/mantle/support/interface-enumerable.php
index 835fe24d3..45cee43d5 100644
--- a/src/mantle/support/interface-enumerable.php
+++ b/src/mantle/support/interface-enumerable.php
@@ -959,6 +959,14 @@ public function count_by( $callback = null );
*/
public function collect();
+ /**
+ * Indicate that the model's string representation should be escaped when __toString is invoked.
+ *
+ * @param bool $escape
+ * @return $this
+ */
+ public function escape_when_casting_to_string( bool $escape = true ): static;
+
/**
* Convert the collection to its string representation.
*
diff --git a/src/mantle/support/traits/trait-enumerates-values.php b/src/mantle/support/traits/trait-enumerates-values.php
index 0ac9d9989..02929afd6 100644
--- a/src/mantle/support/traits/trait-enumerates-values.php
+++ b/src/mantle/support/traits/trait-enumerates-values.php
@@ -2,17 +2,15 @@
/**
* Enumerates_Values trait file.
*
- * phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
- * phpcs:disable Squiz.Commenting.FunctionComment.MissingParamComment
- * phpcs:disable Squiz.Commenting.FunctionComment.ParamNameNoMatch
- * phpcs:disable Squiz.Commenting.FunctionComment.MissingParamTag
- * phpcs:disable WordPress.PHP.StrictInArray.MissingTrueStrict
+ * phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter, Squiz.Commenting.FunctionComment, WordPress.NamingConventions.ValidVariableName, WordPress.PHP.StrictInArray.MissingTrueStrict, WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
*
* @package Mantle
*/
namespace Mantle\Support\Traits;
+use BackedEnum;
+use CachingIterator;
use Closure;
use Exception;
use Mantle\Contracts\Support\Arrayable;
@@ -20,10 +18,13 @@
use Mantle\Support\Arr;
use Mantle\Support\Collection;
use Mantle\Support\Enumerable;
-use JsonSerializable;
use Mantle\Support\Higher_Order_Collection_Proxy;
-use Symfony\Component\VarDumper\VarDumper;
+use InvalidArgumentException;
+use JsonSerializable;
use Traversable;
+use UnexpectedValueException;
+use UnitEnum;
+use WeakMap;
use function Mantle\Support\Helpers\data_get;
@@ -31,7 +32,7 @@
* Enumerate_Values trait.
*
* @template TKey of array-key
- * @template TValue
+ * @template-covariant TValue
*
* @property-read Higher_Order_Collection_Proxy $average
* @property-read Higher_Order_Collection_Proxy $avg
@@ -58,15 +59,21 @@
trait Enumerates_Values {
use Conditionable;
+ /**
+ * Indicates that the object's string representation should be escaped when __toString is invoked.
+ */
+ protected bool $escape_when_casting_to_string = false;
+
/**
* The methods that can be proxied.
*
- * @var array
+ * @var array
*/
protected static $proxies = [
'average',
'avg',
'contains',
+ 'doesnt_contain',
'each',
'every',
'filter',
@@ -78,6 +85,7 @@ trait Enumerates_Values {
'max',
'min',
'partition',
+ 'percentage',
'reject',
'skip_until',
'skip_while',
@@ -88,7 +96,9 @@ trait Enumerates_Values {
'take_until',
'take_while',
'unique',
+ 'unless',
'until',
+ 'when',
];
/**
@@ -131,11 +141,39 @@ public static function unwrap( $value ) {
return $value instanceof Enumerable ? $value->all() : $value;
}
+ /**
+ * Create a new instance with no items.
+ *
+ * @return static
+ */
+ public static function empty() {
+ return new static( [] );
+ }
+
+ /**
+ * Create a new collection by invoking the callback a given amount of times.
+ *
+ * @template TTimesValue
+ *
+ * @param int $number
+ * @param (callable(int): TTimesValue)|null $callback
+ * @return static
+ */
+ public static function times( $number, ?callable $callback = null ) {
+ if ( $number < 1 ) {
+ return new static();
+ }
+
+ return static::range( 1, $number )
+ ->unless( $callback === null )
+ ->map( $callback );
+ }
+
/**
* Alias for the "avg" method.
*
- * @param callable|string|null $callback
- * @return mixed
+ * @param (callable(TValue): float|int)|string|null $callback
+ * @return float|int|null
*/
public function average( $callback = null ) {
return $this->avg( $callback );
@@ -144,9 +182,9 @@ public function average( $callback = null ) {
/**
* Alias for the "contains" method.
*
- * @param mixed $key
- * @param mixed $operator
- * @param mixed $value
+ * @param (callable(TValue, TKey): bool)|TValue|string $key
+ * @param mixed $operator
+ * @param mixed $value
* @return bool
*/
public function some( $key, $operator = null, $value = null ) {
@@ -154,52 +192,24 @@ public function some( $key, $operator = null, $value = null ) {
}
/**
- * Determine if an item exists, using strict comparison.
- *
- * @param mixed $key
- * @param mixed $value
- * @return bool
- */
- public function contains_strict( $key, $value = null ) {
- if ( func_num_args() === 2 ) {
- return $this->contains(
- fn ( $item ) => data_get( $item, $key ) === $value
- );
- }
-
- if ( $this->use_as_callable( $key ) ) {
- return ! is_null( $this->first( $key ) );
- }
-
- foreach ( $this as $item ) {
- if ( $item === $key ) {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Dump the items and end the script.
+ * Dump the given arguments and terminate execution.
*
* @param mixed ...$args
*/
public function dd( ...$args ): never {
$this->dump( ...$args );
- exit( 1 );
+ dd();
}
/**
* Dump the items.
+ *
+ * @param mixed ...$args
+ * @return $this
*/
- public function dump(): static {
- ( new static( func_get_args() ) )
- ->push( $this->all() )
- ->each(
- fn ( $item ) => VarDumper::dump( $item ),
- );
+ public function dump( ...$args ) {
+ dump( $this->all(), ...$args );
return $this;
}
@@ -223,17 +233,15 @@ public function each( callable $callback ) {
/**
* Execute a callback over each nested chunk of items.
*
- * @param callable(array): mixed $callback
+ * @param callable(...mixed): mixed $callback
* @return static
*/
public function each_spread( callable $callback ) {
- return $this->each(
- function ( $chunk, $key ) use ( $callback ) {
- $chunk[] = $key;
+ return $this->each( function ( $chunk, $key ) use ( $callback ) {
+ $chunk[] = $key;
- return $callback( ...$chunk );
- }
- );
+ return $callback( ...$chunk );
+ } );
}
/**
@@ -263,15 +271,60 @@ public function every( $key, $operator = null, $value = null ) {
/**
* Get the first item by the given key value pair.
*
- * @param string $key
- * @param mixed $operator
- * @param mixed $value
+ * @param callable|string $key
+ * @param mixed $operator
+ * @param mixed $value
* @return TValue|null
*/
public function first_where( $key, $operator = null, $value = null ) {
return $this->first( $this->operator_for_where( ...func_get_args() ) );
}
+ /**
+ * Get a single key's value from the first matching item in the collection.
+ *
+ * @template TValueDefault
+ *
+ * @param string $key
+ * @param TValueDefault|(\Closure(): TValueDefault) $default
+ * @return TValue|TValueDefault
+ */
+ public function value( $key, $default = null ) {
+ if ( $value = $this->first_where( $key ) ) {
+ return data_get( $value, $key, $default );
+ }
+
+ return value( $default );
+ }
+
+ /**
+ * Ensure that every item in the collection is of the expected type.
+ *
+ * @template TEnsureOfType
+ *
+ * @param class-string|array> $type
+ * @return static
+ *
+ * @throws \UnexpectedValueException
+ */
+ public function ensure( $type ) {
+ $allowedTypes = is_array( $type ) ? $type : [ $type ];
+
+ return $this->each( function ( $item, $index ) use ( $allowedTypes ) {
+ $itemType = get_debug_type( $item );
+
+ foreach ( $allowedTypes as $allowedType ) {
+ if ( $itemType === $allowedType || $item instanceof $allowedType ) {
+ return true;
+ }
+ }
+
+ throw new UnexpectedValueException(
+ sprintf( "Collection should only include [%s] items, but '%s' found at position %d.", implode( ', ', $allowedTypes ), $itemType, $index )
+ );
+ } );
+ }
+
/**
* Determine if the collection is not empty.
*
@@ -286,17 +339,15 @@ public function is_not_empty() {
*
* @template TMapSpreadValue
*
- * @param callable(mixed): TMapSpreadValue $callback
+ * @param callable(mixed...): TMapSpreadValue $callback
* @return static
*/
public function map_spread( callable $callback ) {
- return $this->map(
- function ( $chunk, $key ) use ( $callback ) {
- $chunk[] = $key;
+ return $this->map( function ( $chunk, $key ) use ( $callback ) {
+ $chunk[] = $key;
- return $callback( ...$chunk );
- }
- );
+ return $callback( ...$chunk );
+ } );
}
/**
@@ -322,7 +373,7 @@ public function map_to_groups( callable $callback ) {
* @template TFlatMapKey of array-key
* @template TFlatMapValue
*
- * @param callable(TValue, TKey): (\Illuminate\Support\Collection|array) $callback
+ * @param callable(TValue, TKey): (\Mantle\Support\Collection|array) $callback
* @return static
*/
public function flat_map( callable $callback ) {
@@ -338,9 +389,11 @@ public function flat_map( callable $callback ) {
* @return static
*/
public function map_into( $class ) {
- return $this->map(
- fn ( $value, $key ) => new $class( $value, $key )
- );
+ if ( is_subclass_of( $class, BackedEnum::class ) ) {
+ return $this->map( fn ( $value, $key ) => $class::from( $value ) );
+ }
+
+ return $this->map( fn ( $value, $key ) => new $class( $value, $key ) );
}
/**
@@ -352,13 +405,9 @@ public function map_into( $class ) {
public function min( $callback = null ) {
$callback = $this->value_retriever( $callback );
- return $this->map(
- fn ( $value ) => $callback( $value )
- )->filter(
- fn ( $value ) => ! is_null( $value )
- )->reduce(
- fn ( $result, $value ) => is_null( $result ) || $value < $result ? $value : $result
- );
+ return $this->map( fn ( $value ) => $callback( $value ) )
+ ->filter( fn ( $value ) => ! is_null( $value ) )
+ ->reduce( fn ( $result, $value ) => is_null( $result ) || $value < $result ? $value : $result );
}
/**
@@ -370,28 +419,24 @@ public function min( $callback = null ) {
public function max( $callback = null ) {
$callback = $this->value_retriever( $callback );
- return $this->filter(
- fn ( $value ) => ! is_null( $value )
- )->reduce(
- function ( $result, $item ) use ( $callback ) {
- $value = $callback( $item );
+ return $this->filter( fn ( $value ) => ! is_null( $value ) )->reduce( function ( $result, $item ) use ( $callback ) {
+ $value = $callback( $item );
- return is_null( $result ) || $value > $result ? $value : $result;
- }
- );
+ return is_null( $result ) || $value > $result ? $value : $result;
+ } );
}
/**
* "Paginate" the collection by slicing it into a smaller collection.
*
* @param int $page
- * @param int $per_page
+ * @param int $perPage
* @return static
*/
- public function for_page( $page, $per_page ) {
- $offset = max( 0, ( $page - 1 ) * $per_page );
+ public function for_page( $page, $perPage ) {
+ $offset = max( 0, ( $page - 1 ) * $perPage );
- return $this->slice( $offset, $per_page );
+ return $this->slice( $offset, $perPage );
}
/**
@@ -407,8 +452,8 @@ public function partition( $key, $operator = null, $value = null ) {
$failed = [];
$callback = func_num_args() === 1
- ? $this->value_retriever( $key )
- : $this->operator_for_where( ...func_get_args() );
+ ? $this->value_retriever( $key )
+ : $this->operator_for_where( ...func_get_args() );
foreach ( $this as $key => $item ) {
if ( $callback( $item, $key ) ) {
@@ -421,6 +466,24 @@ public function partition( $key, $operator = null, $value = null ) {
return new static( [ new static( $passed ), new static( $failed ) ] );
}
+ /**
+ * Calculate the percentage of items that pass a given truth test.
+ *
+ * @param (callable(TValue, TKey): bool) $callback
+ * @param int $precision
+ * @return float|null
+ */
+ public function percentage( callable $callback, int $precision = 2 ) {
+ if ( $this->is_empty() ) {
+ return null;
+ }
+
+ return round(
+ $this->filter( $callback )->count() / $this->count() * 100,
+ $precision
+ );
+ }
+
/**
* Get the sum of the given values.
*
@@ -428,16 +491,11 @@ public function partition( $key, $operator = null, $value = null ) {
* @return mixed
*/
public function sum( $callback = null ) {
- if ( is_null( $callback ) ) {
- $callback = fn ( $value ) => $value;
- } else {
- $callback = $this->value_retriever( $callback );
- }
+ $callback = is_null( $callback )
+ ? $this->identity()
+ : $this->value_retriever( $callback );
- return $this->reduce(
- fn ( $result, $item ) => $result + $callback( $item ),
- 0
- );
+ return $this->reduce( fn ( $result, $item ) => $result + $callback( $item ), 0 );
}
/**
@@ -445,8 +503,8 @@ public function sum( $callback = null ) {
*
* @template TWhenEmptyReturnType
*
- * @param (callable( $this): TWhenEmptyReturnType) $callback The callback to apply.
- * @param (callable( $this): TWhenEmptyReturnType)|null $default The callback to apply if the collection is not empty.
+ * @param (callable($this): TWhenEmptyReturnType) $callback
+ * @param (callable($this): TWhenEmptyReturnType)|null $default
* @return $this|TWhenEmptyReturnType
*/
public function when_empty( callable $callback, ?callable $default = null ) {
@@ -458,8 +516,8 @@ public function when_empty( callable $callback, ?callable $default = null ) {
*
* @template TWhenNotEmptyReturnType
*
- * @param callable( $this): TWhenNotEmptyReturnType $callback The callback to apply.
- * @param (callable( $this): TWhenNotEmptyReturnType)|null $default The callback to apply if the collection is empty.
+ * @param callable($this): TWhenNotEmptyReturnType $callback
+ * @param (callable($this): TWhenNotEmptyReturnType)|null $default
* @return $this|TWhenNotEmptyReturnType
*/
public function when_not_empty( callable $callback, ?callable $default = null ) {
@@ -471,8 +529,8 @@ public function when_not_empty( callable $callback, ?callable $default = null )
*
* @template TUnlessEmptyReturnType
*
- * @param callable( $this): TUnlessEmptyReturnType $callback The callback to apply.
- * @param (callable( $this): TUnlessEmptyReturnType)|null $default The callback to apply if the collection is empty.
+ * @param callable($this): TUnlessEmptyReturnType $callback
+ * @param (callable($this): TUnlessEmptyReturnType)|null $default
* @return $this|TUnlessEmptyReturnType
*/
public function unless_empty( callable $callback, ?callable $default = null ) {
@@ -484,8 +542,8 @@ public function unless_empty( callable $callback, ?callable $default = null ) {
*
* @template TUnlessNotEmptyReturnType
*
- * @param callable( $this): TUnlessNotEmptyReturnType $callback The callback to apply.
- * @param (callable( $this): TUnlessNotEmptyReturnType)|null $default The callback to apply if the collection is not empty.
+ * @param callable($this): TUnlessNotEmptyReturnType $callback
+ * @param (callable($this): TUnlessNotEmptyReturnType)|null $default
* @return $this|TUnlessNotEmptyReturnType
*/
public function unless_not_empty( callable $callback, ?callable $default = null ) {
@@ -495,9 +553,9 @@ public function unless_not_empty( callable $callback, ?callable $default = null
/**
* Filter items by the given key value pair.
*
- * @param string $key
- * @param mixed $operator
- * @param mixed $value
+ * @param callable|string $key
+ * @param mixed $operator
+ * @param mixed $value
* @return static
*/
public function where( $key, $operator = null, $value = null ) {
@@ -505,7 +563,7 @@ public function where( $key, $operator = null, $value = null ) {
}
/**
- * Filter items where the given key is not null.
+ * Filter items where the value for the given key is null.
*
* @param string|null $key
* @return static
@@ -515,7 +573,7 @@ public function where_null( $key = null ) {
}
/**
- * Filter items where the given key is null.
+ * Filter items where the value for the given key is not null.
*
* @param string|null $key
* @return static
@@ -538,24 +596,22 @@ public function where_strict( $key, $value ) {
/**
* Filter items by the given key value pair.
*
- * @param string $key The key to check.
- * @param \Mantle\Contracts\Support\Arrayable|iterable $values Values to search for.
- * @param bool $strict Whether to use strict comparison.
+ * @param string $key
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $values
+ * @param bool $strict
* @return static
*/
public function where_in( $key, $values, $strict = false ) {
$values = $this->get_arrayable_items( $values );
- return $this->filter(
- fn ( $item ) => in_array( data_get( $item, $key ), $values, $strict ) // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
- );
+ return $this->filter( fn ( $item ) => in_array( data_get( $item, $key ), $values, $strict ) );
}
/**
* Filter items by the given key value pair using strict comparison.
*
- * @param string $key The key to check.
- * @param \Mantle\Contracts\Support\Arrayable|iterable $values Values to search for.
+ * @param string $key
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $values
* @return static
*/
public function where_in_strict( $key, $values ) {
@@ -565,8 +621,8 @@ public function where_in_strict( $key, $values ) {
/**
* Filter items such that the value of the given key is between the given values.
*
- * @param string $key The key to check.
- * @param \Mantle\Contracts\Support\Arrayable|iterable $values Values to search for.
+ * @param string $key
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $values
* @return static
*/
public function where_between( $key, $values ) {
@@ -576,8 +632,8 @@ public function where_between( $key, $values ) {
/**
* Filter items such that the value of the given key is not between the given values.
*
- * @param string $key The key to check.
- * @param \Mantle\Contracts\Support\Arrayable|iterable $values Values to search against.
+ * @param string $key
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $values
* @return static
*/
public function where_not_between( $key, $values ) {
@@ -589,24 +645,22 @@ public function where_not_between( $key, $values ) {
/**
* Filter items by the given key value pair.
*
- * @param string $key The key to check.
- * @param \Mantle\Contracts\Support\Arrayable|iterable $values Values to search against.
- * @param bool $strict Whether to use strict comparison.
+ * @param string $key
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $values
+ * @param bool $strict
* @return static
*/
public function where_not_in( $key, $values, $strict = false ) {
$values = $this->get_arrayable_items( $values );
- return $this->reject(
- fn ( $item ) => in_array( data_get( $item, $key ), $values, $strict ) // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
- );
+ return $this->reject( fn ( $item ) => in_array( data_get( $item, $key ), $values, $strict ) );
}
/**
* Filter items by the given key value pair using strict comparison.
*
- * @param string $key The key to check.
- * @param \Mantle\Contracts\Support\Arrayable|iterable $values Values to search against.
+ * @param string $key
+ * @param \Mantle\Contracts\Support\Arrayable|iterable $values
* @return static
*/
public function where_not_in_strict( $key, $values ) {
@@ -614,7 +668,7 @@ public function where_not_in_strict( $key, $values ) {
}
/**
- * Filter the items, removing any items that don't match the given type.
+ * Filter the items, removing any items that don't match the given type(s).
*
* @template TWhereInstanceOf
*
@@ -622,9 +676,19 @@ public function where_not_in_strict( $key, $values ) {
* @return static
*/
public function where_instance_of( $type ) {
- return $this->filter(
- fn ( $value ) => $value instanceof $type,
- );
+ return $this->filter( function ( $value ) use ( $type ) {
+ if ( is_array( $type ) ) {
+ foreach ( $type as $classType ) {
+ if ( $value instanceof $classType ) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ return $value instanceof $type;
+ } );
}
/**
@@ -632,7 +696,7 @@ public function where_instance_of( $type ) {
*
* @template TPipeReturnType
*
- * @param callable( $this): TPipeReturnType $callback The callback to pass the collection to.
+ * @param callable($this): TPipeReturnType $callback
* @return TPipeReturnType
*/
public function pipe( callable $callback ) {
@@ -640,31 +704,114 @@ public function pipe( callable $callback ) {
}
/**
- * Pass the collection to the given callback and then return it.
+ * Pass the collection into a new class.
*
- * @param callable( $this): mixed $callback The callback to pass the collection to.
- * @return $this
+ * @template TPipeIntoValue
+ *
+ * @param class-string $class
+ * @return TPipeIntoValue
*/
- public function tap( callable $callback ) {
- $callback( clone $this );
+ public function pipe_into( $class ) {
+ return new $class( $this );
+ }
- return $this;
+ /**
+ * Pass the collection through a series of callable pipes and return the result.
+ *
+ * @param array $callbacks
+ * @return mixed
+ */
+ public function pipe_through( $callbacks ) {
+ return Collection::make( $callbacks )->reduce(
+ fn ( $carry, $callback ) => $callback( $carry ),
+ $this,
+ );
+ }
+
+ /**
+ * Reduce the collection to a single value.
+ *
+ * @template TReduceInitial
+ * @template TReduceReturnType
+ *
+ * @param callable(TReduceInitial|TReduceReturnType, TValue, TKey): TReduceReturnType $callback
+ * @param TReduceInitial $initial
+ * @return TReduceReturnType
+ */
+ public function reduce( callable $callback, $initial = null ) {
+ $result = $initial;
+
+ foreach ( $this as $key => $value ) {
+ $result = $callback( $result, $value, $key );
+ }
+
+ return $result;
+ }
+
+ /**
+ * Reduce the collection to multiple aggregate values.
+ *
+ * @param callable $callback
+ * @param mixed ...$initial
+ * @return array
+ *
+ * @throws \UnexpectedValueException
+ */
+ public function reduce_spread( callable $callback, ...$initial ) {
+ $result = $initial;
+
+ foreach ( $this as $key => $value ) {
+ $result = call_user_func_array( $callback, array_merge( $result, [ $value, $key ] ) );
+
+ if ( ! is_array( $result ) ) {
+ throw new UnexpectedValueException( sprintf(
+ "%s::reduceSpread expects reducer to return an array, but got a '%s' instead.",
+ class_basename( static::class ), gettype( $result )
+ ) );
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Reduce an associative collection to a single value.
+ *
+ * @template TReduceWithKeysInitial
+ * @template TReduceWithKeysReturnType
+ *
+ * @param callable(TReduceWithKeysInitial|TReduceWithKeysReturnType, TValue, TKey): TReduceWithKeysReturnType $callback
+ * @param TReduceWithKeysInitial $initial
+ * @return TReduceWithKeysReturnType
+ */
+ public function reduce_with_keys( callable $callback, $initial = null ) {
+ return $this->reduce( $callback, $initial );
}
/**
* Create a collection of all elements that do not pass a given truth test.
*
- * @param callable|mixed $callback
+ * @param (callable(TValue, TKey): bool)|bool|TValue $callback
* @return static
*/
public function reject( $callback = true ) {
$use_as_callable = $this->use_as_callable( $callback );
- return $this->filter(
- fn ( $value, $key ) => $use_as_callable
- ? ! $callback( $value, $key )
- : $value != $callback // phpcs:ignore Universal.Operators.StrictComparisons.LooseNotEqual, WordPress.PHP.StrictComparisons.LooseComparison
- );
+ return $this->filter( fn ( $value, $key ) => $use_as_callable
+ ? ! $callback( $value, $key )
+ : $value != $callback ); // phpcs:ignore Universal.Operators.StrictComparisons.LooseNotEqual
+ }
+
+ /**
+ * Pass the collection to the given callback and then return it.
+ *
+ * @param callable($this): mixed $callback
+ * @return $this
+ */
+ public function tap( callable $callback ) {
+ $callback( $this );
+
+ return $this;
}
/**
@@ -679,16 +826,13 @@ public function unique( $key = null, $strict = false ) {
$exists = [];
- return $this->reject(
- function ( $item, $key ) use ( $callback, $strict, &$exists ) {
- $id = $callback( $item, $key );
- if ( in_array( $id, $exists, $strict ) ) {
- return true;
- }
-
- $exists[] = $id;
+ return $this->reject( function ( $item, $key ) use ( $callback, $strict, &$exists ) {
+ if ( in_array( $id = $callback( $item, $key ), $exists, $strict ) ) {
+ return true;
}
- );
+
+ $exists[] = $id;
+ } );
}
/**
@@ -713,43 +857,29 @@ public function collect() {
/**
* Get the collection of items as a plain array.
*
- * @return array
- */
- public function to_array() {
- return $this->map(
- fn ( $value ) => $value instanceof Arrayable ? $value->to_array() : $value,
- )->all();
- }
-
- /**
- * Alias for the "to_array" method.
- *
- * @return array
+ * @return array
*/
- public function toArray() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
- return $this->to_array();
+ public function to_array(): array {
+ return $this->map( fn ( $value ) => $value instanceof Arrayable ? $value->to_array() : $value )->all();
}
/**
* Convert the object into something JSON serializable.
*
- * @return array
+ * @return array
*/
- public function jsonSerialize(): mixed { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
- return array_map(
- function ( $value ) {
- if ( $value instanceof JsonSerializable ) {
- return $value->jsonSerialize();
- } elseif ( $value instanceof Jsonable ) {
- return json_decode( $value->to_json(), true );
- } elseif ( $value instanceof Arrayable ) {
- return $value->to_array();
- }
+ public function jsonSerialize(): mixed {
+ return array_map( function ( $value ) {
+ if ( $value instanceof JsonSerializable ) {
+ return $value->jsonSerialize();
+ } elseif ( $value instanceof Jsonable ) {
+ return json_decode( $value->to_json(), true );
+ } elseif ( $value instanceof Arrayable ) {
+ return $value->to_array();
+ }
- return $value;
- },
- $this->all()
- );
+ return $value;
+ }, $this->all() );
}
/**
@@ -759,25 +889,17 @@ function ( $value ) {
* @return string
*/
public function to_json( $options = 0 ) {
- return json_encode( $this->jsonSerialize(), $options ); // phpcs:ignore WordPress.WP.AlternativeFunctions.json_encode_json_encode
+ return json_encode( $this->jsonSerialize(), $options );
}
/**
- * Count the number of items in the collection using a given truth test.
+ * Get a CachingIterator instance.
*
- * @param callable|null $callback
- * @return static
+ * @param int $flags
+ * @return \CachingIterator
*/
- public function count_by( $callback = null ) {
- if ( is_null( $callback ) ) {
- $callback = fn ( $value ) => $value;
- }
-
- return new static(
- $this->group_by( $callback )->map(
- fn ( $value ) => $value->count()
- )
- );
+ public function getCachingIterator( $flags = CachingIterator::CALL_TOSTRING ) {
+ return new CachingIterator( $this->getIterator(), $flags );
}
/**
@@ -786,7 +908,21 @@ public function count_by( $callback = null ) {
* @return string
*/
public function __toString() {
- return $this->to_json();
+ return $this->escape_when_casting_to_string
+ ? esc_html( $this->to_json() )
+ : $this->to_json();
+ }
+
+ /**
+ * Indicate that the model's string representation should be escaped when __toString is invoked.
+ *
+ * @param bool $escape
+ * @return $this
+ */
+ public function escape_when_casting_to_string( bool $escape = true ): static {
+ $this->escape_when_casting_to_string = $escape;
+
+ return $this;
}
/**
@@ -795,7 +931,7 @@ public function __toString() {
* @param string $method
*/
public static function proxy( $method ): void {
- static::$proxies[] = $method; // phpcs:ignore WordPressVIPMinimum.Variables.VariableAnalysis.StaticOutsideClass
+ static::$proxies[] = $method;
}
/**
@@ -804,10 +940,10 @@ public static function proxy( $method ): void {
* @param string $key
* @return mixed
*
- * @throws \Exception Throw on nonexistent property keys.
+ * @throws \Exception
*/
public function __get( $key ) {
- if ( ! in_array( $key, static::$proxies ) ) { // phpcs:ignore WordPressVIPMinimum.Variables.VariableAnalysis.StaticOutsideClass
+ if ( ! in_array( $key, static::$proxies ) ) {
throw new Exception( "Property [{$key}] does not exist on this collection instance." );
}
@@ -817,36 +953,41 @@ public function __get( $key ) {
/**
* Results array of items from Collection or Arrayable.
*
+ * @throws \InvalidArgumentException if the items are not an array or iterable
+ *
* @param mixed $items
* @return array
*/
protected function get_arrayable_items( $items ) {
if ( is_array( $items ) ) {
return $items;
- } elseif ( $items instanceof Enumerable ) {
- return $items->all();
- } elseif ( $items instanceof Arrayable ) {
- return $items->to_array();
- } elseif ( $items instanceof Jsonable ) {
- return json_decode( $items->to_json(), true );
- } elseif ( $items instanceof JsonSerializable ) {
- return (array) $items->jsonSerialize();
- } elseif ( $items instanceof Traversable ) {
- return iterator_to_array( $items );
}
- return (array) $items;
+ return match ( true ) {
+ $items instanceof WeakMap => throw new InvalidArgumentException( 'Collections can not be created using instances of WeakMap.' ),
+ $items instanceof Enumerable => $items->all(),
+ $items instanceof Arrayable => $items->to_array(),
+ $items instanceof Traversable => iterator_to_array( $items ),
+ $items instanceof Jsonable => json_decode( $items->to_json(), true ),
+ $items instanceof JsonSerializable => (array) $items->jsonSerialize(),
+ $items instanceof UnitEnum => [ $items ],
+ default => (array) $items,
+ };
}
/**
* Get an operator checker callback.
*
- * @param string $key
- * @param string|null $operator
- * @param mixed $value
+ * @param callable|string $key
+ * @param string|null $operator
+ * @param mixed $value
* @return \Closure
*/
protected function operator_for_where( $key, $operator = null, $value = null ) {
+ if ( $this->use_as_callable( $key ) ) {
+ return $key;
+ }
+
if ( func_num_args() === 1 ) {
$value = true;
@@ -864,34 +1005,28 @@ protected function operator_for_where( $key, $operator = null, $value = null ) {
$strings = array_filter(
[ $retrieved, $value ],
- fn ( $value ) => is_string( $value ) || ( is_object( $value ) && method_exists( $value, '__toString' ) )
+ fn ( $value ) => is_string( $value ) || ( is_object( $value ) && method_exists( $value, '__toString' ) ),
);
- if ( count( $strings ) < 2 && count( array_filter( [ $retrieved, $value ], 'is_object' ) ) === 1 ) {
- return in_array( $operator, [ '!=', '<>', '!==' ] );
+ if ( count( $strings ) < 2 && count( array_filter( [ $retrieved, $value ], 'is_object' ) ) == 1 ) { // phpcs:ignore Universal.Operators.StrictComparisons
+ return in_array( $operator, [ '!=', '<>', '!==' ] ); // phpcs:ignore Universal.Operators.StrictComparisons
}
- switch ( $operator ) {
- default:
- case '=':
- case '==':
- return $retrieved == $value; // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual
- case '!=':
- case '<>':
- return $retrieved !== $value;
- case '<':
- return $retrieved < $value;
- case '>':
- return $retrieved > $value;
- case '<=':
- return $retrieved <= $value;
- case '>=':
- return $retrieved >= $value;
- case '===':
- return $retrieved === $value;
- case '!==':
- return $retrieved !== $value;
- }
+ /* phpcs:disable Universal.Operators.StrictComparisons */
+
+ return match ( $operator ) {
+ '!=', '<>', 'not' => $retrieved != $value,
+ '<' => $retrieved < $value,
+ '>' => $retrieved > $value,
+ '<=' => $retrieved <= $value,
+ '>=' => $retrieved >= $value,
+ '<=>' => $retrieved <=> $value,
+ '===' => $retrieved === $value,
+ '!==' => $retrieved !== $value,
+ default => $retrieved == $value,
+ };
+
+ /* phpcs:enable Universal.Operators.StrictComparisons */
};
}
@@ -922,7 +1057,7 @@ protected function value_retriever( $value ) {
* Make a function to check an item's equality.
*
* @param mixed $value
- * @return \Closure
+ * @return \Closure(mixed): bool
*/
protected function equality( $value ) {
return fn ( $item ) => $item === $value;
@@ -937,4 +1072,13 @@ protected function equality( $value ) {
protected function negate( Closure $callback ) {
return fn ( ...$params ) => ! $callback( ...$params );
}
+
+ /**
+ * Make a function that returns what's passed to it.
+ *
+ * @return \Closure(TValue): TValue
+ */
+ protected function identity() {
+ return fn ( $value ) => $value;
+ }
}
diff --git a/src/mantle/testing/class-installation-manager.php b/src/mantle/testing/class-installation-manager.php
index 817bf93c6..480e8bf36 100644
--- a/src/mantle/testing/class-installation-manager.php
+++ b/src/mantle/testing/class-installation-manager.php
@@ -188,6 +188,52 @@ public function with_active_plugins( array $plugins ): static {
return $this->plugins( $plugins );
}
+ /**
+ * Define if the testing suite should use the experimental feature that will
+ * use the site's home URL host as the HTTP host when making requests.
+ *
+ * Without enabling this feature, the HTTP host will be set to the value of
+ * the WP_TESTS_DOMAIN constant and all relative URLs will be calculated from
+ * that domain.
+ *
+ * In the next major release of Mantle, this feature will be enabled by default.
+ *
+ * @param bool $enable Whether to enable the experimental feature.
+ */
+ public function with_experimental_testing_url_host( bool $enable = true ): static {
+ return $this->before(
+ fn () => putenv( 'MANTLE_EXPERIMENTAL_TESTING_USE_HOME_URL_HOST=' . ( $enable ? '1' : '0' ) ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.runtime_configuration_putenv
+ );
+ }
+
+ /**
+ * Define a custom option to be set after the installation is loaded.
+ *
+ * @param string $option Option name.
+ * @param mixed $value Option value.
+ */
+ public function with_option( string $option, mixed $value ): static {
+ return $this->loaded( fn () => update_option( $option, $value ) );
+ }
+
+ /**
+ * Define the site/home URLs to be set after the installation is loaded.
+ *
+ * @param string|null $home Home URL.
+ * @param string|null $site Site URL.
+ */
+ public function with_url( ?string $home = null, ?string $site = null ): static {
+ if ( $home ) {
+ $this->with_option( 'home', $home );
+ }
+
+ if ( $site ) {
+ $this->with_option( 'siteurl', $site );
+ }
+
+ return $this;
+ }
+
/**
* Install the Mantle Testing Framework.
*
diff --git a/src/mantle/testing/class-pending-testable-request.php b/src/mantle/testing/class-pending-testable-request.php
index ef1f54130..017ea260c 100644
--- a/src/mantle/testing/class-pending-testable-request.php
+++ b/src/mantle/testing/class-pending-testable-request.php
@@ -49,7 +49,7 @@ class Pending_Testable_Request {
/**
* Indicates whether the request should be made over HTTPS.
*/
- public bool $https = false;
+ public ?bool $forced_https = null;
/**
* The cookies for the request.
@@ -95,12 +95,15 @@ public function with_header( string $name, string $value ): static {
}
/**
- * Define whether the request should be made over HTTPS.
+ * Define whether the request should be forced to be made over HTTPS.
*
- * @param bool $value Whether to use HTTPS.
+ * This method will override the protocol of the URL passed when creating a
+ * testable request.
+ *
+ * @param bool|null $value Whether to use HTTPS.
*/
- public function with_https( bool $value ): static {
- $this->https = $value;
+ public function with_https( ?bool $value ): static {
+ $this->forced_https = $value;
return $this;
}
@@ -235,11 +238,14 @@ public function call( string $method, mixed $uri, array $parameters = [], array
$uri = $this->infer_url( $uri );
}
+ $scheme = $this->get_default_url_scheme();
+ $host = $this->get_default_url_host();
+
// Build a full URL from partial URIs.
if ( '/' === $uri[0] ) {
- $url = 'https://' . WP_TESTS_DOMAIN . $uri;
+ $url = "{$scheme}://{$host}{$uri}";
} elseif ( false === strpos( $uri, '://' ) ) {
- $url = 'https://' . WP_TESTS_DOMAIN . '/' . $uri;
+ $url = "{$scheme}://{$host}/{uri}";
} else {
$url = $uri;
}
@@ -432,11 +438,8 @@ protected function reset_request_state(): void {
}
}
- if ( $this->https ) {
- $_SERVER['HTTPS'] = 'on';
- } else {
- unset( $_SERVER['HTTPS'] );
- }
+ // Clear the HTTPS flag which will be set as-needed by the call method.
+ unset( $_SERVER['HTTPS'] );
// phpcs:enable
}
@@ -453,8 +456,12 @@ protected function reset_request_state(): void {
protected function set_server_state( $method, $url, $server, $data, array $cookies = [] ): void {
// phpcs:disable WordPress.Security.NonceVerification
$_SERVER['REQUEST_METHOD'] = strtoupper( $method );
- $_SERVER['SERVER_NAME'] = WP_TESTS_DOMAIN;
$_SERVER['SERVER_PORT'] = '80';
+
+ $_SERVER['SERVER_NAME'] = $_SERVER['HTTP_HOST'] = $this->is_experimental_use_home_url_host_enabled()
+ ? wp_parse_url( home_url(), PHP_URL_HOST )
+ : WP_TESTS_DOMAIN;
+
unset( $_SERVER['PATH_INFO'] );
$parts = wp_parse_url( $url );
@@ -469,6 +476,11 @@ protected function set_server_state( $method, $url, $server, $data, array $cooki
$req = $url;
}
+ // Set HTTPS if it is being forced or if the URL being requested is HTTPS.
+ if ( $this->forced_https || ( isset( $parts['scheme'] ) && 'https' === $parts['scheme'] ) ) {
+ $_SERVER['HTTPS'] = 'on';
+ }
+
$_SERVER['QUERY_STRING'] = $parts['query'] ?? '';
$_SERVER['REQUEST_URI'] = $req;
@@ -539,6 +551,48 @@ protected function replace_rest_api(): void {
add_action( 'parse_request', [ $this, 'serve_rest_api_request' ] );
}
+ /**
+ * Get the default URL scheme.
+ *
+ * If the request is being overridden to use HTTPS via {@see with_https()},
+ * this will return 'https'. Otherwise, it will return the scheme of the home
+ * URL of the WordPress installation.
+ */
+ protected function get_default_url_scheme(): string {
+ if ( $this->forced_https ) {
+ return 'https';
+ }
+
+ if ( ! $this->is_experimental_use_home_url_host_enabled() ) {
+ return 'http';
+ }
+
+ return wp_parse_url( home_url(), PHP_URL_SCHEME );
+ }
+
+ /**
+ * Get the default URL host.
+ *
+ * If the `MANTLE_EXPERIMENTAL_TESTING_USE_HOME_URL_HOST` environment variable
+ * is set, this will return the host of the home URL. Otherwise, it will
+ * return the host defined in the WordPress tests configuration.
+ *
+ * With the next major release of Mantle, we will be shifting to using the
+ * home URL host by default.
+ */
+ protected function get_default_url_host(): string {
+ return $this->is_experimental_use_home_url_host_enabled()
+ ? wp_parse_url( home_url(), PHP_URL_HOST )
+ : WP_TESTS_DOMAIN;
+ }
+
+ /**
+ * Check if the experimental testing URL host feature is enabled.
+ */
+ protected function is_experimental_use_home_url_host_enabled(): bool {
+ return Utils::env_bool( 'MANTLE_EXPERIMENTAL_TESTING_USE_HOME_URL_HOST', false );
+ }
+
/**
* Server the REST API request if applicable.
*
diff --git a/src/mantle/testing/concerns/trait-makes-http-requests.php b/src/mantle/testing/concerns/trait-makes-http-requests.php
index b49c6ab2a..ba0ab951e 100644
--- a/src/mantle/testing/concerns/trait-makes-http-requests.php
+++ b/src/mantle/testing/concerns/trait-makes-http-requests.php
@@ -138,9 +138,9 @@ public function with_header( string $name, string $value ): Pending_Testable_Req
/**
* Create a pending request with the HTTPS enabled/disabled.
*
- * @param bool $value Whether to use HTTPS.
+ * @param bool|null $value Whether to use HTTPS.
*/
- public function with_https( bool $value = true ): Pending_Testable_Request {
+ public function with_https( ?bool $value = true ): Pending_Testable_Request {
return $this->create_pending_request()->with_https( $value );
}
diff --git a/tests/Support/CollectionTest.php b/tests/Support/CollectionTest.php
index 48c953158..922f820a7 100644
--- a/tests/Support/CollectionTest.php
+++ b/tests/Support/CollectionTest.php
@@ -14,6 +14,7 @@
use Mantle\Database\Model;
use InvalidArgumentException;
use JsonSerializable;
+use Mantle\Support\Lazy_Collection;
use Mantle\Support\Stringable;
use Mantle\Testing\Framework_Test_Case;
use Mockery as m;
@@ -28,8 +29,7 @@ class CollectionTest extends Framework_Test_Case {
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testFirstReturnsFirstItemInCollection($collection)
- {
+ public function testFirstReturnsFirstItemInCollection( $collection ) {
$c = new $collection(['foo', 'bar']);
$this->assertSame('foo', $c->first());
}
@@ -38,8 +38,7 @@ public function testFirstReturnsFirstItemInCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testFirstWithCallback($collection)
- {
+ public function testFirstWithCallback( $collection ) {
$data = new $collection(['foo', 'bar', 'baz']);
$result = $data->first(function ($value) {
return $value === 'bar';
@@ -51,8 +50,7 @@ public function testFirstWithCallback($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testFirstWithCallbackAndDefault($collection)
- {
+ public function testFirstWithCallbackAndDefault( $collection ) {
$data = new $collection(['foo', 'bar']);
$result = $data->first(function ($value) {
return $value === 'baz';
@@ -64,8 +62,7 @@ public function testFirstWithCallbackAndDefault($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testFirstWithDefaultAndWithoutCallback($collection)
- {
+ public function testFirstWithDefaultAndWithoutCallback( $collection ) {
$data = new $collection;
$result = $data->first(null, 'default');
$this->assertSame('default', $result);
@@ -75,8 +72,7 @@ public function testFirstWithDefaultAndWithoutCallback($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testFirstWhere($collection)
- {
+ public function testFirstWhere( $collection ) {
$data = new $collection([
['material' => 'paper', 'type' => 'book'],
['material' => 'rubber', 'type' => 'gasket'],
@@ -92,8 +88,7 @@ public function testFirstWhere($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testLastReturnsLastItemInCollection($collection)
- {
+ public function testLastReturnsLastItemInCollection( $collection ) {
$c = new $collection(['foo', 'bar']);
$this->assertSame('bar', $c->last());
}
@@ -102,8 +97,7 @@ public function testLastReturnsLastItemInCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testLastWithCallback($collection)
- {
+ public function testLastWithCallback( $collection ) {
$data = new $collection([100, 200, 300]);
$result = $data->last(function ($value) {
return $value < 250;
@@ -119,8 +113,7 @@ public function testLastWithCallback($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testLastWithCallbackAndDefault($collection)
- {
+ public function testLastWithCallbackAndDefault( $collection ) {
$data = new $collection(['foo', 'bar']);
$result = $data->last(function ($value) {
return $value === 'baz';
@@ -132,8 +125,7 @@ public function testLastWithCallbackAndDefault($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testLastWithDefaultAndWithoutCallback($collection)
- {
+ public function testLastWithDefaultAndWithoutCallback( $collection ) {
$data = new $collection;
$result = $data->last(null, 'default');
$this->assertSame('default', $result);
@@ -161,8 +153,7 @@ public function testShiftReturnsAndRemovesFirstItemInCollection()
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testEmptyCollectionIsEmpty($collection)
- {
+ public function testEmptyCollectionIsEmpty( $collection ) {
$c = new $collection;
$this->assertTrue($c->is_empty());
@@ -172,8 +163,7 @@ public function testEmptyCollectionIsEmpty($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testEmptyCollectionIsNotEmpty($collection)
- {
+ public function testEmptyCollectionIsNotEmpty( $collection ) {
$c = new $collection(['foo', 'bar']);
$this->assertFalse($c->is_empty());
@@ -184,8 +174,7 @@ public function testEmptyCollectionIsNotEmpty($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testCollectionIsConstructed($collection)
- {
+ public function testCollectionIsConstructed( $collection ) {
$data = new $collection('foo');
$this->assertSame(['foo'], $data->all());
@@ -206,22 +195,21 @@ public function testCollectionIsConstructed($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
-// public function testCollectionShuffleWithSeed($collection)
-// {
-// $data = new $collection(range(0, 100, 10));
-//
-// $firstRandom = $data->shuffle(1234);
-// $secondRandom = $data->shuffle(1234);
-//
-// $this->assertEquals($firstRandom, $secondRandom);
-// }
+ public function testCollectionShuffleWithSeed($collection)
+ {
+ $data = new $collection(range(0, 100, 10));
+
+ $firstRandom = $data->shuffle(1234);
+ $secondRandom = $data->shuffle(1234);
+
+ $this->assertEquals($firstRandom, $secondRandom);
+ }
/**
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSkipMethod($collection)
- {
+ public function testSkipMethod( $collection ) {
$data = new $collection([1, 2, 3, 4, 5, 6]);
$data = $data->skip(4)->values();
@@ -233,46 +221,45 @@ public function testSkipMethod($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
-// public function testSkipUntil($collection)
-// {
-// $data = new $collection([1, 1, 2, 2, 3, 3, 4, 4]);
-//
-// $data = $data->skipUntil(3)->values();
-//
-// $this->assertSame([3, 3, 4, 4], $data->all());
-//
-// $data = $data->skipUntil(function ($value, $key) {
-// return $value > 3;
-// })->values();
-//
-// $this->assertSame([4, 4], $data->all());
-// }
+ public function testSkipUntil($collection)
+ {
+ $data = new $collection([1, 1, 2, 2, 3, 3, 4, 4]);
+
+ $data = $data->skip_until(3)->values();
+
+ $this->assertSame([3, 3, 4, 4], $data->all());
+
+ $data = $data->skip_until(function ($value, $key) {
+ return $value > 3;
+ })->values();
+
+ $this->assertSame([4, 4], $data->all());
+ }
/**
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
-// public function testSkipWhile($collection)
-// {
-// $data = new $collection([1, 1, 2, 2, 3, 3, 4, 4]);
-//
-// $data = $data->skipWhile(1)->values();
-//
-// $this->assertSame([2, 2, 3, 3, 4, 4], $data->all());
-//
-// $data = $data->skipWhile(function ($value, $key) {
-// return $value < 3;
-// })->values();
-//
-// $this->assertSame([3, 3, 4, 4], $data->all());
-// }
+ public function testSkipWhile($collection)
+ {
+ $data = new $collection([1, 1, 2, 2, 3, 3, 4, 4]);
+
+ $data = $data->skip_while(1)->values();
+
+ $this->assertSame([2, 2, 3, 3, 4, 4], $data->all());
+
+ $data = $data->skip_while(function ($value, $key) {
+ return $value < 3;
+ })->values();
+
+ $this->assertSame([3, 3, 4, 4], $data->all());
+ }
/**
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testGetArrayableItems($collection)
- {
+ public function testGetArrayableItems( $collection ) {
$data = new $collection;
$class = new ReflectionClass($collection);
@@ -308,8 +295,7 @@ public function testGetArrayableItems($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testToArrayCallsToArrayOnEachItemInCollection($collection)
- {
+ public function testToArrayCallsToArrayOnEachItemInCollection( $collection ) {
$item1 = m::mock(Arrayable::class);
$item1->shouldReceive('to_array')->once()->andReturn('foo.array');
$item2 = m::mock(Arrayable::class);
@@ -324,8 +310,7 @@ public function testToArrayCallsToArrayOnEachItemInCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testJsonSerializeCallsToArrayOrJsonSerializeOnEachItemInCollection($collection)
- {
+ public function testJsonSerializeCallsToArrayOrJsonSerializeOnEachItemInCollection( $collection ) {
$item1 = m::mock(JsonSerializable::class);
$item1->shouldReceive('jsonSerialize')->once()->andReturn('foo.json');
$item2 = m::mock(Arrayable::class);
@@ -340,8 +325,7 @@ public function testJsonSerializeCallsToArrayOrJsonSerializeOnEachItemInCollecti
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testToJsonEncodesTheJsonSerializeResult($collection)
- {
+ public function testToJsonEncodesTheJsonSerializeResult( $collection ) {
$c = $this->getMockBuilder($collection)->onlyMethods(['jsonSerialize'])->getMock();
$c->expects($this->once())->method('jsonSerialize')->willReturn('foo');
$results = $c->to_json();
@@ -352,8 +336,7 @@ public function testToJsonEncodesTheJsonSerializeResult($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testCastingToStringJsonEncodesTheToArrayResult($collection)
- {
+ public function testCastingToStringJsonEncodesTheToArrayResult( $collection ) {
$c = $this->getMockBuilder($collection)->onlyMethods(['jsonSerialize'])->getMock();
$c->expects($this->once())->method('jsonSerialize')->willReturn('foo');
@@ -437,8 +420,7 @@ public function testForgetArrayOfKeys()
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testCountable($collection)
- {
+ public function testCountable( $collection ) {
$c = new $collection(['foo', 'bar']);
$this->assertCount(2, $c);
}
@@ -447,8 +429,7 @@ public function testCountable($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testCountableByWithoutPredicate($collection)
- {
+ public function testCountableByWithoutPredicate( $collection ) {
$c = new $collection(['foo', 'foo', 'foo', 'bar', 'bar', 'foobar']);
$this->assertEquals(['foo' => 3, 'bar' => 2, 'foobar' => 1], $c->count_by()->all());
@@ -463,8 +444,7 @@ public function testCountableByWithoutPredicate($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testCountableByWithPredicate($collection)
- {
+ public function testCountableByWithPredicate( $collection ) {
$c = new $collection(['alice', 'aaron', 'bob', 'carla']);
$this->assertEquals(['a' => 2, 'b' => 1, 'c' => 1], $c->count_by(function ($name) {
return substr($name, 0, 1);
@@ -487,8 +467,7 @@ public function testIterable()
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testFilter($collection)
- {
+ public function testFilter( $collection ) {
$c = new $collection([['id' => 1, 'name' => 'Hello'], ['id' => 2, 'name' => 'World']]);
$this->assertEquals([1 => ['id' => 2, 'name' => 'World']], $c->filter(function ($item) {
return $item['id'] == 2;
@@ -507,184 +486,183 @@ public function testFilter($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
-// public function testHigherOrderKeyBy($collection)
-// {
-// $c = new $collection([
-// ['id' => 'id1', 'name' => 'first'],
-// ['id' => 'id2', 'name' => 'second'],
-// ]);
-//
-// $this->assertEquals(['id1' => 'first', 'id2' => 'second'], $c->keyBy->id->map->name->all());
-// }
-
- /**
- * @dataProvider collectionClassProvider
- */
- #[DataProvider( 'collectionClassProvider' )]
-// public function testHigherOrderUnique($collection)
-// {
-// $c = new $collection([
-// ['id' => '1', 'name' => 'first'],
-// ['id' => '1', 'name' => 'second'],
-// ]);
-//
-// $this->assertCount(1, $c->unique->id);
-// }
-
- /**
- * @dataProvider collectionClassProvider
- */
- #[DataProvider( 'collectionClassProvider' )]
-// public function testHigherOrderFilter($collection)
-// {
-// $c = new $collection([
-// new class {
-// public $name = 'Alex';
-//
-// public function active()
-// {
-// return true;
-// }
-// },
-// new class {
-// public $name = 'John';
-//
-// public function active()
-// {
-// return false;
-// }
-// },
-// ]);
-//
-// $this->assertCount(1, $c->filter->active());
-// }
-
- /**
- * @dataProvider collectionClassProvider
- */
- #[DataProvider( 'collectionClassProvider' )]
-// public function testWhere($collection)
-// {
-// $c = new $collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);
-//
-// $this->assertEquals(
-// [['v' => 3], ['v' => '3']],
-// $c->where('v', 3)->values()->all()
-// );
-// $this->assertEquals(
-// [['v' => 3], ['v' => '3']],
-// $c->where('v', '=', 3)->values()->all()
-// );
-// $this->assertEquals(
-// [['v' => 3], ['v' => '3']],
-// $c->where('v', '==', 3)->values()->all()
-// );
-// $this->assertEquals(
-// [['v' => 3], ['v' => '3']],
-// $c->where('v', 'garbage', 3)->values()->all()
-// );
-// $this->assertEquals(
-// [['v' => 3]],
-// $c->where('v', '===', 3)->values()->all()
-// );
-//
-// $this->assertEquals(
-// [['v' => 1], ['v' => 2], ['v' => 4]],
-// $c->where('v', '<>', 3)->values()->all()
-// );
-// $this->assertEquals(
-// [['v' => 1], ['v' => 2], ['v' => 4]],
-// $c->where('v', '!=', 3)->values()->all()
-// );
-// $this->assertEquals(
-// [['v' => 1], ['v' => 2], ['v' => '3'], ['v' => 4]],
-// $c->where('v', '!==', 3)->values()->all()
-// );
-// $this->assertEquals(
-// [['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3']],
-// $c->where('v', '<=', 3)->values()->all()
-// );
-// $this->assertEquals(
-// [['v' => 3], ['v' => '3'], ['v' => 4]],
-// $c->where('v', '>=', 3)->values()->all()
-// );
-// $this->assertEquals(
-// [['v' => 1], ['v' => 2]],
-// $c->where('v', '<', 3)->values()->all()
-// );
-// $this->assertEquals(
-// [['v' => 4]],
-// $c->where('v', '>', 3)->values()->all()
-// );
-//
-// $object = (object) ['foo' => 'bar'];
-//
-// $this->assertEquals(
-// [],
-// $c->where('v', $object)->values()->all()
-// );
-//
-// $this->assertEquals(
-// [['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]],
-// $c->where('v', '<>', $object)->values()->all()
-// );
-//
-// $this->assertEquals(
-// [['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]],
-// $c->where('v', '!=', $object)->values()->all()
-// );
-//
-// $this->assertEquals(
-// [['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]],
-// $c->where('v', '!==', $object)->values()->all()
-// );
-//
-// $this->assertEquals(
-// [],
-// $c->where('v', '>', $object)->values()->all()
-// );
-//
-// $c = new $collection([['v' => 1], ['v' => $object]]);
-// $this->assertEquals(
-// [['v' => $object]],
-// $c->where('v', $object)->values()->all()
-// );
-//
-// $this->assertEquals(
-// [['v' => 1], ['v' => $object]],
-// $c->where('v', '<>', null)->values()->all()
-// );
-//
-// $this->assertEquals(
-// [],
-// $c->where('v', '<', null)->values()->all()
-// );
-//
-// $c = new $collection([['v' => 1], ['v' => new HtmlString('hello')]]);
-// $this->assertEquals(
-// [['v' => new HtmlString('hello')]],
-// $c->where('v', 'hello')->values()->all()
-// );
-//
-// $c = new $collection([['v' => 1], ['v' => 'hello']]);
-// $this->assertEquals(
-// [['v' => 'hello']],
-// $c->where('v', new HtmlString('hello'))->values()->all()
-// );
-//
-// $c = new $collection([['v' => 1], ['v' => 2], ['v' => null]]);
-// $this->assertEquals(
-// [['v' => 1], ['v' => 2]],
-// $c->where('v')->values()->all()
-// );
-// }
-
- /**
- * @dataProvider collectionClassProvider
- */
- #[DataProvider( 'collectionClassProvider' )]
- public function testWhereStrict($collection)
+ public function testHigherOrderKeyBy($collection)
+ {
+ $c = new $collection([
+ ['id' => 'id1', 'name' => 'first'],
+ ['id' => 'id2', 'name' => 'second'],
+ ]);
+
+ $this->assertEquals(['id1' => 'first', 'id2' => 'second'], $c->key_by->id->map->name->all());
+ }
+
+ /**
+ * @dataProvider collectionClassProvider
+ */
+ #[DataProvider( 'collectionClassProvider' )]
+ public function testHigherOrderUnique($collection)
{
+ $c = new $collection([
+ ['id' => '1', 'name' => 'first'],
+ ['id' => '1', 'name' => 'second'],
+ ]);
+
+ $this->assertCount(1, $c->unique->id);
+ }
+
+ /**
+ * @dataProvider collectionClassProvider
+ */
+ #[DataProvider( 'collectionClassProvider' )]
+ public function testHigherOrderFilter($collection)
+ {
+ $c = new $collection([
+ new class {
+ public $name = 'Alex';
+
+ public function active()
+ {
+ return true;
+ }
+ },
+ new class {
+ public $name = 'John';
+
+ public function active()
+ {
+ return false;
+ }
+ },
+ ]);
+
+ $this->assertCount(1, $c->filter->active());
+ }
+
+ /**
+ * @dataProvider collectionClassProvider
+ */
+ #[DataProvider( 'collectionClassProvider' )]
+ public function testWhere($collection)
+ {
+ $c = new $collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);
+
+ $this->assertEquals(
+ [['v' => 3], ['v' => '3']],
+ $c->where('v', 3)->values()->all()
+ );
+ $this->assertEquals(
+ [['v' => 3], ['v' => '3']],
+ $c->where('v', '=', 3)->values()->all()
+ );
+ $this->assertEquals(
+ [['v' => 3], ['v' => '3']],
+ $c->where('v', '==', 3)->values()->all()
+ );
+ $this->assertEquals(
+ [['v' => 3], ['v' => '3']],
+ $c->where('v', 'garbage', 3)->values()->all()
+ );
+ $this->assertEquals(
+ [['v' => 3]],
+ $c->where('v', '===', 3)->values()->all()
+ );
+
+ $this->assertEquals(
+ [['v' => 1], ['v' => 2], ['v' => 4]],
+ $c->where('v', '<>', 3)->values()->all()
+ );
+ $this->assertEquals(
+ [['v' => 1], ['v' => 2], ['v' => 4]],
+ $c->where('v', '!=', 3)->values()->all()
+ );
+ $this->assertEquals(
+ [['v' => 1], ['v' => 2], ['v' => '3'], ['v' => 4]],
+ $c->where('v', '!==', 3)->values()->all()
+ );
+ $this->assertEquals(
+ [['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3']],
+ $c->where('v', '<=', 3)->values()->all()
+ );
+ $this->assertEquals(
+ [['v' => 3], ['v' => '3'], ['v' => 4]],
+ $c->where('v', '>=', 3)->values()->all()
+ );
+ $this->assertEquals(
+ [['v' => 1], ['v' => 2]],
+ $c->where('v', '<', 3)->values()->all()
+ );
+ $this->assertEquals(
+ [['v' => 4]],
+ $c->where('v', '>', 3)->values()->all()
+ );
+
+ $object = (object) ['foo' => 'bar'];
+
+ $this->assertEquals(
+ [],
+ $c->where('v', $object)->values()->all()
+ );
+
+ $this->assertEquals(
+ [['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]],
+ $c->where('v', '<>', $object)->values()->all()
+ );
+
+ $this->assertEquals(
+ [['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]],
+ $c->where('v', '!=', $object)->values()->all()
+ );
+
+ $this->assertEquals(
+ [['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]],
+ $c->where('v', '!==', $object)->values()->all()
+ );
+
+ $this->assertEquals(
+ [],
+ $c->where('v', '>', $object)->values()->all()
+ );
+
+ $c = new $collection([['v' => 1], ['v' => $object]]);
+ $this->assertEquals(
+ [['v' => $object]],
+ $c->where('v', $object)->values()->all()
+ );
+
+ $this->assertEquals(
+ [['v' => 1], ['v' => $object]],
+ $c->where('v', '<>', null)->values()->all()
+ );
+
+ $this->assertEquals(
+ [],
+ $c->where('v', '<', null)->values()->all()
+ );
+
+ // $c = new $collection([['v' => 1], ['v' => new HtmlString('hello')]]);
+ // $this->assertEquals(
+ // [['v' => new HtmlString('hello')]],
+ // $c->where('v', 'hello')->values()->all()
+ // );
+
+ // $c = new $collection([['v' => 1], ['v' => 'hello']]);
+ // $this->assertEquals(
+ // [['v' => 'hello']],
+ // $c->where('v', new HtmlString('hello'))->values()->all()
+ // );
+
+ $c = new $collection([['v' => 1], ['v' => 2], ['v' => null]]);
+ $this->assertEquals(
+ [['v' => 1], ['v' => 2]],
+ $c->where('v')->values()->all()
+ );
+ }
+
+ /**
+ * @dataProvider collectionClassProvider
+ */
+ #[DataProvider( 'collectionClassProvider' )]
+ public function testWhereStrict( $collection ) {
$c = new $collection([['v' => 3], ['v' => '3']]);
$this->assertEquals(
@@ -697,8 +675,7 @@ public function testWhereStrict($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWhereInstanceOf($collection)
- {
+ public function testWhereInstanceOf( $collection ) {
$c = new $collection([new stdClass, new stdClass, new $collection, new stdClass]);
$this->assertCount(3, $c->where_instance_of(stdClass::class));
}
@@ -707,8 +684,7 @@ public function testWhereInstanceOf($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWhereIn($collection)
- {
+ public function testWhereIn( $collection ) {
$c = new $collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);
$this->assertEquals([['v' => 1], ['v' => 3], ['v' => '3']], $c->where_in('v', [1, 3])->values()->all());
}
@@ -717,8 +693,7 @@ public function testWhereIn($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWhereInStrict($collection)
- {
+ public function testWhereInStrict( $collection ) {
$c = new $collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);
$this->assertEquals([['v' => 1], ['v' => 3]], $c->where_in_strict('v', [1, 3])->values()->all());
}
@@ -727,8 +702,7 @@ public function testWhereInStrict($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWhereNotIn($collection)
- {
+ public function testWhereNotIn( $collection ) {
$c = new $collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);
$this->assertEquals([['v' => 2], ['v' => 4]], $c->where_not_in('v', [1, 3])->values()->all());
}
@@ -737,8 +711,7 @@ public function testWhereNotIn($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWhereNotInStrict($collection)
- {
+ public function testWhereNotInStrict( $collection ) {
$c = new $collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);
$this->assertEquals([['v' => 2], ['v' => '3'], ['v' => 4]], $c->where_not_in_strict('v', [1, 3])->values()->all());
}
@@ -747,8 +720,7 @@ public function testWhereNotInStrict($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testValues($collection)
- {
+ public function testValues( $collection ) {
$c = new $collection([['id' => 1, 'name' => 'Hello'], ['id' => 2, 'name' => 'World']]);
$this->assertEquals([['id' => 2, 'name' => 'World']], $c->filter(function ($item) {
return $item['id'] == 2;
@@ -759,8 +731,7 @@ public function testValues($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testBetween($collection)
- {
+ public function testBetween( $collection ) {
$c = new $collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);
$this->assertEquals([['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]],
@@ -773,8 +744,7 @@ public function testBetween($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWhereNotBetween($collection)
- {
+ public function testWhereNotBetween( $collection ) {
$c = new $collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);
$this->assertEquals([['v' => 1]], $c->where_not_between('v', [2, 4])->values()->all());
@@ -786,8 +756,7 @@ public function testWhereNotBetween($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testFlatten($collection)
- {
+ public function testFlatten( $collection ) {
// Flat arrays are unaffected
$c = new $collection(['#foo', '#bar', '#baz']);
$this->assertEquals(['#foo', '#bar', '#baz'], $c->flatten()->all());
@@ -825,8 +794,7 @@ public function testFlatten($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testFlattenWithDepth($collection)
- {
+ public function testFlattenWithDepth( $collection ) {
// No depth flattens recursively
$c = new $collection([['#foo', ['#bar', ['#baz']]], '#zap']);
$this->assertEquals(['#foo', '#bar', '#baz', '#zap'], $c->flatten()->all());
@@ -843,8 +811,7 @@ public function testFlattenWithDepth($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testFlattenIgnoresKeys($collection)
- {
+ public function testFlattenIgnoresKeys( $collection ) {
// No depth ignores keys
$c = new $collection(['#foo', ['key' => '#bar'], ['key' => '#baz'], 'key' => '#zap']);
$this->assertEquals(['#foo', '#bar', '#baz', '#zap'], $c->flatten()->all());
@@ -858,8 +825,7 @@ public function testFlattenIgnoresKeys($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMergeNull($collection)
- {
+ public function testMergeNull( $collection ) {
$c = new $collection(['name' => 'Hello']);
$this->assertEquals(['name' => 'Hello'], $c->merge(null)->all());
}
@@ -868,8 +834,7 @@ public function testMergeNull($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMergeArray($collection)
- {
+ public function testMergeArray( $collection ) {
$c = new $collection(['name' => 'Hello']);
$this->assertEquals(['name' => 'Hello', 'id' => 1], $c->merge(['id' => 1])->all());
}
@@ -878,8 +843,7 @@ public function testMergeArray($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMergeCollection($collection)
- {
+ public function testMergeCollection( $collection ) {
$c = new $collection(['name' => 'Hello']);
$this->assertEquals(['name' => 'World', 'id' => 1], $c->merge(new $collection(['name' => 'World', 'id' => 1]))->all());
}
@@ -888,8 +852,7 @@ public function testMergeCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMergeRecursiveNull($collection)
- {
+ public function testMergeRecursiveNull( $collection ) {
$c = new $collection(['name' => 'Hello']);
$this->assertEquals(['name' => 'Hello'], $c->merge_recursive(null)->all());
}
@@ -898,8 +861,7 @@ public function testMergeRecursiveNull($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMergeRecursiveArray($collection)
- {
+ public function testMergeRecursiveArray( $collection ) {
$c = new $collection(['name' => 'Hello', 'id' => 1]);
$this->assertEquals(['name' => 'Hello', 'id' => [1, 2]], $c->merge_recursive(['id' => 2])->all());
}
@@ -908,8 +870,7 @@ public function testMergeRecursiveArray($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMergeRecursiveCollection($collection)
- {
+ public function testMergeRecursiveCollection( $collection ) {
$c = new $collection(['name' => 'Hello', 'id' => 1, 'meta' => ['tags' => ['a', 'b'], 'roles' => 'admin']]);
$this->assertEquals(
['name' => 'Hello', 'id' => 1, 'meta' => ['tags' => ['a', 'b', 'c'], 'roles' => ['admin', 'editor']]],
@@ -921,8 +882,7 @@ public function testMergeRecursiveCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testReplaceNull($collection)
- {
+ public function testReplaceNull( $collection ) {
$c = new $collection(['a', 'b', 'c']);
$this->assertEquals(['a', 'b', 'c'], $c->replace(null)->all());
}
@@ -931,8 +891,7 @@ public function testReplaceNull($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testReplaceArray($collection)
- {
+ public function testReplaceArray( $collection ) {
$c = new $collection(['a', 'b', 'c']);
$this->assertEquals(['a', 'd', 'e'], $c->replace([1 => 'd', 2 => 'e'])->all());
}
@@ -941,8 +900,7 @@ public function testReplaceArray($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testReplaceCollection($collection)
- {
+ public function testReplaceCollection( $collection ) {
$c = new $collection(['a', 'b', 'c']);
$this->assertEquals(
['a', 'd', 'e'],
@@ -954,8 +912,7 @@ public function testReplaceCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testReplaceRecursiveNull($collection)
- {
+ public function testReplaceRecursiveNull( $collection ) {
$c = new $collection(['a', 'b', ['c', 'd']]);
$this->assertEquals(['a', 'b', ['c', 'd']], $c->replace_recursive(null)->all());
}
@@ -964,8 +921,7 @@ public function testReplaceRecursiveNull($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testReplaceRecursiveArray($collection)
- {
+ public function testReplaceRecursiveArray( $collection ) {
$c = new $collection(['a', 'b', ['c', 'd']]);
$this->assertEquals(['z', 'b', ['c', 'e']], $c->replace_recursive(['z', 2 => [1 => 'e']])->all());
}
@@ -974,8 +930,7 @@ public function testReplaceRecursiveArray($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testReplaceRecursiveCollection($collection)
- {
+ public function testReplaceRecursiveCollection( $collection ) {
$c = new $collection(['a', 'b', ['c', 'd']]);
$this->assertEquals(
['z', 'b', ['c', 'e']],
@@ -987,8 +942,7 @@ public function testReplaceRecursiveCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testUnionNull($collection)
- {
+ public function testUnionNull( $collection ) {
$c = new $collection(['name' => 'Hello']);
$this->assertEquals(['name' => 'Hello'], $c->union(null)->all());
}
@@ -997,8 +951,7 @@ public function testUnionNull($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testUnionArray($collection)
- {
+ public function testUnionArray( $collection ) {
$c = new $collection(['name' => 'Hello']);
$this->assertEquals(['name' => 'Hello', 'id' => 1], $c->union(['id' => 1])->all());
}
@@ -1007,8 +960,7 @@ public function testUnionArray($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testUnionCollection($collection)
- {
+ public function testUnionCollection( $collection ) {
$c = new $collection(['name' => 'Hello']);
$this->assertEquals(['name' => 'Hello', 'id' => 1], $c->union(new $collection(['name' => 'World', 'id' => 1]))->all());
}
@@ -1017,8 +969,7 @@ public function testUnionCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testDiffCollection($collection)
- {
+ public function testDiffCollection( $collection ) {
$c = new $collection(['id' => 1, 'first_word' => 'Hello']);
$this->assertEquals(['id' => 1], $c->diff(new $collection(['first_word' => 'Hello', 'last_word' => 'World']))->all());
}
@@ -1027,8 +978,7 @@ public function testDiffCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testDiffUsingWithCollection($collection)
- {
+ public function testDiffUsingWithCollection( $collection ) {
$c = new $collection(['en_GB', 'fr', 'HR']);
// demonstrate that diffKeys wont support case insensitivity
$this->assertEquals(['en_GB', 'fr', 'HR'], $c->diff(new $collection(['en_gb', 'hr']))->values()->to_array());
@@ -1040,8 +990,7 @@ public function testDiffUsingWithCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testDiffUsingWithNull($collection)
- {
+ public function testDiffUsingWithNull( $collection ) {
$c = new $collection(['en_GB', 'fr', 'HR']);
$this->assertEquals(['en_GB', 'fr', 'HR'], $c->diff_using(null, 'strcasecmp')->values()->to_array());
}
@@ -1050,8 +999,7 @@ public function testDiffUsingWithNull($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testDiffNull($collection)
- {
+ public function testDiffNull( $collection ) {
$c = new $collection(['id' => 1, 'first_word' => 'Hello']);
$this->assertEquals(['id' => 1, 'first_word' => 'Hello'], $c->diff(null)->all());
}
@@ -1060,8 +1008,7 @@ public function testDiffNull($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testDiffKeys($collection)
- {
+ public function testDiffKeys( $collection ) {
$c1 = new $collection(['id' => 1, 'first_word' => 'Hello']);
$c2 = new $collection(['id' => 123, 'foo_bar' => 'Hello']);
$this->assertEquals(['first_word' => 'Hello'], $c1->diff_keys($c2)->all());
@@ -1071,8 +1018,7 @@ public function testDiffKeys($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testDiffKeysUsing($collection)
- {
+ public function testDiffKeysUsing( $collection ) {
$c1 = new $collection(['id' => 1, 'first_word' => 'Hello']);
$c2 = new $collection(['ID' => 123, 'foo_bar' => 'Hello']);
// demonstrate that diffKeys wont support case insensitivity
@@ -1085,8 +1031,7 @@ public function testDiffKeysUsing($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testDiffAssoc($collection)
- {
+ public function testDiffAssoc( $collection ) {
$c1 = new $collection(['id' => 1, 'first_word' => 'Hello', 'not_affected' => 'value']);
$c2 = new $collection(['id' => 123, 'foo_bar' => 'Hello', 'not_affected' => 'value']);
$this->assertEquals(['id' => 1, 'first_word' => 'Hello'], $c1->diff_assoc($c2)->all());
@@ -1096,8 +1041,7 @@ public function testDiffAssoc($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testDiffAssocUsing($collection)
- {
+ public function testDiffAssocUsing( $collection ) {
$c1 = new $collection(['a' => 'green', 'b' => 'brown', 'c' => 'blue', 'red']);
$c2 = new $collection(['A' => 'green', 'yellow', 'red']);
// demonstrate that the case of the keys will affect the output when diffAssoc is used
@@ -1110,8 +1054,7 @@ public function testDiffAssocUsing($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testDuplicates($collection)
- {
+ public function testDuplicates( $collection ) {
$duplicates = $collection::make([1, 2, 1, 'laravel', null, 'laravel', 'php', null])->duplicates()->all();
$this->assertSame([2 => 1, 5 => 'laravel', 7 => null], $duplicates);
@@ -1133,8 +1076,7 @@ public function testDuplicates($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testDuplicatesWithKey($collection)
- {
+ public function testDuplicatesWithKey( $collection ) {
$items = [['framework' => 'vue'], ['framework' => 'laravel'], ['framework' => 'laravel']];
$duplicates = $collection::make($items)->duplicates('framework')->all();
$this->assertSame([2 => 'laravel'], $duplicates);
@@ -1144,8 +1086,7 @@ public function testDuplicatesWithKey($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testDuplicatesWithCallback($collection)
- {
+ public function testDuplicatesWithCallback( $collection ) {
$items = [['framework' => 'vue'], ['framework' => 'laravel'], ['framework' => 'laravel']];
$duplicates = $collection::make($items)->duplicates(function ($item) {
return $item['framework'];
@@ -1157,8 +1098,7 @@ public function testDuplicatesWithCallback($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testDuplicatesWithStrict($collection)
- {
+ public function testDuplicatesWithStrict( $collection ) {
$duplicates = $collection::make([1, 2, 1, 'laravel', null, 'laravel', 'php', null])->duplicates_strict()->all();
$this->assertSame([2 => 1, 5 => 'laravel', 7 => null], $duplicates);
@@ -1180,8 +1120,7 @@ public function testDuplicatesWithStrict($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testEach($collection)
- {
+ public function testEach( $collection ) {
$c = new $collection($original = [1, 2, 'foo' => 'bar', 'bam' => 'baz']);
$result = [];
@@ -1204,8 +1143,7 @@ public function testEach($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testEachSpread($collection)
- {
+ public function testEachSpread( $collection ) {
$c = new $collection([[1, 'a'], [2, 'b']]);
$result = [];
@@ -1240,8 +1178,7 @@ public function testEachSpread($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testIntersectNull($collection)
- {
+ public function testIntersectNull( $collection ) {
$c = new $collection(['id' => 1, 'first_word' => 'Hello']);
$this->assertEquals([], $c->intersect(null)->all());
}
@@ -1250,8 +1187,7 @@ public function testIntersectNull($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testIntersectCollection($collection)
- {
+ public function testIntersectCollection( $collection ) {
$c = new $collection(['id' => 1, 'first_word' => 'Hello']);
$this->assertEquals(['first_word' => 'Hello'], $c->intersect(new $collection(['first_world' => 'Hello', 'last_word' => 'World']))->all());
}
@@ -1260,8 +1196,7 @@ public function testIntersectCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testIntersectByKeysNull($collection)
- {
+ public function testIntersectByKeysNull( $collection ) {
$c = new $collection(['name' => 'Mateus', 'age' => 18]);
$this->assertEquals([], $c->intersect_by_keys(null)->all());
}
@@ -1270,8 +1205,7 @@ public function testIntersectByKeysNull($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testIntersectByKeys($collection)
- {
+ public function testIntersectByKeys( $collection ) {
$c = new $collection(['name' => 'Mateus', 'age' => 18]);
$this->assertEquals(['name' => 'Mateus'], $c->intersect_by_keys(new $collection(['name' => 'Mateus', 'surname' => 'Guimaraes']))->all());
}
@@ -1280,8 +1214,7 @@ public function testIntersectByKeys($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testUnique($collection)
- {
+ public function testUnique( $collection ) {
$c = new $collection(['Hello', 'World', 'World']);
$this->assertEquals(['Hello', 'World'], $c->unique()->all());
@@ -1293,8 +1226,7 @@ public function testUnique($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testUniqueWithCallback($collection)
- {
+ public function testUniqueWithCallback( $collection ) {
$c = new $collection([
1 => ['id' => 1, 'first' => 'Taylor', 'last' => 'Otwell'],
2 => ['id' => 2, 'first' => 'Taylor', 'last' => 'Otwell'],
@@ -1329,8 +1261,7 @@ public function testUniqueWithCallback($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testUniqueStrict($collection)
- {
+ public function testUniqueStrict( $collection ) {
$c = new $collection([
[
'id' => '0',
@@ -1362,8 +1293,7 @@ public function testUniqueStrict($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testCollapse($collection)
- {
+ public function testCollapse( $collection ) {
$data = new $collection([[$object1 = new stdClass], [$object2 = new stdClass]]);
$this->assertEquals([$object1, $object2], $data->collapse()->all());
}
@@ -1372,8 +1302,7 @@ public function testCollapse($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testCollapseWithNestedCollections($collection)
- {
+ public function testCollapseWithNestedCollections( $collection ) {
$data = new $collection([new $collection([1, 2, 3]), new $collection([4, 5, 6])]);
$this->assertEquals([1, 2, 3, 4, 5, 6], $data->collapse()->all());
}
@@ -1382,8 +1311,7 @@ public function testCollapseWithNestedCollections($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testJoin($collection)
- {
+ public function testJoin( $collection ) {
$this->assertSame('a, b, c', (new $collection(['a', 'b', 'c']))->join(', '));
$this->assertSame('a, b and c', (new $collection(['a', 'b', 'c']))->join(', ', ' and '));
@@ -1399,8 +1327,7 @@ public function testJoin($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testCrossJoin($collection)
- {
+ public function testCrossJoin( $collection ) {
// Cross join with an array
$this->assertEquals(
[[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']],
@@ -1432,8 +1359,7 @@ public function testCrossJoin($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSort($collection)
- {
+ public function testSort( $collection ) {
$data = (new $collection([5, 3, 1, 2, 4]))->sort();
$this->assertEquals([1, 2, 3, 4, 5], $data->values()->all());
@@ -1454,8 +1380,7 @@ public function testSort($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSortDesc($collection)
- {
+ public function testSortDesc( $collection ) {
$data = (new $collection([5, 3, 1, 2, 4]))->sort_desc();
$this->assertEquals([5, 4, 3, 2, 1], $data->values()->all());
@@ -1476,8 +1401,7 @@ public function testSortDesc($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSortWithCallback($collection)
- {
+ public function testSortWithCallback( $collection ) {
$data = (new $collection([5, 3, 1, 2, 4]))->sort(function ($a, $b) {
if ($a === $b) {
return 0;
@@ -1493,8 +1417,7 @@ public function testSortWithCallback($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSortBy($collection)
- {
+ public function testSortBy( $collection ) {
$data = new $collection(['taylor', 'dayle']);
$data = $data->sort_by(function ($x) {
return $x;
@@ -1514,8 +1437,7 @@ public function testSortBy($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSortByString($collection)
- {
+ public function testSortByString( $collection ) {
$data = new $collection([['name' => 'taylor'], ['name' => 'dayle']]);
$data = $data->sort_by('name', SORT_STRING);
@@ -1531,8 +1453,7 @@ public function testSortByString($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSortByAlwaysReturnsAssoc($collection)
- {
+ public function testSortByAlwaysReturnsAssoc( $collection ) {
$data = new $collection(['a' => 'taylor', 'b' => 'dayle']);
$data = $data->sort_by(function ($x) {
return $x;
@@ -1552,8 +1473,7 @@ public function testSortByAlwaysReturnsAssoc($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSortKeys($collection)
- {
+ public function testSortKeys( $collection ) {
$data = new $collection(['b' => 'dayle', 'a' => 'taylor']);
$this->assertSame(['a' => 'taylor', 'b' => 'dayle'], $data->sort_keys()->all());
@@ -1563,8 +1483,7 @@ public function testSortKeys($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSortKeysDesc($collection)
- {
+ public function testSortKeysDesc( $collection ) {
$data = new $collection(['a' => 'taylor', 'b' => 'dayle']);
$this->assertSame(['b' => 'dayle', 'a' => 'taylor'], $data->sort_keys_desc()->all());
@@ -1574,8 +1493,7 @@ public function testSortKeysDesc($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testReverse($collection)
- {
+ public function testReverse( $collection ) {
$data = new $collection(['zaeed', 'alan']);
$reversed = $data->reverse();
@@ -1591,8 +1509,7 @@ public function testReverse($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testFlip($collection)
- {
+ public function testFlip( $collection ) {
$data = new $collection(['name' => 'taylor', 'framework' => 'laravel']);
$this->assertEquals(['taylor' => 'name', 'laravel' => 'framework'], $data->flip()->to_array());
}
@@ -1601,8 +1518,7 @@ public function testFlip($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testChunk($collection)
- {
+ public function testChunk( $collection ) {
$data = new $collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
$data = $data->chunk(3);
@@ -1617,8 +1533,7 @@ public function testChunk($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testChunkWhenGivenZeroAsSize($collection)
- {
+ public function testChunkWhenGivenZeroAsSize( $collection ) {
$data = new $collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
$this->assertEquals(
@@ -1631,8 +1546,7 @@ public function testChunkWhenGivenZeroAsSize($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testChunkWhenGivenLessThanZero($collection)
- {
+ public function testChunkWhenGivenLessThanZero( $collection ) {
$data = new $collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
$this->assertEquals(
@@ -1645,57 +1559,56 @@ public function testChunkWhenGivenLessThanZero($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
-// public function testEvery($collection)
-// {
-// $c = new $collection([]);
-// $this->assertTrue($c->every('key', 'value'));
-// $this->assertTrue($c->every(function () {
-// return false;
-// }));
-//
-// $c = new $collection([['age' => 18], ['age' => 20], ['age' => 20]]);
-// $this->assertFalse($c->every('age', 18));
-// $this->assertTrue($c->every('age', '>=', 18));
-// $this->assertTrue($c->every(function ($item) {
-// return $item['age'] >= 18;
-// }));
-// $this->assertFalse($c->every(function ($item) {
-// return $item['age'] >= 20;
-// }));
-//
-// $c = new $collection([null, null]);
-// $this->assertTrue($c->every(function ($item) {
-// return $item === null;
-// }));
-//
-// $c = new $collection([['active' => true], ['active' => true]]);
-// $this->assertTrue($c->every('active'));
-// $this->assertTrue($c->every->active);
-// $this->assertFalse($c->concat([['active' => false]])->every->active);
-// }
+ public function testEvery($collection)
+ {
+ $c = new $collection([]);
+ $this->assertTrue($c->every('key', 'value'));
+ $this->assertTrue($c->every(function () {
+ return false;
+ }));
+
+ $c = new $collection([['age' => 18], ['age' => 20], ['age' => 20]]);
+ $this->assertFalse($c->every('age', 18));
+ $this->assertTrue($c->every('age', '>=', 18));
+ $this->assertTrue($c->every(function ($item) {
+ return $item['age'] >= 18;
+ }));
+ $this->assertFalse($c->every(function ($item) {
+ return $item['age'] >= 20;
+ }));
+
+ $c = new $collection([null, null]);
+ $this->assertTrue($c->every(function ($item) {
+ return $item === null;
+ }));
+
+ $c = new $collection([['active' => true], ['active' => true]]);
+ $this->assertTrue($c->every('active'));
+ $this->assertTrue($c->every->active);
+ $this->assertFalse($c->concat([['active' => false]])->every->active);
+ }
/**
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
-// public function testExcept($collection)
-// {
-// $data = new $collection(['first' => 'Taylor', 'last' => 'Otwell', 'email' => 'taylorotwell@gmail.com']);
-//
-// $this->assertEquals(['first' => 'Taylor'], $data->except(['last', 'email', 'missing'])->all());
-// $this->assertEquals(['first' => 'Taylor'], $data->except('last', 'email', 'missing')->all());
-//
-// $this->assertEquals(['first' => 'Taylor'], $data->except(collect(['last', 'email', 'missing']))->all());
-// $this->assertEquals(['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], $data->except(['last'])->all());
-// $this->assertEquals(['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], $data->except('last')->all());
-// }
+ public function testExcept($collection)
+ {
+ $data = new $collection(['first' => 'Taylor', 'last' => 'Otwell', 'email' => 'taylorotwell@gmail.com']);
+
+ $this->assertEquals(['first' => 'Taylor'], $data->except(['last', 'email', 'missing'])->all());
+ $this->assertEquals(['first' => 'Taylor'], $data->except('last', 'email', 'missing')->all());
+
+ $this->assertEquals(['first' => 'Taylor'], $data->except(collect(['last', 'email', 'missing']))->all());
+ $this->assertEquals(['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], $data->except(['last'])->all());
+ $this->assertEquals(['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], $data->except('last')->all());
+ }
/**
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testExceptSelf($collection)
- {
+ public function testExceptSelf( $collection ) {
$data = new $collection(['first' => 'Taylor', 'last' => 'Otwell']);
$this->assertEquals(['first' => 'Taylor', 'last' => 'Otwell'], $data->except($data)->all());
}
@@ -1704,8 +1617,7 @@ public function testExceptSelf($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testPluckWithArrayAndObjectValues($collection)
- {
+ public function testPluckWithArrayAndObjectValues( $collection ) {
$data = new $collection([(object) ['name' => 'taylor', 'email' => 'foo'], ['name' => 'dayle', 'email' => 'bar']]);
$this->assertEquals(['taylor' => 'foo', 'dayle' => 'bar'], $data->pluck('email', 'name')->all());
$this->assertEquals(['foo', 'bar'], $data->pluck('email')->all());
@@ -1715,8 +1627,7 @@ public function testPluckWithArrayAndObjectValues($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testPluckWithArrayAccessValues($collection)
- {
+ public function testPluckWithArrayAccessValues( $collection ) {
$data = new $collection([
new TestArrayAccessImplementation(['name' => 'taylor', 'email' => 'foo']),
new TestArrayAccessImplementation(['name' => 'dayle', 'email' => 'bar']),
@@ -1730,8 +1641,7 @@ public function testPluckWithArrayAccessValues($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testHas($collection)
- {
+ public function testHas( $collection ) {
$data = new $collection(['id' => 1, 'first' => 'Hello', 'second' => 'World']);
$this->assertTrue($data->has('first'));
$this->assertFalse($data->has('third'));
@@ -1743,8 +1653,7 @@ public function testHas($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testImplode($collection)
- {
+ public function testImplode( $collection ) {
$data = new $collection([['name' => 'taylor', 'email' => 'foo'], ['name' => 'dayle', 'email' => 'bar']]);
$this->assertSame('foobar', $data->implode('email'));
$this->assertSame('foo,bar', $data->implode('email', ','));
@@ -1758,8 +1667,7 @@ public function testImplode($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testImplodeStringable($collection)
- {
+ public function testImplodeStringable( $collection ) {
$data = new $collection( [
Stringable::make( 'example' ),
Stringable::make( 'string' ),
@@ -1779,8 +1687,7 @@ public function testImplodeStringable($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testImplodeStr($collection)
- {
+ public function testImplodeStr( $collection ) {
$data = new $collection( [
Stringable::make( 'example' ),
Stringable::make( 'string' ),
@@ -1795,8 +1702,7 @@ public function testImplodeStr($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testTake($collection)
- {
+ public function testTake( $collection ) {
$data = new $collection(['taylor', 'dayle', 'shawn']);
$data = $data->take(2);
$this->assertEquals(['taylor', 'dayle'], $data->all());
@@ -1820,45 +1726,44 @@ public function testPutWithNoKey()
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
-// public function testRandom($collection)
-// {
-// $data = new $collection([1, 2, 3, 4, 5, 6]);
-//
-// $random = $data->random();
-// $this->assertIsInt($random);
-// $this->assertContains($random, $data->all());
-//
-// $random = $data->random(0);
-// $this->assertInstanceOf($collection, $random);
-// $this->assertCount(0, $random);
-//
-// $random = $data->random(1);
-// $this->assertInstanceOf($collection, $random);
-// $this->assertCount(1, $random);
-//
-// $random = $data->random(2);
-// $this->assertInstanceOf($collection, $random);
-// $this->assertCount(2, $random);
-//
-// $random = $data->random('0');
-// $this->assertInstanceOf($collection, $random);
-// $this->assertCount(0, $random);
-//
-// $random = $data->random('1');
-// $this->assertInstanceOf($collection, $random);
-// $this->assertCount(1, $random);
-//
-// $random = $data->random('2');
-// $this->assertInstanceOf($collection, $random);
-// $this->assertCount(2, $random);
-// }
+ public function testRandom($collection)
+ {
+ $data = new $collection([1, 2, 3, 4, 5, 6]);
+
+ $random = $data->random();
+ $this->assertIsInt($random);
+ $this->assertContains($random, $data->all());
+
+ $random = $data->random(0);
+ $this->assertInstanceOf($collection, $random);
+ $this->assertCount(0, $random);
+
+ $random = $data->random(1);
+ $this->assertInstanceOf($collection, $random);
+ $this->assertCount(1, $random);
+
+ $random = $data->random(2);
+ $this->assertInstanceOf($collection, $random);
+ $this->assertCount(2, $random);
+
+ $random = $data->random('0');
+ $this->assertInstanceOf($collection, $random);
+ $this->assertCount(0, $random);
+
+ $random = $data->random('1');
+ $this->assertInstanceOf($collection, $random);
+ $this->assertCount(1, $random);
+
+ $random = $data->random('2');
+ $this->assertInstanceOf($collection, $random);
+ $this->assertCount(2, $random);
+ }
/**
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testRandomOnEmptyCollection($collection)
- {
+ public function testRandomOnEmptyCollection( $collection ) {
$data = new $collection;
$random = $data->random(0);
@@ -1874,8 +1779,7 @@ public function testRandomOnEmptyCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testTakeLast($collection)
- {
+ public function testTakeLast( $collection ) {
$data = new $collection(['taylor', 'dayle', 'shawn']);
$data = $data->take(-2);
$this->assertEquals([1 => 'dayle', 2 => 'shawn'], $data->all());
@@ -1884,181 +1788,133 @@ public function testTakeLast($collection)
/**
* @dataProvider collectionClassProvider
*/
- #[DataProvider( 'collectionClassProvider' )]
-// public function testTakeUntilUsingValue($collection)
-// {
-// $data = new $collection([1, 2, 3, 4]);
-//
-// $data = $data->takeUntil(3);
-//
-// $this->assertSame([1, 2], $data->to_array());
-// }
+ #[DataProvider('collectionClassProvider')]
+ public function testTakeUntilUsingValue( $collection ) {
+ $data = new $collection([1, 2, 3, 4]);
- /**
- * @dataProvider collectionClassProvider
- */
- #[DataProvider( 'collectionClassProvider' )]
-// public function testTakeUntilUsingCallback($collection)
-// {
-// $data = new $collection([1, 2, 3, 4]);
-//
-// $data = $data->takeUntil(function ($item) {
-// return $item >= 3;
-// });
-//
-// $this->assertSame([1, 2], $data->to_array());
-// }
+ $data = $data->take_until(3);
+
+ $this->assertSame([1, 2], $data->to_array());
+ }
/**
* @dataProvider collectionClassProvider
*/
- #[DataProvider( 'collectionClassProvider' )]
-// public function testTakeUntilReturnsAllItemsForUnmetValue($collection)
-// {
-// $data = new $collection([1, 2, 3, 4]);
-//
-// $actual = $data->takeUntil(99);
-//
-// $this->assertSame($data->to_array(), $actual->to_array());
-//
-// $actual = $data->takeUntil(function ($item) {
-// return $item >= 99;
-// });
-//
-// $this->assertSame($data->to_array(), $actual->to_array());
-// }
+ #[DataProvider('collectionClassProvider')]
+ public function testTakeUntilUsingCallback( $collection ) {
+ $data = new $collection([1, 2, 3, 4]);
+
+ $data = $data->take_until(function ($item) {
+ return $item >= 3;
+ });
+
+ $this->assertSame([1, 2], $data->to_array());
+ }
/**
* @dataProvider collectionClassProvider
*/
- #[DataProvider( 'collectionClassProvider' )]
-// public function testTakeUntilCanBeProxied($collection)
-// {
-// $data = new $collection([
-// new TestSupportCollectionHigherOrderItem('Adam'),
-// new TestSupportCollectionHigherOrderItem('Taylor'),
-// new TestSupportCollectionHigherOrderItem('Jason'),
-// ]);
-//
-// $actual = $data->takeUntil->is('Jason');
-//
-// $this->assertCount(2, $actual);
-// $this->assertSame('Adam', $actual->get(0)->name);
-// $this->assertSame('Taylor', $actual->get(1)->name);
-// }
+ #[DataProvider('collectionClassProvider')]
+ public function testTakeUntilReturnsAllItemsForUnmetValue( $collection ) {
+ $data = new $collection([1, 2, 3, 4]);
+
+ $actual = $data->take_until(99);
+
+ $this->assertSame($data->to_array(), $actual->to_array());
+
+ $actual = $data->take_until(function ($item) {
+ return $item >= 99;
+ });
+
+ $this->assertSame($data->to_array(), $actual->to_array());
+ }
/**
* @dataProvider collectionClassProvider
*/
- #[DataProvider( 'collectionClassProvider' )]
-// public function testTakeWhileUsingValue($collection)
-// {
-// $data = new $collection([1, 1, 2, 2, 3, 3]);
-//
-// $data = $data->takeWhile(1);
-//
-// $this->assertSame([1, 1], $data->to_array());
-// }
+ #[DataProvider('collectionClassProvider')]
+ public function testTakeUntilCanBeProxied( $collection ) {
+ $data = new $collection([
+ new TestSupportCollectionHigherOrderItem('Adam'),
+ new TestSupportCollectionHigherOrderItem('Taylor'),
+ new TestSupportCollectionHigherOrderItem('Jason'),
+ ]);
+
+ $actual = $data->take_until->is('Jason');
+
+ $this->assertCount(2, $actual);
+ $this->assertSame('Adam', $actual->get(0)->name);
+ $this->assertSame('Taylor', $actual->get(1)->name);
+ }
/**
* @dataProvider collectionClassProvider
*/
- #[DataProvider( 'collectionClassProvider' )]
-// public function testTakeWhileUsingCallback($collection)
-// {
-// $data = new $collection([1, 2, 3, 4]);
-//
-// $data = $data->takeWhile(function ($item) {
-// return $item < 3;
-// });
-//
-// $this->assertSame([1, 2], $data->to_array());
-// }
+ #[DataProvider('collectionClassProvider')]
+ public function testTakeWhileUsingValue( $collection ) {
+ $data = new $collection([1, 1, 2, 2, 3, 3]);
+
+ $data = $data->take_while(1);
+
+ $this->assertSame([1, 1], $data->to_array());
+ }
/**
* @dataProvider collectionClassProvider
*/
- #[DataProvider( 'collectionClassProvider' )]
-// public function testTakeWhileReturnsNoItemsForUnmetValue($collection)
-// {
-// $data = new $collection([1, 2, 3, 4]);
-//
-// $actual = $data->takeWhile(2);
-//
-// $this->assertSame([], $actual->to_array());
-//
-// $actual = $data->takeWhile(function ($item) {
-// return $item == 99;
-// });
-//
-// $this->assertSame([], $actual->to_array());
-// }
+ #[DataProvider('collectionClassProvider')]
+ public function testTakeWhileUsingCallback( $collection ) {
+ $data = new $collection([1, 2, 3, 4]);
+
+ $data = $data->take_while(function ($item) {
+ return $item < 3;
+ });
+
+ $this->assertSame([1, 2], $data->to_array());
+ }
/**
* @dataProvider collectionClassProvider
*/
- #[DataProvider( 'collectionClassProvider' )]
-// public function testTakeWhileCanBeProxied($collection)
-// {
-// $data = new $collection([
-// new TestSupportCollectionHigherOrderItem('Adam'),
-// new TestSupportCollectionHigherOrderItem('Adam'),
-// new TestSupportCollectionHigherOrderItem('Taylor'),
-// new TestSupportCollectionHigherOrderItem('Taylor'),
-// ]);
-//
-// $actual = $data->takeWhile->is('Adam');
-//
-// $this->assertCount(2, $actual);
-// $this->assertSame('Adam', $actual->get(0)->name);
-// $this->assertSame('Adam', $actual->get(1)->name);
-// }
+ #[DataProvider('collectionClassProvider')]
+ public function testTakeWhileReturnsNoItemsForUnmetValue( $collection ) {
+ $data = new $collection([1, 2, 3, 4]);
+
+ $actual = $data->take_while(2);
+
+ $this->assertSame([], $actual->to_array());
+
+ $actual = $data->take_while(function ($item) {
+ return $item == 99;
+ });
+
+ $this->assertSame([], $actual->to_array());
+ }
/**
* @dataProvider collectionClassProvider
*/
- #[DataProvider( 'collectionClassProvider' )]
-// public function testMacroable($collection)
-// {
-// // Foo() macro : unique values starting with A
-// $collection::macro('foo', function () {
-// return $this->filter(function ($item) {
-// return strpos($item, 'a') === 0;
-// })
-// ->unique()
-// ->values();
-// });
-//
-// $c = new $collection(['a', 'a', 'aa', 'aaa', 'bar']);
-//
-// $this->assertSame(['a', 'aa', 'aaa'], $c->foo()->all());
-// }
+ #[DataProvider('collectionClassProvider')]
+ public function testTakeWhileCanBeProxied( $collection ) {
+ $data = new $collection([
+ new TestSupportCollectionHigherOrderItem('Adam'),
+ new TestSupportCollectionHigherOrderItem('Adam'),
+ new TestSupportCollectionHigherOrderItem('Taylor'),
+ new TestSupportCollectionHigherOrderItem('Taylor'),
+ ]);
- /**
- * @dataProvider collectionClassProvider
- */
- #[DataProvider( 'collectionClassProvider' )]
-// public function testCanAddMethodsToProxy($collection)
-// {
-// $collection::macro('adults', function ($callback) {
-// return $this->filter(function ($item) use ($callback) {
-// return $callback($item) >= 18;
-// });
-// });
-//
-// $collection::proxy('adults');
-//
-// $c = new $collection([['age' => 3], ['age' => 12], ['age' => 18], ['age' => 56]]);
-//
-// $this->assertSame([['age' => 18], ['age' => 56]], $c->adults->age->values()->all());
-// }
+ $actual = $data->take_while->is('Adam');
+
+ $this->assertCount(2, $actual);
+ $this->assertSame('Adam', $actual->get(0)->name);
+ $this->assertSame('Adam', $actual->get(1)->name);
+ }
/**
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMakeMethod($collection)
- {
+ public function testMakeMethod( $collection ) {
$data = $collection::make('foo');
$this->assertEquals(['foo'], $data->all());
}
@@ -2067,8 +1923,7 @@ public function testMakeMethod($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMakeMethodFromNull($collection)
- {
+ public function testMakeMethodFromNull( $collection ) {
$data = $collection::make(null);
$this->assertEquals([], $data->all());
@@ -2080,8 +1935,7 @@ public function testMakeMethodFromNull($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMakeMethodFromCollection($collection)
- {
+ public function testMakeMethodFromCollection( $collection ) {
$firstCollection = $collection::make(['foo' => 'bar']);
$secondCollection = $collection::make($firstCollection);
$this->assertEquals(['foo' => 'bar'], $secondCollection->all());
@@ -2091,8 +1945,7 @@ public function testMakeMethodFromCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMakeMethodFromArray($collection)
- {
+ public function testMakeMethodFromArray( $collection ) {
$data = $collection::make(['foo' => 'bar']);
$this->assertEquals(['foo' => 'bar'], $data->all());
}
@@ -2101,8 +1954,7 @@ public function testMakeMethodFromArray($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWrapWithScalar($collection)
- {
+ public function testWrapWithScalar( $collection ) {
$data = $collection::wrap('foo');
$this->assertEquals(['foo'], $data->all());
}
@@ -2111,8 +1963,7 @@ public function testWrapWithScalar($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWrapWithArray($collection)
- {
+ public function testWrapWithArray( $collection ) {
$data = $collection::wrap(['foo']);
$this->assertEquals(['foo'], $data->all());
}
@@ -2121,8 +1972,7 @@ public function testWrapWithArray($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWrapWithArrayable($collection)
- {
+ public function testWrapWithArrayable( $collection ) {
$data = $collection::wrap($o = new TestArrayableObject);
$this->assertEquals([$o], $data->all());
}
@@ -2131,8 +1981,7 @@ public function testWrapWithArrayable($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWrapWithJsonable($collection)
- {
+ public function testWrapWithJsonable( $collection ) {
$data = $collection::wrap($o = new TestJsonableObject);
$this->assertEquals([$o], $data->all());
}
@@ -2141,8 +1990,7 @@ public function testWrapWithJsonable($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWrapWithJsonSerialize($collection)
- {
+ public function testWrapWithJsonSerialize( $collection ) {
$data = $collection::wrap($o = new TestJsonSerializeObject);
$this->assertEquals([$o], $data->all());
}
@@ -2151,39 +1999,38 @@ public function testWrapWithJsonSerialize($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
-// public function testWrapWithCollectionClass($collection)
-// {
-// $data = $collection::wrap($collection::make(['foo']));
-// $this->assertEquals(['foo'], $data->all());
-// }
+ public function testWrapWithCollectionClass($collection)
+ {
+ $data = $collection::wrap($collection::make(['foo']));
+ $this->assertEquals(['foo'], $data->all());
+ }
/**
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
-// public function testWrapWithCollectionSubclass($collection)
-// {
-// $data = TestCollectionSubclass::wrap($collection::make(['foo']));
-// $this->assertEquals(['foo'], $data->all());
-// $this->assertInstanceOf(TestCollectionSubclass::class, $data);
-// }
+ public function testWrapWithCollectionSubclass($collection)
+ {
+ $data = TestCollectionSubclass::wrap($collection::make(['foo']));
+ $this->assertEquals(['foo'], $data->all());
+ $this->assertInstanceOf(TestCollectionSubclass::class, $data);
+ }
/**
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
-// public function testUnwrapCollection($collection)
-// {
-// $data = new $collection(['foo']);
-// $this->assertEquals(['foo'], $collection::unwrap($data));
-// }
+ public function testUnwrapCollection($collection)
+ {
+ $data = new $collection(['foo']);
+ $this->assertEquals(['foo'], $collection::unwrap($data));
+ }
/**
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testUnwrapCollectionWithArray($collection)
- {
+ public function testUnwrapCollectionWithArray( $collection ) {
$this->assertEquals(['foo'], $collection::unwrap(['foo']));
}
@@ -2191,8 +2038,7 @@ public function testUnwrapCollectionWithArray($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testUnwrapCollectionWithScalar($collection)
- {
+ public function testUnwrapCollectionWithScalar( $collection ) {
$this->assertSame('foo', $collection::unwrap('foo'));
}
@@ -2200,8 +2046,7 @@ public function testUnwrapCollectionWithScalar($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testTimesMethod($collection)
- {
+ public function testTimesMethod( $collection ) {
$two = $collection::times(2, function ($number) {
return 'slug-'.$number;
});
@@ -2226,8 +2071,7 @@ public function testTimesMethod($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testConstructMakeFromObject($collection)
- {
+ public function testConstructMakeFromObject( $collection ) {
$object = new stdClass;
$object->foo = 'bar';
$data = $collection::make($object);
@@ -2238,8 +2082,7 @@ public function testConstructMakeFromObject($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testConstructMethod($collection)
- {
+ public function testConstructMethod( $collection ) {
$data = new $collection('foo');
$this->assertEquals(['foo'], $data->all());
}
@@ -2248,8 +2091,7 @@ public function testConstructMethod($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testConstructMethodFromNull($collection)
- {
+ public function testConstructMethodFromNull( $collection ) {
$data = new $collection(null);
$this->assertEquals([], $data->all());
@@ -2261,8 +2103,7 @@ public function testConstructMethodFromNull($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testConstructMethodFromCollection($collection)
- {
+ public function testConstructMethodFromCollection( $collection ) {
$firstCollection = new $collection(['foo' => 'bar']);
$secondCollection = new $collection($firstCollection);
$this->assertEquals(['foo' => 'bar'], $secondCollection->all());
@@ -2272,8 +2113,7 @@ public function testConstructMethodFromCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testConstructMethodFromArray($collection)
- {
+ public function testConstructMethodFromArray( $collection ) {
$data = new $collection(['foo' => 'bar']);
$this->assertEquals(['foo' => 'bar'], $data->all());
}
@@ -2282,8 +2122,7 @@ public function testConstructMethodFromArray($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testConstructMethodFromObject($collection)
- {
+ public function testConstructMethodFromObject( $collection ) {
$object = new stdClass;
$object->foo = 'bar';
$data = new $collection($object);
@@ -2314,8 +2153,7 @@ public function testSplice()
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testGetPluckValueWithAccessors($collection)
- {
+ public function testGetPluckValueWithAccessors( $collection ) {
$model = new TestAccessorEloquentTestStub(['some' => 'foo']);
$modelTwo = new TestAccessorEloquentTestStub(['some' => 'bar']);
$data = new $collection([$model, $modelTwo]);
@@ -2327,8 +2165,7 @@ public function testGetPluckValueWithAccessors($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMap($collection)
- {
+ public function testMap( $collection ) {
$data = new $collection(['first' => 'taylor', 'last' => 'otwell']);
$data = $data->map(function ($item, $key) {
return $key.'-'.strrev($item);
@@ -2340,8 +2177,7 @@ public function testMap($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMapSpread($collection)
- {
+ public function testMapSpread( $collection ) {
$c = new $collection([[1, 'a'], [2, 'b']]);
$result = $c->map_spread(function ($number, $character) {
@@ -2365,8 +2201,7 @@ public function testMapSpread($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testFlatMap($collection)
- {
+ public function testFlatMap( $collection ) {
$data = new $collection([
['name' => 'taylor', 'hobbies' => ['programming', 'basketball']],
['name' => 'adam', 'hobbies' => ['music', 'powerlifting']],
@@ -2381,8 +2216,7 @@ public function testFlatMap($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMapToDictionary($collection)
- {
+ public function testMapToDictionary( $collection ) {
$data = new $collection([
['id' => 1, 'name' => 'A'],
['id' => 2, 'name' => 'B'],
@@ -2415,8 +2249,7 @@ public function testMapToDictionaryReturnFalsy() {
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMapToDictionaryWithNumericKeys($collection)
- {
+ public function testMapToDictionaryWithNumericKeys( $collection ) {
$data = new $collection([1, 2, 3, 2, 1]);
$groups = $data->map_to_dictionary(function ($item, $key) {
@@ -2430,8 +2263,7 @@ public function testMapToDictionaryWithNumericKeys($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMapToGroups($collection)
- {
+ public function testMapToGroups( $collection ) {
$data = new $collection([
['id' => 1, 'name' => 'A'],
['id' => 2, 'name' => 'B'],
@@ -2452,8 +2284,7 @@ public function testMapToGroups($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMapToGroupsWithNumericKeys($collection)
- {
+ public function testMapToGroupsWithNumericKeys( $collection ) {
$data = new $collection([1, 2, 3, 2, 1]);
$groups = $data->map_to_groups(function ($item, $key) {
@@ -2467,8 +2298,7 @@ public function testMapToGroupsWithNumericKeys($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMapWithKeys($collection)
- {
+ public function testMapWithKeys( $collection ) {
$data = new $collection([
['name' => 'Blastoise', 'type' => 'Water', 'idx' => 9],
['name' => 'Charmander', 'type' => 'Fire', 'idx' => 4],
@@ -2487,8 +2317,7 @@ public function testMapWithKeys($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMapWithKeysIntegerKeys($collection)
- {
+ public function testMapWithKeysIntegerKeys( $collection ) {
$data = new $collection([
['id' => 1, 'name' => 'A'],
['id' => 3, 'name' => 'B'],
@@ -2507,8 +2336,7 @@ public function testMapWithKeysIntegerKeys($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMapWithKeysMultipleRows($collection)
- {
+ public function testMapWithKeysMultipleRows( $collection ) {
$data = new $collection([
['id' => 1, 'name' => 'A'],
['id' => 2, 'name' => 'B'],
@@ -2534,8 +2362,7 @@ public function testMapWithKeysMultipleRows($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMapWithKeysCallbackKey($collection)
- {
+ public function testMapWithKeysCallbackKey( $collection ) {
$data = new $collection([
3 => ['id' => 1, 'name' => 'A'],
5 => ['id' => 3, 'name' => 'B'],
@@ -2554,8 +2381,7 @@ public function testMapWithKeysCallbackKey($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMapInto($collection)
- {
+ public function testMapInto( $collection ) {
$data = new $collection([
'first', 'second',
]);
@@ -2570,8 +2396,7 @@ public function testMapInto($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testNth($collection)
- {
+ public function testNth( $collection ) {
$data = new $collection([
6 => 'a',
4 => 'b',
@@ -2591,8 +2416,7 @@ public function testNth($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMapWithKeysOverwritingKeys($collection)
- {
+ public function testMapWithKeysOverwritingKeys( $collection ) {
$data = new $collection([
['id' => 1, 'name' => 'A'],
['id' => 2, 'name' => 'B'],
@@ -2623,8 +2447,7 @@ public function testTransform()
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testGroupByAttribute($collection)
- {
+ public function testGroupByAttribute( $collection ) {
$data = new $collection([['rating' => 1, 'url' => '1'], ['rating' => 1, 'url' => '1'], ['rating' => 2, 'url' => '2']]);
$result = $data->group_by('rating');
@@ -2638,8 +2461,7 @@ public function testGroupByAttribute($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testGroupByCallable($collection)
- {
+ public function testGroupByCallable( $collection ) {
$data = new $collection([['rating' => 1, 'url' => '1'], ['rating' => 1, 'url' => '1'], ['rating' => 2, 'url' => '2']]);
$result = $data->group_by([$this, 'sortByRating']);
@@ -2663,8 +2485,7 @@ public function sortByUrl(array $value)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testGroupByAttributePreservingKeys($collection)
- {
+ public function testGroupByAttributePreservingKeys( $collection ) {
$data = new $collection([10 => ['rating' => 1, 'url' => '1'], 20 => ['rating' => 1, 'url' => '1'], 30 => ['rating' => 2, 'url' => '2']]);
$result = $data->group_by('rating', true);
@@ -2681,8 +2502,7 @@ public function testGroupByAttributePreservingKeys($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testGroupByClosureWhereItemsHaveSingleGroup($collection)
- {
+ public function testGroupByClosureWhereItemsHaveSingleGroup( $collection ) {
$data = new $collection([['rating' => 1, 'url' => '1'], ['rating' => 1, 'url' => '1'], ['rating' => 2, 'url' => '2']]);
$result = $data->group_by(function ($item) {
@@ -2696,8 +2516,7 @@ public function testGroupByClosureWhereItemsHaveSingleGroup($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testGroupByClosureWhereItemsHaveSingleGroupPreservingKeys($collection)
- {
+ public function testGroupByClosureWhereItemsHaveSingleGroupPreservingKeys( $collection ) {
$data = new $collection([10 => ['rating' => 1, 'url' => '1'], 20 => ['rating' => 1, 'url' => '1'], 30 => ['rating' => 2, 'url' => '2']]);
$result = $data->group_by(function ($item) {
@@ -2716,8 +2535,7 @@ public function testGroupByClosureWhereItemsHaveSingleGroupPreservingKeys($colle
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testGroupByClosureWhereItemsHaveMultipleGroups($collection)
- {
+ public function testGroupByClosureWhereItemsHaveMultipleGroups( $collection ) {
$data = new $collection([
['user' => 1, 'roles' => ['Role_1', 'Role_3']],
['user' => 2, 'roles' => ['Role_1', 'Role_2']],
@@ -2749,8 +2567,7 @@ public function testGroupByClosureWhereItemsHaveMultipleGroups($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testGroupByClosureWhereItemsHaveMultipleGroupsPreservingKeys($collection)
- {
+ public function testGroupByClosureWhereItemsHaveMultipleGroupsPreservingKeys( $collection ) {
$data = new $collection([
10 => ['user' => 1, 'roles' => ['Role_1', 'Role_3']],
20 => ['user' => 2, 'roles' => ['Role_1', 'Role_2']],
@@ -2782,54 +2599,53 @@ public function testGroupByClosureWhereItemsHaveMultipleGroupsPreservingKeys($co
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
-// public function testGroupByMultiLevelAndClosurePreservingKeys($collection)
-// {
-// $data = new $collection([
-// 10 => ['user' => 1, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_3']],
-// 20 => ['user' => 2, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_2']],
-// 30 => ['user' => 3, 'skilllevel' => 2, 'roles' => ['Role_1']],
-// 40 => ['user' => 4, 'skilllevel' => 2, 'roles' => ['Role_2']],
-// ]);
-//
-// $result = $data->group_by([
-// 'skilllevel',
-// function ($item) {
-// return $item['roles'];
-// },
-// ], true);
-//
-// $expected_result = [
-// 1 => [
-// 'Role_1' => [
-// 10 => ['user' => 1, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_3']],
-// 20 => ['user' => 2, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_2']],
-// ],
-// 'Role_3' => [
-// 10 => ['user' => 1, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_3']],
-// ],
-// 'Role_2' => [
-// 20 => ['user' => 2, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_2']],
-// ],
-// ],
-// 2 => [
-// 'Role_1' => [
-// 30 => ['user' => 3, 'skilllevel' => 2, 'roles' => ['Role_1']],
-// ],
-// 'Role_2' => [
-// 40 => ['user' => 4, 'skilllevel' => 2, 'roles' => ['Role_2']],
-// ],
-// ],
-// ];
-//
-// $this->assertEquals($expected_result, $result->to_array());
-// }
-
- /**
- * @dataProvider collectionClassProvider
- */
- #[DataProvider( 'collectionClassProvider' )]
- public function testKeyByAttribute($collection)
+ public function testGroupByMultiLevelAndClosurePreservingKeys($collection)
{
+ $data = new $collection([
+ 10 => ['user' => 1, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_3']],
+ 20 => ['user' => 2, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_2']],
+ 30 => ['user' => 3, 'skilllevel' => 2, 'roles' => ['Role_1']],
+ 40 => ['user' => 4, 'skilllevel' => 2, 'roles' => ['Role_2']],
+ ]);
+
+ $result = $data->group_by([
+ 'skilllevel',
+ function ($item) {
+ return $item['roles'];
+ },
+ ], true);
+
+ $expected_result = [
+ 1 => [
+ 'Role_1' => [
+ 10 => ['user' => 1, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_3']],
+ 20 => ['user' => 2, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_2']],
+ ],
+ 'Role_3' => [
+ 10 => ['user' => 1, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_3']],
+ ],
+ 'Role_2' => [
+ 20 => ['user' => 2, 'skilllevel' => 1, 'roles' => ['Role_1', 'Role_2']],
+ ],
+ ],
+ 2 => [
+ 'Role_1' => [
+ 30 => ['user' => 3, 'skilllevel' => 2, 'roles' => ['Role_1']],
+ ],
+ 'Role_2' => [
+ 40 => ['user' => 4, 'skilllevel' => 2, 'roles' => ['Role_2']],
+ ],
+ ],
+ ];
+
+ $this->assertEquals($expected_result, $result->to_array());
+ }
+
+ /**
+ * @dataProvider collectionClassProvider
+ */
+ #[DataProvider( 'collectionClassProvider' )]
+ public function testKeyByAttribute( $collection ) {
$data = new $collection([['rating' => 1, 'name' => '1'], ['rating' => 2, 'name' => '2'], ['rating' => 3, 'name' => '3']]);
$result = $data->key_by('rating');
@@ -2845,8 +2661,7 @@ public function testKeyByAttribute($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testKeyByClosure($collection)
- {
+ public function testKeyByClosure( $collection ) {
$data = new $collection([
['firstname' => 'Taylor', 'lastname' => 'Otwell', 'locale' => 'US'],
['firstname' => 'Lucas', 'lastname' => 'Michot', 'locale' => 'FR'],
@@ -2864,13 +2679,12 @@ public function testKeyByClosure($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testKeyByObject($collection)
- {
+ public function testKeyByObject( $collection ) {
$data = new $collection([
['firstname' => 'Taylor', 'lastname' => 'Otwell', 'locale' => 'US'],
['firstname' => 'Lucas', 'lastname' => 'Michot', 'locale' => 'FR'],
]);
- $result = $data->key_by(function ($item, $key) use ($collection) {
+ $result = $data->key_by(function ($item, $key) use ( $collection ) {
return new $collection([$key, $item['firstname'], $item['lastname']]);
});
$this->assertEquals([
@@ -2883,112 +2697,111 @@ public function testKeyByObject($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
-// public function testContains($collection)
-// {
-// $c = new $collection([1, 3, 5]);
-//
-// $this->assertTrue($c->contains(1));
-// $this->assertTrue($c->contains('1'));
-// $this->assertFalse($c->contains(2));
-// $this->assertFalse($c->contains('2'));
-//
-// $c = new $collection(['1']);
-// $this->assertTrue($c->contains('1'));
-// $this->assertTrue($c->contains(1));
-//
-// $c = new $collection([null]);
-// $this->assertTrue($c->contains(false));
-// $this->assertTrue($c->contains(null));
-// $this->assertTrue($c->contains([]));
-// $this->assertTrue($c->contains(0));
-// $this->assertTrue($c->contains(''));
-//
-// $c = new $collection([0]);
-// $this->assertTrue($c->contains(0));
-// $this->assertTrue($c->contains('0'));
-// $this->assertTrue($c->contains(false));
-// $this->assertTrue($c->contains(null));
-//
-// $this->assertTrue($c->contains(function ($value) {
-// return $value < 5;
-// }));
-// $this->assertFalse($c->contains(function ($value) {
-// return $value > 5;
-// }));
-//
-// $c = new $collection([['v' => 1], ['v' => 3], ['v' => 5]]);
-//
-// $this->assertTrue($c->contains('v', 1));
-// $this->assertFalse($c->contains('v', 2));
-//
-// $c = new $collection(['date', 'class', (object) ['foo' => 50]]);
-//
-// $this->assertTrue($c->contains('date'));
-// $this->assertTrue($c->contains('class'));
-// $this->assertFalse($c->contains('foo'));
-//
-// $c = new $collection([['a' => false, 'b' => false], ['a' => true, 'b' => false]]);
-//
-// $this->assertTrue($c->contains->a);
-// $this->assertFalse($c->contains->b);
-//
-// $c = new $collection([
-// null, 1, 2,
-// ]);
-//
-// $this->assertTrue($c->contains(function ($value) {
-// return is_null($value);
-// }));
-// }
-
- /**
- * @dataProvider collectionClassProvider
- */
- #[DataProvider( 'collectionClassProvider' )]
-// public function testSome($collection)
-// {
-// $c = new $collection([1, 3, 5]);
-//
-// $this->assertTrue($c->some(1));
-// $this->assertFalse($c->some(2));
-// $this->assertTrue($c->some(function ($value) {
-// return $value < 5;
-// }));
-// $this->assertFalse($c->some(function ($value) {
-// return $value > 5;
-// }));
-//
-// $c = new $collection([['v' => 1], ['v' => 3], ['v' => 5]]);
-//
-// $this->assertTrue($c->some('v', 1));
-// $this->assertFalse($c->some('v', 2));
-//
-// $c = new $collection(['date', 'class', (object) ['foo' => 50]]);
-//
-// $this->assertTrue($c->some('date'));
-// $this->assertTrue($c->some('class'));
-// $this->assertFalse($c->some('foo'));
-//
-// $c = new $collection([['a' => false, 'b' => false], ['a' => true, 'b' => false]]);
-//
-// $this->assertTrue($c->some->a);
-// $this->assertFalse($c->some->b);
-//
-// $c = new $collection([
-// null, 1, 2,
-// ]);
-//
-// $this->assertTrue($c->some(function ($value) {
-// return is_null($value);
-// }));
-// }
-
- /**
- * @dataProvider collectionClassProvider
- */
- #[DataProvider( 'collectionClassProvider' )]
- public function testContainsStrict($collection)
+ public function testContains($collection)
+ {
+ $c = new $collection([1, 3, 5]);
+
+ $this->assertTrue($c->contains(1));
+ $this->assertTrue($c->contains('1'));
+ $this->assertFalse($c->contains(2));
+ $this->assertFalse($c->contains('2'));
+
+ $c = new $collection(['1']);
+ $this->assertTrue($c->contains('1'));
+ $this->assertTrue($c->contains(1));
+
+ $c = new $collection([null]);
+ $this->assertTrue($c->contains(false));
+ $this->assertTrue($c->contains(null));
+ $this->assertTrue($c->contains([]));
+ $this->assertTrue($c->contains(0));
+ $this->assertTrue($c->contains(''));
+
+ $c = new $collection([0]);
+ $this->assertTrue($c->contains(0));
+ $this->assertTrue($c->contains('0'));
+ $this->assertTrue($c->contains(false));
+ $this->assertTrue($c->contains(null));
+
+ $this->assertTrue($c->contains(function ($value) {
+ return $value < 5;
+ }));
+ $this->assertFalse($c->contains(function ($value) {
+ return $value > 5;
+ }));
+
+ $c = new $collection([['v' => 1], ['v' => 3], ['v' => 5]]);
+
+ $this->assertTrue($c->contains('v', 1));
+ $this->assertFalse($c->contains('v', 2));
+
+ $c = new $collection(['date', 'class', (object) ['foo' => 50]]);
+
+ $this->assertTrue($c->contains('date'));
+ $this->assertTrue($c->contains('class'));
+ $this->assertFalse($c->contains('foo'));
+
+ $c = new $collection([['a' => false, 'b' => false], ['a' => true, 'b' => false]]);
+
+ $this->assertTrue($c->contains->a);
+ $this->assertFalse($c->contains->b);
+
+ $c = new $collection([
+ null, 1, 2,
+ ]);
+
+ $this->assertTrue($c->contains(function ($value) {
+ return is_null($value);
+ }));
+ }
+
+ /**
+ * @dataProvider collectionClassProvider
+ */
+ #[DataProvider( 'collectionClassProvider' )]
+ public function testSome($collection)
{
+ $c = new $collection([1, 3, 5]);
+
+ $this->assertTrue($c->some(1));
+ $this->assertFalse($c->some(2));
+ $this->assertTrue($c->some(function ($value) {
+ return $value < 5;
+ }));
+ $this->assertFalse($c->some(function ($value) {
+ return $value > 5;
+ }));
+
+ $c = new $collection([['v' => 1], ['v' => 3], ['v' => 5]]);
+
+ $this->assertTrue($c->some('v', 1));
+ $this->assertFalse($c->some('v', 2));
+
+ $c = new $collection(['date', 'class', (object) ['foo' => 50]]);
+
+ $this->assertTrue($c->some('date'));
+ $this->assertTrue($c->some('class'));
+ $this->assertFalse($c->some('foo'));
+
+ $c = new $collection([['a' => false, 'b' => false], ['a' => true, 'b' => false]]);
+
+ $this->assertTrue($c->some->a);
+ $this->assertFalse($c->some->b);
+
+ $c = new $collection([
+ null, 1, 2,
+ ]);
+
+ $this->assertTrue($c->some(function ($value) {
+ return is_null($value);
+ }));
+ }
+
+ /**
+ * @dataProvider collectionClassProvider
+ */
+ #[DataProvider( 'collectionClassProvider' )]
+ public function testContainsStrict( $collection ) {
$c = new $collection([1, 3, 5, '02']);
$this->assertTrue($c->contains_strict(1));
@@ -3036,10 +2849,15 @@ public function testContainsStrict($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testContainsWithOperator($collection)
- {
+ public function testContainsWithOperator( $collection ) {
$c = new $collection([['v' => 1], ['v' => 3], ['v' => '4'], ['v' => 5]]);
+ // Stict comparisons.
+ $this->assertTrue($c->contains('v', '4'));
+ $this->assertTrue($c->contains('v', '=', '4'));
+
+ // Loose comparisons.
+ $this->assertTrue($c->contains('v', 4));
$this->assertTrue($c->contains('v', '=', 4));
$this->assertTrue($c->contains('v', '==', 4));
$this->assertFalse($c->contains('v', '===', 4));
@@ -3050,8 +2868,7 @@ public function testContainsWithOperator($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testGettingSumFromCollection($collection)
- {
+ public function testGettingSumFromCollection( $collection ) {
$c = new $collection([(object) ['foo' => 50], (object) ['foo' => 50]]);
$this->assertEquals(100, $c->sum('foo'));
@@ -3065,8 +2882,7 @@ public function testGettingSumFromCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testCanSumValuesWithoutACallback($collection)
- {
+ public function testCanSumValuesWithoutACallback( $collection ) {
$c = new $collection([1, 2, 3, 4, 5]);
$this->assertEquals(15, $c->sum());
}
@@ -3075,8 +2891,7 @@ public function testCanSumValuesWithoutACallback($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testGettingSumFromEmptyCollection($collection)
- {
+ public function testGettingSumFromEmptyCollection( $collection ) {
$c = new $collection;
$this->assertEquals(0, $c->sum('foo'));
}
@@ -3085,8 +2900,7 @@ public function testGettingSumFromEmptyCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testValueRetrieverAcceptsDotNotation($collection)
- {
+ public function testValueRetrieverAcceptsDotNotation( $collection ) {
$c = new $collection([
(object) ['id' => 1, 'foo' => ['bar' => 'B']], (object) ['id' => 2, 'foo' => ['bar' => 'A']],
]);
@@ -3120,8 +2934,7 @@ public function testPullReturnsDefault()
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testRejectRemovesElementsPassingTruthTest($collection)
- {
+ public function testRejectRemovesElementsPassingTruthTest( $collection ) {
$c = new $collection(['foo', 'bar']);
$this->assertEquals(['foo'], $c->reject('bar')->values()->all());
@@ -3151,8 +2964,7 @@ public function testRejectRemovesElementsPassingTruthTest($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testRejectWithoutAnArgumentRemovesTruthyValues($collection)
- {
+ public function testRejectWithoutAnArgumentRemovesTruthyValues( $collection ) {
$data1 = new $collection([
false,
true,
@@ -3175,8 +2987,7 @@ public function testRejectWithoutAnArgumentRemovesTruthyValues($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSearchReturnsIndexOfFirstFoundItem($collection)
- {
+ public function testSearchReturnsIndexOfFirstFoundItem( $collection ) {
$c = new $collection([1, 2, 3, 4, 5, 2, 5, 'foo' => 'bar']);
$this->assertEquals(1, $c->search(2));
@@ -3194,8 +3005,7 @@ public function testSearchReturnsIndexOfFirstFoundItem($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSearchInStrictMode($collection)
- {
+ public function testSearchInStrictMode( $collection ) {
$c = new $collection([false, 0, 1, [], '']);
$this->assertFalse($c->search('false', true));
$this->assertFalse($c->search('1', true));
@@ -3210,8 +3020,7 @@ public function testSearchInStrictMode($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSearchReturnsFalseWhenItemIsNotFound($collection)
- {
+ public function testSearchReturnsFalseWhenItemIsNotFound( $collection ) {
$c = new $collection([1, 2, 3, 4, 5, 'foo' => 'bar']);
$this->assertFalse($c->search(6));
@@ -3228,8 +3037,7 @@ public function testSearchReturnsFalseWhenItemIsNotFound($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testKeys($collection)
- {
+ public function testKeys( $collection ) {
$c = new $collection(['name' => 'taylor', 'framework' => 'laravel']);
$this->assertEquals(['name', 'framework'], $c->keys()->all());
}
@@ -3238,8 +3046,7 @@ public function testKeys($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testPaginate($collection)
- {
+ public function testPaginate( $collection ) {
$c = new $collection(['one', 'two', 'three', 'four']);
$this->assertEquals(['one', 'two'], $c->for_page(0, 2)->all());
$this->assertEquals(['one', 'two'], $c->for_page(1, 2)->all());
@@ -3275,38 +3082,37 @@ public function testPushWithOneItem()
$this->assertSame($expected, $actual);
}
-// public function testPushWithMultipleItems()
-// {
-// $expected = [
-// 0 => 4,
-// 1 => 5,
-// 2 => 6,
-// 3 => 'Jonny',
-// 4 => 'from',
-// 5 => 'Laroe',
-// 6 => 'Jonny',
-// 7 => 'from',
-// 8 => 'Laroe',
-// 9 => 'a',
-// 10 => 'b',
-// 11 => 'c',
-// ];
-//
-// $data = new Collection([4, 5, 6]);
-// $data->push('Jonny', 'from', 'Laroe');
-// $data->push(...[11 => 'Jonny', 12 => 'from', 13 => 'Laroe']);
-// $data->push(...collect(['a', 'b', 'c']));
-// $actual = $data->push(...[])->to_array();
-//
-// $this->assertSame($expected, $actual);
-// }
-
- /**
- * @dataProvider collectionClassProvider
- */
- #[DataProvider( 'collectionClassProvider' )]
- public function testZip($collection)
+ public function testPushWithMultipleItems()
{
+ $expected = [
+ 0 => 4,
+ 1 => 5,
+ 2 => 6,
+ 3 => 'Jonny',
+ 4 => 'from',
+ 5 => 'Laroe',
+ 6 => 'Jonny',
+ 7 => 'from',
+ 8 => 'Laroe',
+ 9 => 'a',
+ 10 => 'b',
+ 11 => 'c',
+ ];
+
+ $data = new Collection([4, 5, 6]);
+ $data->push('Jonny', 'from', 'Laroe');
+ $data->push(...[11 => 'Jonny', 12 => 'from', 13 => 'Laroe']);
+ $data->push(...collect(['a', 'b', 'c']));
+ $actual = $data->push(...[])->to_array();
+
+ $this->assertSame($expected, $actual);
+ }
+
+ /**
+ * @dataProvider collectionClassProvider
+ */
+ #[DataProvider( 'collectionClassProvider' )]
+ public function testZip( $collection ) {
$c = new $collection([1, 2, 3]);
$c = $c->zip(new $collection([4, 5, 6]));
$this->assertInstanceOf($collection, $c);
@@ -3337,8 +3143,7 @@ public function testZip($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testPadPadsArrayWithValue($collection)
- {
+ public function testPadPadsArrayWithValue( $collection ) {
$c = new $collection([1, 2, 3]);
$c = $c->pad(4, 0);
$this->assertEquals([1, 2, 3, 0], $c->all());
@@ -3360,8 +3165,7 @@ public function testPadPadsArrayWithValue($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testGettingMaxItemsFromCollection($collection)
- {
+ public function testGettingMaxItemsFromCollection( $collection ) {
$c = new $collection([(object) ['foo' => 10], (object) ['foo' => 20]]);
$this->assertEquals(20, $c->max(function ($item) {
return $item->foo;
@@ -3384,8 +3188,7 @@ public function testGettingMaxItemsFromCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testGettingMinItemsFromCollection($collection)
- {
+ public function testGettingMinItemsFromCollection( $collection ) {
$c = new $collection([(object) ['foo' => 10], (object) ['foo' => 20]]);
$this->assertEquals(10, $c->min(function ($item) {
return $item->foo;
@@ -3418,8 +3221,7 @@ public function testGettingMinItemsFromCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testOnly($collection)
- {
+ public function testOnly( $collection ) {
$data = new $collection( [
'first' => 'Taylor',
'last' => 'Otwell',
@@ -3436,12 +3238,9 @@ public function testOnly($collection)
$this->assertEquals( [ 'first' => 'Taylor', 'email' => 'taylorotwell@gmail.com' ], $data->only( collect( [ 'first', 'email' ] ) )->all() );
}
- /**
- * @dataProvider collectionClassProvider
- */
- #[DataProvider( 'collectionClassProvider' )]
- public function testOnlyChildren($collection)
- {
+ public function testOnlyChildren() {
+ $collection = Collection::class;
+
$data = new $collection( [
[
'first' => 'Taylor',
@@ -3496,8 +3295,7 @@ public function testOnlyChildren($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testGettingAvgItemsFromCollection($collection)
- {
+ public function testGettingAvgItemsFromCollection( $collection ) {
$c = new $collection([(object) ['foo' => 10], (object) ['foo' => 20]]);
$this->assertEquals(15, $c->avg(function ($item) {
return $item->foo;
@@ -3527,8 +3325,7 @@ public function testGettingAvgItemsFromCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testJsonSerialize($collection)
- {
+ public function testJsonSerialize( $collection ) {
$c = new $collection([
new TestArrayableObject,
new TestJsonableObject,
@@ -3548,8 +3345,7 @@ public function testJsonSerialize($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testCombineWithArray($collection)
- {
+ public function testCombineWithArray( $collection ) {
$expected = [
1 => 4,
2 => 5,
@@ -3566,8 +3362,7 @@ public function testCombineWithArray($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testCombineWithCollection($collection)
- {
+ public function testCombineWithCollection( $collection ) {
$expected = [
1 => 4,
2 => 5,
@@ -3585,8 +3380,7 @@ public function testCombineWithCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testConcatWithArray($collection)
- {
+ public function testConcatWithArray( $collection ) {
$expected = [
0 => 4,
1 => 5,
@@ -3614,8 +3408,7 @@ public function testConcatWithArray($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testConcatWithCollection($collection)
- {
+ public function testConcatWithCollection( $collection ) {
$expected = [
0 => 4,
1 => 5,
@@ -3645,8 +3438,7 @@ public function testConcatWithCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testReduce($collection)
- {
+ public function testReduce( $collection ) {
$data = new $collection([1, 2, 3]);
$this->assertEquals(6, $data->reduce(function ($carry, $element) {
return $carry += $element;
@@ -3657,8 +3449,7 @@ public function testReduce($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testRandomThrowsAnExceptionUsingAmountBiggerThanCollectionSize($collection)
- {
+ public function testRandomThrowsAnExceptionUsingAmountBiggerThanCollectionSize( $collection ) {
$this->expectException(InvalidArgumentException::class);
$data = new $collection([1, 2, 3]);
@@ -3669,8 +3460,7 @@ public function testRandomThrowsAnExceptionUsingAmountBiggerThanCollectionSize($
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testPipe($collection)
- {
+ public function testPipe( $collection ) {
$data = new $collection([1, 2, 3]);
$this->assertEquals(6, $data->pipe(function ($data) {
@@ -3682,8 +3472,7 @@ public function testPipe($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMedianValueWithArrayCollection($collection)
- {
+ public function testMedianValueWithArrayCollection( $collection ) {
$data = new $collection([1, 2, 2, 4]);
$this->assertEquals(2, $data->median());
@@ -3693,8 +3482,7 @@ public function testMedianValueWithArrayCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMedianValueByKey($collection)
- {
+ public function testMedianValueByKey( $collection ) {
$data = new $collection([
(object) ['foo' => 1],
(object) ['foo' => 2],
@@ -3708,8 +3496,7 @@ public function testMedianValueByKey($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMedianOnCollectionWithNull($collection)
- {
+ public function testMedianOnCollectionWithNull( $collection ) {
$data = new $collection([
(object) ['foo' => 1],
(object) ['foo' => 2],
@@ -3723,8 +3510,7 @@ public function testMedianOnCollectionWithNull($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testEvenMedianCollection($collection)
- {
+ public function testEvenMedianCollection( $collection ) {
$data = new $collection([
(object) ['foo' => 0],
(object) ['foo' => 3],
@@ -3736,8 +3522,7 @@ public function testEvenMedianCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMedianOutOfOrderCollection($collection)
- {
+ public function testMedianOutOfOrderCollection( $collection ) {
$data = new $collection([
(object) ['foo' => 0],
(object) ['foo' => 5],
@@ -3750,8 +3535,7 @@ public function testMedianOutOfOrderCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMedianOnEmptyCollectionReturnsNull($collection)
- {
+ public function testMedianOnEmptyCollectionReturnsNull( $collection ) {
$data = new $collection;
$this->assertNull($data->median());
}
@@ -3760,8 +3544,7 @@ public function testMedianOnEmptyCollectionReturnsNull($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testModeOnNullCollection($collection)
- {
+ public function testModeOnNullCollection( $collection ) {
$data = new $collection;
$this->assertNull($data->mode());
}
@@ -3770,8 +3553,7 @@ public function testModeOnNullCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testMode($collection)
- {
+ public function testMode( $collection ) {
$data = new $collection([1, 2, 3, 4, 4, 5]);
$this->assertEquals([4], $data->mode());
}
@@ -3780,8 +3562,7 @@ public function testMode($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testModeValueByKey($collection)
- {
+ public function testModeValueByKey( $collection ) {
$data = new $collection([
(object) ['foo' => 1],
(object) ['foo' => 1],
@@ -3795,8 +3576,7 @@ public function testModeValueByKey($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWithMultipleModeValues($collection)
- {
+ public function testWithMultipleModeValues( $collection ) {
$data = new $collection([1, 2, 2, 1]);
$this->assertEquals([1, 2], $data->mode());
}
@@ -3805,8 +3585,7 @@ public function testWithMultipleModeValues($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSliceOffset($collection)
- {
+ public function testSliceOffset( $collection ) {
$data = new $collection([1, 2, 3, 4, 5, 6, 7, 8]);
$this->assertEquals([4, 5, 6, 7, 8], $data->slice(3)->values()->to_array());
}
@@ -3815,8 +3594,7 @@ public function testSliceOffset($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSliceNegativeOffset($collection)
- {
+ public function testSliceNegativeOffset( $collection ) {
$data = new $collection([1, 2, 3, 4, 5, 6, 7, 8]);
$this->assertEquals([6, 7, 8], $data->slice(-3)->values()->to_array());
}
@@ -3825,8 +3603,7 @@ public function testSliceNegativeOffset($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSliceOffsetAndLength($collection)
- {
+ public function testSliceOffsetAndLength( $collection ) {
$data = new $collection([1, 2, 3, 4, 5, 6, 7, 8]);
$this->assertEquals([4, 5, 6], $data->slice(3, 3)->values()->to_array());
}
@@ -3835,8 +3612,7 @@ public function testSliceOffsetAndLength($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSliceOffsetAndNegativeLength($collection)
- {
+ public function testSliceOffsetAndNegativeLength( $collection ) {
$data = new $collection([1, 2, 3, 4, 5, 6, 7, 8]);
$this->assertEquals([4, 5, 6, 7], $data->slice(3, -1)->values()->to_array());
}
@@ -3845,8 +3621,7 @@ public function testSliceOffsetAndNegativeLength($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSliceNegativeOffsetAndLength($collection)
- {
+ public function testSliceNegativeOffsetAndLength( $collection ) {
$data = new $collection([1, 2, 3, 4, 5, 6, 7, 8]);
$this->assertEquals([4, 5, 6], $data->slice(-5, 3)->values()->to_array());
}
@@ -3855,8 +3630,7 @@ public function testSliceNegativeOffsetAndLength($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSliceNegativeOffsetAndNegativeLength($collection)
- {
+ public function testSliceNegativeOffsetAndNegativeLength( $collection ) {
$data = new $collection([1, 2, 3, 4, 5, 6, 7, 8]);
$this->assertEquals([3, 4, 5, 6], $data->slice(-6, -2)->values()->to_array());
}
@@ -3865,8 +3639,7 @@ public function testSliceNegativeOffsetAndNegativeLength($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testCollectionFromTraversable($collection)
- {
+ public function testCollectionFromTraversable( $collection ) {
$data = new $collection(new ArrayObject([1, 2, 3]));
$this->assertEquals([1, 2, 3], $data->to_array());
}
@@ -3875,8 +3648,7 @@ public function testCollectionFromTraversable($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testCollectionFromTraversableWithKeys($collection)
- {
+ public function testCollectionFromTraversableWithKeys( $collection ) {
$data = new $collection(new ArrayObject(['foo' => 1, 'bar' => 2, 'baz' => 3]));
$this->assertEquals(['foo' => 1, 'bar' => 2, 'baz' => 3], $data->to_array());
}
@@ -3885,8 +3657,7 @@ public function testCollectionFromTraversableWithKeys($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSplitCollectionWithADivisibleCount($collection)
- {
+ public function testSplitCollectionWithADivisibleCount( $collection ) {
$data = new $collection(['a', 'b', 'c', 'd']);
$this->assertEquals(
@@ -3910,8 +3681,7 @@ public function testSplitCollectionWithADivisibleCount($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSplitCollectionWithAnUndivisableCount($collection)
- {
+ public function testSplitCollectionWithAnUndivisableCount( $collection ) {
$data = new $collection(['a', 'b', 'c']);
$this->assertEquals(
@@ -3926,8 +3696,7 @@ public function testSplitCollectionWithAnUndivisableCount($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSplitCollectionWithCountLessThenDivisor($collection)
- {
+ public function testSplitCollectionWithCountLessThenDivisor( $collection ) {
$data = new $collection(['a']);
$this->assertEquals(
@@ -3942,8 +3711,7 @@ public function testSplitCollectionWithCountLessThenDivisor($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSplitCollectionIntoThreeWithCountOfFour($collection)
- {
+ public function testSplitCollectionIntoThreeWithCountOfFour( $collection ) {
$data = new $collection(['a', 'b', 'c', 'd']);
$this->assertEquals(
@@ -3958,8 +3726,7 @@ public function testSplitCollectionIntoThreeWithCountOfFour($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSplitCollectionIntoThreeWithCountOfFive($collection)
- {
+ public function testSplitCollectionIntoThreeWithCountOfFive( $collection ) {
$data = new $collection(['a', 'b', 'c', 'd', 'e']);
$this->assertEquals(
@@ -3974,8 +3741,7 @@ public function testSplitCollectionIntoThreeWithCountOfFive($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSplitCollectionIntoSixWithCountOfTen($collection)
- {
+ public function testSplitCollectionIntoSixWithCountOfTen( $collection ) {
$data = new $collection(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']);
$this->assertEquals(
@@ -3990,8 +3756,7 @@ public function testSplitCollectionIntoSixWithCountOfTen($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testSplitEmptyCollection($collection)
- {
+ public function testSplitEmptyCollection( $collection ) {
$data = new $collection;
$this->assertEquals(
@@ -4006,8 +3771,7 @@ public function testSplitEmptyCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testHigherOrderCollectionGroupBy($collection)
- {
+ public function testHigherOrderCollectionGroupBy( $collection ) {
$data = new $collection([
new TestSupportCollectionHigherOrderItem,
new TestSupportCollectionHigherOrderItem('TAYLOR'),
@@ -4030,8 +3794,7 @@ public function testHigherOrderCollectionGroupBy($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testHigherOrderCollectionMap($collection)
- {
+ public function testHigherOrderCollectionMap( $collection ) {
$person1 = (object) ['name' => 'Taylor'];
$person2 = (object) ['name' => 'Yaz'];
@@ -4048,8 +3811,7 @@ public function testHigherOrderCollectionMap($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testHigherOrderCollectionMapFromArrays($collection)
- {
+ public function testHigherOrderCollectionMapFromArrays( $collection ) {
$person1 = ['name' => 'Taylor'];
$person2 = ['name' => 'Yaz'];
@@ -4066,8 +3828,7 @@ public function testHigherOrderCollectionMapFromArrays($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testPartition($collection)
- {
+ public function testPartition( $collection ) {
$data = new $collection(range(1, 10));
[$firstPartition, $secondPartition] = $data->partition(function ($i) {
@@ -4082,8 +3843,7 @@ public function testPartition($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testPartitionCallbackWithKey($collection)
- {
+ public function testPartitionCallbackWithKey( $collection ) {
$data = new $collection(['zero', 'one', 'two', 'three']);
[$even, $odd] = $data->partition(function ($item, $index) {
@@ -4098,8 +3858,7 @@ public function testPartitionCallbackWithKey($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testPartitionByKey($collection)
- {
+ public function testPartitionByKey( $collection ) {
$courses = new $collection([
['free' => true, 'title' => 'Basic'], ['free' => false, 'title' => 'Premium'],
]);
@@ -4114,8 +3873,7 @@ public function testPartitionByKey($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testPartitionWithOperators($collection)
- {
+ public function testPartitionWithOperators( $collection ) {
$data = new $collection([
['name' => 'Tim', 'age' => 17],
['name' => 'Agatha', 'age' => 62],
@@ -4152,8 +3910,7 @@ public function testPartitionWithOperators($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testPartitionPreservesKeys($collection)
- {
+ public function testPartitionPreservesKeys( $collection ) {
$courses = new $collection([
'a' => ['free' => true], 'b' => ['free' => false], 'c' => ['free' => true],
]);
@@ -4168,8 +3925,7 @@ public function testPartitionPreservesKeys($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testPartitionEmptyCollection($collection)
- {
+ public function testPartitionEmptyCollection( $collection ) {
$data = new $collection;
$this->assertCount(2, $data->partition(function () {
@@ -4181,25 +3937,24 @@ public function testPartitionEmptyCollection($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
-// public function testHigherOrderPartition($collection)
-// {
-// $courses = new $collection([
-// 'a' => ['free' => true], 'b' => ['free' => false], 'c' => ['free' => true],
-// ]);
-//
-// [$free, $premium] = $courses->partition->free->all();
-//
-// $this->assertSame(['a' => ['free' => true], 'c' => ['free' => true]], $free->to_array());
-//
-// $this->assertSame(['b' => ['free' => false]], $premium->to_array());
-// }
+ public function testHigherOrderPartition($collection)
+ {
+ $courses = new $collection([
+ 'a' => ['free' => true], 'b' => ['free' => false], 'c' => ['free' => true],
+ ]);
+
+ [$free, $premium] = $courses->partition->free->all();
+
+ $this->assertSame(['a' => ['free' => true], 'c' => ['free' => true]], $free->to_array());
+
+ $this->assertSame(['b' => ['free' => false]], $premium->to_array());
+ }
/**
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testTap($collection)
- {
+ public function testTap( $collection ) {
$data = new $collection([1, 2, 3]);
$fromTap = [];
@@ -4215,8 +3970,7 @@ public function testTap($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWhen($collection)
- {
+ public function testWhen( $collection ) {
$data = new $collection(['michael', 'tom']);
$data = $data->when('adam', function ($data, $newName) {
@@ -4238,8 +3992,7 @@ public function testWhen($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWhenDefault($collection)
- {
+ public function testWhenDefault( $collection ) {
$data = new $collection(['michael', 'tom']);
$data = $data->when(false, function ($data) {
@@ -4255,12 +4008,11 @@ public function testWhenDefault($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWhenEmpty($collection)
- {
+ public function testWhenEmpty( $collection ) {
$data = new $collection(['michael', 'tom']);
- $data = $data->when_empty(function ($collection) {
- return $data->concat(['adam']);
+ $data = $data->when_empty(function ( $collection ) {
+ throw new Exception('whenEmpty() should not trigger on a collection with items');
});
$this->assertSame(['michael', 'tom'], $data->to_array());
@@ -4278,8 +4030,7 @@ public function testWhenEmpty($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWhenEmptyDefault($collection)
- {
+ public function testWhenEmptyDefault( $collection ) {
$data = new $collection(['michael', 'tom']);
$data = $data->when_empty(function ($data) {
@@ -4295,8 +4046,7 @@ public function testWhenEmptyDefault($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWhenNotEmpty($collection)
- {
+ public function testWhenNotEmpty( $collection ) {
$data = new $collection(['michael', 'tom']);
$data = $data->when_not_empty(function ($data) {
@@ -4318,8 +4068,7 @@ public function testWhenNotEmpty($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWhenNotEmptyDefault($collection)
- {
+ public function testWhenNotEmptyDefault( $collection ) {
$data = new $collection(['michael', 'tom']);
$data = $data->when_not_empty(function ($data) {
@@ -4335,8 +4084,7 @@ public function testWhenNotEmptyDefault($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testUnless($collection)
- {
+ public function testUnless( $collection ) {
$data = new $collection(['michael', 'tom']);
$data = $data->unless(false, function ($data) {
@@ -4358,8 +4106,7 @@ public function testUnless($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testUnlessDefault($collection)
- {
+ public function testUnlessDefault( $collection ) {
$data = new $collection(['michael', 'tom']);
$data = $data->unless(true, function ($data) {
@@ -4375,8 +4122,7 @@ public function testUnlessDefault($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testUnlessEmpty($collection)
- {
+ public function testUnlessEmpty( $collection ) {
$data = new $collection(['michael', 'tom']);
$data = $data->unless_empty(function ($data) {
@@ -4398,8 +4144,7 @@ public function testUnlessEmpty($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testUnlessEmptyDefault($collection)
- {
+ public function testUnlessEmptyDefault( $collection ) {
$data = new $collection(['michael', 'tom']);
$data = $data->unless_empty(function ($data) {
@@ -4415,8 +4160,7 @@ public function testUnlessEmptyDefault($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testUnlessNotEmpty($collection)
- {
+ public function testUnlessNotEmpty( $collection ) {
$data = new $collection(['michael', 'tom']);
$data = $data->unless_not_empty(function ($data) {
@@ -4438,8 +4182,7 @@ public function testUnlessNotEmpty($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testUnlessNotEmptyDefault($collection)
- {
+ public function testUnlessNotEmptyDefault( $collection ) {
$data = new $collection(['michael', 'tom']);
$data = $data->unless_not_empty(function ($data) {
@@ -4455,8 +4198,7 @@ public function testUnlessNotEmptyDefault($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testHasReturnsValidResults($collection)
- {
+ public function testHasReturnsValidResults( $collection ) {
$data = new $collection(['foo' => 'one', 'bar' => 'two', 1 => 'three']);
$this->assertTrue($data->has('foo'));
$this->assertTrue($data->has('foo', 'bar', 1));
@@ -4480,8 +4222,7 @@ public function testPutAddsItemToCollection()
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testItThrowsExceptionWhenTryingToAccessNoProxyProperty($collection)
- {
+ public function testItThrowsExceptionWhenTryingToAccessNoProxyProperty( $collection ) {
$data = new $collection;
$this->expectException(Exception::class);
$this->expectExceptionMessage('Property [foo] does not exist on this collection instance.');
@@ -4492,8 +4233,7 @@ public function testItThrowsExceptionWhenTryingToAccessNoProxyProperty($collecti
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testGetWithNullReturnsNull($collection)
- {
+ public function testGetWithNullReturnsNull( $collection ) {
$data = new $collection([1, 2, 3]);
$this->assertNull($data->get(null));
}
@@ -4502,8 +4242,7 @@ public function testGetWithNullReturnsNull($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWhereNull($collection)
- {
+ public function testWhereNull( $collection ) {
$data = new $collection([
['name' => 'Taylor'],
['name' => null],
@@ -4523,8 +4262,7 @@ public function testWhereNull($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWhereNullWithoutKey($collection)
- {
+ public function testWhereNullWithoutKey( $collection ) {
$collection = new $collection([1, null, 3, 'null', false, true]);
$this->assertSame([
1 => null,
@@ -4535,8 +4273,7 @@ public function testWhereNullWithoutKey($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWhereNotNull($collection)
- {
+ public function testWhereNotNull( $collection ) {
$data = new $collection($originalData = [
['name' => 'Taylor'],
['name' => null],
@@ -4559,8 +4296,7 @@ public function testWhereNotNull($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testWhereNotNullWithoutKey($collection)
- {
+ public function testWhereNotNullWithoutKey( $collection ) {
$data = new $collection([1, null, 3, 'null', false, true]);
$this->assertSame([
@@ -4576,8 +4312,7 @@ public function testWhereNotNullWithoutKey($collection)
* @dataProvider collectionClassProvider
*/
#[DataProvider( 'collectionClassProvider' )]
- public function testCollect($collection)
- {
+ public function testCollect( $collection ) {
$data = $collection::make([
'a' => 1,
'b' => 2,
@@ -4593,11 +4328,9 @@ public function testCollect($collection)
], $data->all());
}
- /**
- * @dataProvider collectionClassProvider
- */
- #[DataProvider( 'collectionClassProvider' )]
- public function test_from_wp_query( $collection ) {
+ public function test_from_wp_query() {
+ $collection = Collection::class;
+
static::factory()->post->create_many( 5 );
$query = new \WP_Query(
[
@@ -4613,21 +4346,17 @@ public function test_from_wp_query( $collection ) {
} ) );
}
- /**
- * @dataProvider collectionClassProvider
- */
- #[DataProvider( 'collectionClassProvider' )]
- public function test_from_empty_wp_query( $collection ) {
+ public function test_from_empty_wp_query() {
+ $collection = Collection::class;
+
$query = new \WP_Query();
$c = $collection::from( $query );
$this->assertTrue( $c->is_empty() );
}
- /**
- * @dataProvider collectionClassProvider
- */
- #[DataProvider( 'collectionClassProvider' )]
- public function test_from_fallback( $collection ) {
+ public function test_from_fallback() {
+ $collection = Collection::class;
+
$c = $collection::from( ['a', 'b'] );
$this->assertSame( 2, count( $c->all() ) );
$this->assertEquals( ['a', 'b'], $c->intersect( ['a', 'b'] )->all() );
@@ -4642,6 +4371,7 @@ public static function collectionClassProvider()
{
return [
[Collection::class],
+ [Lazy_Collection::class],
];
}
}
@@ -4767,5 +4497,5 @@ public function __construct($value)
}
class TestCollectionSubclass extends Collection {
- //
+
}
diff --git a/tests/Testing/Concerns/MakesHttpRequestsTest.php b/tests/Testing/Concerns/MakesHttpRequestsTest.php
index 9d8f5d260..1c179ddb3 100644
--- a/tests/Testing/Concerns/MakesHttpRequestsTest.php
+++ b/tests/Testing/Concerns/MakesHttpRequestsTest.php
@@ -27,6 +27,8 @@ class MakesHttpRequestsTest extends Framework_Test_Case {
protected function setUp(): void {
parent::setUp();
+ putenv( 'MANTLE_EXPERIMENTAL_TESTING_USE_HOME_URL_HOST=' );
+
remove_all_actions( 'template_redirect' );
}
@@ -357,7 +359,9 @@ public function test_wp_is_rest_endpoint() {
]
);
- $this->get( rest_url( '/mantle/v1/' . __FUNCTION__ ) );
+ $this
+ ->get( rest_url( '/mantle/v1/' . __FUNCTION__ ) )
+ ->assertJsonPath( 'key', 'value here' );
$this->assertFalse( wp_is_rest_endpoint() );
}
@@ -389,7 +393,13 @@ public function test_match_snapshot_rest() {
] );
}
- public function test_https_request() {
+ public function test_url_scheme_http_by_default() {
+ $this->get( '/' )->assertOk();
+
+ $this->assertEmpty( $_SERVER['HTTPS'] ?? '' );
+ }
+
+ public function test_url_scheme_https_opt_in() {
$this->get( '/' )->assertOk();
$this->assertEmpty( $_SERVER['HTTPS'] ?? '' );
@@ -399,6 +409,51 @@ public function test_https_request() {
$this->assertEquals( 'on', $_SERVER['HTTPS'] );
}
+ public function test_url_scheme_https_by_home_url() {
+ putenv( 'MANTLE_EXPERIMENTAL_TESTING_USE_HOME_URL_HOST=1' );
+
+ $home_url = get_option( 'home' );
+
+ $this->assertEquals( 'http://' . WP_TESTS_DOMAIN, $home_url );
+ $this->assertEquals( 'http://' . WP_TESTS_DOMAIN, home_url() );
+
+ update_option( 'home', 'https://' . WP_TESTS_DOMAIN );
+
+ $this->assertEquals( 'https://' . WP_TESTS_DOMAIN, home_url() );
+
+ $this->get( '/' )->assertOk();
+
+ $this->assertEquals( 'on', $_SERVER['HTTPS'] ?? '' );
+ }
+
+ #[Group( 'experimental' )]
+ #[Group( 'experiment-testing-url-host' )]
+ public function test_experimental_default_url_host() {
+ $this->get( '/' )->assertOk();
+
+ $this->assertEquals( 'http://' . WP_TESTS_DOMAIN, home_url() );
+ $this->assertEquals( WP_TESTS_DOMAIN, $_SERVER['HTTP_HOST'] );
+
+ $this->setup_experiment_testing_url_host();
+
+ $this->get( '/' )->assertOk();
+
+ $this->assertEquals( 'subdomain.' . WP_TESTS_DOMAIN, $_SERVER['HTTP_HOST'] );
+ }
+
+ #[Group( 'experimental' )]
+ #[Group( 'experiment-testing-url-host' )]
+ public function test_experimental_redirect_to() {
+ $this->setup_experiment_testing_url_host();
+
+ $this->app['router']->get(
+ '/route-to-redirect/',
+ fn () => redirect()->to( '/redirected/' ),
+ );
+
+ $this->get( '/route-to-redirect/' )->assertRedirect( '/redirected/' );
+ }
+
public function test_multiple_requests() {
$methods = collect( get_class_methods( $this ) )
->filter( fn ( $method ) => false === strpos( $method, '_snapshot_' ) )
@@ -411,9 +466,20 @@ public function test_multiple_requests() {
continue;
}
+ $this->setUp();
+
$this->$method();
+
+ $this->tearDown();
}
}
+
+ protected function setup_experiment_testing_url_host() {
+ putenv( 'MANTLE_EXPERIMENTAL_TESTING_USE_HOME_URL_HOST=1' );
+
+ update_option( 'home', 'https://subdomain.' . WP_TESTS_DOMAIN );
+ $this->assertEquals( 'https://subdomain.' . WP_TESTS_DOMAIN, home_url() );
+ }
}
class JsonSerializableMixedResourcesStub implements JsonSerializable {