├── .phpunit-watcher.yml
├── .styleci.yml
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── composer.json
├── infection.json.dist
├── psalm.xml
├── psalm80.xml
├── rector.php
└── src
├── Clock
└── StaticClock.php
├── Container
├── Exception
│ └── NotFoundException.php
└── SimpleContainer.php
├── EventDispatcher
└── SimpleEventDispatcher.php
├── Log
└── SimpleLogger.php
└── SimpleCache
├── Action.php
├── Exception
└── InvalidArgumentException.php
├── MemorySimpleCache.php
└── SimpleCacheActionLogger.php
/.phpunit-watcher.yml:
--------------------------------------------------------------------------------
1 | watch:
2 | directories:
3 | - src
4 | - tests
5 | fileMask: '*.php'
6 | notifications:
7 | passingTests: false
8 | failingTests: false
9 | phpunit:
10 | binaryPath: vendor/bin/phpunit
11 | timeout: 180
12 |
--------------------------------------------------------------------------------
/.styleci.yml:
--------------------------------------------------------------------------------
1 | preset: psr12
2 | risky: true
3 |
4 | version: 8.1
5 |
6 | finder:
7 | exclude:
8 | - docs
9 | - vendor
10 |
11 | enabled:
12 | - alpha_ordered_traits
13 | - array_indentation
14 | - array_push
15 | - combine_consecutive_issets
16 | - combine_consecutive_unsets
17 | - combine_nested_dirname
18 | - declare_strict_types
19 | - dir_constant
20 | - fully_qualified_strict_types
21 | - function_to_constant
22 | - hash_to_slash_comment
23 | - is_null
24 | - logical_operators
25 | - magic_constant_casing
26 | - magic_method_casing
27 | - method_separation
28 | - modernize_types_casting
29 | - native_function_casing
30 | - native_function_type_declaration_casing
31 | - no_alias_functions
32 | - no_empty_comment
33 | - no_empty_phpdoc
34 | - no_empty_statement
35 | - no_extra_block_blank_lines
36 | - no_short_bool_cast
37 | - no_superfluous_elseif
38 | - no_unneeded_control_parentheses
39 | - no_unneeded_curly_braces
40 | - no_unneeded_final_method
41 | - no_unset_cast
42 | - no_unused_imports
43 | - no_unused_lambda_imports
44 | - no_useless_else
45 | - no_useless_return
46 | - normalize_index_brace
47 | - php_unit_dedicate_assert
48 | - php_unit_dedicate_assert_internal_type
49 | - php_unit_expectation
50 | - php_unit_mock
51 | - php_unit_mock_short_will_return
52 | - php_unit_namespaced
53 | - php_unit_no_expectation_annotation
54 | - phpdoc_no_empty_return
55 | - phpdoc_no_useless_inheritdoc
56 | - phpdoc_order
57 | - phpdoc_property
58 | - phpdoc_scalar
59 | - phpdoc_singular_inheritdoc
60 | - phpdoc_trim
61 | - phpdoc_trim_consecutive_blank_line_separation
62 | - phpdoc_type_to_var
63 | - phpdoc_types
64 | - phpdoc_types_order
65 | - print_to_echo
66 | - regular_callable_call
67 | - return_assignment
68 | - self_accessor
69 | - self_static_accessor
70 | - set_type_to_cast
71 | - short_array_syntax
72 | - short_list_syntax
73 | - simplified_if_return
74 | - single_quote
75 | - standardize_not_equals
76 | - ternary_to_null_coalescing
77 | - trailing_comma_in_multiline_array
78 | - unalign_double_arrow
79 | - unalign_equals
80 | - empty_loop_body_braces
81 | - integer_literal_case
82 | - union_type_without_spaces
83 |
84 | disabled:
85 | - function_declaration
86 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Yii Test Support Change Log
2 |
3 | ## 3.0.3 under development
4 |
5 | - New #80: Add PSR-20 static clock implementation (@samdark)
6 |
7 | ## 3.0.2 February 23, 2025
8 |
9 | - Chg #76: Change PHP constraint in `composer.json` to `~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0` (@vjik)
10 | - Bug #76: Explicitly mark nullable parameters (@vjik)
11 |
12 | ## 3.0.1 February 09, 2024
13 |
14 | - Enh #70: Add "testing" keyword to composer.json for suggest package to require-dev section (@samdark)
15 |
16 | ## 3.0.0 June 29, 2022
17 |
18 | - Chg #45: Update `psr/simple-cache` version to `^2.0|^3.0` (@vjik)
19 |
20 | ## 2.0.0 June 16, 2022
21 |
22 | - Chg #43: Raise the minimum `psr/log` version to `^2.0|^3.0` and the minimum PHP version to 8.0 (@rustamwin)
23 |
24 | ## 1.4.0 March 24, 2022
25 |
26 | - Enh #40: Add custom callback for method `has()` of `SimpleContainer` (@vjik)
27 | - Bug #40: Catch only `NotFoundException` instead of `Throwable` in `SimpleContainer::has()` method (@vjik)
28 |
29 | ## 1.3.0 March 15, 2021
30 |
31 | - Enh #29: Add `SimpleLogger` class, which is an implementation of `LoggerInterface` (@devanych)
32 |
33 | ## 1.2.1 March 07, 2021
34 |
35 | - Enh #26: Support PSR Container v2.0 (@roxblnfk)
36 |
37 | ## 1.2.0 February 23, 2021
38 |
39 | - Enh #24: Add `SimpleEventDispatcher::getEventClasses()` that return classes of dispatched events (@vjik)
40 |
41 | ## 1.1.0 February 22, 2021
42 |
43 | - Enh #23: Add `SimpleEventDispatcher::clearEvents()` that clear all events in event dispatcher (@vjik)
44 |
45 | ## 1.0.0 December 24, 2020
46 |
47 | - Initial release.
48 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright © 2008 by Yii Software ()
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions
6 | are met:
7 |
8 | * Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 | * Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in
12 | the documentation and/or other materials provided with the
13 | distribution.
14 | * Neither the name of Yii Software nor the names of its
15 | contributors may be used to endorse or promote products derived
16 | from this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Yii Test Support
6 |
7 |
8 |
9 | [](https://packagist.org/packages/yiisoft/test-support)
10 | [](https://packagist.org/packages/yiisoft/test-support)
11 | [](https://github.com/yiisoft/test-support/actions/workflows/build.yml)
12 | [](https://codecov.io/gh/yiisoft/test-support)
13 | [](https://dashboard.stryker-mutator.io/reports/github.com/yiisoft/test-support/master)
14 | [](https://github.com/yiisoft/test-support/actions/workflows/static.yml?query=branch%3Amaster)
15 | [](https://shepherd.dev/github/yiisoft/test-support)
16 |
17 | The package is intended to simplify the process of testing application elements that depend on PSR interfaces.
18 |
19 | ## Requirements
20 |
21 | - PHP 8.0 or higher.
22 |
23 | ## Installation
24 |
25 | The package could be installed with [Composer](https://getcomposer.org):
26 |
27 | ```shell
28 | composer require yiisoft/test-support --dev
29 | ```
30 |
31 | In case you need to satisfy PSR virtual packages (`*-implementation` requirements), add the following to `require-dev`
32 | as well:
33 |
34 | ```shell
35 | "yiisoft/psr-dummy-provider": "1.0"
36 | ```
37 |
38 | ## Documentation
39 |
40 | - Guide: [English](docs/guide/en/README.md), [Português - Brasil](docs/guide/pt-BR/README.md), [Русский](docs/guide/ru/README.md)
41 | - [Internals](docs/internals.md)
42 |
43 | If you need help or have a question, the [Yii Forum](https://forum.yiiframework.com/c/yii-3-0/63) is a good place for that.
44 | You may also check out other [Yii Community Resources](https://www.yiiframework.com/community).
45 |
46 | ## License
47 |
48 | The Yii Test Support is free software. It is released under the terms of the BSD License.
49 | Please see [`LICENSE`](./LICENSE.md) for more information.
50 |
51 | Maintained by [Yii Software](https://www.yiiframework.com/).
52 |
53 | ## Support the project
54 |
55 | [](https://opencollective.com/yiisoft)
56 |
57 | ## Follow updates
58 |
59 | [](https://www.yiiframework.com/)
60 | [](https://twitter.com/yiiframework)
61 | [](https://t.me/yii3en)
62 | [](https://www.facebook.com/groups/yiitalk)
63 | [](https://yiiframework.com/go/slack)
64 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "yiisoft/test-support",
3 | "type": "library",
4 | "description": "Supporting tools for testing",
5 | "keywords": [
6 | "yii",
7 | "testing"
8 | ],
9 | "homepage": "https://www.yiiframework.com/",
10 | "license": "BSD-3-Clause",
11 | "support": {
12 | "issues": "https://github.com/yiisoft/test-support/issues?state=open",
13 | "source": "https://github.com/yiisoft/test-support",
14 | "forum": "https://www.yiiframework.com/forum/",
15 | "wiki": "https://www.yiiframework.com/wiki/",
16 | "irc": "ircs://irc.libera.chat:6697/yii",
17 | "chat": "https://t.me/yii3en"
18 | },
19 | "funding": [
20 | {
21 | "type": "opencollective",
22 | "url": "https://opencollective.com/yiisoft"
23 | },
24 | {
25 | "type": "github",
26 | "url": "https://github.com/sponsors/yiisoft"
27 | }
28 | ],
29 | "require": {
30 | "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0",
31 | "psr/clock": "^1.0",
32 | "psr/container": "^1.0 || ^2.0",
33 | "psr/event-dispatcher": "^1.0",
34 | "psr/log": "^2.0|^3.0",
35 | "psr/simple-cache": "^2.0|^3.0"
36 | },
37 | "require-dev": {
38 | "maglnet/composer-require-checker": "^4.4",
39 | "phpunit/phpunit": "^9.6.22",
40 | "rector/rector": "^2.0.9",
41 | "roave/infection-static-analysis-plugin": "^1.25",
42 | "spatie/phpunit-watcher": "^1.23.6",
43 | "vimeo/psalm": "^4.30 || ^5.26.1 || ^6.8.6"
44 | },
45 | "autoload": {
46 | "psr-4": {
47 | "Yiisoft\\Test\\Support\\": "src"
48 | }
49 | },
50 | "autoload-dev": {
51 | "psr-4": {
52 | "Yiisoft\\Test\\Support\\Tests\\": "tests"
53 | }
54 | },
55 | "scripts": {
56 | "test": "phpunit --testdox --no-interaction",
57 | "test-watch": "phpunit-watcher watch"
58 | },
59 | "config": {
60 | "sort-packages": true,
61 | "bump-after-update": "dev",
62 | "allow-plugins": {
63 | "infection/extension-installer": true,
64 | "composer/package-versions-deprecated": true
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/infection.json.dist:
--------------------------------------------------------------------------------
1 | {
2 | "source": {
3 | "directories": [
4 | "src"
5 | ]
6 | },
7 | "logs": {
8 | "text": "php:\/\/stderr",
9 | "stryker": {
10 | "report": "master"
11 | }
12 | },
13 | "mutators": {
14 | "@default": true
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/psalm.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/psalm80.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/rector.php:
--------------------------------------------------------------------------------
1 | paths([
11 | __DIR__ . '/src',
12 | __DIR__ . '/tests',
13 | ]);
14 |
15 | // register a single rule
16 | $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);
17 |
18 | // define sets of rules
19 | $rectorConfig->sets([
20 | LevelSetList::UP_TO_PHP_80,
21 | ]);
22 | };
23 |
--------------------------------------------------------------------------------
/src/Clock/StaticClock.php:
--------------------------------------------------------------------------------
1 | now;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Container/Exception/NotFoundException.php:
--------------------------------------------------------------------------------
1 | id;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Container/SimpleContainer.php:
--------------------------------------------------------------------------------
1 | factory = $factory ??
38 | /** @return mixed */
39 | static function (string $id) {
40 | throw new NotFoundException($id);
41 | };
42 |
43 | $this->hasCallback = $hasCallback ??
44 | function (string $id): bool {
45 | try {
46 | $this->get($id);
47 | return true;
48 | } catch (NotFoundException) {
49 | return false;
50 | }
51 | };
52 | }
53 |
54 | public function get($id)
55 | {
56 | if (!array_key_exists($id, $this->definitions)) {
57 | $this->definitions[$id] = ($this->factory)($id);
58 | }
59 | return $this->definitions[$id];
60 | }
61 |
62 | public function has($id): bool
63 | {
64 | if (array_key_exists($id, $this->definitions)) {
65 | return true;
66 | }
67 | return ($this->hasCallback)($id);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/EventDispatcher/SimpleEventDispatcher.php:
--------------------------------------------------------------------------------
1 |
20 | */
21 | private array $events = [];
22 |
23 | /**
24 | * @param Closure ...$listeners Functions that will handle each event.
25 | */
26 | public function __construct(Closure ...$listeners)
27 | {
28 | $this->listeners = $listeners;
29 | }
30 |
31 | public function dispatch(object $event): object
32 | {
33 | $this->events[] = $event;
34 | foreach ($this->listeners as $listener) {
35 | if ($event instanceof StoppableEventInterface && $event->isPropagationStopped()) {
36 | return $event;
37 | }
38 | $listener($event);
39 | }
40 | return $event;
41 | }
42 |
43 | /**
44 | * @return object[]
45 | * @psalm-return list