diff --git a/composer.json b/composer.json index c4bfed2..be54799 100644 --- a/composer.json +++ b/composer.json @@ -20,13 +20,10 @@ }, "require-dev": { "symfony/validator": "*", - "phpunit/phpunit": "^9.5", + "phpunit/phpunit": "^10.0", "doctrine/doctrine-bundle": "*", - "symfony/yaml": "^5.3", - "symfony/intl": "^5.3", - "squizlabs/php_codesniffer": "^3.6", - "slevomat/coding-standard": "^7.0", - "vimeo/psalm": "^4.10" + "symfony/yaml": "*", + "symfony/intl": "*" }, "autoload": { "psr-4": { @@ -37,5 +34,10 @@ "psr-4": { "Arxy\\TranslationsBundle\\Tests\\": "tests/" } + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } } } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index aa0b5a8..80ddcb3 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -5,7 +5,6 @@ namespace Arxy\TranslationsBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; -use Symfony\Component\Config\Definition\Builder\NodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; @@ -19,7 +18,7 @@ /** * {@inheritDoc} */ - public function getConfigTreeBuilder() + public function getConfigTreeBuilder(): TreeBuilder { $treeBuilder = new TreeBuilder('arxy_translations'); diff --git a/src/Translator.php b/src/Translator.php index d21d816..d9fe54d 100644 --- a/src/Translator.php +++ b/src/Translator.php @@ -97,7 +97,7 @@ public function reset(): void $this->version = $version->get(); } - public function warmUp(string $cacheDir): array + public function warmUp(string $cacheDir, ?string $buildDir = null): array { $this->warmUp = true; try { diff --git a/tests/Integration/Entity/Language.php b/tests/Integration/Entity/Language.php index 3a3dcbf..07e1ff5 100644 --- a/tests/Integration/Entity/Language.php +++ b/tests/Integration/Entity/Language.php @@ -7,19 +7,15 @@ use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; -/** - * @ORM\Entity() - * @ORM\Table(name="languages") - * @ORM\ChangeTrackingPolicy("DEFERRED_EXPLICIT") - */ +#[ORM\Entity] +#[ORM\Table(name: 'languages')] +#[ORM\ChangeTrackingPolicy('DEFERRED_EXPLICIT')] class Language { - /** - * @ORM\Id - * @ORM\Column(name="locale", type="string", length=35, nullable=false) - * @Assert\NotNull() - * @Assert\Locale() - */ + #[ORM\Id] + #[ORM\Column(name: 'locale', type: 'string', length: 35, nullable: false)] + #[Assert\NotNull] + #[Assert\Locale] protected ?string $locale = null; public function __construct(?string $locale) diff --git a/tests/Integration/Entity/Token.php b/tests/Integration/Entity/Token.php index 578f375..de27955 100644 --- a/tests/Integration/Entity/Token.php +++ b/tests/Integration/Entity/Token.php @@ -8,34 +8,29 @@ use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; -/** - * @ORM\Entity() - * @ORM\Table(name="translation_tokens") - * @ORM\ChangeTrackingPolicy("DEFERRED_EXPLICIT") - */ +#[ORM\Entity] +#[ORM\Table(name: 'translation_tokens')] +#[ORM\ChangeTrackingPolicy('DEFERRED_EXPLICIT')] class Token { - /** - * @ORM\Id - * @ORM\Column(type="integer", nullable=false) - * @ORM\GeneratedValue() - */ + #[ORM\Id] + #[ORM\GeneratedValue] + #[ORM\Column(type: 'integer', nullable: false)] private ?int $id = null; - /** - * @ORM\Column(type="text", nullable=false) - */ + #[ORM\Column(type: 'text', nullable: false)] private string $token; - /** - * @ORM\Column(type="string", length=200, nullable=false) - */ + #[ORM\Column(type: 'string', length: 200, nullable: false)] private string $catalogue; /** * @var Collection - * @ORM\OneToMany(targetEntity="Translation", mappedBy="token", cascade={"PERSIST", "REMOVE"}, orphanRemoval=true) */ + #[ORM\OneToMany(mappedBy: 'token', targetEntity: 'Translation', cascade: [ + 'PERSIST', + 'REMOVE', + ], orphanRemoval: true)] private Collection $translations; public function __construct(string $token, string $catalogue) diff --git a/tests/Integration/Entity/Translation.php b/tests/Integration/Entity/Translation.php index 3eb8ed0..4f3a04f 100644 --- a/tests/Integration/Entity/Translation.php +++ b/tests/Integration/Entity/Translation.php @@ -6,32 +6,22 @@ use Doctrine\ORM\Mapping as ORM; -/** - * @ORM\Entity() - * @ORM\Table(name="translations", - * uniqueConstraints={@ORM\UniqueConstraint(columns={"language_id", "token_id"})} - * ) - * @ORM\ChangeTrackingPolicy("DEFERRED_EXPLICIT") - */ +#[ORM\Entity] +#[ORM\Table(name: 'translations', uniqueConstraints: [new ORM\UniqueConstraint(columns: ['language_id', 'token_id'])])] +#[ORM\ChangeTrackingPolicy('DEFERRED_EXPLICIT')] class Translation { - /** - * @ORM\Id() - * @ORM\ManyToOne(targetEntity=Language::class, fetch="EAGER") - * @ORM\JoinColumn(nullable=false, referencedColumnName="locale", onDelete="CASCADE") - */ + #[ORM\Id] + #[ORM\ManyToOne(targetEntity: Language::class, fetch: 'EAGER')] + #[ORM\JoinColumn(referencedColumnName: 'locale', nullable: false, onDelete: 'CASCADE')] protected Language $language; - /** - * @ORM\Id() - * @ORM\ManyToOne(targetEntity=Token::class, fetch="EAGER", inversedBy="translations", cascade={"ALL"}) - * @ORM\JoinColumn(nullable=false, onDelete="CASCADE") - */ + #[ORM\Id] + #[ORM\ManyToOne(targetEntity: Token::class, cascade: ['ALL'], fetch: 'EAGER', inversedBy: 'translations')] + #[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')] protected Token $token; - /** - * @ORM\Column(type="text") - */ + #[ORM\Column(type: 'text')] protected string $translation; public function __construct(Language $language, Token $token, $translation) @@ -51,6 +41,11 @@ public function getToken(): ?Token return $this->token; } + public function setTranslation(string $translation): void + { + $this->translation = $translation; + } + public function getTranslation(): string { return $this->translation; diff --git a/tests/Integration/TranslatorTest.php b/tests/Integration/TranslatorTest.php index eace900..4c79751 100644 --- a/tests/Integration/TranslatorTest.php +++ b/tests/Integration/TranslatorTest.php @@ -4,6 +4,7 @@ namespace Arxy\TranslationsBundle\Tests\Integration; +use Arxy\TranslationsBundle\CacheFlag; use Arxy\TranslationsBundle\Tests\Integration\Entity\Language; use Arxy\TranslationsBundle\Tests\Integration\Entity\Token; use Arxy\TranslationsBundle\Tests\Integration\Entity\Translation; @@ -11,8 +12,9 @@ use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Output\ConsoleOutput; +use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\HttpKernel\KernelInterface; +use Symfony\Contracts\Service\ResetInterface; use Symfony\Contracts\Translation\TranslatorInterface; class TranslatorTest extends KernelTestCase @@ -34,7 +36,7 @@ private function buildDb(KernelInterface $kernel): void 'doctrine:schema:create', ] ), - new ConsoleOutput() + new NullOutput() ); } @@ -122,6 +124,59 @@ public function testTranslate( self::assertSame($expected, $translator->trans($token, $parameters, $catalogue, $locale)); } + public function testCacheFlag(): void + { + $kernel = self::bootKernel(); + $this->buildDb($kernel); + + /** @var EntityManagerInterface $entityManager */ + $entityManager = static::getContainer()->get(EntityManagerInterface::class); + + $bg = new Language('bg'); + $entityManager->persist($bg); + + $en = new Language('en'); + $entityManager->persist($en); + + $helloWorldInBg = new Translation($bg, new Token('hello_world', 'messages'), 'Здравей, свят!'); + $helloWorldInEn = new Translation($en, new Token('hello_world', 'messages'), 'Hello, world!'); + $entityManager->persist($helloWorldInBg); + $entityManager->persist($helloWorldInEn); + $entityManager->flush(); + + /** @var TranslatorInterface $translator */ + $translator = static::getContainer()->get(TranslatorInterface::class); + + self::assertSame('Здравей, свят!', $translator->trans('hello_world', locale: 'bg')); + self::assertSame('Hello, world!', $translator->trans('hello_world', locale: 'en')); + + $helloWorldInBg->setTranslation('Здравей, свят! редактирано'); + $entityManager->persist($helloWorldInBg); + $entityManager->flush(); + + $helloWorldInEn->setTranslation('Hello, world! Edited'); + $entityManager->persist($helloWorldInEn); + $entityManager->flush(); + + if ($translator instanceof ResetInterface) { + $translator->reset(); + } + + self::assertSame('Здравей, свят!', $translator->trans('hello_world', locale: 'bg')); + self::assertSame('Hello, world!', $translator->trans('hello_world', locale: 'en')); + + /** @var CacheFlag $cacheFlag */ + $cacheFlag = static::getContainer()->get(CacheFlag::class); + $cacheFlag->increment($cacheFlag->getVersion()); + + if ($translator instanceof ResetInterface) { + $translator->reset(); + } + + self::assertSame('Здравей, свят! редактирано', $translator->trans('hello_world', locale: 'bg')); + self::assertSame('Hello, world! Edited', $translator->trans('hello_world', locale: 'en')); + } + /** * When Symfony clear cache, tables might not be created, no exception should be thrown in that case. */ @@ -139,7 +194,7 @@ public function testCacheClear(): void 'cache:clear', ] ), - new ConsoleOutput() + new NullOutput() ); $this->expectNotToPerformAssertions(); } diff --git a/tests/Integration/config.yml b/tests/Integration/config.yml index d6f577d..2dbb7b5 100644 --- a/tests/Integration/config.yml +++ b/tests/Integration/config.yml @@ -1,35 +1,41 @@ framework: - test: ~ - default_locale: 'bg' - translator: - default_path: '%kernel.project_dir%/translations' - fallbacks: - - 'en' - - 'nl' + test: ~ + default_locale: 'bg' + translator: + default_path: '%kernel.project_dir%/translations' + fallbacks: + - 'en' + - 'nl' + cache: + default_redis_provider: 'cache.adapter.array' + pools: + cache_flag: + adapter: cache.adapter.array doctrine: - dbal: - driver: pdo_sqlite - memory: true - charset: UTF8 - orm: - auto_generate_proxy_classes: "%kernel.debug%" - naming_strategy: doctrine.orm.naming_strategy.underscore - auto_mapping: true - mappings: - ArxyTranslationsBundleTests: - type: annotation - dir: '%kernel.project_dir%/Entity' - is_bundle: false - prefix: Arxy\TranslationsBundle\Tests\Integration\Entity + dbal: + driver: pdo_sqlite + memory: true + charset: UTF8 + orm: + auto_generate_proxy_classes: "%kernel.debug%" + naming_strategy: doctrine.orm.naming_strategy.underscore + auto_mapping: true + mappings: + ArxyTranslationsBundleTests: + type: attribute + dir: '%kernel.project_dir%/Entity' + is_bundle: false + prefix: Arxy\TranslationsBundle\Tests\Integration\Entity arxy_translations: - repository: Arxy\TranslationsBundle\Tests\Integration\Repository\TranslationRepository + repository: Arxy\TranslationsBundle\Tests\Integration\Repository\TranslationRepository + cache_flag: 'cache_flag' services: - # default configuration for services in *this* file - _defaults: - autowire: true # Automatically injects dependencies in your services. - autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. + # default configuration for services in *this* file + _defaults: + autowire: true # Automatically injects dependencies in your services. + autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. - Arxy\TranslationsBundle\Tests\Integration\Repository\TranslationRepository: ~ + Arxy\TranslationsBundle\Tests\Integration\Repository\TranslationRepository: ~