diff --git a/.github/workflows/coding-style.yml b/.github/workflows/coding-style.yml index 2846908bd..f383b46a6 100644 --- a/.github/workflows/coding-style.yml +++ b/.github/workflows/coding-style.yml @@ -7,7 +7,7 @@ jobs: name: Nette Code Checker runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: php-version: 8.0 @@ -21,7 +21,7 @@ jobs: name: Nette Coding Standard runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: php-version: 8.0 diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 5424fc71f..b5295ede9 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -7,7 +7,7 @@ jobs: name: PHPStan runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: php-version: 7.4 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index aa386a1e9..b3a8120cb 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,7 +13,7 @@ jobs: name: PHP ${{ matrix.php }} tests steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} @@ -32,7 +32,7 @@ jobs: name: Lowest Dependencies runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: php-version: 7.2 @@ -40,16 +40,21 @@ jobs: - run: composer update --no-progress --prefer-dist --prefer-lowest --prefer-stable - run: vendor/bin/tester tests -s -C + - if: failure() + uses: actions/upload-artifact@v3 + with: + name: output + path: tests/**/output code_coverage: name: Code Coverage runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: - php-version: 8.0 + php-version: 8.3 coverage: none - run: composer install --no-progress --prefer-dist diff --git a/composer.json b/composer.json index eeb71a144..f1e927258 100644 --- a/composer.json +++ b/composer.json @@ -31,9 +31,9 @@ "nette/forms": "^3.0", "nette/robot-loader": "^3.2 || ^4.0", "nette/security": "^3.0", - "latte/latte": "^2.10.2 || ^3.0.3", + "latte/latte": "^2.10.2 || ^3.0.12", "tracy/tracy": "^2.6", - "mockery/mockery": "^1.0", + "mockery/mockery": "^1.0 || ^2.0", "phpstan/phpstan-nette": "^0.12", "jetbrains/phpstorm-attributes": "dev-master" }, @@ -42,7 +42,7 @@ "nette/di": "<3.0.7", "nette/forms": "<3.0", "nette/schema": "<1.2", - "latte/latte": "<2.7.1 || >=3.0.0 <3.0.8 || >=3.1", + "latte/latte": "<2.7.1 || >=3.0.0 <3.0.12 || >=3.1", "tracy/tracy": "<2.5" }, "autoload": { diff --git a/readme.md b/readme.md index aa76cfd5e..7ce5d7587 100644 --- a/readme.md +++ b/readme.md @@ -2,8 +2,7 @@ Nette Application MVC ===================== [![Downloads this Month](https://img.shields.io/packagist/dm/nette/application.svg)](https://packagist.org/packages/nette/application) -[![Tests](https://github.com/nette/application/workflows/Tests/badge.svg?branch=master)](https://github.com/nette/application/actions) -[![Coverage Status](https://coveralls.io/repos/github/nette/application/badge.svg?branch=master)](https://coveralls.io/github/nette/application?branch=master) +[![Tests](https://github.com/nette/application/actions/workflows/tests.yml/badge.svg?branch=v3.1)](https://github.com/nette/application/actions) [![Latest Stable Version](https://poser.pugx.org/nette/application/v/stable)](https://github.com/nette/application/releases) [![License](https://img.shields.io/badge/license-New%20BSD-blue.svg)](https://github.com/nette/application/blob/master/license.md) diff --git a/src/Application/Helpers.php b/src/Application/Helpers.php index 56abd45b8..c871640e7 100644 --- a/src/Application/Helpers.php +++ b/src/Application/Helpers.php @@ -21,6 +21,7 @@ final class Helpers /** * Splits name into [module, presenter] or [presenter, action] + * @return array{string, string, string} */ public static function splitName(string $name): array { diff --git a/src/Application/PresenterFactory.php b/src/Application/PresenterFactory.php index 30ccf853e..d1724a1a4 100644 --- a/src/Application/PresenterFactory.php +++ b/src/Application/PresenterFactory.php @@ -33,7 +33,7 @@ class PresenterFactory implements IPresenterFactory /** - * @param callable(string): IPresenter $factory + * @param ?callable(string): IPresenter $factory */ public function __construct(?callable $factory = null) { diff --git a/src/Application/UI/Component.php b/src/Application/UI/Component.php index b8ed3259f..8562f054e 100644 --- a/src/Application/UI/Component.php +++ b/src/Application/UI/Component.php @@ -79,7 +79,7 @@ protected function createComponent(string $name): ?Nette\ComponentModel\ICompone $res = parent::createComponent($name); if ($res && !$res instanceof SignalReceiver && !$res instanceof StatePersistent) { $type = get_class($res); - trigger_error("It seems that component '$name' of type $type is not intended to be used in the Presenter.", E_USER_NOTICE); + trigger_error("It seems that component '$name' of type $type is not intended to be used in the Presenter."); } return $res; @@ -106,7 +106,7 @@ protected function tryCall(string $method, array $params): bool if (!$rc->hasMethod($method)) { return false; } elseif (!$rc->hasCallableMethod($method)) { - throw new Nette\InvalidStateException('Method ' . Nette\Utils\Reflection::toString($rc->getMethod($method)) . ' is not callable.'); + $this->error('Method ' . Nette\Utils\Reflection::toString($rc->getMethod($method)) . ' is not callable.'); } $rm = $rc->getMethod($method); diff --git a/src/Application/UI/ComponentReflection.php b/src/Application/UI/ComponentReflection.php index 5483709e5..ccffd9500 100644 --- a/src/Application/UI/ComponentReflection.php +++ b/src/Application/UI/ComponentReflection.php @@ -34,6 +34,7 @@ final class ComponentReflection extends \ReflectionClass /** * Returns array of class properties that are public and have attribute #[Persistent] or #[Parameter] or annotation @persistent. + * @return array */ public function getParameters(): array { @@ -81,6 +82,7 @@ public function getParameters(): array /** * Returns array of persistent properties. They are public and have attribute #[Persistent] or annotation @persistent. + * @return array */ public function getPersistentParams(): array { diff --git a/src/Application/UI/Control.php b/src/Application/UI/Control.php index a2b24afeb..e8473eb83 100644 --- a/src/Application/UI/Control.php +++ b/src/Application/UI/Control.php @@ -82,7 +82,7 @@ protected function checkTemplateClass(string $class): ?string static::class, $class, Template::class - ), E_USER_NOTICE); + )); return null; } else { return $class; diff --git a/src/Application/UI/Presenter.php b/src/Application/UI/Presenter.php index 28b0b32c2..f8a1627c7 100644 --- a/src/Application/UI/Presenter.php +++ b/src/Application/UI/Presenter.php @@ -535,6 +535,7 @@ public function findLayoutTemplateFile(): ?string /** * Formats layout template file names. + * @return string[] */ public function formatLayoutTemplateFiles(): array { @@ -561,6 +562,7 @@ public function formatLayoutTemplateFiles(): array /** * Formats view template file names. + * @return string[] */ public function formatTemplateFiles(): array { diff --git a/src/Application/exceptions.php b/src/Application/exceptions.php index 35127eb18..cf0414cbc 100644 --- a/src/Application/exceptions.php +++ b/src/Application/exceptions.php @@ -16,7 +16,7 @@ * The exception that is thrown when user attempts to terminate the current presenter or application. * This is special "silent exception" with no error message or code. */ -class AbortException extends \Exception +class AbortException extends \LogicException { } @@ -40,7 +40,7 @@ class InvalidPresenterException extends \Exception /** * The exception that indicates client error with HTTP code 4xx. */ -class BadRequestException extends \Exception +class BadRequestException extends \LogicException { /** @var int */ protected $code = Http\IResponse::S404_NOT_FOUND; diff --git a/src/Bridges/ApplicationDI/ApplicationExtension.php b/src/Bridges/ApplicationDI/ApplicationExtension.php index 03cefac4f..70e0159b5 100644 --- a/src/Bridges/ApplicationDI/ApplicationExtension.php +++ b/src/Bridges/ApplicationDI/ApplicationExtension.php @@ -151,6 +151,7 @@ public function beforeCompile() } + /** @return string[] */ private function findPresenters(): array { $config = $this->getConfig(); diff --git a/src/Bridges/ApplicationDI/LatteExtension.php b/src/Bridges/ApplicationDI/LatteExtension.php index 608e7982a..7a1ddb16b 100644 --- a/src/Bridges/ApplicationDI/LatteExtension.php +++ b/src/Bridges/ApplicationDI/LatteExtension.php @@ -80,6 +80,9 @@ public function loadConfiguration() ->addSetup('enablePhpLinter', [$config->phpLinter]); foreach ($config->extensions as $extension) { + if ($extension === Latte\Essential\TranslatorExtension::class) { + $extension = new Statement($extension, [new Nette\DI\Definitions\Reference(Nette\Localization\Translator::class)]); + } $this->addExtension($extension); } } @@ -114,7 +117,8 @@ public static function initLattePanel( Nette\Application\UI\TemplateFactory $factory, Tracy\Bar $bar, bool $all = false - ) { + ): void + { if (!$factory instanceof ApplicationLatte\TemplateFactory) { return; } diff --git a/src/Bridges/ApplicationLatte/Nodes/IfCurrentNode.php b/src/Bridges/ApplicationLatte/Nodes/IfCurrentNode.php index a44f74037..dd1c6813f 100644 --- a/src/Bridges/ApplicationLatte/Nodes/IfCurrentNode.php +++ b/src/Bridges/ApplicationLatte/Nodes/IfCurrentNode.php @@ -31,7 +31,7 @@ class IfCurrentNode extends StatementNode public static function create(Tag $tag): \Generator { trigger_error("Tag {ifCurrent} is deprecated, use {if isLinkCurrent('...')} instead (on line {$tag->position->line})", E_USER_DEPRECATED); - $node = new static; + $node = $tag->node = new static; if (!$tag->parser->isEnd()) { $node->destination = $tag->parser->parseUnquotedStringOrExpression(); $tag->parser->stream->tryConsume(','); diff --git a/src/Bridges/ApplicationLatte/Nodes/SnippetAreaNode.php b/src/Bridges/ApplicationLatte/Nodes/SnippetAreaNode.php index 546518592..b4353f431 100644 --- a/src/Bridges/ApplicationLatte/Nodes/SnippetAreaNode.php +++ b/src/Bridges/ApplicationLatte/Nodes/SnippetAreaNode.php @@ -34,7 +34,7 @@ class SnippetAreaNode extends StatementNode /** @return \Generator */ public static function create(Tag $tag, TemplateParser $parser): \Generator { - $node = new static; + $node = $tag->node = new static; $name = $tag->parser->parseUnquotedStringOrExpression(); if ( $name instanceof Expression\ClassConstantFetchNode diff --git a/src/Bridges/ApplicationLatte/Nodes/SnippetNode.php b/src/Bridges/ApplicationLatte/Nodes/SnippetNode.php index 989b887b3..5c7c2b26f 100644 --- a/src/Bridges/ApplicationLatte/Nodes/SnippetNode.php +++ b/src/Bridges/ApplicationLatte/Nodes/SnippetNode.php @@ -41,7 +41,7 @@ public static function create(Tag $tag, TemplateParser $parser): \Generator { $tag->outputMode = $tag::OutputKeepIndentation; - $node = new static; + $node = $tag->node = new static; $node->htmlElement = $tag->isNAttribute() ? $tag->htmlElement : null; if ($tag->parser->isEnd()) { diff --git a/tests/Bridges.DI/LatteExtension.translator.phpt b/tests/Bridges.DI/LatteExtension.translator.phpt new file mode 100644 index 000000000..f555b460e --- /dev/null +++ b/tests/Bridges.DI/LatteExtension.translator.phpt @@ -0,0 +1,46 @@ +load(Tester\FileMock::create(' +latte: + extensions: + - Latte\Essential\TranslatorExtension + +services: + - Translator +', 'neon')); + +$compiler = new DI\Compiler; +$compiler->addExtension('latte', new Nette\Bridges\ApplicationDI\LatteExtension('')); +$code = $compiler->addConfig($config)->compile(); +eval($code); + +$container = new Container; + +$latte = $container->getService('nette.latteFactory')->create(); +$extensions = Assert::with($latte, fn() => $this->extensions); +Assert::equal(new Latte\Essential\TranslatorExtension(new Translator), $extensions[3]); diff --git a/tests/Bridges.DI/RoutingExtension.cache.phpt b/tests/Bridges.DI/RoutingExtension.cache.phpt index 0d5209bb0..bd7423446 100644 --- a/tests/Bridges.DI/RoutingExtension.cache.phpt +++ b/tests/Bridges.DI/RoutingExtension.cache.phpt @@ -76,13 +76,13 @@ test('', function () { }); -Assert::exception(function () { - function myRouterFactory(): Nette\Routing\Router - { - return new Route('path', function () {}); - } +function myRouterFactory(): Nette\Routing\Router +{ + return new Route('path', function () {}); +} +Assert::exception(function () { $loader = new DI\Config\Loader; $config = $loader->load(Tester\FileMock::create(' routing: diff --git a/tests/Bridges.Latte3/TemplateFactory.nonce.control.phpt b/tests/Bridges.Latte3/UIExtension.nonce.control.phpt similarity index 71% rename from tests/Bridges.Latte3/TemplateFactory.nonce.control.phpt rename to tests/Bridges.Latte3/UIExtension.nonce.control.phpt index b0db91521..0f19e5835 100644 --- a/tests/Bridges.Latte3/TemplateFactory.nonce.control.phpt +++ b/tests/Bridges.Latte3/UIExtension.nonce.control.phpt @@ -1,14 +1,13 @@ shouldReceive('create')->andReturn($latte); - $response = Mockery::mock(Nette\Http\IResponse::class); $response->shouldReceive('getHeader')->with('Content-Security-Policy')->andReturn("hello 'nonce-abcd123==' world"); @@ -29,10 +23,9 @@ $control = Mockery::mock(UI\Control::class); $control->shouldReceive('getPresenterIfExists')->andReturn(null); $control->shouldIgnoreMissing(); -$factory = new ApplicationLatte\TemplateFactory($latteFactory); -$factory->createTemplate($control); - +$latte = new Latte\Engine; $latte->setLoader(new Latte\Loaders\StringLoader); +$latte->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension($control)); Assert::match( '', diff --git a/tests/Bridges.Latte3/TemplateFactory.nonce.presenter.phpt b/tests/Bridges.Latte3/UIExtension.nonce.presenter.phpt similarity index 74% rename from tests/Bridges.Latte3/TemplateFactory.nonce.presenter.phpt rename to tests/Bridges.Latte3/UIExtension.nonce.presenter.phpt index 05abfedca..ca0dace3a 100644 --- a/tests/Bridges.Latte3/TemplateFactory.nonce.presenter.phpt +++ b/tests/Bridges.Latte3/UIExtension.nonce.presenter.phpt @@ -1,14 +1,13 @@ shouldReceive('create')->andReturn($latte); - $response = Mockery::mock(Nette\Http\IResponse::class); $response->shouldReceive('getHeader')->with('Content-Security-Policy')->andReturn("hello 'nonce-abcd123==' world"); @@ -32,10 +26,9 @@ $presenter->shouldReceive('getPresenterIfExists')->andReturn($presenter); $presenter->shouldReceive('getHttpResponse')->andReturn($response); $presenter->shouldIgnoreMissing(); -$factory = new ApplicationLatte\TemplateFactory($latteFactory); -$factory->createTemplate($presenter); - +$latte = new Latte\Engine; $latte->setLoader(new Latte\Loaders\StringLoader); +$latte->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension($presenter)); Assert::match( '', diff --git a/tests/Bridges.Latte3/expected/isLinkCurrent.php b/tests/Bridges.Latte3/expected/isLinkCurrent.php index 3871205c8..a86390a52 100644 --- a/tests/Bridges.Latte3/expected/isLinkCurrent.php +++ b/tests/Bridges.Latte3/expected/isLinkCurrent.php @@ -26,7 +26,7 @@ global->fn->isLinkCurrent)('default') ? 'current' : null])) ? ' class="' . LR\Filters::escapeHtmlAttr(implode(" ", array_unique($ʟ_tmp))) . '"' : "" /* line 9 */; + echo ($ʟ_tmp = array_filter([($this->global->fn->isLinkCurrent)(%a%'default') ? 'current' : null])) ? ' class="' . LR\Filters::escapeHtmlAttr(implode(" ", array_unique($ʟ_tmp))) . '"' : "" /* line 9 */; echo '>custom function '; %A% diff --git a/tests/Bridges.Latte3/isLinkCurrent().phpt b/tests/Bridges.Latte3/isLinkCurrent().phpt index bd101c6c1..fd567a251 100644 --- a/tests/Bridges.Latte3/isLinkCurrent().phpt +++ b/tests/Bridges.Latte3/isLinkCurrent().phpt @@ -17,20 +17,14 @@ if (version_compare(Latte\Engine::VERSION, '3', '<')) { Tester\Environment::bypassFinals(); -$latte = new Latte\Engine; - -$latteFactory = Mockery::mock(Nette\Bridges\ApplicationLatte\LatteFactory::class); -$latteFactory->shouldReceive('create')->andReturn($latte); - $presenter = Mockery::mock(Nette\Application\UI\Presenter::class); $presenter->shouldReceive('getPresenterIfExists')->andReturn($presenter); $presenter->shouldReceive('getHttpResponse')->andReturn((Mockery::mock(Nette\Http\IResponse::class))->shouldIgnoreMissing()); $presenter->shouldIgnoreMissing(); -$factory = new Nette\Bridges\ApplicationLatte\TemplateFactory($latteFactory); -$factory->createTemplate($presenter); - +$latte = new Latte\Engine; $latte->setLoader(new Latte\Loaders\StringLoader); +$latte->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension($presenter)); Assert::matchFile( __DIR__ . '/expected/isLinkCurrent.php', diff --git a/tests/Bridges.Latte3/{ifCurrent}.phpt b/tests/Bridges.Latte3/{ifCurrent}.phpt index e2606d7fa..48fed1caa 100644 --- a/tests/Bridges.Latte3/{ifCurrent}.phpt +++ b/tests/Bridges.Latte3/{ifCurrent}.phpt @@ -16,18 +16,14 @@ Tester\Environment::bypassFinals(); $latte = new Latte\Engine; -$latteFactory = Mockery::mock(Nette\Bridges\ApplicationLatte\LatteFactory::class); -$latteFactory->shouldReceive('create')->andReturn($latte); - $presenter = Mockery::mock(Nette\Application\UI\Presenter::class); $presenter->shouldReceive('getPresenterIfExists')->andReturn($presenter); $presenter->shouldReceive('getHttpResponse')->andReturn((Mockery::mock(Nette\Http\IResponse::class))->shouldIgnoreMissing()); $presenter->shouldIgnoreMissing(); -$factory = new Nette\Bridges\ApplicationLatte\TemplateFactory($latteFactory); -$factory->createTemplate($presenter); - +$latte = new Latte\Engine; $latte->setLoader(new Latte\Loaders\StringLoader); +$latte->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension($presenter)); Assert::matchFile( __DIR__ . '/expected/ifCurrent.php', diff --git a/tests/UI/Component.redirect().phpt b/tests/UI/Component.redirect().phpt index 2a749c432..46be12e32 100644 --- a/tests/UI/Component.redirect().phpt +++ b/tests/UI/Component.redirect().phpt @@ -26,7 +26,7 @@ class TestPresenter extends Application\UI\Presenter public function sendResponse(Application\Response $response): void { - $this->response = $response; + parent::sendResponse($this->response = $response); } } @@ -43,7 +43,10 @@ $presenter->injectPrimary( test('', function () use ($presenter) { - $presenter->redirect('foo'); + try { + $presenter->redirect('foo'); + } catch (Throwable $e) { + } Assert::type(Nette\Application\Responses\RedirectResponse::class, $presenter->response); Assert::same(302, $presenter->response->getCode()); Assert::same('http://localhost/?action=foo&presenter=test', $presenter->response->getUrl()); @@ -51,7 +54,10 @@ test('', function () use ($presenter) { test('', function () use ($presenter) { - $presenter->redirect('foo', ['arg' => 1]); + try { + $presenter->redirect('foo', ['arg' => 1]); + } catch (Throwable $e) { + } Assert::type(Nette\Application\Responses\RedirectResponse::class, $presenter->response); Assert::same(302, $presenter->response->getCode()); Assert::same('http://localhost/?arg=1&action=foo&presenter=test', $presenter->response->getUrl()); @@ -59,7 +65,10 @@ test('', function () use ($presenter) { test('', function () use ($presenter) { - $presenter->redirect('foo', 2); + try { + $presenter->redirect('foo', 2); + } catch (Throwable $e) { + } Assert::type(Nette\Application\Responses\RedirectResponse::class, $presenter->response); Assert::same(302, $presenter->response->getCode()); Assert::same('http://localhost/?val=2&action=foo&presenter=test', $presenter->response->getUrl()); @@ -67,7 +76,10 @@ test('', function () use ($presenter) { test('', function () use ($presenter) { - $presenter->redirectPermanent('foo', 2); + try { + $presenter->redirectPermanent('foo', 2); + } catch (Throwable $e) { + } Assert::type(Nette\Application\Responses\RedirectResponse::class, $presenter->response); Assert::same(301, $presenter->response->getCode()); Assert::same('http://localhost/?val=2&action=foo&presenter=test', $presenter->response->getUrl()); @@ -75,7 +87,10 @@ test('', function () use ($presenter) { test('', function () use ($presenter) { - $presenter->redirectPermanent('foo', ['arg' => 1]); + try { + $presenter->redirectPermanent('foo', ['arg' => 1]); + } catch (Throwable $e) { + } Assert::type(Nette\Application\Responses\RedirectResponse::class, $presenter->response); Assert::same(301, $presenter->response->getCode()); Assert::same('http://localhost/?arg=1&action=foo&presenter=test', $presenter->response->getUrl()); diff --git a/tests/UI/Presenter.getParameters.phpt b/tests/UI/ComponentReflection.getParameters().phpt similarity index 93% rename from tests/UI/Presenter.getParameters.phpt rename to tests/UI/ComponentReflection.getParameters().phpt index e4e916a8c..8c95daae0 100644 --- a/tests/UI/Presenter.getParameters.phpt +++ b/tests/UI/ComponentReflection.getParameters().phpt @@ -1,9 +1,5 @@ testSection; - } -} - -class MockSessionSection extends Nette\Http\SessionSection -{ - public $testedKeyExistence; - - public $storedKey; - - public $storedValue; - - public $testExpiration; - - public $testExpirationVariables; - - - public function __construct() - { - } - - - public function __isset(string $name): bool - { - $this->testedKeyExistence = $name; - return false; - } - - - public function __set(string $name, $value): void - { - $this->storedKey = $name; - $this->storedValue = $value; - } - - - public function setExpiration($expiraton, $variables = null) - { - $this->testExpiration = $expiraton; - $this->testExpirationVariables = $variables; - } - - - public function offsetExists($name): bool - { - return $this->__isset($name); - } +test('ok', function () { + $testedKeyExistence = $storedKey = $storedValue = $testExpiration = $testExpirationVariables = null; - public function offsetSet($name, $value): void - { - $this->__set($name, $value); - } + $sessionSectionMock = Mockery::mock(Nette\Http\SessionSection::class); + $sessionSectionMock->shouldReceive('setExpiration') + ->andReturnUsing(function ($expiration, $variables = null) use (&$testExpiration, &$testExpirationVariables, $sessionSectionMock) { + $testExpiration = $expiration; + $testExpirationVariables = $variables; + return $sessionSectionMock; + }); + $sessionSectionMock->shouldReceive('offsetExists') + ->andReturnUsing(function ($name) use (&$testedKeyExistence) { + $testedKeyExistence = $name; + return false; + }); - public function offsetGet($name) - { - } - - - public function offsetUnset($name): void - { - } -} + $sessionSectionMock->shouldReceive('offsetSet') + ->andReturnUsing(function ($name, $value) use (&$storedKey, &$storedValue) { + $storedKey = $name; + $storedValue = $value; + }); -class MockUser extends Security\User -{ - public function __construct() - { - } + $sessionMock = Mockery::mock(Nette\Http\Session::class); + $sessionMock->shouldReceive('getSection') + ->andReturn($sessionSectionMock); + $userMock = Mockery::mock(Nette\Security\User::class); + $userMock->shouldReceive('getId') + ->andReturn('test_id'); - public function getId() - { - return 'test_id'; - } -} -test('', function () { $presenter = new TestPresenter; $presenter->injectPrimary( null, @@ -124,26 +62,52 @@ test('', function () { new Application\Routers\SimpleRouter, new Http\Request(new Http\UrlScript), new Http\Response, - $session = new MockSession, - $user = new MockUser + $sessionMock, + $userMock ); - $section = $session->testSection = new MockSessionSection($session); - $applicationRequest = new Application\Request('', '', []); $presenter->run($applicationRequest); $expiration = '+1 year'; $key = $presenter->storeRequest($expiration); - Assert::same($expiration, $section->testExpiration); - Assert::same($key, $section->testExpirationVariables); - Assert::same($key, $section->testedKeyExistence); - Assert::same($key, $section->storedKey); - Assert::same([$user->getId(), $applicationRequest], $section->storedValue); + Assert::same($expiration, $testExpiration); + Assert::same($key, $testExpirationVariables); + Assert::same($key, $testedKeyExistence); + Assert::same($key, $storedKey); + Assert::same([$userMock->getId(), $applicationRequest], $storedValue); }); -test('', function () { + +test('no user', function () { + $testedKeyExistence = $storedKey = $storedValue = $testExpiration = $testExpirationVariables = null; + + $sessionSectionMock = Mockery::mock(Nette\Http\SessionSection::class); + $sessionSectionMock->shouldReceive('setExpiration') + ->andReturnUsing(function ($expiration, $variables = null) use (&$testExpiration, &$testExpirationVariables, $sessionSectionMock) { + $testExpiration = $expiration; + $testExpirationVariables = $variables; + return $sessionSectionMock; + }); + + $sessionSectionMock->shouldReceive('offsetExists') + ->andReturnUsing(function ($name) use (&$testedKeyExistence) { + $testedKeyExistence = $name; + return false; + }); + + $sessionSectionMock->shouldReceive('offsetSet') + ->andReturnUsing(function ($name, $value) use (&$storedKey, &$storedValue) { + $storedKey = $name; + $storedValue = $value; + }); + + $sessionMock = Mockery::mock(Nette\Http\Session::class); + $sessionMock->shouldReceive('getSection') + ->andReturn($sessionSectionMock); + + $presenter = new TestPresenter; $presenter->injectPrimary( null, @@ -151,20 +115,18 @@ test('', function () { new Application\Routers\SimpleRouter, new Http\Request(new Http\UrlScript), new Http\Response, - $session = new MockSession + $sessionMock ); - $section = $session->testSection = new MockSessionSection($session); - $applicationRequest = new Application\Request('', '', []); $presenter->run($applicationRequest); $expiration = '+1 year'; $key = $presenter->storeRequest($expiration); - Assert::same($expiration, $section->testExpiration); - Assert::same($key, $section->testExpirationVariables); - Assert::same($key, $section->testedKeyExistence); - Assert::same($key, $section->storedKey); - Assert::same([null, $applicationRequest], $section->storedValue); + Assert::same($expiration, $testExpiration); + Assert::same($key, $testExpirationVariables); + Assert::same($key, $testedKeyExistence); + Assert::same($key, $storedKey); + Assert::same([null, $applicationRequest], $storedValue); }); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 91c483705..4861eb612 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -14,6 +14,7 @@ // configure environment Tester\Environment::setup(); date_default_timezone_set('Europe/Prague'); +Mockery::setLoader(new Mockery\Loader\RequireLoader(getTempDir())); // output buffer level check