Skip to content

Commit 81aa7ac

Browse files
authored
Merge pull request #17 from peckadesign/nette-2.4
Aktualizace pro nette 2.4 a PHP 8.0
2 parents 96e1102 + 6f87246 commit 81aa7ac

8 files changed

+88
-126
lines changed

.github/workflows/php-package-ci.yml

+2-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
runs-on: ubuntu-latest
1010
strategy:
1111
matrix:
12-
php: [ 7.0, 7.1 ]
12+
php: [ 7.4, 8.0 ]
1313
steps:
1414
- uses: actions/checkout@v2
1515
- uses: shivammathur/setup-php@v2
@@ -18,7 +18,6 @@ jobs:
1818

1919
- run: make composer
2020

21-
- if: matrix.php == '7.1'
22-
run: make phpstan
21+
- run: make phpstan
2322

2423
- run: make run-tests

Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ composer:
33
composer update --no-interaction --prefer-dist
44

55
phpstan:
6-
vendor/bin/phpstan analyse -l 5 -c phpstan.neon src/
6+
vendor/bin/phpstan analyse -l 9 -c phpstan.neon src/
77

88
run-tests:
9-
vendor/bin/tester tests
9+
vendor/bin/tester tests -d extension=tokenizer.so

composer.json

+5-5
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@
2121
}
2222
],
2323
"require": {
24-
"php": "~7.0",
25-
"nette/application": ">= 2.2.10 < 2.3.0"
24+
"php": "~7.4 | ~8.0",
25+
"nette/application": "^2.4"
2626
},
2727
"require-dev": {
28-
"phpstan/phpstan": "~0.6.0",
29-
"nette/tester": "~1.7.0",
30-
"mockery/mockery": "~0.9.0"
28+
"phpstan/phpstan": "^1.0",
29+
"nette/tester": "^2.0",
30+
"mockery/mockery": "^1.0"
3131
},
3232
"autoload": {
3333
"psr-4": {

phpstan.neon

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
parameters:
22
ignoreErrors:
3-
- '#Call to an undefined method [a-zA-Z0-9\\_]+::renderAsync\(\)#'
4-
- '#Call to an undefined method [a-zA-Z0-9\\_]+::render\(\)#'
53
fileExtensions:
64
- phpt
75

8-
autoload_directories:
9-
# - %rootDir%/../../../test
10-
6+
treatPhpDocTypesAsCertain: false

src/UI/AsyncControlLink.php

+27-16
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,53 @@
55
final class AsyncControlLink
66
{
77

8-
private static $defaultMessage = 'Load content';
9-
private static $defaultAttributes = [];
8+
private static string $defaultMessage = 'Load content';
9+
1010
/**
11-
* @var string
11+
* @var array<string, string>
1212
*/
13-
private $message;
13+
private static array $defaultAttributes = [];
14+
15+
private string $message;
16+
1417
/**
15-
* @var array
18+
* @var array<string, string>
1619
*/
17-
private $attributes;
18-
20+
private array $attributes;
1921

22+
/**
23+
* @param string|null $message
24+
* @param array<string, string> $attributes
25+
*/
2026
public function __construct(
21-
string $message = NULL,
22-
array $attributes = NULL
23-
) {
24-
$this->message = $message === NULL ? self::$defaultMessage : $message;
25-
$this->attributes = $attributes === NULL ? self::$defaultAttributes : $attributes;
27+
?string $message = null,
28+
?array $attributes = null
29+
)
30+
{
31+
$this->message = $message === null ? self::$defaultMessage : $message;
32+
$this->attributes = $attributes === null ? self::$defaultAttributes : $attributes;
2633
}
2734

28-
29-
public static function setDefault(string $message, array $attributes = [])
35+
/**
36+
* @param array<string, string> $attributes
37+
*/
38+
public static function setDefault(string $message, array $attributes = []): void
3039
{
3140
self::$defaultMessage = $message;
3241
self::$defaultAttributes = $attributes;
3342
}
3443

35-
3644
public function getMessage(): string
3745
{
3846
return $this->message;
3947
}
4048

41-
49+
/**
50+
* @return array<string, string>
51+
*/
4252
public function getAttributes(): array
4353
{
4454
return $this->attributes;
4555
}
56+
4657
}

src/UI/AsyncControlTrait.php

+24-25
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33
namespace Pd\AsyncControl\UI;
44

55
use Nette\Application\UI\Control;
6-
use Nette\Application\UI\Presenter;
76
use Nette\Bridges\ApplicationLatte\Template;
87

98

109
/**
11-
* @method render
10+
* @method render()
1211
*/
1312
trait AsyncControlTrait
1413
{
@@ -19,51 +18,51 @@ trait AsyncControlTrait
1918
protected $asyncRenderer;
2019

2120

22-
public function handleAsyncLoad()
21+
public function handleAsyncLoad(): void
2322
{
2423
if ( ! $this instanceof Control || ! ($presenter = $this->getPresenter(FALSE)) || ! $presenter->isAjax()) {
2524
return;
2625
}
2726
ob_start(function () {
2827
});
2928
try {
30-
$this->renderAsync();
29+
$this->doRender();
3130
} catch (\Throwable $e) {
3231
ob_end_clean();
3332
throw $e;
34-
} catch (\Exception $e) {
35-
ob_end_clean();
36-
throw $e;
3733
}
3834
$content = ob_get_clean();
3935
$presenter->getPayload()->snippets[$this->getSnippetId('async')] = $content;
4036
$presenter->sendPayload();
4137
}
4238

43-
44-
public function renderAsync(string $linkMessage = NULL, array $linkAttributes = NULL)
39+
/**
40+
* @param array<string, string> $linkAttributes
41+
* @return void
42+
*/
43+
public function renderAsync(string $linkMessage = NULL, array $linkAttributes = NULL): void
4544
{
46-
if (
47-
$this instanceof Control
48-
&& $this->getPresenter()->getParameter('_escaped_fragment_') === NULL
49-
&& strpos((string) $this->getPresenter()->getParameter(Presenter::SIGNAL_KEY), sprintf('%s-', $this->getUniqueId())) !== 0
50-
) {
51-
$template = $this->createTemplate();
52-
if ($template instanceof Template) {
53-
$template->add('link', new AsyncControlLink($linkMessage, $linkAttributes));
54-
}
55-
$template->setFile(__DIR__ . '/templates/asyncLoadLink.latte');
56-
$template->render();
57-
} elseif (is_callable($this->asyncRenderer)) {
58-
call_user_func($this->asyncRenderer);
59-
} else {
60-
$this->render();
45+
$template = $this->createTemplate();
46+
if ($template instanceof Template) {
47+
$template->add('link', new AsyncControlLink($linkMessage, $linkAttributes));
6148
}
49+
$template->setFile(__DIR__ . '/templates/asyncLoadLink.latte');
50+
$template->render();
6251
}
6352

6453

65-
public function setAsyncRenderer(callable $renderer)
54+
public function setAsyncRenderer(callable $renderer): void
6655
{
6756
$this->asyncRenderer = $renderer;
6857
}
58+
59+
60+
protected function doRender(): void
61+
{
62+
if (is_callable($this->asyncRenderer)) {
63+
call_user_func($this->asyncRenderer);
64+
} else {
65+
$this->render();
66+
}
67+
}
6968
}

tests/UI/AsyncControlLinkTest.phpt

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ use Tester\TestCase;
88

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

11-
11+
/**
12+
* @testCase
13+
*/
1214
final class AsyncControlLinkTest extends TestCase
1315
{
1416

15-
public function testLink()
17+
public function testLink(): void
1618
{
1719
$link = new AsyncControlLink;
1820
Assert::equal('Load content', $link->getMessage());

tests/UI/AsyncControlTest.phpt

+23-68
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,36 @@
33
namespace Pd\AsyncControl\UI;
44

55
use Mockery;
6-
use Nette\Application\UI\ITemplate;
7-
use Nette\Application\UI\ITemplateFactory;
6+
7+
use Nette\Bridges\ApplicationLatte\TemplateFactory;
8+
use Nette\Bridges\ApplicationLatte\Template;
89
use Nette\Application\UI\Presenter;
910
use Tester\Assert;
1011
use Tester\TestCase;
1112

1213

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

16+
\Tester\Environment::bypassFinals();
1517

18+
/**
19+
* @testCase
20+
*/
1621
final class AsyncControlTest extends TestCase
1722
{
1823

19-
const VALID_SIGNAL = 'control-form-submit';
20-
const FRAGMENT_PARAMETER = '_escaped_fragment_';
21-
2224

23-
public function testHandleAjax()
25+
public function testHandleAjax(): void
2426
{
2527
$presenter = Mockery::mock(Presenter::class);
2628
$presenter->shouldReceive('isAjax')->once()->andReturn(TRUE);
27-
$presenter->shouldReceive('getPayload')->andReturn($payload = new \stdClass);
29+
$presenter->shouldReceive('getPayload')->andReturn($payload = new \stdClass());
2830
$presenter->shouldReceive('sendPayload')->once();
29-
/**
30-
* @var AsyncControl|Mockery\Mock $control
31-
*/
32-
$control = Mockery::mock(AsyncControl::class)->makePartial();
31+
32+
$control = Mockery::mock(AsyncControl::class)->makePartial()->shouldAllowMockingProtectedMethods();
3333
$control->shouldReceive('getPresenter')->andReturn($presenter);
3434
$renderedContent = 'rendered content';
35-
$control->shouldReceive('renderAsync')->once()->andReturnUsing(function () use ($renderedContent) {
35+
$control->shouldReceive('doRender')->once()->andReturnUsing(function () use ($renderedContent) {
3636
echo $renderedContent;
3737
})
3838
;
@@ -43,15 +43,13 @@ final class AsyncControlTest extends TestCase
4343
}
4444

4545

46-
public function testHandleNoAjax()
46+
public function testHandleNoAjax(): void
4747
{
4848
$presenter = Mockery::mock(Presenter::class);
4949
$presenter->shouldReceive('isAjax')->once()->andReturn(FALSE);
5050
$presenter->shouldNotReceive('getPayload');
5151
$presenter->shouldNotReceive('sendPayload');
52-
/**
53-
* @var AsyncControl|Mockery\Mock $control
54-
*/
52+
5553
$control = Mockery::mock(AsyncControl::class)->makePartial();
5654
$control->shouldReceive('getPresenter')->andReturn($presenter);
5755
$control->shouldNotReceive('renderAsync');
@@ -60,82 +58,39 @@ final class AsyncControlTest extends TestCase
6058
}
6159

6260

63-
public function testRenderAsyncLoadLink()
61+
public function testRenderAsyncLoadsLink(): void
6462
{
65-
/**
66-
* @var AsyncControl|Mockery\Mock $control
67-
*/
6863
$control = Mockery::mock(AsyncControl::class)->makePartial();
6964

70-
$template = Mockery::mock(ITemplate::class);
65+
$template = Mockery::mock(Template::class);
66+
$template->shouldReceive('add')->once()->with('link', Mockery::type(AsyncControlLink::class));
7167
$template->shouldReceive('setFile')->once()->withAnyArgs();
7268
$template->shouldReceive('render')->once();
7369

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

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

82-
$control->shouldReceive('getPresenter')->andReturn($presenter);
83-
$control->shouldReceive('getUniqueId')->once()->andReturn('control');
84-
$control->renderAsync();
85-
}
86-
87-
88-
public function testRenderWithSignal()
89-
{
90-
$presenter = Mockery::mock(Presenter::class);
91-
$presenter->shouldReceive('getParameter')->once()->with(self::FRAGMENT_PARAMETER)->andReturn(NULL);
92-
$presenter->shouldReceive('getParameter')->once()->with(Presenter::SIGNAL_KEY)->andReturn(self::VALID_SIGNAL);
93-
/**
94-
* @var AsyncControl|Mockery\Mock $control
95-
*/
96-
$control = Mockery::mock(AsyncControl::class)->makePartial();
97-
$control->shouldReceive('getPresenter')->andReturn($presenter);
98-
$control->shouldReceive('getUniqueId')->once()->andReturn('control');
99-
$control->shouldReceive('render')->once();
100-
$control->renderAsync();
101-
}
102-
103-
104-
public function testRenderWithFragment()
105-
{
106-
$presenter = Mockery::mock(Presenter::class);
107-
$presenter->shouldReceive('getParameter')->once()->with(self::FRAGMENT_PARAMETER)->andReturn('');
108-
/**
109-
* @var AsyncControl|Mockery\Mock $control
110-
*/
111-
$control = Mockery::mock(AsyncControl::class)->makePartial();
112-
$control->shouldReceive('getPresenter')->andReturn($presenter);
113-
$control->shouldReceive('render')->once();
76+
$control->shouldReceive('getPresenter')->once()->andReturn($presenter);
11477
$control->renderAsync();
11578
}
11679

11780

118-
public function testRenderAsyncRenderer()
81+
public function testRenderAsyncRenderer(): void
11982
{
120-
$presenter = Mockery::mock(Presenter::class);
121-
$presenter->shouldReceive('getParameter')->once()->with(self::FRAGMENT_PARAMETER)->andReturn(NULL);
122-
$presenter->shouldReceive('getParameter')->once()->with(Presenter::SIGNAL_KEY)->andReturn(self::VALID_SIGNAL);
123-
/**
124-
* @var AsyncControl|Mockery\Mock $control
125-
*/
126-
$control = Mockery::mock(AsyncControl::class)->makePartial();
127-
$control->shouldReceive('getPresenter')->andReturn($presenter);
128-
$control->shouldReceive('getUniqueId')->once()->andReturn('control');
83+
$control = Mockery::mock(AsyncControl::class)->makePartial()->shouldAllowMockingProtectedMethods();
12984
$asyncRendered = FALSE;
13085
$control->setAsyncRenderer(function () use (&$asyncRendered) {
13186
$asyncRendered = TRUE;
13287
});
133-
$control->renderAsync();
88+
$control->doRender();
13489
Assert::equal(TRUE, $asyncRendered);
13590
}
13691

13792

138-
protected function tearDown()
93+
protected function tearDown(): void
13994
{
14095
parent::tearDown();
14196
Mockery::close();

0 commit comments

Comments
 (0)