diff --git a/.gitignore b/.gitignore
index cb7f3e4ba..c8aeadf8d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -82,5 +82,6 @@ compose.override.yaml
###> phpunit/phpunit ###
/phpunit.xml
/.phpunit.result.cache
+/.phpunit.cache
###< phpunit/phpunit ###
diff --git a/composer.json b/composer.json
index 42aa83d4d..359d3efa1 100644
--- a/composer.json
+++ b/composer.json
@@ -98,7 +98,7 @@
"bobdenotter/configuration-notices": "^1.2",
"bobdenotter/weatherwidget": "^1.1",
"bolt/newswidget": "^1.3",
- "dama/doctrine-test-bundle": "^6.6.0",
+ "dama/doctrine-test-bundle": "^6.0",
"nyholm/psr7": "^1.4",
"ondram/ci-detector": "^4.1",
"php-http/curl-client": "^2.2",
@@ -108,7 +108,7 @@
"phpstan/phpstan": "^1.2.0",
"phpstan/phpstan-doctrine": "^1.0",
"phpstan/phpstan-symfony": "^1.0.1",
- "phpunit/phpunit": "^8.5",
+ "phpunit/phpunit": "^9.6",
"se/selenium-server-standalone": "^3.141",
"symfony/browser-kit": "^5.4",
"symfony/css-selector": "^5.4",
@@ -123,7 +123,8 @@
"composer/package-versions-deprecated": true,
"drupol/composer-packages": true,
"symfony/flex": true,
- "php-http/discovery": true
+ "php-http/discovery": true,
+ "dealerdirect/phpcodesniffer-composer-installer": false
}
},
"extra": {
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 7f403a2c4..d83a45b17 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,21 +1,19 @@
-
+ failOnWarning="true"
+ bootstrap="phpunit.bootstrap.php">
-
+
-
@@ -26,15 +24,12 @@
-
tests/php/
-
-
+
-
diff --git a/symfony.lock b/symfony.lock
index fd3656993..0aca9af59 100644
--- a/symfony.lock
+++ b/symfony.lock
@@ -389,9 +389,6 @@
"phpunit/php-timer": {
"version": "2.1.2"
},
- "phpunit/php-token-stream": {
- "version": "3.1.1"
- },
"phpunit/phpunit": {
"version": "4.7",
"recipe": {
@@ -475,9 +472,6 @@
"sebastian/recursion-context": {
"version": "3.0.0"
},
- "sebastian/resource-operations": {
- "version": "2.0.1"
- },
"sebastian/type": {
"version": "1.1.4"
},
diff --git a/tests/php/Controller/Backend/ContentEditControllerTest.bak b/tests/php/Controller/Backend/ContentEditControllerTest.bak
index b7f0d64b8..ecbd10af3 100644
--- a/tests/php/Controller/Backend/ContentEditControllerTest.bak
+++ b/tests/php/Controller/Backend/ContentEditControllerTest.bak
@@ -51,8 +51,8 @@ X-Robots-Tag: noindex
public function testCreateNewComplexNestedContent(): void
{
- // (2) use self::$container to access the service container
- $container = self::$container;
+ // (2) use self::getContainer() to access the service container
+ $container = self::getContainer();
$admin = $this->getEm()->getRepository(User::class)->findOneByUsername('admin');
$this->client->loginUser($admin);
diff --git a/tests/php/Menu/FrontendMenuBuilderTest.php b/tests/php/Menu/FrontendMenuBuilderTest.php
index a612b79ae..0a2033894 100644
--- a/tests/php/Menu/FrontendMenuBuilderTest.php
+++ b/tests/php/Menu/FrontendMenuBuilderTest.php
@@ -4,6 +4,7 @@
namespace Bolt\Tests\Menu;
+use RuntimeException;
use Bolt\Collection\DeepCollection;
use Bolt\Menu\FrontendMenuBuilder;
use Bolt\Tests\DbAwareTestCase;
@@ -31,7 +32,7 @@ protected function setUp(): void
{
parent::setUp();
- $this->menuBuilder = self::$container->get(FrontendMenuBuilder::class);
+ $this->menuBuilder = self::getContainer()->get(FrontendMenuBuilder::class);
// Setup mocks for testing the localized menu
$this->twig = $this->createMock(Environment::class);
@@ -42,9 +43,21 @@ protected function setUp(): void
$this->request->attributes = $this->createMock(ParameterBag::class);
$this->request->attributes
+ ->expects($matcher = $this->atMost(2))
->method('get')
- ->withConsecutive(['_route'], ['_route_params'])
- ->willReturn('homepage_locale', []);
+ ->willReturnCallback(function (string $route) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('_route', $route);
+ return 'homepage_locale';
+ }
+
+ if ($matcher->getInvocationCount() === 2) {
+ $this->assertSame('_route_params', $route);
+ return [];
+ }
+
+ throw new RuntimeException('Unexpected call');
+ });
$this->app = $this->createMock(AppVariable::class);
$this->app->method('getRequest')->willReturn($this->request);
$this->twig->method('getGlobals')->willReturn(['app' => $this->app]);
@@ -52,7 +65,7 @@ protected function setUp(): void
public function testNonExistingMenu(): void
{
- $this->expectException(\RuntimeException::class);
+ $this->expectException(RuntimeException::class);
$this->menuBuilder->buildMenu($this->twig, 'foo');
}
diff --git a/tests/php/Twig/ContentExtensionTestCase.php b/tests/php/Twig/ContentExtensionTestCase.php
index f51081fc2..3c7fe5550 100644
--- a/tests/php/Twig/ContentExtensionTestCase.php
+++ b/tests/php/Twig/ContentExtensionTestCase.php
@@ -16,6 +16,7 @@
use Doctrine\Common\Collections\ArrayCollection;
use PHPUnit\Framework\MockObject\MockObject;
use Twig\Environment;
+use RuntimeException;
class ContentExtensionTestCase extends DbAwareTestCase
{
@@ -35,7 +36,7 @@ protected function setUp(): void
{
parent::setUp();
- $this->extension = self::$container->get(ContentExtension::class);
+ $this->extension = self::getContainer()->get(ContentExtension::class);
$this->content = $this->createMock(Content::class);
$this->definition = $this->createMock(ContentType::class);
$this->content->method('getDefinition')
@@ -45,20 +46,50 @@ protected function setUp(): void
public function testTitle(): void
{
- $this->definition->method('has')
- ->withConsecutive(['title_format'])
- ->willReturn(true);
- $this->definition->method('get')
- ->withConsecutive(['title_format'])
- ->willReturn('{number}: {title}');
+ $this->definition
+ ->expects($matcher = $this->exactly(1))
+ ->method('has')
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('title_format', $parameters[0]);
+ }
+ return true;
+ });
+ $this->definition
+ ->expects($matcher = $this->exactly(1))
+ ->method('get')
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('title_format', $parameters[0]);
+ }
+ return '{number}: {title}';
+ });
$this->content->method('getId')
->willReturn(1);
- $this->content->method('hasField')
- ->withConsecutive(['number'], ['title'])
- ->willReturnOnConsecutiveCalls(false, true);
- $this->content->method('getField')
- ->withConsecutive(['title'])
- ->willReturn($this->field);
+ $this->content
+ ->expects($matcher = $this->exactly(2))
+ ->method('hasField')
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('number', $parameters[0]);
+ return false;
+ }
+ if ($matcher->getInvocationCount() === 2) {
+ $this->assertSame('title', $parameters[0]);
+ return true;
+ }
+
+ throw new RuntimeException('Unexpected call');
+ });
+ $this->content
+ ->expects($matcher = $this->exactly(1))
+ ->method('getField')
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('title', $parameters[0]);
+ }
+ return $this->field;
+ });
$this->field->method('isTranslatable')
->willReturn(false);
$this->field->method('__toString')
@@ -69,17 +100,41 @@ public function testTitle(): void
public function testTitleFields(): void
{
- $this->definition->method('has')
- ->withConsecutive(['title_format'])
- ->willReturn(true);
- $this->definition->method('get')
- ->withConsecutive(['title_format'])
- ->willReturn('{number}: {title}');
+ $this->definition
+ ->expects($matcher = $this->exactly(1))
+ ->method('has')
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('title_format', $parameters[0]);
+ }
+ return true;
+ });
+ $this->definition
+ ->expects($matcher = $this->exactly(1))
+ ->method('get')
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('title_format', $parameters[0]);
+ }
+ return '{number}: {title}';
+ });
$this->content->method('getId')
->willReturn(1);
- $this->content->method('hasField')
- ->withConsecutive(['number'], ['title'])
- ->willReturnOnConsecutiveCalls(false, true);
+ $this->content
+ ->expects($matcher = $this->exactly(2))
+ ->method('hasField')
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('number', $parameters[0]);
+ return false;
+ }
+ if ($matcher->getInvocationCount() === 2) {
+ $this->assertSame('title', $parameters[0]);
+ return true;
+ }
+
+ throw new RuntimeException('Unexpected call');
+ });
$this->assertSame(['number', 'title'], $this->extension->getTitleFieldsNames($this->content));
}
@@ -96,9 +151,15 @@ public function testContentImage(): void
$this->assertNull($this->extension->getImage($this->content));
- $imagefield->method('get')
- ->withConsecutive(['filename'])
- ->willReturn('example.jpg');
+ $imagefield
+ ->expects($matcher = $this->exactly(1))
+ ->method('get')
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('filename', $parameters[0]);
+ }
+ return 'example.jpg';
+ });
$this->assertSame($imagefield, $this->extension->getImage($this->content));
}
@@ -107,9 +168,14 @@ public function testContentImageWithImagelist(): void
$field1 = $this->createMock(Field::class);
$field2 = $this->createMock(Field::class);
$image1 = $this->createMock(ImageField::class);
- $image1->method('get')
- ->withConsecutive(['filename'])
- ->willReturn('testimage.jpg');
+ $image1->expects($matcher = $this->exactly(1))
+ ->method('get')
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('filename', $parameters[0]);
+ }
+ return 'testimage.jpg';
+ });
$image2 = $this->createMock(ImageField::class);
$imagelist = $this->createMock(ImagelistField::class);
$field3 = $this->createMock(Field::class);
@@ -128,24 +194,66 @@ public function testExcerptOnString(): void
public function testExceptFromFormatShort(): void
{
- $this->definition->method('get')
- ->withConsecutive(['excerpt_format'])
- ->willReturn('{subheading}: {body}');
-
- $this->content->method('hasField')
- ->withConsecutive(['subheading'], ['body'])
- ->willReturnOnConsecutiveCalls(true, true);
+ $this->definition
+ ->expects($matcher = $this->exactly(1))
+ ->method('get')
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('excerpt_format', $parameters[0]);
+ }
+ return '{subheading}: {body}';
+ });
+
+ $this->content
+ ->expects($matcher = $this->exactly(2))
+ ->method('hasField')
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('subheading', $parameters[0]);
+ return true;
+ }
+ if ($matcher->getInvocationCount() === 2) {
+ $this->assertSame('body', $parameters[0]);
+ return true;
+ }
+
+ throw new RuntimeException('Unexpected call');
+ });
$field1 = $this->createMock(Field::class);
$field2 = $this->createMock(Field::class);
$field1->method('__toString')->willReturn("In this week's news");
$field2->method('__toString')->willReturn('Bolt 4 is pretty awesome.');
- $this->content->method('getField')
- ->withConsecutive(['subheading'], ['body'])
- ->willReturnOnConsecutiveCalls($field1, $field2);
- $this->definition->method('has')
- ->withConsecutive(['excerpt_format'], ['subheading'], ['body'])
- ->willReturn(true);
+ $this->content
+ ->expects($matcher = $this->exactly(2))
+ ->method('getField')
+ ->willReturnCallback(function (...$parameters) use ($matcher, $field1, $field2) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('subheading', $parameters[0]);
+ return $field1;
+ }
+ if ($matcher->getInvocationCount() === 2) {
+ $this->assertSame('body', $parameters[0]);
+ return $field2;
+ }
+
+ throw new RuntimeException('Unexpected call');
+ });
+ $this->definition
+ ->expects($matcher = $this->exactly(3))
+ ->method('has')
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('excerpt_format', $parameters[0]);
+ }
+ if ($matcher->getInvocationCount() === 2) {
+ $this->assertSame('subheading', $parameters[0]);
+ }
+ if ($matcher->getInvocationCount() === 3) {
+ $this->assertSame('body', $parameters[0]);
+ }
+ return true;
+ });
$this->content->method('getId')
->willReturn(1);
@@ -154,24 +262,66 @@ public function testExceptFromFormatShort(): void
public function testExceptFromFormatFull(): void
{
- $this->definition->method('get')
- ->withConsecutive(['excerpt_format'])
- ->willReturn('{subheading}: {body}');
-
- $this->content->method('hasField')
- ->withConsecutive(['subheading'], ['body'])
- ->willReturnOnConsecutiveCalls(true, true);
+ $this->definition
+ ->expects($matcher = $this->exactly(1))
+ ->method('get')
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('excerpt_format', $parameters[0]);
+ }
+ return '{subheading}: {body}';
+ });
+
+ $this->content
+ ->expects($matcher = $this->exactly(2))
+ ->method('hasField')
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('subheading', $parameters[0]);
+ return true;
+ }
+ if ($matcher->getInvocationCount() === 2) {
+ $this->assertSame('body', $parameters[0]);
+ return true;
+ }
+
+ throw new RuntimeException('Unexpected call');
+ });
$field1 = $this->createMock(Field::class);
$field2 = $this->createMock(Field::class);
$field1->method('__toString')->willReturn("In this week's news");
$field2->method('__toString')->willReturn('Bolt 4 is pretty awesome.');
- $this->content->method('getField')
- ->withConsecutive(['subheading'], ['body'])
- ->willReturnOnConsecutiveCalls($field1, $field2);
- $this->definition->method('has')
- ->withConsecutive(['excerpt_format'], ['subheading'], ['body'])
- ->willReturn(true);
+ $this->content
+ ->expects($matcher = $this->exactly(2))
+ ->method('getField')
+ ->willReturnCallback(function (...$parameters) use ($matcher, $field1, $field2) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('subheading', $parameters[0]);
+ return $field1;
+ }
+ if ($matcher->getInvocationCount() === 2) {
+ $this->assertSame('body', $parameters[0]);
+ return $field2;
+ }
+
+ throw new RuntimeException('Unexpected call');
+ });
+ $this->definition
+ ->expects($matcher = $this->exactly(3))
+ ->method('has')
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('excerpt_format', $parameters[0]);
+ }
+ if ($matcher->getInvocationCount() === 2) {
+ $this->assertSame('subheading', $parameters[0]);
+ }
+ if ($matcher->getInvocationCount() === 3) {
+ $this->assertSame('body', $parameters[0]);
+ }
+ return true;
+ });
$this->content->method('getId')
->willReturn(1);
diff --git a/tests/php/Twig/FieldExtensionTestCase.php b/tests/php/Twig/FieldExtensionTestCase.php
index 7092bebcc..fbe751634 100644
--- a/tests/php/Twig/FieldExtensionTestCase.php
+++ b/tests/php/Twig/FieldExtensionTestCase.php
@@ -24,7 +24,7 @@ protected function setUp(): void
{
parent::setUp();
- $this->extension = self::$container->get(FieldExtension::class);
+ $this->extension = self::getContainer()->get(FieldExtension::class);
$this->field = $this->createMock(Field::class);
$this->fieldType = $this->createMock(FieldType::class);
@@ -34,18 +34,30 @@ protected function setUp(): void
public function testFieldLabel(): void
{
- $this->fieldType->method('get')
- ->withConsecutive(['label'])
- ->wilLReturn('Test field');
+ $this->fieldType
+ ->expects($matcher = $this->exactly(1))
+ ->method('get')
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('label', $parameters[0]);
+ }
+ return 'Test field';
+ });
$this->assertSame('Test field', $this->extension->getLabel($this->field));
}
public function testFieldType(): void
{
- $this->fieldType->method('get')
- ->withConsecutive(['type'])
- ->willReturn('embed');
+ $this->fieldType
+ ->expects($matcher = $this->exactly(1))
+ ->method('get')
+ ->willReturnCallback(function (...$parameters) use ($matcher) {
+ if ($matcher->getInvocationCount() === 1) {
+ $this->assertSame('type', $parameters[0]);
+ }
+ return 'embed';
+ });
$this->assertSame('embed', $this->extension->getType($this->field));
}
diff --git a/tests/php/Twig/TextExtensionTestCase.php b/tests/php/Twig/TextExtensionTestCase.php
index 486ade7cf..738bbd0ab 100644
--- a/tests/php/Twig/TextExtensionTestCase.php
+++ b/tests/php/Twig/TextExtensionTestCase.php
@@ -16,7 +16,7 @@ protected function setUp(): void
{
parent::setUp();
- $this->extension = self::$container->get(TextExtension::class);
+ $this->extension = self::getContainer()->get(TextExtension::class);
}
public function testPlainText(): void
diff --git a/tests/php/Twig/TokenParserTestCase.php b/tests/php/Twig/TokenParserTestCase.php
index 58b848ace..f84a8d61d 100644
--- a/tests/php/Twig/TokenParserTestCase.php
+++ b/tests/php/Twig/TokenParserTestCase.php
@@ -4,6 +4,8 @@
namespace Bolt\Tests\Twig;
+use PHPUnit\Framework\TestCase;
+use ReflectionProperty;
use Twig\Environment;
use Twig\Loader\LoaderInterface;
use Twig\Node\Node;
@@ -17,7 +19,7 @@
* @author Gawain Lynch
* @author Bob den Otter
*/
-abstract class TokenParserTestCase extends \PHPUnit\Framework\TestCase
+abstract class TokenParserTestCase extends TestCase
{
protected function getParser(TokenStream $tokenStream, AbstractTokenParser $testParser): Parser
{
@@ -26,7 +28,7 @@ protected function getParser(TokenStream $tokenStream, AbstractTokenParser $test
$parser = new Parser($env);
$parser->setParent(new Node());
- $p = new \ReflectionProperty($parser, 'stream');
+ $p = new ReflectionProperty($parser, 'stream');
$p->setAccessible(true);
$p->setValue($parser, $tokenStream);
diff --git a/tests/php/Utils/StrTest.php b/tests/php/Utils/StrTest.php
index 2c2de5bd2..8118ecd38 100644
--- a/tests/php/Utils/StrTest.php
+++ b/tests/php/Utils/StrTest.php
@@ -4,9 +4,10 @@
namespace Bolt\Tests\Utils;
+use PHPUnit\Framework\TestCase;
use Bolt\Common\Str;
-class StrTest extends \PHPUnit\Framework\TestCase
+class StrTest extends TestCase
{
public function testSlug(): void
{
diff --git a/tests/php/Widget/Injector/RequestZoneTest.php b/tests/php/Widget/Injector/RequestZoneTest.php
index 4135a27b2..3b3635b57 100644
--- a/tests/php/Widget/Injector/RequestZoneTest.php
+++ b/tests/php/Widget/Injector/RequestZoneTest.php
@@ -4,6 +4,7 @@
namespace Bolt\Tests\Widget\Injector;
+use ReflectionClass;
use Bolt\Widget\Injector\RequestZone;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
@@ -13,7 +14,7 @@ class RequestZoneTest extends TestCase
{
public function providerZone()
{
- $o = new \ReflectionClass(RequestZone::class);
+ $o = new ReflectionClass(RequestZone::class);
$constants = (new Collection(array_keys($o->getConstants())))
->filter(function ($v) {
return mb_strpos($v, 'NOWHERE') === false;