Skip to content

Commit

Permalink
Merge pull request #17 from peckadesign/nette-2.4
Browse files Browse the repository at this point in the history
Aktualizace pro nette 2.4 a PHP 8.0
  • Loading branch information
krejzyeu authored Jan 10, 2024
2 parents 96e1102 + 6f87246 commit 81aa7ac
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 126 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/php-package-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
php: [ 7.0, 7.1 ]
php: [ 7.4, 8.0 ]
steps:
- uses: actions/checkout@v2
- uses: shivammathur/setup-php@v2
Expand All @@ -18,7 +18,6 @@ jobs:

- run: make composer

- if: matrix.php == '7.1'
run: make phpstan
- run: make phpstan

- run: make run-tests
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ composer:
composer update --no-interaction --prefer-dist

phpstan:
vendor/bin/phpstan analyse -l 5 -c phpstan.neon src/
vendor/bin/phpstan analyse -l 9 -c phpstan.neon src/

run-tests:
vendor/bin/tester tests
vendor/bin/tester tests -d extension=tokenizer.so
10 changes: 5 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
}
],
"require": {
"php": "~7.0",
"nette/application": ">= 2.2.10 < 2.3.0"
"php": "~7.4 | ~8.0",
"nette/application": "^2.4"
},
"require-dev": {
"phpstan/phpstan": "~0.6.0",
"nette/tester": "~1.7.0",
"mockery/mockery": "~0.9.0"
"phpstan/phpstan": "^1.0",
"nette/tester": "^2.0",
"mockery/mockery": "^1.0"
},
"autoload": {
"psr-4": {
Expand Down
6 changes: 1 addition & 5 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
parameters:
ignoreErrors:
- '#Call to an undefined method [a-zA-Z0-9\\_]+::renderAsync\(\)#'
- '#Call to an undefined method [a-zA-Z0-9\\_]+::render\(\)#'
fileExtensions:
- phpt

autoload_directories:
# - %rootDir%/../../../test

treatPhpDocTypesAsCertain: false
43 changes: 27 additions & 16 deletions src/UI/AsyncControlLink.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,53 @@
final class AsyncControlLink
{

private static $defaultMessage = 'Load content';
private static $defaultAttributes = [];
private static string $defaultMessage = 'Load content';

/**
* @var string
* @var array<string, string>
*/
private $message;
private static array $defaultAttributes = [];

private string $message;

/**
* @var array
* @var array<string, string>
*/
private $attributes;

private array $attributes;

/**
* @param string|null $message
* @param array<string, string> $attributes
*/
public function __construct(
string $message = NULL,
array $attributes = NULL
) {
$this->message = $message === NULL ? self::$defaultMessage : $message;
$this->attributes = $attributes === NULL ? self::$defaultAttributes : $attributes;
?string $message = null,
?array $attributes = null
)
{
$this->message = $message === null ? self::$defaultMessage : $message;
$this->attributes = $attributes === null ? self::$defaultAttributes : $attributes;
}


public static function setDefault(string $message, array $attributes = [])
/**
* @param array<string, string> $attributes
*/
public static function setDefault(string $message, array $attributes = []): void
{
self::$defaultMessage = $message;
self::$defaultAttributes = $attributes;
}


public function getMessage(): string
{
return $this->message;
}


/**
* @return array<string, string>
*/
public function getAttributes(): array
{
return $this->attributes;
}

}
49 changes: 24 additions & 25 deletions src/UI/AsyncControlTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
namespace Pd\AsyncControl\UI;

use Nette\Application\UI\Control;
use Nette\Application\UI\Presenter;
use Nette\Bridges\ApplicationLatte\Template;


/**
* @method render
* @method render()
*/
trait AsyncControlTrait
{
Expand All @@ -19,51 +18,51 @@ trait AsyncControlTrait
protected $asyncRenderer;


public function handleAsyncLoad()
public function handleAsyncLoad(): void
{
if ( ! $this instanceof Control || ! ($presenter = $this->getPresenter(FALSE)) || ! $presenter->isAjax()) {
return;
}
ob_start(function () {
});
try {
$this->renderAsync();
$this->doRender();
} catch (\Throwable $e) {
ob_end_clean();
throw $e;
} catch (\Exception $e) {
ob_end_clean();
throw $e;
}
$content = ob_get_clean();
$presenter->getPayload()->snippets[$this->getSnippetId('async')] = $content;
$presenter->sendPayload();
}


public function renderAsync(string $linkMessage = NULL, array $linkAttributes = NULL)
/**
* @param array<string, string> $linkAttributes
* @return void
*/
public function renderAsync(string $linkMessage = NULL, array $linkAttributes = NULL): void
{
if (
$this instanceof Control
&& $this->getPresenter()->getParameter('_escaped_fragment_') === NULL
&& strpos((string) $this->getPresenter()->getParameter(Presenter::SIGNAL_KEY), sprintf('%s-', $this->getUniqueId())) !== 0
) {
$template = $this->createTemplate();
if ($template instanceof Template) {
$template->add('link', new AsyncControlLink($linkMessage, $linkAttributes));
}
$template->setFile(__DIR__ . '/templates/asyncLoadLink.latte');
$template->render();
} elseif (is_callable($this->asyncRenderer)) {
call_user_func($this->asyncRenderer);
} else {
$this->render();
$template = $this->createTemplate();
if ($template instanceof Template) {
$template->add('link', new AsyncControlLink($linkMessage, $linkAttributes));
}
$template->setFile(__DIR__ . '/templates/asyncLoadLink.latte');
$template->render();
}


public function setAsyncRenderer(callable $renderer)
public function setAsyncRenderer(callable $renderer): void
{
$this->asyncRenderer = $renderer;
}


protected function doRender(): void
{
if (is_callable($this->asyncRenderer)) {
call_user_func($this->asyncRenderer);
} else {
$this->render();
}
}
}
6 changes: 4 additions & 2 deletions tests/UI/AsyncControlLinkTest.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ use Tester\TestCase;

require_once __DIR__ . '/../../vendor/autoload.php';


/**
* @testCase
*/
final class AsyncControlLinkTest extends TestCase
{

public function testLink()
public function testLink(): void
{
$link = new AsyncControlLink;
Assert::equal('Load content', $link->getMessage());
Expand Down
91 changes: 23 additions & 68 deletions tests/UI/AsyncControlTest.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,36 @@
namespace Pd\AsyncControl\UI;

use Mockery;
use Nette\Application\UI\ITemplate;
use Nette\Application\UI\ITemplateFactory;

use Nette\Bridges\ApplicationLatte\TemplateFactory;
use Nette\Bridges\ApplicationLatte\Template;
use Nette\Application\UI\Presenter;
use Tester\Assert;
use Tester\TestCase;


require_once __DIR__ . '/../../vendor/autoload.php';

\Tester\Environment::bypassFinals();

/**
* @testCase
*/
final class AsyncControlTest extends TestCase
{

const VALID_SIGNAL = 'control-form-submit';
const FRAGMENT_PARAMETER = '_escaped_fragment_';


public function testHandleAjax()
public function testHandleAjax(): void
{
$presenter = Mockery::mock(Presenter::class);
$presenter->shouldReceive('isAjax')->once()->andReturn(TRUE);
$presenter->shouldReceive('getPayload')->andReturn($payload = new \stdClass);
$presenter->shouldReceive('getPayload')->andReturn($payload = new \stdClass());
$presenter->shouldReceive('sendPayload')->once();
/**
* @var AsyncControl|Mockery\Mock $control
*/
$control = Mockery::mock(AsyncControl::class)->makePartial();

$control = Mockery::mock(AsyncControl::class)->makePartial()->shouldAllowMockingProtectedMethods();
$control->shouldReceive('getPresenter')->andReturn($presenter);
$renderedContent = 'rendered content';
$control->shouldReceive('renderAsync')->once()->andReturnUsing(function () use ($renderedContent) {
$control->shouldReceive('doRender')->once()->andReturnUsing(function () use ($renderedContent) {
echo $renderedContent;
})
;
Expand All @@ -43,15 +43,13 @@ final class AsyncControlTest extends TestCase
}


public function testHandleNoAjax()
public function testHandleNoAjax(): void
{
$presenter = Mockery::mock(Presenter::class);
$presenter->shouldReceive('isAjax')->once()->andReturn(FALSE);
$presenter->shouldNotReceive('getPayload');
$presenter->shouldNotReceive('sendPayload');
/**
* @var AsyncControl|Mockery\Mock $control
*/

$control = Mockery::mock(AsyncControl::class)->makePartial();
$control->shouldReceive('getPresenter')->andReturn($presenter);
$control->shouldNotReceive('renderAsync');
Expand All @@ -60,82 +58,39 @@ final class AsyncControlTest extends TestCase
}


public function testRenderAsyncLoadLink()
public function testRenderAsyncLoadsLink(): void
{
/**
* @var AsyncControl|Mockery\Mock $control
*/
$control = Mockery::mock(AsyncControl::class)->makePartial();

$template = Mockery::mock(ITemplate::class);
$template = Mockery::mock(Template::class);
$template->shouldReceive('add')->once()->with('link', Mockery::type(AsyncControlLink::class));
$template->shouldReceive('setFile')->once()->withAnyArgs();
$template->shouldReceive('render')->once();

$templateFactory = Mockery::mock(ITemplateFactory::class);
$templateFactory = Mockery::mock(TemplateFactory::class);
$templateFactory->shouldReceive('createTemplate')->once()->with($control)->andReturn($template);

$presenter = Mockery::mock(Presenter::class);
$presenter->shouldReceive('getParameter')->once()->with(self::FRAGMENT_PARAMETER)->andReturn(NULL);
$presenter->shouldReceive('getParameter')->once()->with(Presenter::SIGNAL_KEY)->andReturn(NULL);
$presenter->shouldReceive('getTemplateFactory')->once()->andReturn($templateFactory);

$control->shouldReceive('getPresenter')->andReturn($presenter);
$control->shouldReceive('getUniqueId')->once()->andReturn('control');
$control->renderAsync();
}


public function testRenderWithSignal()
{
$presenter = Mockery::mock(Presenter::class);
$presenter->shouldReceive('getParameter')->once()->with(self::FRAGMENT_PARAMETER)->andReturn(NULL);
$presenter->shouldReceive('getParameter')->once()->with(Presenter::SIGNAL_KEY)->andReturn(self::VALID_SIGNAL);
/**
* @var AsyncControl|Mockery\Mock $control
*/
$control = Mockery::mock(AsyncControl::class)->makePartial();
$control->shouldReceive('getPresenter')->andReturn($presenter);
$control->shouldReceive('getUniqueId')->once()->andReturn('control');
$control->shouldReceive('render')->once();
$control->renderAsync();
}


public function testRenderWithFragment()
{
$presenter = Mockery::mock(Presenter::class);
$presenter->shouldReceive('getParameter')->once()->with(self::FRAGMENT_PARAMETER)->andReturn('');
/**
* @var AsyncControl|Mockery\Mock $control
*/
$control = Mockery::mock(AsyncControl::class)->makePartial();
$control->shouldReceive('getPresenter')->andReturn($presenter);
$control->shouldReceive('render')->once();
$control->shouldReceive('getPresenter')->once()->andReturn($presenter);
$control->renderAsync();
}


public function testRenderAsyncRenderer()
public function testRenderAsyncRenderer(): void
{
$presenter = Mockery::mock(Presenter::class);
$presenter->shouldReceive('getParameter')->once()->with(self::FRAGMENT_PARAMETER)->andReturn(NULL);
$presenter->shouldReceive('getParameter')->once()->with(Presenter::SIGNAL_KEY)->andReturn(self::VALID_SIGNAL);
/**
* @var AsyncControl|Mockery\Mock $control
*/
$control = Mockery::mock(AsyncControl::class)->makePartial();
$control->shouldReceive('getPresenter')->andReturn($presenter);
$control->shouldReceive('getUniqueId')->once()->andReturn('control');
$control = Mockery::mock(AsyncControl::class)->makePartial()->shouldAllowMockingProtectedMethods();
$asyncRendered = FALSE;
$control->setAsyncRenderer(function () use (&$asyncRendered) {
$asyncRendered = TRUE;
});
$control->renderAsync();
$control->doRender();
Assert::equal(TRUE, $asyncRendered);
}


protected function tearDown()
protected function tearDown(): void
{
parent::tearDown();
Mockery::close();
Expand Down

0 comments on commit 81aa7ac

Please sign in to comment.