diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12e5e20..670b024 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: strategy: fail-fast: false matrix: - php-version: ["7.4", "8.0", "8.1", "8.2", "8.3", "8.4"] + php-version: ["7.4", "8.0", "8.1", "8.2", "8.3", "8.4", "8.5"] steps: - name: Checkout uses: actions/checkout@v4 @@ -48,8 +48,17 @@ jobs: - name: Validate composer.json run: composer validate --strict --no-check-lock + # PHPUnit 9 (PHP 7.4/8.0) uses the legacy `` schema; + # PHPUnit 10/11 (PHP 8.1+) uses the modern `` schema. + # Each version's schema validator rejects the other's syntax as a runner + # warning, so we keep two config files and pick per matrix entry. - name: Run PHPUnit with coverage - run: ./vendor/bin/phpunit --coverage-clover coverage.xml --coverage-text + run: | + if [[ "${{ matrix.php-version }}" == "7.4" || "${{ matrix.php-version }}" == "8.0" ]]; then + ./vendor/bin/phpunit -c phpunit-legacy.xml.dist --coverage-clover coverage.xml --coverage-text + else + ./vendor/bin/phpunit --coverage-clover coverage.xml --coverage-text + fi - name: Enforce >= 80% line coverage run: | diff --git a/.phpunit.result.cache b/.phpunit.result.cache index 6e76343..94909d7 100644 --- a/.phpunit.result.cache +++ b/.phpunit.result.cache @@ -1 +1 @@ -{"version":1,"defects":{"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testTransportExceptionReturnsTransportErrorResult":4},"times":{"Dev1\\NotifyCore\\Tests\\DTO\\PushResultTest::testSuccessDefaults":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushResultTest::testFailurePropagatesErrorFields":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushTargetTest::testRejectsEmptyTarget":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushTargetTest::testStoresTokenAsString":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushTargetTest::testStoresTopic":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushTargetTest::testStoresCondition":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testConstructorRequiresProjectId":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testEndpointInterpolatesProjectId":0.001,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testSuccessfulSendReturnsId":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testFailureMapsFcmErrorStatus":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testDataOnlyPushOmitsNotificationBlock":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testDataValuesAreStringified":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testTargetPrefersToken":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testAndroidOptionsAreSerialized":0.001,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testTransportExceptionReturnsTransportErrorResult":0,"Dev1\\NotifyCore\\Tests\\Registry\\ClientRegistryTest::testFirstRegisteredBecomesDefault":0.001,"Dev1\\NotifyCore\\Tests\\Registry\\ClientRegistryTest::testAsDefaultSwitchesDefault":0,"Dev1\\NotifyCore\\Tests\\Registry\\ClientRegistryTest::testUnknownClientThrows":0,"Dev1\\NotifyCore\\Tests\\Registry\\ClientRegistryTest::testRemoveClearsDefault":0,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testRequiresEmailAndKey":0.008,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testSuccessfulTokenIsCachedInMemory":0.004,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testPsr16CacheIsPopulatedAndReused":0.001,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testRetriesOn5xxThenSucceeds":0.002,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testRetriesOnTransportExceptionThenSucceeds":0.002,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testExhaustedRetriesThrowTransient":0.003,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testNon5xxErrorDoesNotRetry":0.001,"Dev1\\NotifyCore\\Tests\\DTO\\PushResultTest::testUnregisteredHelper":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushResultTest::testInvalidArgumentHelper":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushResultTest::testQuotaExceededHelper":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushResultTest::testTransientHelper":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushTargetTest::testRejectsAmbiguousTarget":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushTargetTest::testRejectsAllThreeSet":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientRetryTest::testRetriesOn503ThenSucceeds":0.001,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientRetryTest::testRetriesOnTransportException":0.001,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientRetryTest::testRetriesOn429":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientRetryTest::testExhaustedRetriesReturnsTransientResult":0.001,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientRetryTest::testClientErrorDoesNotRetry":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientRetryTest::testFcmErrorCodeDetailOverridesStatus":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientRetryTest::testPushResultTransientHelper":0.001,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testPriorityNormalizes":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testPriorityRejectsUnknownValue":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testChannelIdEmittedExactlyOnce":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testTtlIsSecondsString":0,"Dev1\\NotifyCore\\Tests\\Registry\\ClientRegistryTest::testRemoveUnknownReturnsFalse":0,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testMalformedCacheEntryIsIgnored":0.001,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testCacheReadFailureFallsBackToNetwork":0.001,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testCacheWriteFailureIsSwallowed":0.001,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testScopeArrayIsSpaceJoinedInJwt":0.002,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testHttp200WithoutAccessTokenThrows":0.001,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testInvalidPrivateKeyThrowsAtSignTime":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testTopicTargetSerializesAsTopic":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testConditionTargetSerializesAsCondition":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testApnsPlatformOptionsAreSerialized":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testRawArrayOverridesArePassedThroughUntouched":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testTokenAcquisitionFailureReturnsTokenErrorResult":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testNonJsonErrorBodyFallsBackToHttpStatusCode":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testCustomEndpointInterpolatesProjectId":0,"Dev1\\NotifyCore\\Tests\\Factory\\FcmClientFactoryTest::testCreateReturnsFcmHttpV1Client":0,"Dev1\\NotifyCore\\Tests\\Factory\\FcmClientFactoryTest::testCreatePropagatesConfigValidation":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testNegativeTtlClampsToZero":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testWithNotificationMergesIntoNotificationMap":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testChannelIdCoexistsWithNotificationMap":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testWithDataReplacesPreviousData":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testWithExtraMergesIntoOutputRoot":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testMergePrefersOtherForScalarsAndMergesMaps":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testMergeOtherOverridesChannelAndTtl":0,"Dev1\\NotifyCore\\Tests\\Platform\\ApnsOptionsTest::testEmptyOptionsProduceEmptyArray":0,"Dev1\\NotifyCore\\Tests\\Platform\\ApnsOptionsTest::testHeadersOnlyEmitsHeadersKey":0,"Dev1\\NotifyCore\\Tests\\Platform\\ApnsOptionsTest::testApsIsNestedUnderBody":0,"Dev1\\NotifyCore\\Tests\\Platform\\ApnsOptionsTest::testCustomPayloadMergesAtBodyRoot":0,"Dev1\\NotifyCore\\Tests\\Platform\\ApnsOptionsTest::testWithHeadersMergesRecursively":0,"Dev1\\NotifyCore\\Tests\\Platform\\ApnsOptionsTest::testMergePrefersOtherForScalarsAndMergesMaps":0,"Dev1\\NotifyCore\\Tests\\Platform\\ApnsOptionsTest::testCustomWithoutApsStillProducesBody":0,"Dev1\\NotifyCore\\Tests\\Registry\\ClientRegistryTest::testSetDefaultSwitchesDefault":0,"Dev1\\NotifyCore\\Tests\\Registry\\ClientRegistryTest::testSetDefaultUnknownThrows":0,"Dev1\\NotifyCore\\Tests\\Registry\\ClientRegistryTest::testNamesListsRegisteredClients":0}} \ No newline at end of file +{"version":1,"defects":{"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testTransportExceptionReturnsTransportErrorResult":4},"times":{"Dev1\\NotifyCore\\Tests\\DTO\\PushResultTest::testSuccessDefaults":0.001,"Dev1\\NotifyCore\\Tests\\DTO\\PushResultTest::testFailurePropagatesErrorFields":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushTargetTest::testRejectsEmptyTarget":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushTargetTest::testStoresTokenAsString":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushTargetTest::testStoresTopic":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushTargetTest::testStoresCondition":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testConstructorRequiresProjectId":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testEndpointInterpolatesProjectId":0.001,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testSuccessfulSendReturnsId":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testFailureMapsFcmErrorStatus":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testDataOnlyPushOmitsNotificationBlock":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testDataValuesAreStringified":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testTargetPrefersToken":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testAndroidOptionsAreSerialized":0.001,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testTransportExceptionReturnsTransportErrorResult":0,"Dev1\\NotifyCore\\Tests\\Registry\\ClientRegistryTest::testFirstRegisteredBecomesDefault":0,"Dev1\\NotifyCore\\Tests\\Registry\\ClientRegistryTest::testAsDefaultSwitchesDefault":0,"Dev1\\NotifyCore\\Tests\\Registry\\ClientRegistryTest::testUnknownClientThrows":0,"Dev1\\NotifyCore\\Tests\\Registry\\ClientRegistryTest::testRemoveClearsDefault":0,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testRequiresEmailAndKey":0.008,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testSuccessfulTokenIsCachedInMemory":0.005,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testPsr16CacheIsPopulatedAndReused":0.001,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testRetriesOn5xxThenSucceeds":0.002,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testRetriesOnTransportExceptionThenSucceeds":0.002,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testExhaustedRetriesThrowTransient":0.003,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testNon5xxErrorDoesNotRetry":0.001,"Dev1\\NotifyCore\\Tests\\DTO\\PushResultTest::testUnregisteredHelper":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushResultTest::testInvalidArgumentHelper":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushResultTest::testQuotaExceededHelper":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushResultTest::testTransientHelper":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushTargetTest::testRejectsAmbiguousTarget":0,"Dev1\\NotifyCore\\Tests\\DTO\\PushTargetTest::testRejectsAllThreeSet":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientRetryTest::testRetriesOn503ThenSucceeds":0.001,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientRetryTest::testRetriesOnTransportException":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientRetryTest::testRetriesOn429":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientRetryTest::testExhaustedRetriesReturnsTransientResult":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientRetryTest::testClientErrorDoesNotRetry":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientRetryTest::testFcmErrorCodeDetailOverridesStatus":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientRetryTest::testPushResultTransientHelper":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testPriorityNormalizes":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testPriorityRejectsUnknownValue":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testChannelIdEmittedExactlyOnce":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testTtlIsSecondsString":0,"Dev1\\NotifyCore\\Tests\\Registry\\ClientRegistryTest::testRemoveUnknownReturnsFalse":0,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testMalformedCacheEntryIsIgnored":0.001,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testCacheReadFailureFallsBackToNetwork":0.001,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testCacheWriteFailureIsSwallowed":0.001,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testScopeArrayIsSpaceJoinedInJwt":0.001,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testHttp200WithoutAccessTokenThrows":0.001,"Dev1\\NotifyCore\\Tests\\Auth\\GoogleServiceAccountTokenProviderTest::testInvalidPrivateKeyThrowsAtSignTime":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testTopicTargetSerializesAsTopic":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testConditionTargetSerializesAsCondition":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testApnsPlatformOptionsAreSerialized":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testRawArrayOverridesArePassedThroughUntouched":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testTokenAcquisitionFailureReturnsTokenErrorResult":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testNonJsonErrorBodyFallsBackToHttpStatusCode":0,"Dev1\\NotifyCore\\Tests\\Drivers\\FcmHttpV1ClientTest::testCustomEndpointInterpolatesProjectId":0,"Dev1\\NotifyCore\\Tests\\Factory\\FcmClientFactoryTest::testCreateReturnsFcmHttpV1Client":0,"Dev1\\NotifyCore\\Tests\\Factory\\FcmClientFactoryTest::testCreatePropagatesConfigValidation":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testNegativeTtlClampsToZero":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testWithNotificationMergesIntoNotificationMap":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testChannelIdCoexistsWithNotificationMap":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testWithDataReplacesPreviousData":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testWithExtraMergesIntoOutputRoot":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testMergePrefersOtherForScalarsAndMergesMaps":0,"Dev1\\NotifyCore\\Tests\\Platform\\AndroidOptionsTest::testMergeOtherOverridesChannelAndTtl":0,"Dev1\\NotifyCore\\Tests\\Platform\\ApnsOptionsTest::testEmptyOptionsProduceEmptyArray":0,"Dev1\\NotifyCore\\Tests\\Platform\\ApnsOptionsTest::testHeadersOnlyEmitsHeadersKey":0,"Dev1\\NotifyCore\\Tests\\Platform\\ApnsOptionsTest::testApsIsNestedUnderBody":0,"Dev1\\NotifyCore\\Tests\\Platform\\ApnsOptionsTest::testCustomPayloadMergesAtBodyRoot":0,"Dev1\\NotifyCore\\Tests\\Platform\\ApnsOptionsTest::testWithHeadersMergesRecursively":0,"Dev1\\NotifyCore\\Tests\\Platform\\ApnsOptionsTest::testMergePrefersOtherForScalarsAndMergesMaps":0,"Dev1\\NotifyCore\\Tests\\Platform\\ApnsOptionsTest::testCustomWithoutApsStillProducesBody":0,"Dev1\\NotifyCore\\Tests\\Registry\\ClientRegistryTest::testSetDefaultSwitchesDefault":0,"Dev1\\NotifyCore\\Tests\\Registry\\ClientRegistryTest::testSetDefaultUnknownThrows":0,"Dev1\\NotifyCore\\Tests\\Registry\\ClientRegistryTest::testNamesListsRegisteredClients":0}} \ No newline at end of file diff --git a/composer.json b/composer.json index ed712c4..d79e6d1 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "type": "library", "license": "MIT", "require": { - "php": ">=7.4 <8.5", + "php": ">=7.4 <8.6", "psr/http-client": "^1.0", "psr/http-factory": "^1.0", "psr/log": "^1.1 || ^2.0 || ^3.0" @@ -12,7 +12,7 @@ "require-dev": { "nyholm/psr7": "^1.8", "symfony/http-client": "^5.4 || ^6.0 || ^7.0", - "phpunit/phpunit": "^9.6", + "phpunit/phpunit": "^9.6 || ^10.5 || ^11.5", "psr/simple-cache": "^1.0" }, "suggest": { diff --git a/phpunit-legacy.xml.dist b/phpunit-legacy.xml.dist new file mode 100644 index 0000000..dd769dd --- /dev/null +++ b/phpunit-legacy.xml.dist @@ -0,0 +1,19 @@ + + + + + tests + + + + + src + + + diff --git a/phpunit.xml.dist b/phpunit.xml.dist index dd769dd..7482ef2 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -11,9 +11,9 @@ tests - + src - + diff --git a/src/Version.php b/src/Version.php index 8b2e313..4b5a575 100644 --- a/src/Version.php +++ b/src/Version.php @@ -4,11 +4,9 @@ final class Version { - public const VERSION = '1.2.0'; + public const VERSION = '1.2.1'; - public const USER_AGENT = 'Dev1-Notify-Core/1.2.0 (+https://github.com/DEV1-Softworks/notify-core)'; + public const USER_AGENT = 'Dev1-Notify-Core/1.2.1 (+https://github.com/DEV1-Softworks/notify-core)'; - private function __construct() - { - } + private function __construct() {} }