diff --git a/README.md b/README.md index f682451..4b828f8 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,8 @@ wget https://downloads.rclone.org/rclone-current-linux-amd64.deb sudo dpkg -i rclone-current-linux-amd64.deb # Infection install - rm infection.phar -wget https://github.com/infection/infection/releases/download/0.27.0/infection.phar +wget https://github.com/infection/infection/releases/download/0.27.8/infection.phar chmod +x infection.phar # PHP CopyPasteDetector install diff --git a/composer.lock b/composer.lock index e21b6b3..8cbc3ce 100644 --- a/composer.lock +++ b/composer.lock @@ -1046,16 +1046,16 @@ }, { "name": "symfony/console", - "version": "v6.3.4", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6" + "reference": "0d14a9f6d04d4ac38a8cea1171f4554e325dae92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/eca495f2ee845130855ddf1cf18460c38966c8b6", - "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6", + "url": "https://api.github.com/repos/symfony/console/zipball/0d14a9f6d04d4ac38a8cea1171f4554e325dae92", + "reference": "0d14a9f6d04d4ac38a8cea1171f4554e325dae92", "shasum": "" }, "require": { @@ -1116,7 +1116,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.3.4" + "source": "https://github.com/symfony/console/tree/v6.3.8" }, "funding": [ { @@ -1132,7 +1132,7 @@ "type": "tidelift" } ], - "time": "2023-08-16T10:10:12+00:00" + "time": "2023-10-31T08:09:35+00:00" }, { "name": "symfony/deprecation-contracts", @@ -1676,16 +1676,16 @@ }, { "name": "symfony/string", - "version": "v6.3.5", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "13d76d0fb049051ed12a04bef4f9de8715bea339" + "reference": "13880a87790c76ef994c91e87efb96134522577a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/13d76d0fb049051ed12a04bef4f9de8715bea339", - "reference": "13d76d0fb049051ed12a04bef4f9de8715bea339", + "url": "https://api.github.com/repos/symfony/string/zipball/13880a87790c76ef994c91e87efb96134522577a", + "reference": "13880a87790c76ef994c91e87efb96134522577a", "shasum": "" }, "require": { @@ -1742,7 +1742,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.3.5" + "source": "https://github.com/symfony/string/tree/v6.3.8" }, "funding": [ { @@ -1758,20 +1758,20 @@ "type": "tidelift" } ], - "time": "2023-09-18T10:38:32+00:00" + "time": "2023-11-09T08:28:21+00:00" }, { "name": "symfony/yaml", - "version": "v6.3.7", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "9758b6c69d179936435d0ffb577c3708d57e38a8" + "reference": "3493af8a8dad7fa91c77fa473ba23ecd95334a92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/9758b6c69d179936435d0ffb577c3708d57e38a8", - "reference": "9758b6c69d179936435d0ffb577c3708d57e38a8", + "url": "https://api.github.com/repos/symfony/yaml/zipball/3493af8a8dad7fa91c77fa473ba23ecd95334a92", + "reference": "3493af8a8dad7fa91c77fa473ba23ecd95334a92", "shasum": "" }, "require": { @@ -1814,7 +1814,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.3.7" + "source": "https://github.com/symfony/yaml/tree/v6.3.8" }, "funding": [ { @@ -1830,7 +1830,7 @@ "type": "tidelift" } ], - "time": "2023-10-28T23:31:00+00:00" + "time": "2023-11-06T10:58:05+00:00" }, { "name": "twig/twig", @@ -3296,16 +3296,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.40", + "version": "1.10.41", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "93c84b5bf7669920d823631e39904d69b9c7dc5d" + "reference": "c6174523c2a69231df55bdc65b61655e72876d76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/93c84b5bf7669920d823631e39904d69b9c7dc5d", - "reference": "93c84b5bf7669920d823631e39904d69b9c7dc5d", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/c6174523c2a69231df55bdc65b61655e72876d76", + "reference": "c6174523c2a69231df55bdc65b61655e72876d76", "shasum": "" }, "require": { @@ -3354,7 +3354,7 @@ "type": "tidelift" } ], - "time": "2023-10-30T14:48:31+00:00" + "time": "2023-11-05T12:57:57+00:00" }, { "name": "phpunit/php-code-coverage", @@ -4695,16 +4695,16 @@ }, { "name": "spatie/array-to-xml", - "version": "3.2.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/spatie/array-to-xml.git", - "reference": "f9ab39c808500c347d5a8b6b13310bd5221e39e7" + "reference": "84a404e5b67dd21466a0ff47d335129d67b94029" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/f9ab39c808500c347d5a8b6b13310bd5221e39e7", - "reference": "f9ab39c808500c347d5a8b6b13310bd5221e39e7", + "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/84a404e5b67dd21466a0ff47d335129d67b94029", + "reference": "84a404e5b67dd21466a0ff47d335129d67b94029", "shasum": "" }, "require": { @@ -4742,7 +4742,7 @@ "xml" ], "support": { - "source": "https://github.com/spatie/array-to-xml/tree/3.2.0" + "source": "https://github.com/spatie/array-to-xml/tree/3.2.1" }, "funding": [ { @@ -4754,7 +4754,7 @@ "type": "github" } ], - "time": "2023-07-19T18:30:26+00:00" + "time": "2023-11-08T08:19:46+00:00" }, { "name": "squizlabs/php_codesniffer", @@ -4815,16 +4815,16 @@ }, { "name": "symfony/config", - "version": "v6.3.2", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "b47ca238b03e7b0d7880ffd1cf06e8d637ca1467" + "reference": "b7a63887960359e5b59b15826fa9f9be10acbe88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/b47ca238b03e7b0d7880ffd1cf06e8d637ca1467", - "reference": "b47ca238b03e7b0d7880ffd1cf06e8d637ca1467", + "url": "https://api.github.com/repos/symfony/config/zipball/b7a63887960359e5b59b15826fa9f9be10acbe88", + "reference": "b7a63887960359e5b59b15826fa9f9be10acbe88", "shasum": "" }, "require": { @@ -4870,7 +4870,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v6.3.2" + "source": "https://github.com/symfony/config/tree/v6.3.8" }, "funding": [ { @@ -4886,20 +4886,20 @@ "type": "tidelift" } ], - "time": "2023-07-19T20:22:16+00:00" + "time": "2023-11-09T08:28:21+00:00" }, { "name": "symfony/dependency-injection", - "version": "v6.3.5", + "version": "v6.3.8", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "2ed62b3bf98346e1f45529a7b6be2196739bb993" + "reference": "1f30f545c4151f611148fc19e28d54d39e0a00bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/2ed62b3bf98346e1f45529a7b6be2196739bb993", - "reference": "2ed62b3bf98346e1f45529a7b6be2196739bb993", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/1f30f545c4151f611148fc19e28d54d39e0a00bc", + "reference": "1f30f545c4151f611148fc19e28d54d39e0a00bc", "shasum": "" }, "require": { @@ -4951,7 +4951,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.3.5" + "source": "https://github.com/symfony/dependency-injection/tree/v6.3.8" }, "funding": [ { @@ -4967,7 +4967,7 @@ "type": "tidelift" } ], - "time": "2023-09-25T16:46:40+00:00" + "time": "2023-10-31T08:07:48+00:00" }, { "name": "symfony/filesystem", diff --git a/src/App.php b/src/App.php index fc3cf47..2be0ff6 100644 --- a/src/App.php +++ b/src/App.php @@ -37,14 +37,14 @@ class App 'options' => Expect::arrayOf('string', 'string') ]), 'backup' => Expect::arrayOf(Expect::structure([ - 'title' => Expect::string(), - 'source' => Expect::string(), - 'destination' => Expect::string(), - ])), + 'title' => Expect::string()->required(), + 'source' => Expect::string()->required(), + 'destination' => Expect::string()->required(), + ]))->required(), 'notification' => Expect::arrayOf(Expect::structure([ - 'type' => Expect::string(), - 'domain' => Expect::string(), - 'topic' => Expect::string(), + 'type' => Expect::string()->required(), + 'domain' => Expect::string()->required(), + 'topic' => Expect::string()->required(), ])), 'log' => Expect::string()->assert( function (string $path): bool { @@ -53,17 +53,16 @@ class App ), 'templates' => Expect::structure( [ - 'notify' => Expect::string(), - 'error' => Expect::string() + 'notify' => Expect::string()->required(), + 'error' => Expect::string()->required() ] - ) + )->required() ]); $parser = new Yaml(); /** @var array */ $parsedConfig = $parser->parseFile($configFile); - // Merge those values into the configuration schema: $this->config->merge($parsedConfig); diff --git a/tests/AppTest.php b/tests/AppTest.php index 72a21f1..8800337 100644 --- a/tests/AppTest.php +++ b/tests/AppTest.php @@ -6,6 +6,7 @@ namespace App\Tests; use PHPUnit\Framework\TestCase; use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use Psr\Log\LoggerInterface; use App\App; @@ -25,4 +26,55 @@ final class AppTest extends \PHPUnit\Framework\TestCase $this->assertEquals('output.log', $app->getConfig('log')); $this->assertInstanceOf(LoggerInterface::class, $app->getLogger()); } + + public function testBadConfigFileSyntaxError(): void + { + $this->expectException(\TypeError::class); + + $app = new App('tests/config/bad/syntaxerror.yml'); + $app->getConfig('rclone'); + $app->getConfig('rclone.path'); + $app->getConfig('backup'); + $app->getConfig('notification'); + $app->getConfig('log'); + $app->getConfig('templates'); + $app->getConfig('templates.notify'); + $app->getConfig('templates.error'); + + $this->fail('Exception was not thrown'); + } + + public function testBadConfigFileEmpty(): void + { + $this->expectException(\TypeError::class); + + $app = new App('tests/config/bad/empty.yml'); + $app->getConfig('rclone'); + $app->getConfig('rclone.path'); + $app->getConfig('backup'); + $app->getConfig('notification'); + $app->getConfig('log'); + $app->getConfig('templates'); + $app->getConfig('templates.notify'); + $app->getConfig('templates.error'); + + $this->fail('Exception was not thrown'); + } + + public function testBadConfigFileTypos(): void + { + $this->expectException(\League\Config\Exception\ValidationException::class); + + $app = new App('tests/config/bad/typos.yml'); + $app->getConfig('rclone'); + $app->getConfig('rclone.path'); + $app->getConfig('backup'); + $app->getConfig('notification'); + $app->getConfig('log'); + $app->getConfig('templates'); + $app->getConfig('templates.notify'); + $app->getConfig('templates.error'); + + $this->fail('Exception was not thrown'); + } } diff --git a/tests/config/bad/empty.yml b/tests/config/bad/empty.yml new file mode 100644 index 0000000..e69de29 diff --git a/tests/config/bad/syntaxerror.yml b/tests/config/bad/syntaxerror.yml new file mode 100644 index 0000000..4cafa69 --- /dev/null +++ b/tests/config/bad/syntaxerror.yml @@ -0,0 +1,6 @@ + +Someone +Me +Title +Text + \ No newline at end of file diff --git a/tests/config/bad/typos.yml b/tests/config/bad/typos.yml new file mode 100644 index 0000000..bc16b2d --- /dev/null +++ b/tests/config/bad/typos.yml @@ -0,0 +1,26 @@ +notifikation: + - type: Ntfy + domain: https://ntfy.jcktrue.dk + topic: testing +logger: output.log +rclone: + option: + bwlimit: 6M +backup: + - titel: Example + src: temp/source + dest: temp/destination +template: + notification: | + {{ config.title }} + From {{ config.source }} to {{ config.destination }} + Backup started: {{ start | date }} + Source size: {{ source_size | formatBytes}} + Destination before: {{ destination_size_before | formatBytes}} + Destination after: {{ destination_size_after | formatBytes}} + Destination change : {{ (destination_size_after - destination_size_before) | formatBytes}} + Backup completed: {{ end | date }} + warn: | + {{ config.title }} + Error {{ config.source }} to {{ config.destination }} + {{ exception }}