├── .github ├── assets │ ├── csv.png │ ├── fix.png │ ├── html.png │ ├── logo.jpg │ ├── status.png │ ├── supported-systems.jpg │ ├── translate.png │ ├── validation-empty.png │ └── validation-structure.png └── workflows │ ├── ci_pipe.yml │ ├── pr_pipe.yml │ ├── release.yml │ ├── step_release.yml │ └── step_review.yml ├── .gitignore ├── .php_cs.php ├── .phpstan.neon ├── .run ├── PHPUnit Tests.run.xml ├── Playground JSON.run.xml └── Start Development.run.xml ├── ACKNOWLEDGEMENTS.md ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── bin └── phpunuhi ├── composer.json ├── composer.lock ├── config.xsd ├── devops ├── dev │ ├── docker-compose.yml │ └── scripts │ │ └── install.sh ├── docker_release │ ├── Dockerfile │ └── run.sh ├── makefile └── scripts │ ├── build.php │ └── extract.php ├── infection.json ├── makefile ├── php_min_version.php ├── phparkitect.php ├── phpunit.xml ├── rector.php ├── schema ├── 1.22.xsd ├── 1.23.xsd ├── 1.24.xsd └── dev-main.xsd ├── src ├── AppManager.php ├── Bundles │ ├── Exchange │ │ ├── CSV │ │ │ ├── CSVExchange.php │ │ │ └── Services │ │ │ │ ├── CSVExporter.php │ │ │ │ ├── CSVImporter.php │ │ │ │ ├── CSVWriter.php │ │ │ │ └── CSVWriterInterface.php │ │ ├── ExchangeFactory.php │ │ ├── ExchangeFormat.php │ │ ├── ExchangeInterface.php │ │ ├── HTML │ │ │ ├── HTMLExchange.php │ │ │ └── Services │ │ │ │ ├── HTMLExporter.php │ │ │ │ └── HTMLImporter.php │ │ ├── ImportEntry.php │ │ ├── ImportResult.php │ │ └── JSON │ │ │ └── JsonExchange.php │ ├── Scanner │ │ ├── MJML │ │ │ └── MjmlScanner.php │ │ ├── ScannerFactory.php │ │ ├── ScannerInterface.php │ │ └── TWIG │ │ │ └── TwigScanner.php │ ├── Spelling │ │ ├── Aspell │ │ │ └── AspellSpellChecker.php │ │ ├── Exception │ │ │ ├── SpellingFixingNotSupportedException.php │ │ │ └── SpellingValidationNotSupportedException.php │ │ ├── OpenAI │ │ │ └── OpenAISpellChecker.php │ │ ├── Result │ │ │ ├── MisspelledWord.php │ │ │ └── SpellingValidationResult.php │ │ ├── SpellCheckerFactory.php │ │ └── SpellCheckerInterface.php │ ├── Storage │ │ ├── INI │ │ │ └── IniStorage.php │ │ ├── JSON │ │ │ ├── JsonStorage.php │ │ │ └── Services │ │ │ │ ├── JsonLoader.php │ │ │ │ └── JsonSaver.php │ │ ├── PHP │ │ │ ├── PhpStorage.php │ │ │ └── Services │ │ │ │ ├── PHPLoader.php │ │ │ │ └── PHPSaver.php │ │ ├── PO │ │ │ ├── Models │ │ │ │ └── Block.php │ │ │ └── PoStorage.php │ │ ├── RESX │ │ │ └── ResxStorage.php │ │ ├── Shopware6 │ │ │ ├── Config │ │ │ │ ├── AppManifestXml.php │ │ │ │ ├── FlowActionsXml.php │ │ │ │ ├── PluginConfigXml.php │ │ │ │ └── ShopwareXmlInterface.php │ │ │ ├── Exception │ │ │ │ └── SnippetNotFoundException.php │ │ │ ├── Models │ │ │ │ ├── Snippet.php │ │ │ │ ├── SnippetSet.php │ │ │ │ ├── Sw6Locale.php │ │ │ │ └── UpdateField.php │ │ │ ├── Repository │ │ │ │ ├── EntityRepository.php │ │ │ │ ├── EntityTranslationRepository.php │ │ │ │ ├── LanguageRepository.php │ │ │ │ └── SnippetRepository.php │ │ │ ├── Service │ │ │ │ ├── SnippetSetFinderTrait.php │ │ │ │ ├── TranslationLoader.php │ │ │ │ ├── TranslationSaver.php │ │ │ │ ├── Uuid.php │ │ │ │ └── XmlHandler.php │ │ │ └── Shopware6Storage.php │ │ ├── StorageFactory.php │ │ ├── StorageHierarchy.php │ │ ├── StorageInterface.php │ │ ├── StorageSaveResult.php │ │ ├── Strings │ │ │ └── StringsStorage.php │ │ └── YAML │ │ │ ├── Services │ │ │ ├── YamlLoader.php │ │ │ └── YamlSaver.php │ │ │ └── YamlStorage.php │ └── Translator │ │ ├── DeepL │ │ ├── DeeplTranslator.php │ │ └── Services │ │ │ └── SupportedLanguages.php │ │ ├── GoogleCloud │ │ └── GoogleCloudTranslator.php │ │ ├── GoogleWeb │ │ └── GoogleWebTranslator.php │ │ ├── OpenAI │ │ └── OpenAITranslator.php │ │ ├── TranslatorFactory.php │ │ └── TranslatorInterface.php ├── Commands │ ├── AvailableServicesCommand.php │ ├── CommandEnvVariables.php │ ├── CommandNames.php │ ├── ExportCommand.php │ ├── FixKeysCommand.php │ ├── FixMessCommand.php │ ├── FixSpellingCommand.php │ ├── FixStructureCommand.php │ ├── ImportCommand.php │ ├── ListTranslationKeysCommand.php │ ├── ListTranslationsCommand.php │ ├── MigrateCommand.php │ ├── ScanUsageCommand.php │ ├── StatusCommand.php │ ├── TranslateCommand.php │ ├── ValidateAllCommand.php │ ├── ValidateCommand.php │ ├── ValidateCoverageCommand.php │ ├── ValidateMessCommand.php │ ├── ValidateSimilarityCommand.php │ ├── ValidateSpellingCommand.php │ └── ValidateStructureCommand.php ├── Components │ ├── Configuration │ │ ├── ConfigurationLoader.php │ │ └── Services │ │ │ ├── ConfigurationValidator.php │ │ │ ├── CoverageLoader.php │ │ │ ├── FilterLoader.php │ │ │ ├── LocalesLoader.php │ │ │ ├── LocalesPlaceholderProcessor.php │ │ │ ├── ProtectionLoader.php │ │ │ ├── RulesLoader.php │ │ │ └── StyleLoader.php │ ├── Filter │ │ └── FilterHandler.php │ ├── Reporter │ │ ├── JSON │ │ │ └── JsonReporter.php │ │ ├── JUnit │ │ │ └── JUnitReporter.php │ │ ├── Model │ │ │ ├── ReportResult.php │ │ │ ├── ReportSetResult.php │ │ │ └── ReportTestResult.php │ │ ├── ReporterFactory.php │ │ ├── ReporterInterface.php │ │ └── Service │ │ │ └── ReportTestResultConverter.php │ └── Validator │ │ ├── CaseStyle │ │ ├── CaseStyleValidatorFactory.php │ │ ├── CaseStyleValidatorInterface.php │ │ ├── Exception │ │ │ └── CaseStyleNotFoundException.php │ │ └── Style │ │ │ ├── CamelCaseValidator.php │ │ │ ├── KebabCaseValidator.php │ │ │ ├── LowerCaseValidator.php │ │ │ ├── NoneCaseValidator.php │ │ │ ├── NumberCaseValidator.php │ │ │ ├── PascalCaseValidator.php │ │ │ ├── SnakeCaseValidator.php │ │ │ ├── StartCaseValidator.php │ │ │ └── UpperCaseValidator.php │ │ ├── CaseStyleValidator.php │ │ ├── Coverage │ │ ├── CoverageValidator.php │ │ └── CoverageValidatorResult.php │ │ ├── DuplicateContent │ │ └── DuplicateContent.php │ │ ├── EmptyContent │ │ └── AllowEmptyContent.php │ │ ├── EmptyContentValidator.php │ │ ├── MissingStructureValidator.php │ │ ├── Model │ │ ├── ValidationResult.php │ │ └── ValidationTest.php │ │ ├── Rules │ │ ├── DisallowedTextsRule.php │ │ ├── DuplicateContentRule.php │ │ ├── EmptyContentRule.php │ │ ├── MaxKeyLengthRule.php │ │ ├── NestingDepthRule.php │ │ └── RuleValidatorInterface.php │ │ ├── RulesValidator.php │ │ └── ValidatorInterface.php ├── Exceptions │ ├── ConfigurationException.php │ └── TranslationNotFoundException.php ├── Facades │ └── CLI │ │ ├── CoverageCliFacade.php │ │ ├── MessValidatorCliFacade.php │ │ ├── ReporterCliFacade.php │ │ ├── SpellingValidatorCliFacade.php │ │ ├── TranslationSetCliFacade.php │ │ └── ValidatorCliFacade.php ├── Models │ ├── Command │ │ └── CommandOption.php │ ├── Configuration │ │ ├── Attribute.php │ │ ├── CaseStyle │ │ │ ├── CaseStyle.php │ │ │ ├── CaseStyleIgnoreKey.php │ │ │ └── CaseStyleIgnoreScope.php │ │ ├── CaseStyleSetting.php │ │ ├── Configuration.php │ │ ├── Coverage.php │ │ ├── Coverage │ │ │ ├── LocaleCoverage.php │ │ │ └── TranslationSetCoverage.php │ │ ├── Filter.php │ │ ├── Marker.php │ │ ├── Protection.php │ │ ├── Rule.php │ │ └── Rules.php │ ├── Percentage.php │ ├── Text │ │ └── Text.php │ └── Translation │ │ ├── LazyLocale.php │ │ ├── LazyTranslationSet.php │ │ ├── Locale.php │ │ ├── Translation.php │ │ └── TranslationSet.php ├── PHPUnuhi.php ├── Services │ ├── CaseStyle │ │ ├── CamelCaseConverter.php │ │ ├── CaseStyleConverterFactory.php │ │ ├── CaseStyleConverterInterface.php │ │ ├── LowerCaseConverter.php │ │ └── UpperCaseConverter.php │ ├── Connection │ │ └── ConnectionFactory.php │ ├── Coverage │ │ ├── CoverageService.php │ │ ├── Models │ │ │ ├── CoverageLocale.php │ │ │ ├── CoverageTotal.php │ │ │ └── CoverageTranslationSet.php │ │ └── Traits │ │ │ └── CoverageDataTrait.php │ ├── GroupName │ │ └── GroupNameService.php │ ├── Loaders │ │ ├── Directory │ │ │ └── DirectoryLoader.php │ │ ├── File │ │ │ └── FileLoader.php │ │ └── Xml │ │ │ ├── XmlLoader.php │ │ │ └── XmlLoaderInterface.php │ ├── Maths │ │ └── PercentageCalculator.php │ ├── OpenAI │ │ ├── OpenAIClient.php │ │ ├── OpenAIResponse.php │ │ ├── OpenAIUsageTracker.php │ │ └── pricing.json │ ├── Placeholder │ │ ├── Placeholder.php │ │ ├── PlaceholderEncoder.php │ │ └── PlaceholderExtractor.php │ ├── Process │ │ ├── OSProcess.php │ │ └── ProcessResult.php │ ├── Similarity │ │ └── Similarity.php │ ├── WordCounter │ │ └── WordCounter.php │ └── Writers │ │ ├── Directory │ │ ├── DirectoryWriter.php │ │ └── DirectoryWriterInterface.php │ │ ├── File │ │ ├── FileWriter.php │ │ └── FileWriterInterface.php │ │ └── Xml │ │ ├── XmlWriter.php │ │ └── XmlWriterInterface.php ├── Traits │ ├── ArrayTrait.php │ ├── BinaryTrait.php │ ├── BoolTrait.php │ ├── CommandOutputTrait.php │ ├── CommandTrait.php │ ├── StringTrait.php │ └── XmlTrait.php └── index.php ├── svrunit.xml └── tests ├── phpunit ├── Bundles │ ├── Exchange │ │ ├── CSV │ │ │ └── CSVExchangeTest.php │ │ ├── ExchangeFactoryTest.php │ │ ├── ExchangeFormatTest.php │ │ ├── ImportEntryTest.php │ │ └── ImportResultTest.php │ ├── Scanner │ │ ├── MJML │ │ │ └── MjmlScannerTest.php │ │ └── TWIG │ │ │ └── TwigScannerTest.php │ ├── Storage │ │ ├── JSON │ │ │ ├── JsonStorageTest.php │ │ │ └── Services │ │ │ │ └── JsonSaverTest.php │ │ ├── PHP │ │ │ └── PhpStorageTest.php │ │ ├── PO │ │ │ └── PoStorageTest.php │ │ ├── Shopware6 │ │ │ ├── Shopware6StorageTest.php │ │ │ └── SnippetSetFinderTraitTest.php │ │ ├── StorageFactoryTest.php │ │ ├── StorageHierarchyTest.php │ │ ├── StorageSaveResultTest.php │ │ └── YAML │ │ │ └── YamlStorageTest.php │ └── Translator │ │ ├── DeepL │ │ ├── DeepLTranslatorTest.php │ │ └── Services │ │ │ └── SupportedLanguagesTest.php │ │ ├── GoogleCloud │ │ └── GoogleCloudTranslatorTest.php │ │ ├── GoogleWeb │ │ └── GoogleWebTranslatorTest.php │ │ ├── OpenAI │ │ └── OpenAITranslatorTest.php │ │ └── TranslatorFactoryTest.php ├── Components │ ├── Configuration │ │ ├── ConfigurationLoaderTest.php │ │ └── Services │ │ │ ├── ConfigurationValidatorTest.php │ │ │ ├── FilterLoaderTest.php │ │ │ ├── LocalesLoaderTest.php │ │ │ ├── LocalesPlaceholderProcessorTest.php │ │ │ ├── ProtectionLoaderTest.php │ │ │ ├── RuleLoaderTest.php │ │ │ └── StyleLoaderTest.php │ ├── Filter │ │ └── FilterHandlerTest.php │ ├── Repoter │ │ ├── JSON │ │ │ └── JsonReporterTest.php │ │ ├── JUnit │ │ │ └── JUnitReporterTest.php │ │ ├── Model │ │ │ ├── ReportResultTest.php │ │ │ ├── ReportSetResultTest.php │ │ │ └── ReportTestResultTest.php │ │ └── ReporterFactoryTest.php │ └── Validator │ │ ├── CaseStyle │ │ ├── CaseStyleValidatorFactoryTest.php │ │ └── Style │ │ │ ├── CamelCaseValidatorTest.php │ │ │ ├── KebabCaseValidatorTest.php │ │ │ ├── LowerCaseValidatorTest.php │ │ │ ├── NoneCaseValidatorTest.php │ │ │ ├── NumberCaseValidatorTest.php │ │ │ ├── PascalCaseValidatorTest.php │ │ │ ├── SnakeCaseValidatorTest.php │ │ │ ├── StartCaseValidatorTest.php │ │ │ └── UpperCaseValidatorTest.php │ │ ├── CaseStyleValidatorTest.php │ │ ├── EmptyContent │ │ └── AllowEmptyContentTest.php │ │ ├── EmptyContentValidatorTest.php │ │ ├── MixedStructureValidatorTest.php │ │ ├── Model │ │ ├── ValidationResultTest.php │ │ └── ValidationTestTest.php │ │ ├── Rules │ │ ├── DisallowedTextsRuleTest.php │ │ ├── DuplicateContentRuleTest.php │ │ ├── EmptyContentRuleTest.php │ │ ├── MaxKeyLengthRuleTest.php │ │ └── NestingDepthRuleTest.php │ │ └── RulesValidatorTest.php ├── Models │ ├── Command │ │ └── CommandOptionTest.php │ ├── Configuration │ │ ├── AttributeTest.php │ │ ├── CaseStyle │ │ │ ├── CaseStyleIgnoreKeyTest.php │ │ │ ├── CaseStyleIgnoreScopeTest.php │ │ │ └── CaseStyleTest.php │ │ ├── ConfigurationTest.php │ │ ├── Coverage │ │ │ ├── LocaleCoverageTest.php │ │ │ └── TranslationSetCoverageTest.php │ │ ├── CoverageTest.php │ │ ├── FilterTest.php │ │ ├── MarkerTest.php │ │ ├── ProtectionTest.php │ │ └── RuleTest.php │ └── Translation │ │ ├── LocaleTest.php │ │ ├── TranslationSetTest.php │ │ └── TranslationTest.php ├── PHPUnuhiTest.php ├── Services │ ├── CaseStyle │ │ ├── CamelCaseConverterTest.php │ │ ├── CaseStyleConverterFactoryTest.php │ │ ├── LowerCaseConverterTest.php │ │ └── UpperCaseConverterTest.php │ ├── Connection │ │ └── ConnectionFactoryTest.php │ ├── Coverage │ │ ├── CoverageServiceTest.php │ │ └── Models │ │ │ ├── CoverageLocaleTest.php │ │ │ ├── CoverageSetTest.php │ │ │ └── CoverageTotalTest.php │ ├── GroupName │ │ └── GroupNameServiceTest.php │ ├── Loaders │ │ ├── File │ │ │ └── FileLoaderTest.php │ │ └── Xml │ │ │ └── XmlLoaderTest.php │ ├── Maths │ │ └── PercentageCalculatorTest.php │ ├── Placeholder │ │ ├── PlaceholderEncoderTest.php │ │ ├── PlaceholderExtractorTest.php │ │ └── PlaceholderTest.php │ ├── WordCounter │ │ └── WordCounterTest.php │ └── Writers │ │ ├── Directory │ │ └── DirectoryWriterTest.php │ │ ├── File │ │ └── FileWriterTest.php │ │ └── Xml │ │ └── XmlWriterTest.php ├── Traits │ ├── ArrayTraitTest.php │ ├── BinaryTraitTest.php │ ├── CommandTraitTest.php │ ├── StringTraitTest.php │ └── XmlTraitTest.php └── Utils │ ├── Fakes │ ├── FakeCSVWriter.php │ ├── FakeDirectoryWriter.php │ ├── FakeEmptyDelimiterStorage.php │ ├── FakeExchangeFormat.php │ ├── FakeFileWriter.php │ ├── FakeStorage.php │ ├── FakeStorageNoFilter.php │ ├── FakeTranslator.php │ ├── FakeXmlLoader.php │ └── FakeXmlWriter.php │ └── Traits │ ├── StringCleanerTrait.php │ ├── TestReportBuilderTrait.php │ ├── TranslationSetBuilderTrait.php │ └── XmlLoaderTrait.php ├── playground ├── custom-xml │ ├── autoload.php │ ├── makefile │ ├── phpunuhi.xml │ ├── snippets │ │ ├── de.xml │ │ └── en.xml │ └── src │ │ └── XmlStorage.php ├── ini │ ├── de.ini │ ├── en.ini │ ├── ini_sections.ini │ ├── makefile │ └── phpunuhi.xml ├── json │ ├── bundle │ │ ├── snippets.xml │ │ └── snippets │ │ │ ├── de.json │ │ │ └── nl.json │ ├── makefile │ ├── phpunuhi.xml │ ├── snippets │ │ └── en_newline.json │ └── templates │ │ ├── index.mjml │ │ └── subfolder │ │ ├── index.twig │ │ └── test.mjml ├── makefile ├── php │ ├── de.php │ ├── en.php │ ├── makefile │ └── phpunuhi.xml ├── po │ ├── de.po │ ├── en.po │ ├── makefile │ └── phpunuhi.xml ├── resx │ ├── files │ │ ├── Resources.de.resx │ │ └── Resources.en.resx │ ├── makefile │ └── phpunuhi.xml ├── shopware6-config │ ├── configs │ │ ├── config.xml │ │ ├── flow.xml │ │ └── manifest.xml │ ├── makefile │ └── phpunuhi.xml ├── shopware6 │ ├── makefile │ └── phpunuhi.xml ├── strings │ ├── files │ │ ├── de.lproj │ │ │ └── Localizable.strings │ │ └── en.lproj │ │ │ └── Localizable.strings │ ├── makefile │ └── phpunuhi.xml └── yaml │ ├── de.yaml │ ├── en.yaml │ ├── makefile │ └── phpunuhi.xml ├── scripts ├── check_composer_version.php └── check_xsd.php └── svrunit ├── fixtures ├── custom-command │ ├── autoload.php │ ├── phpunuhi.xml │ └── src │ │ └── CustomCommand.php ├── ini │ ├── de.ini │ ├── en.ini │ ├── ini_sections.ini │ └── phpunuhi.xml ├── json │ ├── de.json │ ├── en.json │ ├── nl.json │ ├── phpunuhi.xml │ └── templates │ │ └── subfolder │ │ ├── index.mjml │ │ └── index.twig ├── php │ ├── de.php │ ├── en.php │ └── phpunuhi.xml ├── shopware6 │ └── phpunuhi.xml └── yaml │ ├── de.yaml │ ├── en.yaml │ ├── nl.yaml │ └── phpunuhi.xml └── tests ├── commands ├── commands.yml └── scanner.yml ├── extensions.yml ├── ini.yml ├── json.yml ├── php.yml ├── shopware6.yml └── yaml.yml /.github/assets/csv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boxblinkracer/phpunuhi/92bb31af1214b50ec6c9a778c3052dc494fbc01b/.github/assets/csv.png -------------------------------------------------------------------------------- /.github/assets/fix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boxblinkracer/phpunuhi/92bb31af1214b50ec6c9a778c3052dc494fbc01b/.github/assets/fix.png -------------------------------------------------------------------------------- /.github/assets/html.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boxblinkracer/phpunuhi/92bb31af1214b50ec6c9a778c3052dc494fbc01b/.github/assets/html.png -------------------------------------------------------------------------------- /.github/assets/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boxblinkracer/phpunuhi/92bb31af1214b50ec6c9a778c3052dc494fbc01b/.github/assets/logo.jpg -------------------------------------------------------------------------------- /.github/assets/status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boxblinkracer/phpunuhi/92bb31af1214b50ec6c9a778c3052dc494fbc01b/.github/assets/status.png -------------------------------------------------------------------------------- /.github/assets/supported-systems.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boxblinkracer/phpunuhi/92bb31af1214b50ec6c9a778c3052dc494fbc01b/.github/assets/supported-systems.jpg -------------------------------------------------------------------------------- /.github/assets/translate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boxblinkracer/phpunuhi/92bb31af1214b50ec6c9a778c3052dc494fbc01b/.github/assets/translate.png -------------------------------------------------------------------------------- /.github/assets/validation-empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boxblinkracer/phpunuhi/92bb31af1214b50ec6c9a778c3052dc494fbc01b/.github/assets/validation-empty.png -------------------------------------------------------------------------------- /.github/assets/validation-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boxblinkracer/phpunuhi/92bb31af1214b50ec6c9a778c3052dc494fbc01b/.github/assets/validation-structure.png -------------------------------------------------------------------------------- /.github/workflows/ci_pipe.yml: -------------------------------------------------------------------------------- 1 | name: CI Pipeline 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | paths-ignore: 9 | - '.github/**' 10 | - '**.md' 11 | - 'makefile' 12 | 13 | jobs: 14 | 15 | # ------------------------------------------------------------------------------------------------------------------------ 16 | 17 | review: 18 | name: Review Pipeline 19 | uses: ./.github/workflows/step_review.yml 20 | with: 21 | PHP_VERSION: 8.2 22 | 23 | # ------------------------------------------------------------------------------------------------------------------------ 24 | 25 | release: 26 | name: Release Pipeline 27 | uses: ./.github/workflows/step_release.yml 28 | needs: [ review ] 29 | secrets: 30 | DOCKER_USERNAME: "${{ secrets.DOCKER_USERNAME }}" 31 | DOCKER_PASSWORD: "${{ secrets.DOCKER_PASSWORD }}" 32 | PACKAGIST_USER: "${{ secrets.PACKAGIST_USER }}" 33 | PACKAGIST_TOKEN: "${{ secrets.PACKAGIST_TOKEN }}" 34 | with: 35 | VERSION: "dev-main" 36 | PHP_VERSION: 8.2 37 | -------------------------------------------------------------------------------- /.github/workflows/pr_pipe.yml: -------------------------------------------------------------------------------- 1 | name: PR Pipeline 2 | 3 | on: [ pull_request, workflow_dispatch ] 4 | 5 | 6 | jobs: 7 | 8 | review: 9 | name: Review Pipeline 10 | uses: ./.github/workflows/step_review.yml 11 | with: 12 | PHP_VERSION: 8.2 13 | 14 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release Version 2 | run-name: Release ${{ github.event.inputs.version }} 3 | 4 | on: 5 | workflow_dispatch: 6 | inputs: 7 | version: 8 | description: 'Version' 9 | required: true 10 | 11 | jobs: 12 | 13 | # ------------------------------------------------------------------------------------------------------------------------ 14 | 15 | review: 16 | name: Review Pipeline 17 | uses: ./.github/workflows/step_review.yml 18 | with: 19 | PHP_VERSION: 8.2 20 | 21 | # ------------------------------------------------------------------------------------------------------------------------ 22 | 23 | release: 24 | name: Release Pipeline 25 | uses: ./.github/workflows/step_release.yml 26 | needs: [ review ] 27 | secrets: 28 | DOCKER_USERNAME: "${{ secrets.DOCKER_USERNAME }}" 29 | DOCKER_PASSWORD: "${{ secrets.DOCKER_PASSWORD }}" 30 | PACKAGIST_USER: "${{ secrets.PACKAGIST_USER }}" 31 | PACKAGIST_TOKEN: "${{ secrets.PACKAGIST_TOKEN }}" 32 | with: 33 | VERSION: ${{ github.event.inputs.version }} 34 | PHP_VERSION: 8.2 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Add any directories, files, or patterns you don't want to be tracked by version control 2 | .DS_Store 3 | /build/phpunuhi.phar 4 | /.idea 5 | /.reports 6 | /.phpunit.result.cache 7 | /build 8 | /src/vendor 9 | /src/composer.lock 10 | /vendor 11 | /.export/ 12 | /tests/e2e/.export 13 | /tests/playground/.exports 14 | /tests/playground/shopware6/.exports 15 | /tests/e2e/.exports 16 | /tests/playground/json/.exports 17 | /tests/playground/ini/.exports 18 | /svrunit.phar 19 | /.svrunit 20 | /tests/svrunit/.exports 21 | /tests/playground/yaml/.exports 22 | /tests/playground/po/.exports 23 | /tests/playground/php/.exports 24 | /tests/playground/shopware6-config/.exports 25 | /tests/playground/resx/.exports 26 | /devops/docker_release/phpunuhi.phar 27 | /tests/svrunit/fixtures/json/de.ini 28 | /tests/svrunit/fixtures/json/en.ini 29 | /tests/svrunit/fixtures/json/nl.ini 30 | /tests/playground/strings/.exports 31 | /.build/ 32 | -------------------------------------------------------------------------------- /.php_cs.php: -------------------------------------------------------------------------------- 1 | setUsingCache(false) 5 | ->setRiskyAllowed(true) 6 | ->setRules([ 7 | '@PSR2' => true, 8 | '@PSR12' => true, 9 | 'ordered_imports' => true, 10 | 'no_unused_imports' => true, 11 | 'array_syntax' => ['syntax' => 'short'], 12 | 'align_multiline_comment' => true, 13 | 'array_indentation' => true, 14 | 'no_empty_phpdoc' => true, 15 | 'no_superfluous_elseif' => true, 16 | 'phpdoc_add_missing_param_annotation' => true, 17 | 'phpdoc_order' => true, 18 | 'phpdoc_trim_consecutive_blank_line_separation' => true, 19 | 'phpdoc_types_order' => true, 20 | 'concat_space' => ['spacing' => 'one'], 21 | 'declare_strict_types' => true, 22 | # ------------------------------------------------- 23 | 'not_operator_with_successor_space' => false, 24 | 'no_superfluous_phpdoc_tags' => false, # this would always remove required mixed annotations 25 | 'yoda_style' => false, 26 | ]) 27 | ->setFinder( 28 | PhpCsFixer\Finder::create() 29 | ->exclude(['./src/vendor']) 30 | ->in(__DIR__ . '/src') 31 | ->in(__DIR__ . '/tests/phpunit') 32 | ); -------------------------------------------------------------------------------- /.phpstan.neon: -------------------------------------------------------------------------------- 1 | includes: 2 | - vendor/spaze/phpstan-disallowed-calls/extension.neon 3 | - vendor/staabm/phpstan-todo-by/extension.neon 4 | 5 | parameters: 6 | level: 9 7 | paths: 8 | - ./src 9 | - ./tests/phpunit 10 | checkExplicitMixed: false 11 | disallowedFunctionCalls: 12 | - function: 'var_dump()' 13 | message: 'use some logger instead' 14 | - function: 'dump()' 15 | message: 'use some logger instead' 16 | - function: 'var_export()' 17 | message: 'use some logger instead' 18 | - function: 'dd()' 19 | message: 'use some logger instead' 20 | - function: 'print_r()' 21 | message: 'use some logger instead' 22 | todo_by: 23 | nonIgnorable: true 24 | referenceTime: "now+7days" -------------------------------------------------------------------------------- /.run/PHPUnit Tests.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.run/Playground JSON.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /.run/Start Development.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023 Christian Dangl 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /bin/phpunuhi: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | usePutenv()->loadEnv($envFile); 45 | } 46 | 47 | AppManager::run($argv); -------------------------------------------------------------------------------- /config.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /devops/dev/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | 3 | phpunuhi: 4 | container_name: phpunuhi 5 | image: dockware/flex:latest 6 | volumes: 7 | - "../../:/app" 8 | ports: 9 | - "22:22" 10 | working_dir: /app 11 | environment: 12 | - PHP_VERSION=8.2 13 | - XDEBUG_ENABLED=1 -------------------------------------------------------------------------------- /devops/dev/scripts/install.sh: -------------------------------------------------------------------------------- 1 | sudo apt-get update 2 | sudo apt-get install -y zip 3 | sudo apt-get install -y unzip 4 | sudo apt-get install -y php-sqlite3 5 | 6 | 7 | sudo chmod 777 /etc/php/8.2/cli/php.ini 8 | sudo echo 'phar.readonly => 0' > /etc/php/8.2/cli/php.ini 9 | 10 | 11 | cd /var/www && make restart-php -------------------------------------------------------------------------------- /devops/docker_release/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:8.3.13-cli-alpine3.20 2 | 3 | COPY --chmod=0755 ./phpunuhi.phar /usr/local/bin/phpunuhi 4 | COPY --chmod=0755 ./run.sh /run.sh 5 | 6 | RUN echo "memory_limit=-1" > /usr/local/etc/php/conf.d/memory-limit.ini \ 7 | && apk add --no-cache \ 8 | icu-dev \ 9 | aspell \ 10 | && docker-php-ext-configure intl \ 11 | && docker-php-ext-install intl pdo_mysql \ 12 | && rm -rf /var/cache/apk/* 13 | 14 | 15 | WORKDIR /app 16 | 17 | ENTRYPOINT ["php", "/usr/local/bin/phpunuhi"] -------------------------------------------------------------------------------- /devops/docker_release/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | php /opt/phpunuhi.phar --directory=project -------------------------------------------------------------------------------- /devops/makefile: -------------------------------------------------------------------------------- 1 | # Makefile Project 2 | 3 | .PHONY: help 4 | .DEFAULT_GOAL := help 5 | 6 | 7 | #------------------------------------------------------------------------------------------------ 8 | 9 | help: 10 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' 11 | 12 | run: ## Starts Docker and installs all dependencies 13 | cd dev && docker-compose down | true; 14 | cd dev && docker-compose up -d 15 | sleep 10 16 | docker exec -it phpunuhi bash -c 'cd /app/devops/dev/scripts && sh install.sh' 17 | docker exec -it phpunuhi bash -c 'cd /app && make dev' 18 | docker exec -it phpunuhi bash -c 'cd /app && make help' 19 | docker exec -it phpunuhi bash -------------------------------------------------------------------------------- /devops/scripts/extract.php: -------------------------------------------------------------------------------- 1 | extractTo(__DIR__ . "/../../.build/content"); 6 | -------------------------------------------------------------------------------- /infection.json: -------------------------------------------------------------------------------- 1 | { 2 | "source": { 3 | "directories": [ 4 | "src/Models/Command", 5 | "src/Models/Configuration" 6 | ] 7 | }, 8 | "bootstrap": "./vendor/autoload.php", 9 | "mutators": { 10 | "@default": true 11 | }, 12 | "logs": { 13 | "text": ".reports/infection/infection.log", 14 | "summary": ".reports/infection/summary.log", 15 | "perMutator": ".reports/infection/per-mutator.md" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /php_min_version.php: -------------------------------------------------------------------------------- 1 | 1 && $argv[1] === '--echo') { 7 | echo getenv('PHP_MIN_VERSION'); 8 | } -------------------------------------------------------------------------------- /phparkitect.php: -------------------------------------------------------------------------------- 1 | that(new ResideInOneOfTheseNamespaces('PHPUnuhi\Commands')) 18 | ->should(new HaveNameMatching('*Command')) 19 | ->because('we want uniform naming'); 20 | 21 | $config->add($mvcClassSet, ...$rules); 22 | }; -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | 13 | ./tests/phpunit 14 | 15 | 16 | 17 | 18 | 19 | ./src 20 | 21 | 22 | src/index.php 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /rector.php: -------------------------------------------------------------------------------- 1 | phpVersion($minVersion); 20 | 21 | 22 | $rectorConfig->paths([ 23 | __DIR__ . '/bin', 24 | __DIR__ . '/devops/scripts', 25 | __DIR__ . '/src', 26 | __DIR__ . '/tests/phpunit', 27 | ]); 28 | 29 | $rectorConfig->importNames(); 30 | 31 | $rectorConfig->sets([ 32 | SetList::DEAD_CODE, 33 | SetList::CODE_QUALITY, 34 | SetList::STRICT_BOOLEANS, 35 | SetList::TYPE_DECLARATION, 36 | SetList::EARLY_RETURN, 37 | SetList::INSTANCEOF, 38 | ]); 39 | 40 | }; 41 | -------------------------------------------------------------------------------- /src/Bundles/Exchange/CSV/Services/CSVWriter.php: -------------------------------------------------------------------------------- 1 | $row 42 | */ 43 | public function writeLine($file, array $row, string $delimiter): void 44 | { 45 | fputcsv($file, $row, $delimiter); 46 | } 47 | 48 | /** 49 | * @param $file 50 | */ 51 | public function close($file): void 52 | { 53 | fclose($file); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Bundles/Exchange/CSV/Services/CSVWriterInterface.php: -------------------------------------------------------------------------------- 1 | $row 22 | */ 23 | public function writeLine($file, array $row, string $delimiter): void; 24 | 25 | /** 26 | * @param resource $file 27 | */ 28 | public function close($file): void; 29 | } 30 | -------------------------------------------------------------------------------- /src/Bundles/Exchange/ExchangeFormat.php: -------------------------------------------------------------------------------- 1 | $options 29 | */ 30 | public function setOptionValues(array $options): void; 31 | 32 | 33 | public function export(TranslationSet $set, string $outputDir, bool $onlyEmpty): void; 34 | 35 | 36 | public function import(string $filename): ImportResult; 37 | } 38 | -------------------------------------------------------------------------------- /src/Bundles/Exchange/HTML/HTMLExchange.php: -------------------------------------------------------------------------------- 1 | $options 34 | */ 35 | public function setOptionValues(array $options): void 36 | { 37 | } 38 | 39 | /** 40 | * @throws TranslationNotFoundException 41 | */ 42 | public function export(TranslationSet $set, string $outputDir, bool $onlyEmpty): void 43 | { 44 | $exporter = new HTMLExporter(); 45 | $exporter->export($set, $outputDir, $onlyEmpty); 46 | } 47 | 48 | /** 49 | * @throws Exception 50 | */ 51 | public function import(string $filename): ImportResult 52 | { 53 | $importer = new HTMLImporter(); 54 | return $importer->import($filename); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Bundles/Exchange/ImportEntry.php: -------------------------------------------------------------------------------- 1 | localeExchangeID = $localeExchangeID; 21 | $this->key = $key; 22 | $this->group = $group; 23 | $this->value = $value; 24 | } 25 | 26 | 27 | 28 | public function getLocaleExchangeID(): string 29 | { 30 | return $this->localeExchangeID; 31 | } 32 | 33 | 34 | public function getKey(): string 35 | { 36 | return $this->key; 37 | } 38 | 39 | 40 | public function getGroup(): string 41 | { 42 | return $this->group; 43 | } 44 | 45 | 46 | public function getValue(): string 47 | { 48 | return $this->value; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Bundles/Exchange/ImportResult.php: -------------------------------------------------------------------------------- 1 | entries = $entries; 21 | } 22 | 23 | /** 24 | * @return ImportEntry[] 25 | */ 26 | public function getEntries(): array 27 | { 28 | return $this->entries; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Bundles/Scanner/MJML/MjmlScanner.php: -------------------------------------------------------------------------------- 1 | word = $word; 22 | $this->suggestions = $suggestions; 23 | } 24 | 25 | 26 | public function getWord(): string 27 | { 28 | return $this->word; 29 | } 30 | 31 | /** 32 | * @return string[] 33 | */ 34 | public function getSuggestions(): array 35 | { 36 | return $this->suggestions; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Bundles/Spelling/Result/SpellingValidationResult.php: -------------------------------------------------------------------------------- 1 | isValid = $isValid; 27 | $this->locale = $locale; 28 | $this->suggestedText = $suggestedText; 29 | $this->misspelledWords = $misspelledWords; 30 | } 31 | 32 | 33 | public function isValid(): bool 34 | { 35 | return $this->isValid; 36 | } 37 | 38 | 39 | public function getLocale(): string 40 | { 41 | return $this->locale; 42 | } 43 | 44 | 45 | public function getSuggestedText(): string 46 | { 47 | return $this->suggestedText; 48 | } 49 | 50 | /** 51 | * @return MisspelledWord[] 52 | */ 53 | public function getMisspelledWords(): array 54 | { 55 | return $this->misspelledWords; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Bundles/Spelling/SpellCheckerInterface.php: -------------------------------------------------------------------------------- 1 | $options 30 | */ 31 | public function setOptionValues(array $options): void; 32 | 33 | /** 34 | * @return string[] 35 | */ 36 | public function getAvailableDictionaries(): array; 37 | 38 | /** 39 | * @param string $locale the locale key of the text such as de-de, en-GB, de, etc. 40 | */ 41 | public function validate(Text $text, string $locale): SpellingValidationResult; 42 | 43 | /** 44 | * @param string $locale the locale key of the text such as de-de, en-GB, de, etc. 45 | */ 46 | public function fixSpelling(Text $text, string $locale): string; 47 | } 48 | -------------------------------------------------------------------------------- /src/Bundles/Storage/PHP/Services/PHPLoader.php: -------------------------------------------------------------------------------- 1 | getLocales() as $locale) { 18 | $arrayData = require($locale->getFilename()); 19 | 20 | if (!is_array($arrayData)) { 21 | $arrayData = []; 22 | } 23 | 24 | $foundTranslationsFlat = $this->getFlatArray($arrayData, $delimiter); 25 | 26 | foreach ($foundTranslationsFlat as $key => $value) { 27 | $locale->addTranslation($key, $value, ''); 28 | } 29 | 30 | // We start with three because the first three lines are the setLineNumbers( 32 | $this->getLineNumbers($arrayData, $delimiter, '', 3, true) 33 | ); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Bundles/Storage/Shopware6/Config/ShopwareXmlInterface.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | public function readTranslations(string $locale): array; 15 | 16 | /** 17 | * @param Translation[] $translations 18 | */ 19 | public function writeTranslations(string $locale, array $translations): void; 20 | } 21 | -------------------------------------------------------------------------------- /src/Bundles/Storage/Shopware6/Exception/SnippetNotFoundException.php: -------------------------------------------------------------------------------- 1 | id = $id; 26 | $this->snippetSetId = $snippetSetId; 27 | $this->key = $key; 28 | $this->value = $value; 29 | $this->author = $author; 30 | $this->customFields = $customFields; 31 | } 32 | 33 | 34 | public function getId(): string 35 | { 36 | return $this->id; 37 | } 38 | 39 | 40 | public function getSnippetSetId(): string 41 | { 42 | return $this->snippetSetId; 43 | } 44 | 45 | 46 | public function getKey(): string 47 | { 48 | return $this->key; 49 | } 50 | 51 | 52 | public function getValue(): string 53 | { 54 | return $this->value; 55 | } 56 | 57 | 58 | public function getAuthor(): string 59 | { 60 | return $this->author; 61 | } 62 | 63 | 64 | public function getCustomFields(): string 65 | { 66 | return $this->customFields; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Bundles/Storage/Shopware6/Models/SnippetSet.php: -------------------------------------------------------------------------------- 1 | id = $id; 19 | $this->name = $name; 20 | $this->iso = $iso; 21 | } 22 | 23 | 24 | public function getId(): string 25 | { 26 | return $this->id; 27 | } 28 | 29 | 30 | public function getName(): string 31 | { 32 | return $this->name; 33 | } 34 | 35 | 36 | public function getIso(): string 37 | { 38 | return $this->iso; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Bundles/Storage/Shopware6/Models/Sw6Locale.php: -------------------------------------------------------------------------------- 1 | languageId = $languageId; 19 | $this->languageName = $languageName; 20 | $this->localeName = $localeName; 21 | } 22 | 23 | 24 | public function getLanguageId(): string 25 | { 26 | return $this->languageId; 27 | } 28 | 29 | 30 | public function getLanguageName(): string 31 | { 32 | return $this->languageName; 33 | } 34 | 35 | 36 | public function getLocaleName(): string 37 | { 38 | return $this->localeName; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Bundles/Storage/Shopware6/Models/UpdateField.php: -------------------------------------------------------------------------------- 1 | field = $field; 17 | $this->value = $value; 18 | } 19 | 20 | 21 | public function getField(): string 22 | { 23 | return $this->field; 24 | } 25 | 26 | 27 | public function getValue(): string 28 | { 29 | return $this->value; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Bundles/Storage/Shopware6/Repository/EntityRepository.php: -------------------------------------------------------------------------------- 1 | pdo = $pdo; 21 | } 22 | 23 | /** 24 | * @return array 25 | */ 26 | public function getEntity(string $entity, string $id): array 27 | { 28 | $stmt = $this->pdo->prepare('SELECT * FROM :tableName WHERE id = :id'); 29 | 30 | $stmt->execute([ 31 | 'tableName' => $entity, 32 | 'id' => $id 33 | ]); 34 | 35 | return $stmt->fetch(PDO::FETCH_ASSOC); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Bundles/Storage/Shopware6/Repository/LanguageRepository.php: -------------------------------------------------------------------------------- 1 | pdo = $pdo; 22 | } 23 | 24 | /** 25 | * @return Sw6Locale[] 26 | */ 27 | public function getLanguages(): array 28 | { 29 | $stmt = $this->pdo->prepare('SELECT l.id as langId, l.name as langName, lc.code as locCode FROM language l INNER JOIN locale lc ON lc.id = l.locale_id'); 30 | $stmt->execute(); 31 | 32 | $dbRows = $stmt->fetchAll(PDO::FETCH_ASSOC); 33 | 34 | $list = []; 35 | 36 | if (!is_array($dbRows)) { 37 | return $list; 38 | } 39 | 40 | foreach ($dbRows as $row) { 41 | $list[] = new Sw6Locale( 42 | $this->binaryToString((string)$row['langId']), 43 | (string)$row['langName'], 44 | (string)$row['locCode'] 45 | ); 46 | } 47 | 48 | return $list; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Bundles/Storage/Shopware6/Service/SnippetSetFinderTrait.php: -------------------------------------------------------------------------------- 1 | getName() === $name; 21 | } 22 | ); 23 | 24 | if (count($filteredSnippetSets) !== 1) { 25 | $filteredSnippetSets = array_filter( 26 | $snippetSets, 27 | function (SnippetSet $set) use ($name): bool { 28 | return $set->getIso() === $name; 29 | } 30 | ); 31 | } 32 | 33 | $count = count($filteredSnippetSets); 34 | if ($count === 0) { 35 | throw new Exception('No Snippet Set found in Shopware for locale / name: ' . $name); 36 | } 37 | 38 | if ($count > 1) { 39 | throw new Exception('Found multiple Snippet Sets found in Shopware for locale / name: ' . $name); 40 | } 41 | 42 | return end($filteredSnippetSets); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Bundles/Storage/StorageHierarchy.php: -------------------------------------------------------------------------------- 1 | nestedStorage = $isNested; 17 | $this->delimiter = $delimiter; 18 | } 19 | 20 | 21 | public function isNestedStorage(): bool 22 | { 23 | return $this->nestedStorage; 24 | } 25 | 26 | 27 | public function getDelimiter(): string 28 | { 29 | return $this->delimiter; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Bundles/Storage/StorageSaveResult.php: -------------------------------------------------------------------------------- 1 | savedLocales = $savedLocales; 18 | $this->savedTranslations = $savedTranslations; 19 | } 20 | 21 | 22 | public function getSavedLocales(): int 23 | { 24 | return $this->savedLocales; 25 | } 26 | 27 | 28 | public function getSavedTranslations(): int 29 | { 30 | return $this->savedTranslations; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Bundles/Storage/YAML/Services/YamlLoader.php: -------------------------------------------------------------------------------- 1 | getFilename()); 19 | 20 | if (!is_array($arrayData)) { 21 | $arrayData = []; 22 | } 23 | 24 | $foundTranslationsFlat = $this->getFlatArray($arrayData, $delimiter); 25 | 26 | foreach ($foundTranslationsFlat as $key => $value) { 27 | # empty yaml values are NULL, so we cast it 28 | $locale->addTranslation($key, (string)$value, ''); 29 | } 30 | 31 | $locale->setLineNumbers( 32 | $this->getLineNumbers($arrayData, $delimiter) 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Bundles/Translator/TranslatorInterface.php: -------------------------------------------------------------------------------- 1 | $options 29 | */ 30 | public function setOptionValues(array $options): void; 31 | 32 | /** 33 | * Translates the given text from the source locale into the target locale. 34 | * @param Placeholder[] $foundPlaceholders 35 | */ 36 | public function translate(string $text, string $sourceLocale, string $targetLocale, array $foundPlaceholders): string; 37 | } 38 | -------------------------------------------------------------------------------- /src/Commands/CommandEnvVariables.php: -------------------------------------------------------------------------------- 1 | setName(CommandNames::VALIDATE) 22 | ->setDescription('[DEPRECATED] Validates all your translations from your configuration. Please use validate:all instead.') 23 | ->addOption('configuration', null, InputOption::VALUE_REQUIRED, '', '') 24 | ->addOption('report-format', null, InputOption::VALUE_REQUIRED, 'The report format for a generated report', '') 25 | ->addOption('report-output', null, InputOption::VALUE_REQUIRED, 'The report output filename for the generated report', '') 26 | ->addOption('ignore-coverage', null, InputOption::VALUE_NONE, 'Ignore a configured coverage setting and proceed with strict validation.'); 27 | 28 | parent::configure(); 29 | } 30 | 31 | /** 32 | * @throws ConfigurationException 33 | */ 34 | public function execute(InputInterface $input, OutputInterface $output): int 35 | { 36 | return (new ValidateAllCommand())->execute($input, $output); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Components/Configuration/Services/FilterLoader.php: -------------------------------------------------------------------------------- 1 | include; 17 | $nodeExcludes = $filterNode->exclude; 18 | 19 | $nodeAllowsKeys = ($nodeAllows !== null) ? $nodeAllows->key : null; 20 | $nodeExcludeKeys = ($nodeExcludes !== null) ? $nodeExcludes->key : null; 21 | 22 | if ($nodeAllowsKeys !== null) { 23 | foreach ($nodeAllowsKeys as $key) { 24 | $filter->addIncludeKey((string)$key); 25 | } 26 | } 27 | 28 | if ($nodeExcludeKeys !== null) { 29 | foreach ($nodeExcludeKeys as $key) { 30 | $filter->addExcludeKey((string)$key); 31 | } 32 | } 33 | 34 | return $filter; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Components/Configuration/Services/ProtectionLoader.php: -------------------------------------------------------------------------------- 1 | marker; 21 | $nodeTerms = $filterNode->term; 22 | 23 | if ($nodeMarkers !== null) { 24 | foreach ($nodeMarkers as $marker) { 25 | $markerStart = $this->getAttribute('start', $marker); 26 | $markerEnd = $this->getAttribute('end', $marker); 27 | 28 | $protection->addMarker($markerStart->getValue(), $markerEnd->getValue()); 29 | } 30 | } 31 | 32 | if ($nodeTerms !== null) { 33 | foreach ($nodeTerms as $term) { 34 | $termValue = (string)$term; 35 | 36 | $protection->addTerm($termValue); 37 | } 38 | } 39 | 40 | return $protection; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Components/Filter/FilterHandler.php: -------------------------------------------------------------------------------- 1 | getFilter(); 14 | 15 | foreach ($set->getLocales() as $locale) { 16 | $translations = $locale->getTranslations(); 17 | 18 | foreach ($translations as $translation) { 19 | if (!$filter->isKeyAllowed($translation->getKey())) { 20 | $locale->removeTranslation($translation->getID()); 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Components/Reporter/Model/ReportResult.php: -------------------------------------------------------------------------------- 1 | suites[] = $result; 19 | } 20 | 21 | /** 22 | * @return ReportSetResult[] 23 | */ 24 | public function getSuites(): array 25 | { 26 | return $this->suites; 27 | } 28 | 29 | 30 | public function getTestCount(): int 31 | { 32 | $count = 0; 33 | foreach ($this->suites as $suite) { 34 | $count += $suite->getTestCount(); 35 | } 36 | 37 | return $count; 38 | } 39 | 40 | 41 | public function getFailureCount(): int 42 | { 43 | $count = 0; 44 | foreach ($this->suites as $suite) { 45 | $count += $suite->getFailureCount(); 46 | } 47 | 48 | return $count; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Components/Reporter/Model/ReportSetResult.php: -------------------------------------------------------------------------------- 1 | name = $name; 20 | } 21 | 22 | 23 | public function getName(): string 24 | { 25 | return $this->name; 26 | } 27 | 28 | 29 | public function addTestResult(ReportTestResult $result): void 30 | { 31 | $this->tests[] = $result; 32 | } 33 | 34 | /** 35 | * @return ReportTestResult[] 36 | */ 37 | public function getTests(): array 38 | { 39 | return $this->tests; 40 | } 41 | 42 | 43 | public function getTestCount(): int 44 | { 45 | return count($this->tests); 46 | } 47 | 48 | 49 | public function getFailureCount(): int 50 | { 51 | $count = 0; 52 | foreach ($this->tests as $test) { 53 | if (!$test->isSuccess()) { 54 | $count++; 55 | } 56 | } 57 | 58 | return $count; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Components/Reporter/ReporterInterface.php: -------------------------------------------------------------------------------- 1 | getTitle(), 16 | $test->getTranslationKey(), 17 | basename($test->getFilename()), 18 | $test->getLineNumber(), 19 | $test->getClassification(), 20 | $test->getFailureMessage(), 21 | $test->isSuccess() 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Components/Validator/CaseStyle/CaseStyleValidatorInterface.php: -------------------------------------------------------------------------------- 1 | 0); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Components/Validator/CaseStyle/Style/KebabCaseValidator.php: -------------------------------------------------------------------------------- 1 | 0); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Components/Validator/CaseStyle/Style/LowerCaseValidator.php: -------------------------------------------------------------------------------- 1 | 0); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Components/Validator/CaseStyle/Style/NoneCaseValidator.php: -------------------------------------------------------------------------------- 1 | 0); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Components/Validator/CaseStyle/Style/SnakeCaseValidator.php: -------------------------------------------------------------------------------- 1 | 0); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Components/Validator/CaseStyle/Style/StartCaseValidator.php: -------------------------------------------------------------------------------- 1 | 0); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Components/Validator/CaseStyle/Style/UpperCaseValidator.php: -------------------------------------------------------------------------------- 1 | 0); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Components/Validator/Coverage/CoverageValidatorResult.php: -------------------------------------------------------------------------------- 1 | success = $success; 22 | $this->coverageExpected = $coverageExpected; 23 | $this->coverageActual = $coverageActual; 24 | $this->scope = $scope; 25 | } 26 | 27 | 28 | public function isSuccess(): bool 29 | { 30 | return $this->success; 31 | } 32 | 33 | 34 | public function getCoverageExpected(): float 35 | { 36 | return $this->coverageExpected; 37 | } 38 | 39 | 40 | public function getCoverageActual(): float 41 | { 42 | return $this->coverageActual; 43 | } 44 | 45 | 46 | public function getScope(): string 47 | { 48 | return $this->scope; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Components/Validator/DuplicateContent/DuplicateContent.php: -------------------------------------------------------------------------------- 1 | locale = $locale; 17 | $this->duplicateAllowed = $duplicateAllowed; 18 | } 19 | 20 | 21 | public function getLocale(): string 22 | { 23 | return $this->locale; 24 | } 25 | 26 | 27 | public function isDuplicateAllowed(): bool 28 | { 29 | return $this->duplicateAllowed; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Components/Validator/EmptyContent/AllowEmptyContent.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | private array $locales; 15 | 16 | 17 | /** 18 | * @param mixed[] $locales 19 | */ 20 | public function __construct(string $key, array $locales) 21 | { 22 | $this->key = $key; 23 | $this->locales = $locales; 24 | } 25 | 26 | 27 | public function getKey(): string 28 | { 29 | return $this->key; 30 | } 31 | 32 | 33 | public function isLocaleAllowed(string $locale): bool 34 | { 35 | # if we have an entry without locales, we allow all locales to be empty 36 | if ($this->locales === []) { 37 | return true; 38 | } 39 | 40 | # if we have a locale with * wildcard, we also allow all locales to be empty 41 | if (in_array('*', $this->locales)) { 42 | return true; 43 | } 44 | 45 | return in_array($locale, $this->locales); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Components/Validator/Model/ValidationResult.php: -------------------------------------------------------------------------------- 1 | tests = $tests; 21 | } 22 | 23 | 24 | public function isValid(): bool 25 | { 26 | return $this->getErrors() === []; 27 | } 28 | 29 | /** 30 | * @return ValidationTest[] 31 | */ 32 | public function getTests(): array 33 | { 34 | return $this->tests; 35 | } 36 | 37 | /** 38 | * @return ValidationTest[] 39 | */ 40 | public function getErrors(): array 41 | { 42 | $errors = []; 43 | 44 | foreach ($this->tests as $test) { 45 | if (!$test->isSuccess()) { 46 | $errors[] = $test; 47 | } 48 | } 49 | 50 | return $errors; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Components/Validator/Rules/RuleValidatorInterface.php: -------------------------------------------------------------------------------- 1 | io = $io; 22 | 23 | $this->coverageValidator = new CoverageValidator(); 24 | } 25 | 26 | 27 | public function execute(Configuration $config): bool 28 | { 29 | $this->io->section('coverage checks'); 30 | $this->io->writeln('Checking minimum coverage...'); 31 | 32 | $rootCovConfig = $config->getCoverage(); 33 | $translationSets = $config->getTranslationSets(); 34 | 35 | $covResult = $this->coverageValidator->validate($rootCovConfig, $translationSets); 36 | 37 | if ($covResult->isSuccess()) { 38 | $this->io->writeln(' [/] PASSED: Minimum coverage is reached.'); 39 | return true; 40 | } 41 | 42 | $this->io->writeln(' [x] FAILED: Coverage not reached for: ' . $covResult->getScope()); 43 | $this->io->writeln(' Expected ' . $covResult->getCoverageExpected() . '%, actual ' . $covResult->getCoverageActual() . '%'); 44 | 45 | return false; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Facades/CLI/ReporterCliFacade.php: -------------------------------------------------------------------------------- 1 | io = $io; 20 | } 21 | 22 | 23 | /** 24 | * @throws ConfigurationException 25 | */ 26 | public function execute(string $reportFormat, string $reportFilename, ReportResult $reportResult): void 27 | { 28 | if ($reportFormat !== '') { 29 | $reporter = ReporterFactory::getInstance()->getReporter($reportFormat); 30 | 31 | if ($reportFilename === '') { 32 | $reportFilename = $reporter->getDefaultFilename(); 33 | } 34 | 35 | $this->io->section('generating report...'); 36 | 37 | $reporter->generate($reportFilename, $reportResult); 38 | 39 | $this->io->writeln('generated: ' . $reportFilename); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Models/Command/CommandOption.php: -------------------------------------------------------------------------------- 1 | name = $name; 17 | $this->hasValue = $hasValue; 18 | } 19 | 20 | 21 | public function getName(): string 22 | { 23 | return $this->name; 24 | } 25 | 26 | 27 | public function hasValue(): bool 28 | { 29 | return $this->hasValue; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Models/Configuration/Attribute.php: -------------------------------------------------------------------------------- 1 | name = $name; 17 | $this->value = $value; 18 | } 19 | 20 | 21 | public function getName(): string 22 | { 23 | return $this->name; 24 | } 25 | 26 | 27 | public function getValue(): string 28 | { 29 | return $this->value; 30 | } 31 | 32 | 33 | public function setValue(string $fixedPath): void 34 | { 35 | $this->value = $fixedPath; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Models/Configuration/CaseStyle/CaseStyle.php: -------------------------------------------------------------------------------- 1 | name = $name; 19 | } 20 | 21 | 22 | public function getName(): string 23 | { 24 | return $this->name; 25 | } 26 | 27 | 28 | public function hasLevel(): bool 29 | { 30 | return $this->level >= self::MIN_LEVEL; 31 | } 32 | 33 | 34 | public function getLevel(): int 35 | { 36 | return $this->level; 37 | } 38 | 39 | 40 | public function setLevel(int $level): void 41 | { 42 | $this->level = $level; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Models/Configuration/CaseStyle/CaseStyleIgnoreKey.php: -------------------------------------------------------------------------------- 1 | key = $key; 18 | $this->fullyQualifiedPath = $fullyQualifiedPath; 19 | } 20 | 21 | 22 | 23 | public function getKey(): string 24 | { 25 | return $this->key; 26 | } 27 | 28 | 29 | public function isFullyQualifiedPath(): bool 30 | { 31 | return $this->fullyQualifiedPath; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Models/Configuration/CaseStyle/CaseStyleIgnoreScope.php: -------------------------------------------------------------------------------- 1 | caseStyles = $caseStyles; 26 | $this->ignoreKeys = $ignoreKeys; 27 | } 28 | 29 | /** 30 | * @return CaseStyle[] 31 | */ 32 | public function getCaseStyles(): array 33 | { 34 | return $this->caseStyles; 35 | } 36 | 37 | /** 38 | * @return CaseStyleIgnoreKey[] 39 | */ 40 | public function getIgnoreKeys(): array 41 | { 42 | return $this->ignoreKeys; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Models/Configuration/Coverage/LocaleCoverage.php: -------------------------------------------------------------------------------- 1 | locale = $locale; 22 | $this->minCoverage = $minCoverage; 23 | 24 | $max = (Percentage::MAX_PERCENTAGE + self::OFFSET); 25 | 26 | if ($this->minCoverage >= $max) { 27 | $this->minCoverage = Percentage::MAX_PERCENTAGE; 28 | } 29 | } 30 | 31 | 32 | public function getLocale(): string 33 | { 34 | return $this->locale; 35 | } 36 | 37 | 38 | public function getMinCoverage(): float 39 | { 40 | return $this->minCoverage; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Models/Configuration/Marker.php: -------------------------------------------------------------------------------- 1 | start = $start; 18 | $this->end = $end; 19 | } 20 | 21 | 22 | 23 | public function getStart(): string 24 | { 25 | return $this->start; 26 | } 27 | 28 | 29 | public function getEnd(): string 30 | { 31 | return $this->end; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Models/Configuration/Protection.php: -------------------------------------------------------------------------------- 1 | markers[] = new Marker($start, $end); 23 | } 24 | 25 | 26 | public function addTerm(string $term): void 27 | { 28 | if (in_array($term, $this->terms)) { 29 | return; 30 | } 31 | 32 | $this->terms[] = $term; 33 | } 34 | 35 | /** 36 | * @return array|Marker[] 37 | */ 38 | public function getMarkers(): array 39 | { 40 | return $this->markers; 41 | } 42 | 43 | /** 44 | * @return array|string[] 45 | */ 46 | public function getTerms(): array 47 | { 48 | return $this->terms; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Models/Configuration/Rule.php: -------------------------------------------------------------------------------- 1 | name = $name; 23 | $this->value = $value; 24 | } 25 | 26 | 27 | public function getName(): string 28 | { 29 | return $this->name; 30 | } 31 | 32 | /** 33 | * @return mixed 34 | */ 35 | public function getValue() 36 | { 37 | return $this->value; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Models/Configuration/Rules.php: -------------------------------------------------------------------------------- 1 | originalText = $originalText; 17 | $this->encodedText = $encodedText; 18 | } 19 | 20 | public function getOriginalText(): string 21 | { 22 | return $this->originalText; 23 | } 24 | 25 | public function getEncodedText(): string 26 | { 27 | return $this->encodedText; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/PHPUnuhi.php: -------------------------------------------------------------------------------- 1 | isValid($text)) { 22 | return $text; 23 | } 24 | 25 | $text = ucwords(str_replace(['-', '_'], ' ', $text)); 26 | 27 | $parts = explode(' ', $text); 28 | 29 | $final = ''; 30 | $first = true; 31 | 32 | foreach ($parts as &$part) { 33 | if ($first) { 34 | $final .= lcfirst(strtolower($part)); 35 | $first = false; 36 | } else { 37 | $final .= ucfirst(strtolower($part)); 38 | } 39 | } 40 | 41 | return $final; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Services/CaseStyle/CaseStyleConverterFactory.php: -------------------------------------------------------------------------------- 1 | converters[] = new UpperCaseConverter(); 21 | $this->converters[] = new LowerCaseConverter(); 22 | $this->converters[] = new CamelCaseConverter(); 23 | } 24 | 25 | /** 26 | * @throws CaseStyleNotFoundException 27 | */ 28 | public function fromIdentifier(string $identifier): CaseStyleConverterInterface 29 | { 30 | foreach ($this->converters as $converter) { 31 | if ($converter->getIdentifier() === $identifier) { 32 | return $converter; 33 | } 34 | } 35 | 36 | throw new CaseStyleNotFoundException('No CaseStyle converter found for identifier: ' . $identifier); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Services/CaseStyle/CaseStyleConverterInterface.php: -------------------------------------------------------------------------------- 1 | setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 22 | 23 | return $pdo; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Services/Coverage/CoverageService.php: -------------------------------------------------------------------------------- 1 | getLocales() as $locale) { 25 | $tmpLocales[] = new CoverageLocale($locale); 26 | } 27 | 28 | $tmpListSets[] = new CoverageTranslationSet($set->getName(), $tmpLocales); 29 | } 30 | 31 | return new CoverageTotal($tmpListSets); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Services/Coverage/Models/CoverageLocale.php: -------------------------------------------------------------------------------- 1 | locale = $locale; 22 | 23 | $this->calculate(); 24 | } 25 | 26 | 27 | 28 | public function getLocaleName(): string 29 | { 30 | return $this->locale->getName(); 31 | } 32 | 33 | 34 | 35 | 36 | private function calculate(): void 37 | { 38 | $wordCounter = new WordCounter(); 39 | 40 | $this->countTranslated = count($this->locale->getValidTranslations()); 41 | $this->countAll = count($this->locale->getTranslationIDs()); 42 | 43 | $this->countWords = 0; 44 | foreach ($this->locale->getValidTranslations() as $translation) { 45 | $this->countWords += $wordCounter->getWordCount($translation->getValue()); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Services/Coverage/Traits/CoverageDataTrait.php: -------------------------------------------------------------------------------- 1 | getRoundedPercentage($this->countTranslated, $this->countAll); 33 | } 34 | 35 | 36 | public function getCountTranslated(): int 37 | { 38 | return $this->countTranslated; 39 | } 40 | 41 | 42 | public function getCountAll(): int 43 | { 44 | return $this->countAll; 45 | } 46 | 47 | 48 | public function getWordCount(): int 49 | { 50 | return $this->countWords; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Services/GroupName/GroupNameService.php: -------------------------------------------------------------------------------- 1 | stringDoesStartsWith($translationId, 'group--'); 18 | 19 | if (!$isGroup) { 20 | return ''; 21 | } 22 | 23 | $group = explode('.', $translationId)[0]; 24 | 25 | return str_replace('group--', '', $group); 26 | } 27 | 28 | 29 | public function getPropertyName(string $translationId): string 30 | { 31 | if (!$this->stringDoesStartsWith($translationId, 'group--')) { 32 | return $translationId; 33 | } 34 | 35 | $group = explode('.', $translationId)[0]; 36 | $group = str_replace('group--', '', $group); 37 | 38 | return str_replace('group--' . $group . '.', '', $translationId); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Services/Loaders/Directory/DirectoryLoader.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | public function getFiles(string $directory, string $extension): array 17 | { 18 | $files = []; 19 | 20 | if (is_dir($directory)) { 21 | // Open the folder 22 | $directoryIterator = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS); 23 | $iterator = new RecursiveIteratorIterator($directoryIterator, RecursiveIteratorIterator::SELF_FIRST); 24 | 25 | // Iterate through files 26 | /** @var SplFileInfo $file */ 27 | foreach ($iterator as $file) { 28 | // Check if it's a file and has the specified extension 29 | if (!$file->isFile()) { 30 | continue; 31 | } 32 | if (pathinfo($file->getFilename(), PATHINFO_EXTENSION) !== $extension) { 33 | continue; 34 | } 35 | $files[] = $file->getPathname(); 36 | } 37 | } 38 | 39 | return $files; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Services/Loaders/File/FileLoader.php: -------------------------------------------------------------------------------- 1 | response = $response; 17 | $this->costsUSD = $costsUSD; 18 | } 19 | 20 | public function getResponse(): string 21 | { 22 | return $this->response; 23 | } 24 | 25 | public function getCostsUSD(): float 26 | { 27 | return $this->costsUSD; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Services/OpenAI/OpenAIUsageTracker.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | private array $requests = []; 15 | 16 | 17 | 18 | public static function getInstance(): OpenAIUsageTracker 19 | { 20 | if (!self::$instance instanceof \PHPUnuhi\Services\OpenAI\OpenAIUsageTracker) { 21 | self::$instance = new self(); 22 | } 23 | 24 | return self::$instance; 25 | } 26 | 27 | 28 | 29 | public function addRequest(string $prompt, float $costUSD): void 30 | { 31 | $this->requests[] = [ 32 | 'prompt' => $prompt, 33 | 'costUSD' => $costUSD, 34 | ]; 35 | } 36 | 37 | public function getRequestCount(): int 38 | { 39 | return count($this->requests); 40 | } 41 | /** 42 | * Gets the total costs rounded to 2 decimal places 43 | */ 44 | public function getTotalCostsUSD(): float 45 | { 46 | $totalCostsUSD = 0; 47 | foreach ($this->requests as $cost) { 48 | $totalCostsUSD += $cost['costUSD']; 49 | } 50 | 51 | return $totalCostsUSD; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Services/OpenAI/pricing.json: -------------------------------------------------------------------------------- 1 | { 2 | "gpt-4": { 3 | "input": 0.00003, 4 | "output": 0.00006 5 | }, 6 | "gpt-4-turbo": { 7 | "input": 0.00001, 8 | "output": 0.00003 9 | }, 10 | "gpt-3.5-turbo": { 11 | "input": 0.0000015, 12 | "output": 0.000002 13 | } 14 | } -------------------------------------------------------------------------------- /src/Services/Placeholder/Placeholder.php: -------------------------------------------------------------------------------- 1 | id = md5($value); 18 | $this->value = $value; 19 | } 20 | 21 | 22 | public function getId(): string 23 | { 24 | return $this->id; 25 | } 26 | 27 | 28 | public function getValue(): string 29 | { 30 | return $this->value; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Services/Placeholder/PlaceholderEncoder.php: -------------------------------------------------------------------------------- 1 | getValue(), 22 | self::ENCODING_MARKER . $placeholder->getId() . self::ENCODING_MARKER, 23 | $tmpValue 24 | ); 25 | } 26 | 27 | return $tmpValue; 28 | } 29 | 30 | /** 31 | * @param Placeholder[] $placeholders 32 | */ 33 | public function decode(string $text, array $placeholders): string 34 | { 35 | $tmpValue = $text; 36 | 37 | foreach ($placeholders as $placeholder) { 38 | $tmpValue = str_replace( 39 | self::ENCODING_MARKER . $placeholder->getId() . self::ENCODING_MARKER, 40 | $placeholder->getValue(), 41 | $tmpValue 42 | ); 43 | } 44 | 45 | return $tmpValue; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Services/Placeholder/PlaceholderExtractor.php: -------------------------------------------------------------------------------- 1 | run(); 16 | 17 | $errorOutput = $process->getErrorOutput(); 18 | $output = $process->getOutput(); 19 | 20 | return new ProcessResult($output, $errorOutput); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Services/Process/ProcessResult.php: -------------------------------------------------------------------------------- 1 | output = trim($output); 23 | $this->errorOutput = trim($errorOutput); 24 | } 25 | 26 | public function isSuccess(): bool 27 | { 28 | return $this->errorOutput === '' || $this->errorOutput === '0'; 29 | } 30 | 31 | public function getOutput(): string 32 | { 33 | return $this->output; 34 | } 35 | 36 | /** 37 | * @return string[] 38 | */ 39 | public function getOutputLines(): array 40 | { 41 | if ($this->_cachedLines === null) { 42 | 43 | # split into lines 44 | /** @var string[] $tmpArray */ 45 | $tmpArray = (array)preg_split('/\r\n|\r|\n/', $this->output); 46 | 47 | $this->_cachedLines = $tmpArray; 48 | 49 | # now remove any empty lines 50 | $this->_cachedLines = array_filter($this->_cachedLines, function ($line): bool { 51 | return trim($line) !== ''; 52 | }); 53 | } 54 | 55 | return $this->_cachedLines; 56 | } 57 | 58 | public function getErrorOutput(): string 59 | { 60 | return $this->errorOutput; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Services/Similarity/Similarity.php: -------------------------------------------------------------------------------- 1 | 12 | */ 13 | public function findSimilarString(array $keys, float $threshold = 70.0): array 14 | { 15 | $similarPairs = []; 16 | 17 | foreach ($keys as $i => $key1) { 18 | $counter = count($keys); 19 | for ($j = $i + 1; $j < $counter; $j++) { 20 | $key2 = $keys[$j]; 21 | $similarity = 0; 22 | similar_text($key1, $key2, $similarity); 23 | 24 | if ($similarity >= $threshold) { 25 | $similarPairs[] = [ 26 | 'key1' => $key1, 27 | 'key2' => $key2, 28 | 'similarity' => $similarity 29 | ]; 30 | } 31 | } 32 | } 33 | 34 | return $similarPairs; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Services/WordCounter/WordCounter.php: -------------------------------------------------------------------------------- 1 | preserveWhiteSpace = false; 20 | $dom->formatOutput = true; 21 | 22 | $dom->loadXML($content); 23 | $out = $dom->saveXML(); 24 | 25 | file_put_contents($filename, $out); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Services/Writers/Xml/XmlWriterInterface.php: -------------------------------------------------------------------------------- 1 | stringDoesContain($string, $item)) { 38 | return true; 39 | } 40 | } 41 | return false; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/index.php: -------------------------------------------------------------------------------- 1 | usePutenv()->loadEnv($envFile); 14 | } 15 | 16 | AppManager::run(); 17 | -------------------------------------------------------------------------------- /svrunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | tests/svrunit/tests 6 | tests/svrunit/tests/commands 7 | 8 | 9 | 10 | tests/svrunit/tests 11 | tests/svrunit/tests/commands 12 | 13 | 14 | 15 | tests/svrunit/tests 16 | tests/svrunit/tests/commands 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/phpunit/Bundles/Exchange/ExchangeFormatTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('csv', ExchangeFormat::CSV); 15 | } 16 | 17 | 18 | public function testFormatHTML(): void 19 | { 20 | $this->assertEquals('html', ExchangeFormat::HTML); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/phpunit/Bundles/Exchange/ImportEntryTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('ex-id', $entry->getLocaleExchangeID()); 17 | } 18 | 19 | 20 | public function testKey(): void 21 | { 22 | $entry = new ImportEntry('', 'key-123', '', ''); 23 | 24 | $this->assertEquals('key-123', $entry->getKey()); 25 | } 26 | 27 | 28 | public function testValue(): void 29 | { 30 | $entry = new ImportEntry('', '', '', 'value-123'); 31 | 32 | $this->assertEquals('value-123', $entry->getValue()); 33 | } 34 | 35 | 36 | public function testGroup(): void 37 | { 38 | $entry = new ImportEntry('', '', 'en', ''); 39 | 40 | $this->assertEquals('en', $entry->getGroup()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/phpunit/Bundles/Exchange/ImportResultTest.php: -------------------------------------------------------------------------------- 1 | assertCount(2, $result->getEntries()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/phpunit/Bundles/Storage/JSON/JsonStorageTest.php: -------------------------------------------------------------------------------- 1 | storage = new JsonStorage(); 18 | } 19 | 20 | 21 | public function testStorageName(): void 22 | { 23 | $this->assertEquals('json', $this->storage->getStorageName()); 24 | } 25 | 26 | 27 | public function testFileExtension(): void 28 | { 29 | $this->assertEquals('json', $this->storage->getFileExtension()); 30 | } 31 | 32 | 33 | public function testSupportsFilter(): void 34 | { 35 | $this->assertFalse($this->storage->supportsFilters()); 36 | } 37 | 38 | 39 | public function testHierarchy(): void 40 | { 41 | $hierarchy = $this->storage->getHierarchy(); 42 | 43 | $this->assertTrue($hierarchy->isNestedStorage()); 44 | $this->assertEquals('.', $hierarchy->getDelimiter()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tests/phpunit/Bundles/Storage/PHP/PhpStorageTest.php: -------------------------------------------------------------------------------- 1 | storage = new PhpStorage(); 18 | } 19 | 20 | 21 | public function testStorageName(): void 22 | { 23 | $this->assertEquals('php', $this->storage->getStorageName()); 24 | } 25 | 26 | 27 | public function testFileExtension(): void 28 | { 29 | $this->assertEquals('php', $this->storage->getFileExtension()); 30 | } 31 | 32 | 33 | public function testSupportsFilter(): void 34 | { 35 | $this->assertFalse($this->storage->supportsFilters()); 36 | } 37 | 38 | 39 | public function testHierarchy(): void 40 | { 41 | $hierarchy = $this->storage->getHierarchy(); 42 | 43 | $this->assertTrue($hierarchy->isNestedStorage()); 44 | $this->assertEquals('.', $hierarchy->getDelimiter()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tests/phpunit/Bundles/Storage/PO/PoStorageTest.php: -------------------------------------------------------------------------------- 1 | storage = new PoStorage(); 18 | } 19 | 20 | 21 | public function testStorageName(): void 22 | { 23 | $this->assertEquals('po', $this->storage->getStorageName()); 24 | } 25 | 26 | 27 | public function testFileExtension(): void 28 | { 29 | $this->assertEquals('po', $this->storage->getFileExtension()); 30 | } 31 | 32 | 33 | public function testSupportsFilter(): void 34 | { 35 | $this->assertFalse($this->storage->supportsFilters()); 36 | } 37 | 38 | 39 | public function testHierarchy(): void 40 | { 41 | $hierarchy = $this->storage->getHierarchy(); 42 | 43 | $this->assertFalse($hierarchy->isNestedStorage()); 44 | $this->assertEquals('', $hierarchy->getDelimiter()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tests/phpunit/Bundles/Storage/Shopware6/Shopware6StorageTest.php: -------------------------------------------------------------------------------- 1 | storage = new Shopware6Storage(); 18 | } 19 | 20 | 21 | public function testStorageName(): void 22 | { 23 | $this->assertEquals('shopware6', $this->storage->getStorageName()); 24 | } 25 | 26 | 27 | public function testFileExtension(): void 28 | { 29 | $this->assertEquals('-', $this->storage->getFileExtension()); 30 | } 31 | 32 | 33 | public function testSupportsFilter(): void 34 | { 35 | $this->assertTrue($this->storage->supportsFilters()); 36 | } 37 | 38 | 39 | public function testHierarchy(): void 40 | { 41 | $hierarchy = $this->storage->getHierarchy(); 42 | 43 | $this->assertFalse($hierarchy->isNestedStorage()); 44 | $this->assertEquals('', $hierarchy->getDelimiter()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tests/phpunit/Bundles/Storage/StorageHierarchyTest.php: -------------------------------------------------------------------------------- 1 | assertEquals(true, $hierarchy->isNestedStorage()); 17 | } 18 | 19 | 20 | public function testDelimiter(): void 21 | { 22 | $hierarchy = new StorageHierarchy(false, '+'); 23 | 24 | $this->assertEquals('+', $hierarchy->getDelimiter()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/phpunit/Bundles/Storage/StorageSaveResultTest.php: -------------------------------------------------------------------------------- 1 | assertEquals(3, $result->getSavedLocales()); 17 | } 18 | 19 | 20 | public function testSavedTranslations(): void 21 | { 22 | $result = new StorageSaveResult(3, 4); 23 | 24 | $this->assertEquals(4, $result->getSavedTranslations()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/phpunit/Bundles/Storage/YAML/YamlStorageTest.php: -------------------------------------------------------------------------------- 1 | storage = new YamlStorage(); 18 | } 19 | 20 | 21 | public function testStorageName(): void 22 | { 23 | $this->assertEquals('yaml', $this->storage->getStorageName()); 24 | } 25 | 26 | 27 | public function testFileExtension(): void 28 | { 29 | $this->assertEquals('yaml', $this->storage->getFileExtension()); 30 | } 31 | 32 | 33 | public function testSupportsFilter(): void 34 | { 35 | $this->assertFalse($this->storage->supportsFilters()); 36 | } 37 | 38 | 39 | public function testHierarchy(): void 40 | { 41 | $hierarchy = $this->storage->getHierarchy(); 42 | 43 | $this->assertTrue($hierarchy->isNestedStorage()); 44 | $this->assertEquals('.', $hierarchy->getDelimiter()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tests/phpunit/Bundles/Translator/GoogleWeb/GoogleWebTranslatorTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('googleweb', $translator->getName()); 17 | } 18 | 19 | 20 | public function testGetOptions(): void 21 | { 22 | $translator = new GoogleWebTranslator(); 23 | 24 | $foundOptions = $translator->getOptions(); 25 | 26 | $this->assertCount(0, $foundOptions); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/phpunit/Components/Configuration/Services/FilterLoaderTest.php: -------------------------------------------------------------------------------- 1 | 22 | 23 | allowed_key1 24 | allowed_key2 25 | 26 | 27 | excluded_key1 28 | excluded_key2 29 | 30 | 31 | '; 32 | 33 | $xmlNode = $this->loadXml($xml); 34 | 35 | $loader = new FilterLoader(); 36 | $actual = $loader->loadFilter($xmlNode); 37 | 38 | 39 | $expected = new Filter(); 40 | $expected->addIncludeKey('allowed_key1'); 41 | $expected->addIncludeKey('allowed_key2'); 42 | $expected->addExcludeKey('excluded_key1'); 43 | $expected->addExcludeKey('excluded_key2'); 44 | 45 | $this->assertEquals($expected, $actual); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/phpunit/Components/Configuration/Services/ProtectionLoaderTest.php: -------------------------------------------------------------------------------- 1 | 21 | 22 | 23 | term1 24 | term2 25 | 26 | '; 27 | 28 | $xmlNode = $this->loadXml($xml); 29 | 30 | $loader = new ProtectionLoader(); 31 | $actual = $loader->loadProtection($xmlNode); 32 | 33 | 34 | $expected = new Protection(); 35 | $expected->addMarker('start1', 'end1'); 36 | $expected->addMarker('start2', 'end2'); 37 | $expected->addTerm('term1'); 38 | $expected->addTerm('term2'); 39 | 40 | $this->assertEquals($expected, $actual); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/phpunit/Components/Repoter/ReporterFactoryTest.php: -------------------------------------------------------------------------------- 1 | expectException(InvalidArgumentException::class); 23 | 24 | $factory->getReporter(''); 25 | } 26 | 27 | /** 28 | * @throws ConfigurationException 29 | */ 30 | public function testUnknownReporterThrowsException(): void 31 | { 32 | $factory = ReporterFactory::getInstance(); 33 | 34 | $this->expectException(ConfigurationException::class); 35 | 36 | $factory->getReporter('unknown'); 37 | } 38 | 39 | /** 40 | * @throws ConfigurationException 41 | */ 42 | public function testJUnitReporterIsFound(): void 43 | { 44 | $factory = ReporterFactory::getInstance(); 45 | 46 | $reporter = $factory->getReporter('junit'); 47 | 48 | $this->assertInstanceOf(JUnitReporter::class, $reporter); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/phpunit/Components/Validator/CaseStyle/CaseStyleValidatorFactoryTest.php: -------------------------------------------------------------------------------- 1 | expectException(CaseStyleNotFoundException::class); 22 | 23 | $factory->fromIdentifier('unknown'); 24 | } 25 | 26 | /** 27 | * @throws CaseStyleNotFoundException 28 | */ 29 | public function testValidatorFound(): void 30 | { 31 | $factory = new CaseStyleValidatorFactory(); 32 | 33 | $validator = $factory->fromIdentifier('camel'); 34 | 35 | $this->assertInstanceOf(CamelCaseValidator::class, $validator); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/phpunit/Components/Validator/CaseStyle/Style/CamelCaseValidatorTest.php: -------------------------------------------------------------------------------- 1 | validator = new CamelCaseValidator(); 19 | } 20 | 21 | 22 | 23 | public function testIdentifier(): void 24 | { 25 | $this->assertEquals('camel', $this->validator->getIdentifier()); 26 | } 27 | 28 | /** 29 | * @return array 30 | */ 31 | public function getData(): array 32 | { 33 | return [ 34 | [true, 'textStyle'], 35 | [true, 'text'], 36 | [false, 'text-style'], 37 | [false, 'text_style'], 38 | [false, 'TEXT-STYLE'], 39 | [false, 'TextStyle'], 40 | ]; 41 | } 42 | 43 | /** 44 | * @dataProvider getData 45 | * 46 | */ 47 | public function testIsValid(bool $expectedValid, string $text): void 48 | { 49 | $isValid = $this->validator->isValid($text); 50 | 51 | $this->assertEquals($expectedValid, $isValid); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/phpunit/Components/Validator/CaseStyle/Style/KebabCaseValidatorTest.php: -------------------------------------------------------------------------------- 1 | validator = new KebabCaseValidator(); 19 | } 20 | 21 | 22 | 23 | public function testIdentifier(): void 24 | { 25 | $this->assertEquals('kebab', $this->validator->getIdentifier()); 26 | } 27 | 28 | /** 29 | * @return array 30 | */ 31 | public function getData(): array 32 | { 33 | return [ 34 | [true, 'text-style'], 35 | [true, 'text'], 36 | [false, 'textStyle'], 37 | [false, 'text_style'], 38 | [false, 'TEXT-STYLE'], 39 | [false, 'TextStyle'], 40 | ]; 41 | } 42 | 43 | /** 44 | * @dataProvider getData 45 | */ 46 | public function testIsValid(bool $expectedValid, string $text): void 47 | { 48 | $isValid = $this->validator->isValid($text); 49 | 50 | $this->assertEquals($expectedValid, $isValid); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/phpunit/Components/Validator/CaseStyle/Style/LowerCaseValidatorTest.php: -------------------------------------------------------------------------------- 1 | validator = new LowerCaseValidator(); 19 | } 20 | 21 | 22 | 23 | public function testIdentifier(): void 24 | { 25 | $this->assertEquals('lower', $this->validator->getIdentifier()); 26 | } 27 | 28 | /** 29 | * @return array 30 | */ 31 | public function getData(): array 32 | { 33 | return [ 34 | [true, 'text'], 35 | [true, 'text_style'], 36 | [false, 'textStyle'], 37 | [false, 'TEXT-STYLE'], 38 | [false, 'TextStyle'], 39 | ]; 40 | } 41 | 42 | /** 43 | * @dataProvider getData 44 | */ 45 | public function testIsValid(bool $expectedValid, string $text): void 46 | { 47 | $isValid = $this->validator->isValid($text); 48 | 49 | $this->assertEquals($expectedValid, $isValid); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/phpunit/Components/Validator/CaseStyle/Style/NoneCaseValidatorTest.php: -------------------------------------------------------------------------------- 1 | validator = new NoneCaseValidator(); 19 | } 20 | 21 | 22 | 23 | public function testIdentifier(): void 24 | { 25 | $this->assertEquals('none', $this->validator->getIdentifier()); 26 | } 27 | 28 | /** 29 | * @return array 30 | */ 31 | public function getData(): array 32 | { 33 | return [ 34 | [true, 'TEXTSTYLE'], 35 | [true, 'TEXT-STYLE'], 36 | [true, 'TEXT-STYLE'], 37 | [true, 'text-style'], 38 | [true, 'text'], 39 | [true, 'textStyle'], 40 | [true, 'text_style'], 41 | [true, 'TextStyle'], 42 | [true, '1Column'], 43 | ]; 44 | } 45 | 46 | /** 47 | * @dataProvider getData 48 | */ 49 | public function testIsValid(bool $expectedValid, string $text): void 50 | { 51 | $isValid = $this->validator->isValid($text); 52 | 53 | $this->assertEquals($expectedValid, $isValid); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/phpunit/Components/Validator/CaseStyle/Style/NumberCaseValidatorTest.php: -------------------------------------------------------------------------------- 1 | validator = new NumberCaseValidator(); 19 | } 20 | 21 | 22 | 23 | public function testIdentifier(): void 24 | { 25 | $this->assertEquals('number', $this->validator->getIdentifier()); 26 | } 27 | 28 | /** 29 | * @return array 30 | */ 31 | public function getData(): array 32 | { 33 | return [ 34 | [true, '0'], 35 | [true, '15'], 36 | [true, '-1'], 37 | [false, 'text0'], 38 | [false, '0text'], 39 | [false, 'text'], 40 | [false, '0_text'], 41 | ]; 42 | } 43 | 44 | /** 45 | * @dataProvider getData 46 | */ 47 | public function testIsValid(bool $expectedValid, string $text): void 48 | { 49 | $isValid = $this->validator->isValid($text); 50 | 51 | $this->assertEquals($expectedValid, $isValid); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/phpunit/Components/Validator/CaseStyle/Style/PascalCaseValidatorTest.php: -------------------------------------------------------------------------------- 1 | validator = new PascalCaseValidator(); 19 | } 20 | 21 | 22 | 23 | public function testIdentifier(): void 24 | { 25 | $this->assertEquals('pascal', $this->validator->getIdentifier()); 26 | } 27 | 28 | /** 29 | * @return array 30 | */ 31 | public function getData(): array 32 | { 33 | return [ 34 | [true, 'Text'], 35 | [true, 'TextStyle'], 36 | [false, 'text'], 37 | [false, 'text-style'], 38 | [false, 'textStyle'], 39 | [false, 'text_style'], 40 | [false, 'TEXT-STYLE'], 41 | ]; 42 | } 43 | 44 | /** 45 | * @dataProvider getData 46 | */ 47 | public function testIsValid(bool $expectedValid, string $text): void 48 | { 49 | $isValid = $this->validator->isValid($text); 50 | 51 | $this->assertEquals($expectedValid, $isValid); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/phpunit/Components/Validator/CaseStyle/Style/SnakeCaseValidatorTest.php: -------------------------------------------------------------------------------- 1 | validator = new SnakeCaseValidator(); 19 | } 20 | 21 | 22 | 23 | public function testIdentifier(): void 24 | { 25 | $this->assertEquals('snake', $this->validator->getIdentifier()); 26 | } 27 | 28 | /** 29 | * @return array 30 | */ 31 | public function getData(): array 32 | { 33 | return [ 34 | [true, 'text_style'], 35 | [true, 'text'], 36 | [false, 'text-style'], 37 | [false, 'textStyle'], 38 | [false, 'TEXT-STYLE'], 39 | [false, 'TextStyle'], 40 | ]; 41 | } 42 | 43 | /** 44 | * @dataProvider getData 45 | */ 46 | public function testIsValid(bool $expectedValid, string $text): void 47 | { 48 | $isValid = $this->validator->isValid($text); 49 | 50 | $this->assertEquals($expectedValid, $isValid); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/phpunit/Components/Validator/CaseStyle/Style/StartCaseValidatorTest.php: -------------------------------------------------------------------------------- 1 | validator = new StartCaseValidator(); 19 | } 20 | 21 | 22 | 23 | public function testIdentifier(): void 24 | { 25 | $this->assertEquals('start', $this->validator->getIdentifier()); 26 | } 27 | 28 | /** 29 | * @return array 30 | */ 31 | public function getData(): array 32 | { 33 | return [ 34 | [true, 'Text'], 35 | [true, 'Textstyle'], 36 | [false, 'TextStyle'], 37 | [false, 'TEXT-STYLE'], 38 | [false, 'text-style'], 39 | [false, 'text'], 40 | [false, 'textStyle'], 41 | [false, 'text_style'], 42 | ]; 43 | } 44 | 45 | /** 46 | * @dataProvider getData 47 | */ 48 | public function testIsValid(bool $expectedValid, string $text): void 49 | { 50 | $isValid = $this->validator->isValid($text); 51 | 52 | $this->assertEquals($expectedValid, $isValid); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/phpunit/Components/Validator/CaseStyle/Style/UpperCaseValidatorTest.php: -------------------------------------------------------------------------------- 1 | validator = new UpperCaseValidator(); 19 | } 20 | 21 | 22 | 23 | public function testIdentifier(): void 24 | { 25 | $this->assertEquals('upper', $this->validator->getIdentifier()); 26 | } 27 | 28 | /** 29 | * @return array 30 | */ 31 | public function getData(): array 32 | { 33 | return [ 34 | [true, 'TEXTSTYLE'], 35 | [true, 'TEXT-STYLE'], 36 | [true, 'TEXT-STYLE'], 37 | [false, 'text-style'], 38 | [false, 'text'], 39 | [false, 'textStyle'], 40 | [false, 'text_style'], 41 | [false, 'TextStyle'], 42 | ]; 43 | } 44 | 45 | /** 46 | * @dataProvider getData 47 | */ 48 | public function testIsValid(bool $expectedValid, string $text): void 49 | { 50 | $isValid = $this->validator->isValid($text); 51 | 52 | $this->assertEquals($expectedValid, $isValid); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/phpunit/Components/Validator/EmptyContent/AllowEmptyContentTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('lblTitle', $data->getKey()); 17 | } 18 | 19 | 20 | public function testLocaleFound(): void 21 | { 22 | $data = new AllowEmptyContent('lblTitle', ['en-GB', 'de-DE']); 23 | 24 | $this->assertTrue($data->isLocaleAllowed('de-DE')); 25 | } 26 | 27 | 28 | public function testLocaleNotFound(): void 29 | { 30 | $data = new AllowEmptyContent('lblTitle', ['en-GB', 'de-DE']); 31 | 32 | $this->assertFalse($data->isLocaleAllowed('fr-FR')); 33 | } 34 | 35 | 36 | public function testLocaleWithWildcardIsAlwaysTrue(): void 37 | { 38 | $data = new AllowEmptyContent('lblTitle', ['*']); 39 | 40 | $this->assertTrue($data->isLocaleAllowed('fr-FR')); 41 | } 42 | 43 | 44 | public function testEmptyLocalesIsAlwaysTrue(): void 45 | { 46 | $data = new AllowEmptyContent('lblTitle', []); 47 | 48 | $this->assertTrue($data->isLocaleAllowed('fr-FR')); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/phpunit/Components/Validator/Model/ValidationResultTest.php: -------------------------------------------------------------------------------- 1 | result = new ValidationResult([$test]); 31 | } 32 | 33 | 34 | public function testGetTests(): void 35 | { 36 | $this->assertCount(1, $this->result->getTests()); 37 | } 38 | 39 | 40 | public function testGetErrors(): void 41 | { 42 | $this->assertCount(1, $this->result->getErrors()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/phpunit/Models/Command/CommandOptionTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('delimiter', $option->getName()); 17 | } 18 | 19 | 20 | public function testHasValue(): void 21 | { 22 | $option = new CommandOption('delimiter', true); 23 | 24 | $this->assertEquals(true, $option->hasValue()); 25 | } 26 | 27 | 28 | public function testHasNoValue(): void 29 | { 30 | $option = new CommandOption('delimiter', false); 31 | 32 | $this->assertEquals(false, $option->hasValue()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/phpunit/Models/Configuration/AttributeTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('format', $attr->getName()); 17 | } 18 | 19 | 20 | public function testValue(): void 21 | { 22 | $attr = new Attribute('format', 'ini'); 23 | 24 | $this->assertEquals('ini', $attr->getValue()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/phpunit/Models/Configuration/CaseStyle/CaseStyleIgnoreKeyTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('lblTitle', $key->getKey()); 17 | } 18 | 19 | 20 | public function testIsFQP(): void 21 | { 22 | $key = new CaseStyleIgnoreKey('lblTitle', false); 23 | 24 | $this->assertEquals(false, $key->isFullyQualifiedPath()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/phpunit/Models/Configuration/CaseStyle/CaseStyleIgnoreScopeTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('global', CaseStyleIgnoreScope::SCOPE_GLOBAL); 15 | } 16 | 17 | 18 | public function testScopeFixed(): void 19 | { 20 | $this->assertEquals('fixed', CaseStyleIgnoreScope::SCOPE_FIXED); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/phpunit/Models/Configuration/CaseStyle/CaseStyleTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('pascal', $style->getName()); 17 | } 18 | 19 | 20 | public function testDefaultLevel(): void 21 | { 22 | $style = new CaseStyle('pascal'); 23 | 24 | $this->assertEquals(-1, $style->getLevel()); 25 | } 26 | 27 | 28 | public function testSetLevel(): void 29 | { 30 | $style = new CaseStyle('pascal'); 31 | $style->setLevel(0); 32 | 33 | $this->assertEquals(0, $style->getLevel()); 34 | } 35 | 36 | 37 | public function testHasLevel(): void 38 | { 39 | $style = new CaseStyle('pascal'); 40 | $style->setLevel(0); 41 | 42 | $this->assertEquals(true, $style->hasLevel()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/phpunit/Models/Configuration/Coverage/LocaleCoverageTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('DE', $cov->getLocale()); 17 | } 18 | 19 | 20 | public function testMinCoverage(): void 21 | { 22 | $cov = new LocaleCoverage('DE', 35); 23 | 24 | $this->assertEquals(35, $cov->getMinCoverage()); 25 | } 26 | 27 | /** 28 | * @testWith [ 99.9, 99.9 ] 29 | * [ 100.0, 100.0 ] 30 | * [ 100.0, 100.1 ] 31 | * 32 | */ 33 | public function testSetMinCoverageIsMaximum100(float $expected, float $input): void 34 | { 35 | $cov = new LocaleCoverage('DE', $input); 36 | 37 | $this->assertEquals($expected, $cov->getMinCoverage()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tests/phpunit/Models/Configuration/MarkerTest.php: -------------------------------------------------------------------------------- 1 | '); 15 | 16 | $this->assertEquals('<', $marker->getStart()); 17 | } 18 | 19 | 20 | public function testEnd(): void 21 | { 22 | $marker = new Marker('<', '>'); 23 | 24 | $this->assertEquals('>', $marker->getEnd()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/phpunit/Models/Configuration/ProtectionTest.php: -------------------------------------------------------------------------------- 1 | addMarker('<', '>'); 17 | $protection->addMarker('[', ']'); 18 | 19 | $this->assertEquals('<', $protection->getMarkers()[0]->getStart()); 20 | $this->assertEquals('[', $protection->getMarkers()[1]->getStart()); 21 | } 22 | 23 | 24 | public function testAddTerm(): void 25 | { 26 | $protection = new Protection(); 27 | 28 | $protection->addTerm('device'); 29 | 30 | $this->assertEquals('device', $protection->getTerms()[0]); 31 | } 32 | 33 | 34 | public function testAddTermDuplicateSkipped(): void 35 | { 36 | $protection = new Protection(); 37 | 38 | $protection->addTerm('hardware'); 39 | $protection->addTerm('device'); 40 | $protection->addTerm('device'); 41 | 42 | $this->assertCount(2, $protection->getTerms()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/phpunit/Models/Configuration/RuleTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('color-rule', $rule->getName()); 17 | } 18 | 19 | 20 | public function testValue(): void 21 | { 22 | $rule = new Rule('color-rule', 'black'); 23 | 24 | $this->assertEquals('black', $rule->getValue()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/phpunit/PHPUnuhiTest.php: -------------------------------------------------------------------------------- 1 | assertNotEmpty(PHPUnuhi::getVersion()); 15 | # a version number has a dot in it 16 | $this->assertStringContainsString('.', PHPUnuhi::getVersion()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/phpunit/Services/CaseStyle/CamelCaseConverterTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('camel', $converter->getIdentifier()); 17 | } 18 | 19 | /** 20 | * @return array 21 | */ 22 | public function getData(): array 23 | { 24 | return [ 25 | ['btnTitle', 'btn-title'], 26 | ['btnTitle', 'BTN-TITLE'], 27 | ['btnTitle', 'btn_title'], 28 | ['btnTitle', 'BTN_TITLE'], 29 | ['btnTitle', 'btnTitle'], 30 | ['btnTitle', 'btn title'], 31 | ]; 32 | } 33 | 34 | /** 35 | * @dataProvider getData 36 | * 37 | */ 38 | public function testConvertCamelCase(string $expected, string $text): void 39 | { 40 | $converter = new CamelCaseConverter(); 41 | 42 | $converted = $converter->convert($text); 43 | 44 | $this->assertEquals($expected, $converted); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tests/phpunit/Services/CaseStyle/CaseStyleConverterFactoryTest.php: -------------------------------------------------------------------------------- 1 | fromIdentifier('upper'); 21 | 22 | $this->assertInstanceOf(UpperCaseConverter::class, $converter); 23 | } 24 | 25 | /** 26 | * @throws CaseStyleNotFoundException 27 | */ 28 | public function testUnknownConverterThrowsException(): void 29 | { 30 | $this->expectException(CaseStyleNotFoundException::class); 31 | 32 | $factory = new CaseStyleConverterFactory(); 33 | $factory->fromIdentifier('unknown'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/phpunit/Services/CaseStyle/LowerCaseConverterTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('lower', $converter->getIdentifier()); 18 | } 19 | 20 | /** 21 | * @return array 22 | */ 23 | public function getData(): array 24 | { 25 | return [ 26 | ['btn-title', 'btn-title'], 27 | ['btn-title', 'BTN-TITLE'], 28 | ['btn_title', 'btn_title'], 29 | ['btn_title', 'BTN_TITLE'], 30 | ['btntitle', 'btnTitle'], 31 | ['btn title', 'BTN TITLE'], 32 | ]; 33 | } 34 | 35 | /** 36 | * @dataProvider getData 37 | * 38 | * @throws Exception 39 | */ 40 | public function testConvert(string $expected, string $text): void 41 | { 42 | $converter = new LowerCaseConverter(); 43 | 44 | $newText = $converter->convert($text); 45 | 46 | $this->assertEquals($expected, $newText); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tests/phpunit/Services/CaseStyle/UpperCaseConverterTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('upper', $converter->getIdentifier()); 18 | } 19 | 20 | /** 21 | * @return array 22 | */ 23 | public function getData(): array 24 | { 25 | return [ 26 | ['BTN-TITLE', 'btn-title'], 27 | ['BTN-TITLE', 'BTN-TITLE'], 28 | ['BTN_TITLE', 'btn_title'], 29 | ['BTN_TITLE', 'BTN_TITLE'], 30 | ['BTNTITLE', 'btnTitle'], 31 | ['BTN TITLE', 'btn title'], 32 | ]; 33 | } 34 | 35 | /** 36 | * @dataProvider getData 37 | * 38 | * @throws Exception 39 | */ 40 | public function testConvert(string $expected, string $text): void 41 | { 42 | $converter = new UpperCaseConverter(); 43 | 44 | $newText = $converter->convert($text); 45 | 46 | $this->assertEquals($expected, $newText); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tests/phpunit/Services/Connection/ConnectionFactoryTest.php: -------------------------------------------------------------------------------- 1 | buildMySQLConnectionString($host, $port, $database); 19 | 20 | $expected = 'mysql:host=localhost;port=3306;dbname=test_db;collation=utf8mb4_unicode_ci'; 21 | 22 | $this->assertEquals($expected, $result); 23 | } 24 | 25 | 26 | public function testConnectionRefused(): void 27 | { 28 | $this->expectExceptionMessage('SQLSTATE[HY000] [2002] Connection refused'); 29 | 30 | $factory = new ConnectionFactory(); 31 | $connStr = $factory->buildMySQLConnectionString('127.0.01', '3306', 'test'); 32 | 33 | $factory->fromConnectionString($connStr, '', ''); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/phpunit/Services/Loaders/File/FileLoaderTest.php: -------------------------------------------------------------------------------- 1 | loader = new FileLoader(); 22 | 23 | $this->testFile = __DIR__ . '/test_file.txt'; 24 | file_put_contents($this->testFile, 'Sample content'); 25 | } 26 | 27 | 28 | public function tearDown(): void 29 | { 30 | if (file_exists($this->testFile)) { 31 | unlink($this->testFile); 32 | } 33 | } 34 | 35 | 36 | public function testLoadFileNotFound(): void 37 | { 38 | $nonExistentFile = 'path/to/non_existent_file.xml'; 39 | 40 | $this->expectException(Exception::class); 41 | $this->expectExceptionMessage('Configuration file not found: ' . $nonExistentFile); 42 | 43 | $this->loader->load($nonExistentFile); 44 | } 45 | 46 | /** 47 | * @throws Exception 48 | */ 49 | public function testLoadFile(): void 50 | { 51 | $result = $this->loader->load($this->testFile); 52 | 53 | $this->assertEquals('Sample content', $result); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/phpunit/Services/Maths/PercentageCalculatorTest.php: -------------------------------------------------------------------------------- 1 | getRoundedPercentage(298, 300); 17 | 18 | $this->assertEquals(99.33, $result); 19 | } 20 | 21 | 22 | public function testRoundedPercentageDivByZero(): void 23 | { 24 | $calculator = new PercentageCalculator(); 25 | 26 | $result = $calculator->getRoundedPercentage(5, 0); 27 | 28 | $this->assertEquals(0, $result); 29 | } 30 | 31 | 32 | public function testEmptyMeansFull(): void 33 | { 34 | $calculator = new PercentageCalculator(); 35 | 36 | $result = $calculator->getRoundedPercentage(0, 0); 37 | 38 | $this->assertEquals(100, $result); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/phpunit/Services/Placeholder/PlaceholderTest.php: -------------------------------------------------------------------------------- 1 | assertEquals(md5('test'), $ph->getId()); 17 | } 18 | 19 | 20 | public function testValue(): void 21 | { 22 | $ph = new Placeholder('{firstname}'); 23 | 24 | $this->assertEquals('{firstname}', $ph->getValue()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/phpunit/Services/WordCounter/WordCounterTest.php: -------------------------------------------------------------------------------- 1 | getWordCount('this is a text!'); 17 | 18 | $this->assertEquals(4, $words); 19 | } 20 | 21 | 22 | public function testOnlyRealWordsAreFound(): void 23 | { 24 | $counter = new WordCounter(); 25 | 26 | $words = $counter->getWordCount('this is a text! ! -'); 27 | 28 | $this->assertEquals(4, $words); 29 | } 30 | 31 | 32 | public function testCountOfEmptyString(): void 33 | { 34 | $counter = new WordCounter(); 35 | 36 | $words = $counter->getWordCount(''); 37 | 38 | $this->assertEquals(0, $words); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/phpunit/Services/Writers/File/FileWriterTest.php: -------------------------------------------------------------------------------- 1 | testFilePath = __DIR__ . '/testfile.txt'; 22 | } 23 | 24 | 25 | protected function tearDown(): void 26 | { 27 | if (file_exists($this->testFilePath)) { 28 | unlink($this->testFilePath); 29 | } 30 | } 31 | 32 | 33 | public function testWriteFile(): void 34 | { 35 | $fileWriter = new FileWriter(); 36 | $content = "Test content"; 37 | 38 | $fileWriter->writeFile($this->testFilePath, $content); 39 | 40 | $this->assertFileExists($this->testFilePath); 41 | $this->assertEquals($content, file_get_contents($this->testFilePath)); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/phpunit/Services/Writers/Xml/XmlWriterTest.php: -------------------------------------------------------------------------------- 1 | testXmlFilePath = __DIR__ . '/testfile.xml'; 26 | } 27 | 28 | 29 | 30 | protected function tearDown(): void 31 | { 32 | if (file_exists($this->testXmlFilePath)) { 33 | unlink($this->testXmlFilePath); 34 | } 35 | } 36 | 37 | 38 | public function testSaveXml(): void 39 | { 40 | $xmlWriter = new XmlWriter(); 41 | $xmlContent = 'Test Content'; 42 | 43 | $xmlWriter->saveXml($this->testXmlFilePath, $xmlContent); 44 | 45 | $actual = (string)file_get_contents($this->testXmlFilePath); 46 | 47 | $expected = $this->buildComparableString($xmlContent); 48 | $actual = $this->buildComparableString($actual); 49 | 50 | $this->assertFileExists($this->testXmlFilePath); 51 | $this->assertEquals($expected, $actual); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/phpunit/Utils/Fakes/FakeCSVWriter.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | private array $writtenLines = []; 15 | 16 | 17 | 18 | public function prepareDirectory(string $outputDir): void 19 | { 20 | } 21 | 22 | /** 23 | * @return array 24 | */ 25 | public function getWrittenLines(): array 26 | { 27 | return $this->writtenLines; 28 | } 29 | 30 | 31 | public function deleteFile(string $filename): void 32 | { 33 | } 34 | 35 | /** 36 | * @return null|resource 37 | */ 38 | public function open(string $filename) 39 | { 40 | $file = fopen('data://text/plain;base64,' . base64_encode('my-memory-text'), 'r'); 41 | 42 | if ($file === false) { 43 | return null; 44 | } 45 | 46 | return $file; 47 | } 48 | 49 | /** 50 | * @param resource $file 51 | * @param array $row 52 | */ 53 | public function writeLine($file, array $row, string $delimiter): void 54 | { 55 | $this->writtenLines[] = $row; 56 | } 57 | 58 | 59 | public function close($file): void 60 | { 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /tests/phpunit/Utils/Fakes/FakeDirectoryWriter.php: -------------------------------------------------------------------------------- 1 | createdDirectory; 18 | } 19 | 20 | 21 | public function createDirectory(string $path): void 22 | { 23 | $this->createdDirectory = $path; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/phpunit/Utils/Fakes/FakeExchangeFormat.php: -------------------------------------------------------------------------------- 1 | providedContent; 19 | } 20 | 21 | public function getProvidedFilename(): string 22 | { 23 | return $this->providedFilename; 24 | } 25 | 26 | public function writeFile(string $filename, string $content): void 27 | { 28 | $this->providedFilename = $filename; 29 | $this->providedContent = $content; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/phpunit/Utils/Fakes/FakeTranslator.php: -------------------------------------------------------------------------------- 1 | xmlString = $xmlString; 20 | } 21 | 22 | 23 | public function loadXML(string $filename): SimpleXMLElement 24 | { 25 | $xml = simplexml_load_string($this->xmlString); 26 | 27 | if (!$xml) { 28 | throw new Exception('Invalid XML'); 29 | } 30 | 31 | return $xml; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/phpunit/Utils/Fakes/FakeXmlWriter.php: -------------------------------------------------------------------------------- 1 | providedXml; 19 | } 20 | 21 | public function getProvidedFilename(): string 22 | { 23 | return $this->providedFilename; 24 | } 25 | 26 | public function saveXml(string $filename, string $content): void 27 | { 28 | $this->providedFilename = $filename; 29 | $this->providedXml = $content; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/phpunit/Utils/Traits/StringCleanerTrait.php: -------------------------------------------------------------------------------- 1 | registerStorage(new XmlStorage()); -------------------------------------------------------------------------------- /tests/playground/custom-xml/makefile: -------------------------------------------------------------------------------- 1 | 2 | FOLDER := custom-xml 3 | 4 | include ../makefile 5 | 6 | -------------------------------------------------------------------------------- /tests/playground/custom-xml/phpunuhi.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | ./snippets/de.xml 15 | .//snippets/en.xml 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /tests/playground/custom-xml/snippets/de.xml: -------------------------------------------------------------------------------- 1 | sub: 2 | sub2: 'ein brandneuer Untertitel' 3 | subsub: 4 | test: 'Subtitle Text' 5 | title: 'Dies ist ein Titel' 6 | title2: 'Dies ist ein völlig neuer Text' 7 | -------------------------------------------------------------------------------- /tests/playground/custom-xml/snippets/en.xml: -------------------------------------------------------------------------------- 1 | sub: 2 | sub2: 'a brand new subtitle' 3 | subsub: 4 | test: 'Subtitle Text' 5 | title: '' 6 | title2: '' 7 | -------------------------------------------------------------------------------- /tests/playground/custom-xml/src/XmlStorage.php: -------------------------------------------------------------------------------- 1 | getLocales() as $locale) { 38 | $locale->addTranslation('key1', 'value1', ''); 39 | } 40 | } 41 | 42 | public function saveTranslationSet(TranslationSet $set): StorageSaveResult 43 | { 44 | 45 | } 46 | 47 | public function saveTranslationLocale(\PHPUnuhi\Models\Translation\Locale $locale, string $filename): StorageSaveResult 48 | { 49 | } 50 | 51 | 52 | } -------------------------------------------------------------------------------- /tests/playground/ini/de.ini: -------------------------------------------------------------------------------- 1 | Title="Titel" 2 | card_description="Eine Beschreibung" 3 | title="" 4 | title2="das ist ein text" 5 | -------------------------------------------------------------------------------- /tests/playground/ini/en.ini: -------------------------------------------------------------------------------- 1 | Title="title" 2 | card_description="A description" 3 | title="" 4 | title2="this is a text" 5 | -------------------------------------------------------------------------------- /tests/playground/ini/ini_sections.ini: -------------------------------------------------------------------------------- 1 | [de] 2 | 3 | description="Meine Beschreibung" 4 | title="Titel" 5 | title2="das ist ein text" 6 | 7 | [en] 8 | 9 | description="my description" 10 | title="title" 11 | title2="this is a text" 12 | -------------------------------------------------------------------------------- /tests/playground/ini/makefile: -------------------------------------------------------------------------------- 1 | 2 | FOLDER := ini 3 | 4 | include ../makefile 5 | 6 | -------------------------------------------------------------------------------- /tests/playground/ini/phpunuhi.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | ./de.ini 17 | ./en.ini 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | ./ini_sections.ini 27 | ./ini_sections.ini 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /tests/playground/json/bundle/snippets.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 3 17 | 18 | false 19 | 20 | 21 | 22 | 23 | * 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | %base_path%/%locale%.json 32 | %base_path%/%locale%.json 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /tests/playground/json/bundle/snippets/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "card-section": { 3 | "greeting": "Hallo %firstname%. Schön dich zu sehen!", 4 | "titleTest": "Allgemein" 5 | }, 6 | "kebab-title": "Allgemein", 7 | "lblCaption": "Caption", 8 | "lblCaption2": "Caption", 9 | "test234": "das Mädchen" 10 | } -------------------------------------------------------------------------------- /tests/playground/json/bundle/snippets/nl.json: -------------------------------------------------------------------------------- 1 | { 2 | "card-section": { 3 | "greeting": "Hallo %firstname%. Leuk je te zien!", 4 | "titleTest": "Over het algemeen" 5 | }, 6 | "kebab-title": "Over het algemeen", 7 | "test234": "het meisje" 8 | } -------------------------------------------------------------------------------- /tests/playground/json/makefile: -------------------------------------------------------------------------------- 1 | 2 | FOLDER := json 3 | 4 | include ../makefile 5 | 6 | -------------------------------------------------------------------------------- /tests/playground/json/phpunuhi.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | %base_path%/%locale%_newline.json 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/playground/json/snippets/en_newline.json: -------------------------------------------------------------------------------- 1 | { 2 | "foo": "bar" 3 | } 4 | -------------------------------------------------------------------------------- /tests/playground/json/templates/index.mjml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boxblinkracer/phpunuhi/92bb31af1214b50ec6c9a778c3052dc494fbc01b/tests/playground/json/templates/index.mjml -------------------------------------------------------------------------------- /tests/playground/json/templates/subfolder/index.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ 'card-section.titleTest' | trans }} 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/playground/json/templates/subfolder/test.mjml: -------------------------------------------------------------------------------- 1 | {{ 'card-section.titleTest' | trans }} -------------------------------------------------------------------------------- /tests/playground/php/de.php: -------------------------------------------------------------------------------- 1 | [ 5 | "sub2" => "ein brandneuer Untertitel", 6 | "subsub" => [ 7 | "test" => "Subtitle Text", 8 | ], 9 | ], 10 | "tite2" => "das ist ein neuer text", 11 | "title" => "Dies ist ein Titel", 12 | ]; 13 | -------------------------------------------------------------------------------- /tests/playground/php/en.php: -------------------------------------------------------------------------------- 1 | [ 5 | "sub2" => "a brand new subtitle", 6 | "subsub" => [ 7 | "test" => "Subtitle Text", 8 | ], 9 | ], 10 | "tite2" => "this is a new text", 11 | "title" => "This is a title", 12 | ]; 13 | -------------------------------------------------------------------------------- /tests/playground/php/makefile: -------------------------------------------------------------------------------- 1 | 2 | FOLDER := php 3 | 4 | include ../makefile 5 | 6 | -------------------------------------------------------------------------------- /tests/playground/php/phpunuhi.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ./de.php 14 | ./en.php 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tests/playground/po/de.po: -------------------------------------------------------------------------------- 1 | msgid "lblTitle" 2 | msgstr "Wert" 3 | 4 | # comment 2 5 | msgid "lblTitle2" 6 | msgstr "Tisch" 7 | 8 | msgid "lblTitle33" 9 | msgstr "Haus" 10 | 11 | msgid "lblTitle4" 12 | msgstr "Das ist ein ganz neuer Text" 13 | -------------------------------------------------------------------------------- /tests/playground/po/en.po: -------------------------------------------------------------------------------- 1 | msgid "lblTitle" 2 | msgstr "Value" 3 | 4 | msgid "lblTitle2" 5 | msgstr "Table" 6 | msgctxt "abc" 7 | 8 | msgid "lblTitle33" 9 | msgstr "House" 10 | 11 | msgid "lblTitle4" 12 | msgstr "This is a whole new text" 13 | -------------------------------------------------------------------------------- /tests/playground/po/makefile: -------------------------------------------------------------------------------- 1 | 2 | FOLDER := po 3 | 4 | include ../makefile 5 | 6 | -------------------------------------------------------------------------------- /tests/playground/po/phpunuhi.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ./%locale%.po 14 | ./%locale%.po 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tests/playground/resx/files/Resources.de.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hallo 5 | 6 | 7 | Auf Wiedersehen 8 | 9 | 10 | Image content not needed 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/playground/resx/files/Resources.en.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Goodbye 7 | 8 | 9 | Hello 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/playground/resx/makefile: -------------------------------------------------------------------------------- 1 | 2 | FOLDER := resx 3 | 4 | include ../makefile 5 | 6 | -------------------------------------------------------------------------------- /tests/playground/resx/phpunuhi.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | ./files/Resources.de.resx 13 | ./files/Resources.en.resx 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /tests/playground/shopware6-config/makefile: -------------------------------------------------------------------------------- 1 | 2 | FOLDER := shopware6-config 3 | 4 | include ../makefile 5 | 6 | -------------------------------------------------------------------------------- /tests/playground/shopware6-config/phpunuhi.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /tests/playground/shopware6/makefile: -------------------------------------------------------------------------------- 1 | 2 | FOLDER := shopware6 3 | 4 | include ../makefile 5 | 6 | -------------------------------------------------------------------------------- /tests/playground/strings/files/de.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Testontroller.strings 4 | 5 | */ 6 | 7 | /* 8 | 9 | COMPONENTS 10 | 11 | ==================================================================================== 12 | 13 | */ 14 | "views.components.textelementinput.placeholder" = "Geben Sie Ihren Text ein"; 15 | 16 | "views.login.placeholder.password" = "Passwort"; 17 | "views.login.btnConnect" = "Mit der App verbinden"; 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tests/playground/strings/files/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- 1 | 2 | "views.login.placeholder.password" = "Password"; 3 | 4 | "views.login.btnConnect" = "Connect to App"; 5 | 6 | "views.components.textelementinput.placeholder" = "Enter your text"; 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /tests/playground/strings/makefile: -------------------------------------------------------------------------------- 1 | 2 | FOLDER := strings 3 | 4 | include ../makefile 5 | 6 | -------------------------------------------------------------------------------- /tests/playground/strings/phpunuhi.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | ./files/en.lproj/Localizable.strings 13 | ./files/de.lproj/Localizable.strings 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /tests/playground/yaml/de.yaml: -------------------------------------------------------------------------------- 1 | sub: 2 | sub2: 'ein brandneuer Untertitel' 3 | subsub: 4 | test: 'Subtitle Text' 5 | title: 'Dies ist ein Titel' 6 | title2: 'Dies ist ein völlig neuer Text' 7 | -------------------------------------------------------------------------------- /tests/playground/yaml/en.yaml: -------------------------------------------------------------------------------- 1 | sub: 2 | sub2: 'a brand new subtitle' 3 | subsub: 4 | test: 'Subtitle Text' 5 | title: '' 6 | title2: '' 7 | -------------------------------------------------------------------------------- /tests/playground/yaml/makefile: -------------------------------------------------------------------------------- 1 | 2 | FOLDER := yaml 3 | 4 | include ../makefile 5 | 6 | -------------------------------------------------------------------------------- /tests/playground/yaml/phpunuhi.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ./de.yaml 14 | ./en.yaml 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 20 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/scripts/check_composer_version.php: -------------------------------------------------------------------------------- 1 | 1) { 4 | $inputVersion = $argv[1]; 5 | } else { 6 | echo "Usage: php check_composer_version.php \n"; 7 | exit(1); 8 | } 9 | 10 | // Read the composer.json file 11 | $composerJsonPath = __DIR__ . '/../../composer.json'; 12 | if (!file_exists($composerJsonPath)) { 13 | echo "Error: composer.json not found.\n"; 14 | exit(1); 15 | } 16 | 17 | $composerData = json_decode(file_get_contents($composerJsonPath), true); 18 | if ($composerData === null || !isset($composerData['version'])) { 19 | echo "Error: Version not found in composer.json.\n"; 20 | exit(1); 21 | } 22 | 23 | $currentVersion = $composerData['version']; 24 | 25 | // Check if the current version is dev-main and ignore it 26 | if ($inputVersion === 'dev-main') { 27 | echo "The provided version is 'dev-main', check ignored.\n"; 28 | exit(0); 29 | } 30 | 31 | // Compare versions 32 | if ($currentVersion === $inputVersion) { 33 | echo "The current version in composer.json matches the input version: $currentVersion\n"; 34 | exit(0); 35 | } else { 36 | echo "The current version in composer.json ($currentVersion) does not match the input version: $inputVersion\n"; 37 | exit(1); 38 | } -------------------------------------------------------------------------------- /tests/scripts/check_xsd.php: -------------------------------------------------------------------------------- 1 | 1) { 4 | $version = $argv[1]; 5 | 6 | echo "Verifying XSD file for version: {$version}\n"; 7 | 8 | // Extract the major and minor parts of the version (e.g., "1.22.1" -> "1.22") 9 | $minorVersion = preg_replace('/(\.\d+)?$/', '', $version); 10 | 11 | $filePath = __DIR__ . "/../../schema/{$minorVersion}.xsd"; 12 | 13 | if (file_exists($filePath)) { 14 | echo "Success: Schema file found: {$minorVersion}.xsd\n"; 15 | exit(0); 16 | } else { 17 | echo "Error: Schema file not found: {$minorVersion}.xsd\n"; 18 | exit(1); 19 | } 20 | } else { 21 | echo "Usage: php check_xsd.php \n"; 22 | exit(1); 23 | } 24 | -------------------------------------------------------------------------------- /tests/svrunit/fixtures/custom-command/autoload.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | ./de.json 15 | ./en.json 16 | ./nl.json 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/svrunit/fixtures/custom-command/src/CustomCommand.php: -------------------------------------------------------------------------------- 1 | setName('custom:command-xy') 21 | ->setDescription('Custom Command') 22 | ->addOption('configuration', null, InputOption::VALUE_REQUIRED, '', ''); 23 | 24 | parent::configure(); 25 | } 26 | 27 | public function execute(InputInterface $input, OutputInterface $output): int 28 | { 29 | $io = new SymfonyStyle($input, $output); 30 | $io->title('PHPUnuhi Custom Command XY'); 31 | 32 | return 0; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/svrunit/fixtures/ini/de.ini: -------------------------------------------------------------------------------- 1 | card_description="Eine Beschreibung" 2 | title="Titel" 3 | -------------------------------------------------------------------------------- /tests/svrunit/fixtures/ini/en.ini: -------------------------------------------------------------------------------- 1 | card_description="A description" 2 | title="title" 3 | -------------------------------------------------------------------------------- /tests/svrunit/fixtures/ini/ini_sections.ini: -------------------------------------------------------------------------------- 1 | [de] 2 | 3 | description="Meine Beschreibung" 4 | title="Titel" 5 | 6 | [en] 7 | 8 | description="my description" 9 | title="title" 10 | -------------------------------------------------------------------------------- /tests/svrunit/fixtures/ini/phpunuhi.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ./de.ini 14 | ./en.ini 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ./ini_sections.ini 24 | ./ini_sections.ini 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /tests/svrunit/fixtures/json/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "card": { 3 | "description": "Das ist die Übersicht aller allgemeinen Punkte.", 4 | "title": "Allgemein" 5 | }, 6 | "title": "Willkommen" 7 | } -------------------------------------------------------------------------------- /tests/svrunit/fixtures/json/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "card": { 3 | "description": "This is the overview of all general points.", 4 | "title": "General" 5 | }, 6 | "title": "Welcome" 7 | } -------------------------------------------------------------------------------- /tests/svrunit/fixtures/json/nl.json: -------------------------------------------------------------------------------- 1 | { 2 | "card": { 3 | "description": "Dit is het overzicht van alle algemene punten.", 4 | "title": "Algemeen" 5 | }, 6 | "title": "Welkom" 7 | } -------------------------------------------------------------------------------- /tests/svrunit/fixtures/json/phpunuhi.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ./de.json 14 | ./en.json 15 | ./nl.json 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tests/svrunit/fixtures/json/templates/subfolder/index.mjml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boxblinkracer/phpunuhi/92bb31af1214b50ec6c9a778c3052dc494fbc01b/tests/svrunit/fixtures/json/templates/subfolder/index.mjml -------------------------------------------------------------------------------- /tests/svrunit/fixtures/json/templates/subfolder/index.twig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boxblinkracer/phpunuhi/92bb31af1214b50ec6c9a778c3052dc494fbc01b/tests/svrunit/fixtures/json/templates/subfolder/index.twig -------------------------------------------------------------------------------- /tests/svrunit/fixtures/php/de.php: -------------------------------------------------------------------------------- 1 | [ 5 | "sub2" => "ein brandneuer Untertitel", 6 | "subsub" => [ 7 | "test" => "Subtitle Text", 8 | ], 9 | ], 10 | "title" => "Dies ist ein Titel", 11 | ]; 12 | -------------------------------------------------------------------------------- /tests/svrunit/fixtures/php/en.php: -------------------------------------------------------------------------------- 1 | [ 5 | "sub2" => "a brand new subtitle", 6 | "subsub" => [ 7 | "test" => "Subtitle Text", 8 | ], 9 | ], 10 | "title" => "This is a title", 11 | ]; 12 | -------------------------------------------------------------------------------- /tests/svrunit/fixtures/php/phpunuhi.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ./de.php 14 | ./en.php 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tests/svrunit/fixtures/shopware6/phpunuhi.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /tests/svrunit/fixtures/yaml/de.yaml: -------------------------------------------------------------------------------- 1 | card: 2 | description: Das ist die Übersicht aller allgemeinen Punkte. 3 | title: Allgemein 4 | title: Herzlich willkommen 5 | -------------------------------------------------------------------------------- /tests/svrunit/fixtures/yaml/en.yaml: -------------------------------------------------------------------------------- 1 | card: 2 | description: This is the overview of all general points. 3 | title: General 4 | title: Welcome 5 | -------------------------------------------------------------------------------- /tests/svrunit/fixtures/yaml/nl.yaml: -------------------------------------------------------------------------------- 1 | card: 2 | description: Dit is het overzicht van alle algemene punten. 3 | title: Algemeen 4 | title: Welkom 5 | -------------------------------------------------------------------------------- /tests/svrunit/fixtures/yaml/phpunuhi.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ./de.yaml 14 | ./en.yaml 15 | ./nl.yaml 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tests/svrunit/tests/commands/scanner.yml: -------------------------------------------------------------------------------- 1 | commands: 2 | 3 | - name: "Scan Usage TWIG" 4 | command: "(($EXEC)) scan:usage --scanner=twig --dir=./tests/svrunit/fixtures/json/templates --configuration=./tests/svrunit/fixtures/json/phpunuhi.xml " 5 | expected: "Key not found in any file" 6 | 7 | - name: "Scan Usage MJML" 8 | command: "(($EXEC)) scan:usage --scanner=mjml --dir=./tests/svrunit/fixtures/json/templates --configuration=./tests/svrunit/fixtures/json/phpunuhi.xml" 9 | expected: "Key not found in any file" 10 | 11 | - name: "Scan Usage with verbose mode shows scanned files" 12 | command: "(($EXEC)) scan:usage --scanner=mjml --dir=./tests/svrunit/fixtures/json/templates --verbose --configuration=./tests/svrunit/fixtures/json/phpunuhi.xml" 13 | expected: "templates/subfolder/index.mjml" -------------------------------------------------------------------------------- /tests/svrunit/tests/extensions.yml: -------------------------------------------------------------------------------- 1 | commands: 2 | 3 | - name: "custom:command-xy from extension is working" 4 | command: "(($EXEC)) custom:command-xy --configuration=./tests/svrunit/fixtures/custom-command/phpunuhi.xml" 5 | expected: "PHPUnuhi Custom Command XY" 6 | -------------------------------------------------------------------------------- /tests/svrunit/tests/ini.yml: -------------------------------------------------------------------------------- 1 | commands: 2 | - name: "Status" 3 | command: "(($EXEC)) status --configuration=./tests/svrunit/fixtures/ini/phpunuhi.xml" 4 | expected: "Coverage: 100%" 5 | - name: "Validate" 6 | command: "(($EXEC)) validate --configuration=./tests/svrunit/fixtures/ini/phpunuhi.xml" 7 | expected: "All translations are valid" 8 | - name: "Export" 9 | command: "(($EXEC)) export --configuration=./tests/svrunit/fixtures/ini/phpunuhi.xml --dir=.svrunit" 10 | expected: "All translations exported" -------------------------------------------------------------------------------- /tests/svrunit/tests/json.yml: -------------------------------------------------------------------------------- 1 | commands: 2 | - name: "Status" 3 | command: "(($EXEC)) status --configuration=./tests/svrunit/fixtures/json/phpunuhi.xml" 4 | expected: "Coverage: 100%" 5 | - name: "Validate" 6 | command: "(($EXEC)) validate --configuration=./tests/svrunit/fixtures/json/phpunuhi.xml" 7 | expected: "All translations are valid" 8 | - name: "Export" 9 | command: "(($EXEC)) export --configuration=./tests/svrunit/fixtures/json/phpunuhi.xml --dir=.svrunit" 10 | expected: "All translations exported" -------------------------------------------------------------------------------- /tests/svrunit/tests/php.yml: -------------------------------------------------------------------------------- 1 | commands: 2 | - name: "Status" 3 | command: "(($EXEC)) status --configuration=./tests/svrunit/fixtures/php/phpunuhi.xml" 4 | expected: "Coverage: 100%" 5 | - name: "Validate" 6 | command: "(($EXEC)) validate --configuration=./tests/svrunit/fixtures/php/phpunuhi.xml" 7 | expected: "All translations are valid" 8 | - name: "Export" 9 | command: "(($EXEC)) export --configuration=./tests/svrunit/fixtures/php/phpunuhi.xml --dir=.svrunit" 10 | expected: "All translations exported" -------------------------------------------------------------------------------- /tests/svrunit/tests/shopware6.yml: -------------------------------------------------------------------------------- 1 | commands: 2 | - name: "Format requires database" 3 | command: "(($EXEC)) status --configuration=./tests/svrunit/fixtures/shopware6/phpunuhi.xml" 4 | expected: "Connection refused" -------------------------------------------------------------------------------- /tests/svrunit/tests/yaml.yml: -------------------------------------------------------------------------------- 1 | commands: 2 | - name: "Status" 3 | command: "(($EXEC)) status --configuration=./tests/svrunit/fixtures/yaml/phpunuhi.xml" 4 | expected: "Coverage: 100%" 5 | - name: "Validate" 6 | command: "(($EXEC)) validate --configuration=./tests/svrunit/fixtures/yaml/phpunuhi.xml" 7 | expected: "All translations are valid" 8 | - name: "Export" 9 | command: "(($EXEC)) export --configuration=./tests/svrunit/fixtures/yaml/phpunuhi.xml --dir=.svrunit" 10 | expected: "All translations exported" 11 | --------------------------------------------------------------------------------