com web/bugs: Add tests fixes: .gitignore composer.json composer.lock phpunit.xml.dist src/Autoloader.php tests/AutoloaderTest.php
tests/Container/ContainerTest.php tests/Container/MockDependency.php tests/Container/MockService.php tests/Mocks/responses/dev-body.txt
tests/Mocks/responses/stable-body.txt tests/Template/ContextTest.php tests/Template/EngineTest.php tests/Unit/AutoloaderTest.php
tests/Unit/Container/ContainerTest.php tests/Unit/Cont

From: Date: Thu, 16 May 2019 20:05:30 +0000
Subject: com web/bugs: Add tests fixes: .gitignore composer.json composer.lock phpunit.xml.dist src/Autoloader.php tests/AutoloaderTest.php
tests/Container/ContainerTest.php tests/Container/MockDependency.php tests/Container/MockService.php tests/Mocks/responses/dev-body.txt
tests/Mocks/responses/stable-body.txt tests/Template/ContextTest.php tests/Template/EngineTest.php tests/Unit/AutoloaderTest.php
tests/Unit/Container/ContainerTest.php tests/Unit/Cont
Groups: php.webmaster 
Request: Send a blank email to php-webmaster+get-28032@lists.php.net to get a copy of this message
Commit: f762db348dc0ef698bdbd3cd4c95530b1266e027 Author: Pieter Hordijk <info@pieterhordijk.com> Thu, 16 May 2019 16:05:18 +0300 Committer: Peter Kokot <peterkokot@gmail.com> Thu, 16 May 2019 22:05:30 +0200 Parents: 3c825bc8531f1896d823c77eba97b2b709338427 Branches: master Link: http://git.php.net/?p=web/bugs.git;a=commitdiff;h=f762db348dc0ef698bdbd3cd4c95530b1266e027 Log: Add tests fixes - Added filter to phpunit config - This enables support for coverage support - Moved unit tests to dedicated directory - Also created constants for the locations of the fixtures and mocks for testing so we do not have to use relative paths in tests - Updated phpunit to 8 - Added type information to tests - Added return type and parameter type declarations for tests - Added strict types to tests - CS fixes in tests - Aligning arrays, consistent string concatenation, removed unused local vars - Added constant for test cache directory - Make the autoloader also properly work on windows - Windows does not care about the directory separator used so just trim both variant from the end. Changed paths: M .gitignore M composer.json M composer.lock M phpunit..xml.dist M src/Autoloader.php D tests/AutoloaderTest.php D tests/Container/ContainerTest.php D tests/Container/MockDependency.php D tests/Container/MockService.php A tests/Mocks/responses/dev-body.txt A tests/Mocks/responses/stable-body.txt D tests/Template/ContextTest.php D tests/Template/EngineTest.php A tests/Unit/AutoloaderTest.php A tests/Unit/Container/ContainerTest.php A tests/Unit/Container/MockDependency.php A tests/Unit/Container/MockService.php A tests/Unit/Template/ContextTest.php A tests/Unit/Template/EngineTest.php A tests/Unit/Utils/CacheTest.php A tests/Unit/Utils/CaptchaTest.php A tests/Unit/Utils/UploaderTest.php A tests/Unit/Utils/Versions/ClientTest.php A tests/Unit/Utils/Versions/GeneratorTest.php D tests/Utils/CacheTest.php D tests/Utils/CaptchaTest.php D tests/Utils/UploaderTest.php D tests/Utils/Versions/ClientTest.php D tests/Utils/Versions/GeneratorTest.php A tests/bootstrap.php D tests/mock/responses/dev-body.txt D tests/mock/responses/stable-body.txt

diff --git a/.gitignore b/.gitignore index 07c61bc..8d0441e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,9 @@ +# These files are generated during application running or testing and are +# intentionally untracked to ignore by Git. For other development environment +# specific files, such as editor configuration, a good practice is to exclude +# them using the .git/info/exclude in the cloned repository or a global +# .gitignore file. + # Uploaded patches /uploads/ @@ -6,6 +12,7 @@ # Local specific PHPUnit configuration /phpunit.xml +.phpunit.result.cache # Transient and temporary generated files /var/ diff --git a/composer.json b/composer.json index 438518b..c32eeda 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "ext-session": "*" }, "require-dev": { - "phpunit/phpunit": "^7.5" + "phpunit/phpunit": "^8.1.5" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index b5c6108..63aa327 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c4d7d1e13a174de9ebf8016cf7872528", + "content-hash": "dba2ed92613c9c0acb06a57f86464228", "packages": [], "packages-dev": [ { @@ -430,40 +430,40 @@ }, { "name": "phpunit/php-code-coverage", - "version": "6.1.4", + "version": "7.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d" + "reference": "0317a769a81845c390e19684d9ba25d7f6aa4707" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", - "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/0317a769a81845c390e19684d9ba25d7f6aa4707", + "reference": "0317a769a81845c390e19684d9ba25d7f6aa4707", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", - "php": "^7.1", - "phpunit/php-file-iterator": "^2.0", + "php": "^7.2", + "phpunit/php-file-iterator": "^2.0.2", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^3.0", + "phpunit/php-token-stream": "^3.0.1", "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.1 || ^4.0", + "sebastian/environment": "^4.1", "sebastian/version": "^2.0.1", "theseer/tokenizer": "^1.1" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^8.0" }, "suggest": { - "ext-xdebug": "^2.6.0" + "ext-xdebug": "^2.6.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "6.1-dev" + "dev-master": "7.0-dev" } }, "autoload": { @@ -489,7 +489,7 @@ "testing", "xunit" ], - "time": "2018-10-31T16:06:48+00:00" + "time": "2019-02-26T07:38:26+00:00" }, { "name": "phpunit/php-file-iterator", @@ -682,16 +682,16 @@ }, { "name": "phpunit/phpunit", - "version": "7.5.9", + "version": "8.1.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "134669cf0eeac3f79bc7f0c793efbc158bffc160" + "reference": "01392d4b5878aa617e8d9bc7a529e5febc8fe956" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/134669cf0eeac3f79bc7f0c793efbc158bffc160", - "reference": "134669cf0eeac3f79bc7f0c793efbc158bffc160", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/01392d4b5878aa617e8d9bc7a529e5febc8fe956", + "reference": "01392d4b5878aa617e8d9bc7a529e5febc8fe956", "shasum": "" }, "require": { @@ -701,27 +701,25 @@ "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", + "ext-xmlwriter": "*", "myclabs/deep-copy": "^1.7", "phar-io/manifest": "^1.0.2", "phar-io/version": "^2.0", - "php": "^7.1", + "php": "^7.2", "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^6.0.7", + "phpunit/php-code-coverage": "^7.0", "phpunit/php-file-iterator": "^2.0.1", "phpunit/php-text-template": "^1.2.1", "phpunit/php-timer": "^2.1", "sebastian/comparator": "^3.0", "sebastian/diff": "^3.0", - "sebastian/environment": "^4.0", + "sebastian/environment": "^4.1", "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", + "sebastian/global-state": "^3.0", "sebastian/object-enumerator": "^3.0.3", "sebastian/resource-operations": "^2.0", "sebastian/version": "^2.0.1" }, - "conflict": { - "phpunit/phpunit-mock-objects": "*" - }, "require-dev": { "ext-pdo": "*" }, @@ -736,7 +734,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "7.5-dev" + "dev-master": "8.1-dev" } }, "autoload": { @@ -762,7 +760,7 @@ "testing", "xunit" ], - "time": "2019-04-19T15:50:46+00:00" + "time": "2019-05-14T04:57:31+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -931,16 +929,16 @@ }, { "name": "sebastian/environment", - "version": "4.2.1", + "version": "4.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "3095910f0f0fb155ac4021fc51a4a7a39ac04e8a" + "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/3095910f0f0fb155ac4021fc51a4a7a39ac04e8a", - "reference": "3095910f0f0fb155ac4021fc51a4a7a39ac04e8a", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/f2a2c8e1c97c11ace607a7a667d73d47c19fe404", + "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404", "shasum": "" }, "require": { @@ -980,7 +978,7 @@ "environment", "hhvm" ], - "time": "2019-04-25T07:55:20+00:00" + "time": "2019-05-05T09:05:15+00:00" }, { "name": "sebastian/exporter", @@ -1051,23 +1049,26 @@ }, { "name": "sebastian/global-state", - "version": "2.0.0", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", + "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", "shasum": "" }, "require": { - "php": "^7.0" + "php": "^7.2", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "ext-dom": "*", + "phpunit/phpunit": "^8.0" }, "suggest": { "ext-uopz": "*" @@ -1075,7 +1076,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1098,7 +1099,7 @@ "keywords": [ "global state" ], - "time": "2017-04-27T15:39:26+00:00" + "time": "2019-02-01T05:30:01+00:00" }, { "name": "sebastian/object-enumerator", diff --git a/phpunit.xml.dist b/phpunit.xml.dist index a793290..e19c661 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -6,7 +6,7 @@ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/7.4/phpunit.xsd" backupGlobals="false" colors="true" - bootstrap="vendor/autoload.php"> + bootstrap="tests/bootstrap.php"> <php> <ini name="error_reporting" value="-1" /> <ini name="date.timezone" value="UTC" /> @@ -17,4 +17,10 @@ <directory>tests/</directory> </testsuite> </testsuites> + + <filter> + <whitelist> + <directory>./src</directory> + </whitelist> + </filter> </phpunit> diff --git a/src/Autoloader.php b/src/Autoloader.php index ae526e0..ecd1251 100644 --- a/src/Autoloader.php +++ b/src/Autoloader.php @@ -83,7 +83,7 @@ class Autoloader $prefix = trim($prefix, '\\') . '\\'; // normalize the base directory with a trailing separator - $baseDir = rtrim($baseDir, DIRECTORY_SEPARATOR) . '/'; + $baseDir = rtrim($baseDir, '\\/') . '/'; // initialize the namespace prefix array if (isset($this->prefixes[$prefix]) === false) { diff --git a/tests/AutoloaderTest.php b/tests/AutoloaderTest.php deleted file mode 100644 index 16ef816..0000000 --- a/tests/AutoloaderTest.php +++ /dev/null @@ -1,99 +0,0 @@ -<?php - -namespace App\Tests; - -use App\Autoloader; -use PHPUnit\Framework\TestCase; - -class MockAutoloader extends Autoloader -{ - protected $files = []; - - public function setFiles(array $files) - { - $this->files = $files; - } - - protected function requireFile($file) - { - return in_array($file, $this->files); - } -} - -class AutoloaderTest extends TestCase -{ - protected $autoloader; - - protected function setUp() - { - $this->autoloader = new MockAutoloader; - - $this->autoloader->setFiles([ - '/vendor/foo.bar/src/ClassName.php', - '/vendor/foo.bar/src/DoomClassName.php', - '/vendor/foo.bar/tests/ClassNameTest.php', - '/vendor/foo.bardoom/src/ClassName.php', - '/vendor/foo.bar.baz.dib/src/ClassName.php', - '/vendor/foo.bar.baz.dib.zim.gir/src/ClassName.php', - '/src/lib/ClassName.php', - '/src/libfoo/ClassFoo.php', - ]); - - $this->autoloader->addNamespace( - 'Foo\Bar', - '/vendor/foo.bar/src' - ); - - $this->autoloader->addNamespace( - 'Foo\Bar', - '/vendor/foo.bar/tests' - ); - - $this->autoloader->addNamespace( - 'Foo\\BarDoom', - '/vendor/foo.bardoom/src/' - ); - - $this->autoloader->addNamespace( - 'Foo\Bar\Baz\Dib', - '/vendor/foo.bar.baz.dib/src/' - ); - - $this->autoloader->addNamespace( - 'Foo\Bar\Baz\Dib\Zim\Gir', - '/vendor/foo.bar.baz.dib.zim.gir/src/' - ); - - $this->autoloader->addClassmap( - 'ClassName', - '/src/lib/ClassName.php' - ); - - $this->autoloader->addClassmap( - 'ClassFoo', - '/src/libfoo/ClassFoo.php' - ); - } - - /** - * @dataProvider classesProvider - */ - public function testLoad($class, $expected) - { - $this->assertEquals($expected, $this->autoloader->load($class)); - } - - public function classesProvider() - { - return [ - ['Foo\Bar\ClassName', '/vendor/foo.bar/src/ClassName.php'], - ['Foo\Bar\ClassNameTest', '/vendor/foo.bar/tests/ClassNameTest.php'], - ['ClassName', '/src/lib/ClassName.php'], - ['ClassFoo', '/src/libfoo/ClassFoo.php'], - ['No_Vendor\No_Package\NoClass', false], - ['Foo\Bar\Baz\Dib\Zim\Gir\ClassName', '/vendor/foo.bar.baz.dib.zim.gir/src/ClassName.php'], - ['Foo\Bar\DoomClassName', '/vendor/foo.bar/src/DoomClassName.php'], - ['Foo\BarDoom\ClassName', '/vendor/foo.bardoom/src/ClassName.php'], - ]; - } -} diff --git a/tests/Container/ContainerTest.php b/tests/Container/ContainerTest.php deleted file mode 100644 index 42e1a74..0000000 --- a/tests/Container/ContainerTest.php +++ /dev/null @@ -1,109 +0,0 @@ -<?php - -namespace App\Tests\Container; - -use App\Container\Container; -use PHPUnit\Framework\TestCase; - -class ContainerTest extends TestCase -{ - public function testContainer() - { - // Create container - $container = new Container(); - - // Service definitions - $container->set(MockService::class, function ($c) { - $service = new MockService($c->get(MockDependency::class), 'foo'); - $service->setProperty('group.param'); - - return $service; - }); - - $container->set(MockDependency::class, function ($c) { - return new MockDependency('group.param'); - }); - - // Check retrieval of service - $service = $container->get(MockService::class); - $this->assertInstanceOf(MockService::class, $service); - - // Check retrieval of dependency - $dependency = $container->get(MockDependency::class); - $this->assertInstanceOf(MockDependency::class, $dependency); - - // Check that the dependency has been reused - $this->assertSame($dependency, $service->getDependency()); - - // Check the service calls have initialized - $this->assertEquals('group.param', $service->getProperty()); - } - - public function testHas() - { - $container = new Container(); - - $this->assertFalse($container->has(MockDependency::class)); - - $container->set(MockDependency::class, function ($c) { - return new MockDependency('group.param'); - }); - - $this->assertFalse($container->has(MockService::class)); - $this->assertTrue($container->has(MockDependency::class)); - } - - /** - * @expectedException App\Container\Exception\EntryNotFoundException - */ - public function testServiceNotFound() - { - $container = new Container(); - $container->get('foo'); - } - - /** - * @expectedException App\Container\Exception\ContainerException - * @expectedExceptionMessage entry must be callable - */ - public function testBadServiceEntry() - { - $container = new Container(); - $container->set(\stdClass::class, ''); - $container->get(\stdClass::class); - } - - /** - * @expectedException App\Container\Exception\ContainerException - * @expectedExceptionMessage circular reference - */ - public function testCircularReference() - { - $container = new Container(); - - $container->set(MockService::class, function ($c) { - return new MockService($c->get(MockService::class)); - }); - - $container->set(MockService::class, function ($c) { - return new MockService($c->get(MockService::class)); - }); - - $container->get(MockService::class); - } - - public function testParametersAndServices() - { - $container = new Container([ - 'foo' => 'bar', - 'baz' => function ($c) { - return $c->get('foo'); - }, - ]); - - $this->assertTrue($container->has('foo')); - $this->assertTrue($container->has('baz')); - $this->assertEquals('bar', $container->get('foo')); - $this->assertEquals('bar', $container->get('baz')); - } -} diff --git a/tests/Container/MockDependency.php b/tests/Container/MockDependency.php deleted file mode 100644 index dc2c3a9..0000000 --- a/tests/Container/MockDependency.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php - -namespace App\Tests\Container; - -/** - * Mock service dependency class for testing container. - */ -class MockDependency -{ - private $parameter; - - public function __construct($parameter) - { - $this->parameter = $parameter; - } - - public function getParameter() - { - return $this->parameter; - } -} diff --git a/tests/Container/MockService.php b/tests/Container/MockService.php deleted file mode 100644 index 7d12d39..0000000 --- a/tests/Container/MockService.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php - -namespace App\Tests\Container; - -/** - * Mock service class for testing container. - */ -class MockService -{ - private $dependency; - private $property; - - public function __construct(MockDependency $dependency) - { - $this->dependency = $dependency; - } - - public function getDependency() - { - return $this->dependency; - } - - public function setProperty($value) - { - $this->property = $value; - } - - public function getProperty() - { - return $this->property; - } -} diff --git a/tests/Mocks/responses/dev-body.txt b/tests/Mocks/responses/dev-body.txt new file mode 100644 index 0000000..77697a6 --- /dev/null +++ b/tests/Mocks/responses/dev-body.txt @@ -0,0 +1 @@ +["5.6.40-dev","7.0.33-dev","7.1.25-dev","7.2.14-dev","7.2.14RC1","7.3.1-dev","7.3.1RC1"] diff --git a/tests/Mocks/responses/stable-body.txt b/tests/Mocks/responses/stable-body.txt new file mode 100644 index 0000000..d4daa41 --- /dev/null +++ b/tests/Mocks/responses/stable-body.txt @@ -0,0 +1 @@ +{"5":{"5.6":{"announcement":true,"source":[{"filename":"php-5.6.39.tar.bz2","name":"PHP 5.6.39 (tar.bz2)","sha256":"b3db2345f50c010b01fe041b4e0f66c5aa28eb325135136f153e18da01583ad5","date":"06 Dec 2018"},{"filename":"php-5.6.39.tar.gz","name":"PHP 5.6.39 (tar.gz)","sha256":"127b122b7d6c7f3c211c0ffa554979370c3131196137404a51a391d8e2e9c7bb","date":"06 Dec 2018"},{"filename":"php-5.6.39.tar.xz","name":"PHP 5.6.39 (tar.xz)","sha256":"8147576001a832ff3d03cb2980caa2d6b584a10624f87ac459fcd3948c6e4a10","date":"06 Dec 2018"}],"version":"5.6.39"}},"7":{"7.0":{"announcement":true,"source":[{"filename":"php-7.0.33.tar.bz2","name":"PHP 7.0.33 (tar.bz2)","sha256":"4933ea74298a1ba046b0246fe3771415c84dfb878396201b56cb5333abe86f07","date":"06 Dec 2018"},{"filename":"php-7.0.33.tar.gz","name":"PHP 7.0.33 (tar.gz)","sha256":"d71a6ecb6b13dc53fed7532a7f8f949c4044806f067502f8fb6f9facbb40452a","date":"06 Dec 2018"},{"filename":"php-7.0.33.tar.xz","name":"PHP 7.0.33 (tar.xz)","sha256":"ab8c5be6e32b1f8d032909dedaaaa4bbb1a209e519abb01a52ce3914f9a13d96","date":"06 Dec 2018"}],"version":"7.0.33"},"7.1":{"announcement":true,"source":[{"filename":"php-7.1.25.tar.bz2","name":"PHP 7.1.25 (tar.bz2)","sha256":"002cdc880ac7cfaede2c389204d366108847db0f3ac72edf1ba95c0577f9aaac","date":"06 Dec 2018"},{"filename":"php-7.1.25.tar.gz","name":"PHP 7.1.25 (tar.gz)","sha256":"7dc40e202140e8b4fb3d992c15a68d98dc06b805e6b218497d260abbe51f5958","date":"06 Dec 2018"},{"filename":"php-7.1.25.tar.xz","name":"PHP 7.1.25 (tar.xz)","sha256":"0fd8dad1903cd0b2d615a1fe4209f99e53b7292403c8ffa1919c0f4dd1eada88","date":"06 Dec 2018"}],"version":"7.1.25"},"7.2":{"announcement":true,"source":[{"filename":"php-7.2.13.tar.bz2","name":"PHP 7.2.13 (tar.bz2)","sha256":"5b4a46fb76491bcd3eee1213773382e570f6ecf9b22d623b24e2822298b3e92d","date":"06 Dec 2018"},{"filename":"php-7.2.13.tar.gz","name":"PHP 7.2.13 (tar.gz)","sha256":"e563cee406b1ec96649c22ed2b35796cfe4e9aa9afa6eab6be4cf2fe5d724744","date":"06 Dec 2018"},{"filename":"php-7.2.13.tar.xz","name":"PHP 7.2.13 (tar.xz)","sha256":"14b0429abdb46b65c843e5882c9a8c46b31dfbf279c747293b8ab950c2644a4b","date":"06 Dec 2018"}],"version":"7.2.13"},"7.3":{"announcement":true,"source":[{"filename":"php-7.3.0.tar.bz2","name":"PHP 7.3.0 (tar.bz2)","sha256":"7a267daec9969a997c5c8028c350229646748e0fcc71e2f2dbb157ddcee87c67","date":"06 Dec 2018"},{"filename":"php-7.3.0.tar.gz","name":"PHP 7.3.0 (tar.gz)","sha256":"391bd0f91d9bdd01ab47ef9607bad8c65e35bc9bb098fb7777b2556e2c847b11","date":"06 Dec 2018"},{"filename":"php-7.3.0.tar.xz","name":"PHP 7.3.0 (tar.xz)","sha256":"7d195cad55af8b288c3919c67023a14ff870a73e3acc2165a6d17a4850a560b5","date":"06 Dec 2018"}],"version":"7.3.0"}}} diff --git a/tests/Template/ContextTest.php b/tests/Template/ContextTest.php deleted file mode 100644 index 5092f69..0000000 --- a/tests/Template/ContextTest.php +++ /dev/null @@ -1,78 +0,0 @@ -<?php - -namespace App\Tests\Template; - -use PHPUnit\Framework\TestCase; -use App\Template\Context; - -class ContextTest extends TestCase -{ - public function setUp() - { - $this->context = new Context(__DIR__.'/../fixtures/templates'); - } - - public function testBlock() - { - $this->context->start('foo'); - echo 'bar'; - $this->context->end('foo'); - - $this->assertEquals($this->context->block('foo'), 'bar'); - - $this->context->append('foo'); - echo 'baz'; - $this->context->end('foo'); - - $this->assertEquals($this->context->block('foo'), 'barbaz'); - - $this->context->start('foo'); - echo 'overridden'; - $this->context->end('foo'); - - $this->assertEquals($this->context->block('foo'), 'overridden'); - } - - public function testInclude() - { - ob_start(); - $this->context->include('includes/banner.php'); - $content = ob_get_clean(); - - $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/templates/includes/banner.php'), $content); - } - - public function testIncludeReturn() - { - $variable = $this->context->include('includes/variable.php'); - - $this->assertEquals(include __DIR__.'/../fixtures/templates/includes/variable.php', $variable); - } - - /** - * @dataProvider attacksProvider - */ - public function testEscaping($malicious, $escaped, $noHtml) - { - $this->assertEquals($escaped, $this->context->e($malicious)); - } - - /** - * @dataProvider attacksProvider - */ - public function testNoHtml($malicious, $escaped, $noHtml) - { - $this->assertEquals($noHtml, $this->context->noHtml($malicious)); - } - - public function attacksProvider() - { - return [ - [ - '<iframe src="javascript:alert(\'Xss\')";></iframe>', - '&lt;iframe src=&quot;javascript:alert(&#039;Xss&#039;)&quot;;&gt;&lt;/iframe&gt;', - '&lt;iframe src&equals;&quot;javascript&colon;alert&lpar;&apos;Xss&apos;&rpar;&quot;&semi;&gt;&lt;&sol;iframe&gt;' - ] - ]; - } -} diff --git a/tests/Template/EngineTest.php b/tests/Template/EngineTest.php deleted file mode 100644 index 16174b5..0000000 --- a/tests/Template/EngineTest.php +++ /dev/null @@ -1,186 +0,0 @@ -<?php - -namespace App\Tests\Template; - -use PHPUnit\Framework\TestCase; -use App\Template\Engine; - -class EngineTest extends TestCase -{ - public function setUp() - { - $this->template = new Engine(__DIR__.'/../fixtures/templates'); - } - - public function testView() - { - $content = $this->template->render('pages/view.php', [ - 'foo' => 'Lorem ipsum dolor sit amet.', - 'sidebar' => 'PHP is a popular general-purpose scripting language that is especially suited to web development', - ]); - - $this->assertRegexp('/Lorem ipsum dolor sit amet/', $content); - $this->assertRegexp('/PHP is a popular general-purpose/', $content); - } - - public function testRegisterNew() - { - // Register callable function - $this->template->register('addAsterisks', function ($var) { - return '***'.$var.'***'; - }); - - // Register callable object and method - $object = new class { - public $property; - - public function doSomething($argument) {} - }; - $this->template->register('doSomething', [$object, 'doSomething']); - - $content = $this->template->render('pages/add_function.php', [ - 'foo' => 'Lorem ipsum dolor sit amet.', - ]); - - $this->assertRegexp('/\*\*\*Lorem ipsum dolor sit amet\.\*\*\*/', $content); - } - - public function testRegisterExisting() - { - $this->expectException(\Exception::class); - - $this->template->register('noHtml', function ($var) { - return $var; - }); - } - - public function testAssignments() - { - $this->template->assign([ - 'parameter' => 'FooBarBaz', - ]); - - $content = $this->template->render('pages/assignments.php', [ - 'foo' => 'Lorem ipsum dolor sit amet.', - ]); - - $this->assertRegexp('/Lorem ipsum dolor sit amet\./', $content); - $this->assertRegexp('/FooBarBaz/', $content); - } - - public function testMerge() - { - $this->template->assign([ - 'foo', - 'bar', - 'qux' => 'quux', - ]); - - $this->template->assign([ - 'baz', - 'qux' => 'quuz', - ]); - - $this->assertEquals(['baz', 'bar', 'qux' => 'quuz'], $this->template->getVariables()); - } - - public function testVariablesScope() - { - $this->template->assign([ - 'parameter' => 'Parameter value', - ]); - - $content = $this->template->render('pages/invalid_variables.php', [ - 'foo' => 'Lorem ipsum dolor sit amet', - ]); - - $expected = var_export([ - 'parameter' => 'Parameter value', - 'foo' => 'Lorem ipsum dolor sit amet', - ], true); - - $this->assertEquals($expected, $content); - } - - public function testInvalidVariables() - { - $this->template->assign([ - 'Invalid value with key 0', - 'parameter' => 'Parameter value', - 'Invalid value with key 1', - ]); - - $this->expectException(\Exception::class); - - $content = $this->template->render('pages/invalid_variables.php', [ - 'foo' => 'Lorem ipsum dolor sit amet', - 1 => 'Invalid overridden value with key 1', - ]); - } - - public function testOverrides() - { - $this->template->assign([ - 'pageParameter_1' => 'Page parameter 1', - 'pageParameter_2' => 'Page parameter 2', - 'layoutParameter_1' => 'Layout parameter 1', - 'layoutParameter_2' => 'Layout parameter 2', - 'layoutParameter_3' => 'Layout parameter 3', - ]); - - $content = $this->template->render('pages/overrides.php', [ - 'pageParameter_2' => 'Overridden parameter 2', - 'layoutParameter_2' => 'Layout overridden parameter 2', - ]); - - $this->assertRegexp('/Page parameter 1/', $content); - $this->assertRegexp('/^((?!Page parameter 2).)*$/s', $content); - $this->assertRegexp('/Overridden parameter 2/', $content); - $this->assertRegexp('/Layout parameter 1/', $content); - $this->assertRegexp('/^((?!Layout parameter 2).)*$/s', $content); - $this->assertRegexp('/Layout overridden parameter 2/', $content); - } - - public function testAppending() - { - $content = $this->template->render('pages/appending.php'); - - $this->assertRegexp('/file\_1\.js/', $content); - $this->assertRegexp('/file\_2\.js/', $content); - } - - public function testIncluding() - { - $content = $this->template->render('pages/including.php'); - - $this->assertRegexp('/\<form method\=\"post\"\>/', $content); - $this->assertRegexp('/Banner inclusion/', $content); - } - - public function testNoLayout() - { - $content = $this->template->render('pages/no_layout.rss'); - - $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/templates/pages/no_layout.rss'), $content); - } - - public function testMissingTemplate() - { - $this->template->assign([ - 'parameter' => 'Parameter value', - ]); - - $this->expectException(\Exception::class); - - $content = $this->template->render('pages/this/does/not/exist.php', [ - 'foo' => 'Lorem ipsum dolor sit amet', - ]); - } - - public function testExtending() - { - $this->expectException(\Exception::class); - - $html = $this->template->render('pages/extends.php'); - } -} diff --git a/tests/Unit/AutoloaderTest.php b/tests/Unit/AutoloaderTest.php new file mode 100644 index 0000000..164c158 --- /dev/null +++ b/tests/Unit/AutoloaderTest.php @@ -0,0 +1,100 @@ +<?php declare(strict_types=1); + +namespace App\Tests\Unit; + +use App\Autoloader; +use PHPUnit\Framework\TestCase; + +class MockAutoloader extends Autoloader +{ + protected $files = []; + + public function setFiles(array $files) + { + $this->files = $files; + } + + protected function requireFile($file) + { + return in_array($file, $this->files); + } +} + +class AutoloaderTest extends TestCase +{ + /** @var MockAutoloader */ + protected $autoloader; + + protected function setUp(): void + { + $this->autoloader = new MockAutoloader; + + $this->autoloader->setFiles([ + '/vendor/foo.bar/src/ClassName.php', + '/vendor/foo.bar/src/DoomClassName.php', + '/vendor/foo.bar/tests/ClassNameTest.php', + '/vendor/foo.bardoom/src/ClassName.php', + '/vendor/foo.bar.baz.dib/src/ClassName.php', + '/vendor/foo.bar.baz.dib.zim.gir/src/ClassName.php', + '/src/lib/ClassName.php', + '/src/libfoo/ClassFoo.php', + ]); + + $this->autoloader->addNamespace( + 'Foo\Bar', + '/vendor/foo.bar/src' + ); + + $this->autoloader->addNamespace( + 'Foo\Bar', + '/vendor/foo.bar/tests' + ); + + $this->autoloader->addNamespace( + 'Foo\\BarDoom', + '/vendor/foo.bardoom/src/' + ); + + $this->autoloader->addNamespace( + 'Foo\Bar\Baz\Dib', + '/vendor/foo.bar.baz.dib/src/' + ); + + $this->autoloader->addNamespace( + 'Foo\Bar\Baz\Dib\Zim\Gir', + '/vendor/foo.bar.baz.dib.zim.gir/src/' + ); + + $this->autoloader->addClassmap( + 'ClassName', + '/src/lib/ClassName.php' + ); + + $this->autoloader->addClassmap( + 'ClassFoo', + '/src/libfoo/ClassFoo.php' + ); + } + + /** + * @dataProvider classesProvider + */ + public function testLoad(string $class, $expected): void + { + $this->assertEquals($expected, $this->autoloader->load($class)); + } + + public function classesProvider(): array + { + return [ + ['Foo\Bar\ClassName', '/vendor/foo.bar/src/ClassName.php'], + ['Foo\Bar\ClassNameTest', '/vendor/foo.bar/tests/ClassNameTest.php'], + ['ClassName', '/src/lib/ClassName.php'], + ['ClassFoo', '/src/libfoo/ClassFoo.php'], + ['No_Vendor\No_Package\NoClass', false], + ['Foo\Bar\Baz\Dib\Zim\Gir\ClassName', '/vendor/foo.bar.baz.dib.zim.gir/src/ClassName.php'], + ['Foo\Bar\DoomClassName', '/vendor/foo.bar/src/DoomClassName.php'], + ['Foo\BarDoom\ClassName', '/vendor/foo.bardoom/src/ClassName.php'], + ]; + } +} diff --git a/tests/Unit/Container/ContainerTest.php b/tests/Unit/Container/ContainerTest.php new file mode 100644 index 0000000..9d33cb5 --- /dev/null +++ b/tests/Unit/Container/ContainerTest.php @@ -0,0 +1,110 @@ +<?php declare(strict_types=1); + +namespace App\Tests\Unit\Container; + +use App\Container\Container; +use App\Container\Exception\ContainerException; +use App\Container\Exception\EntryNotFoundException; +use PHPUnit\Framework\TestCase; + +class ContainerTest extends TestCase +{ + public function testContainer(): void + { + // Create container + $container = new Container(); + + // Service definitions + $container->set(MockService::class, function (Container $container) { + $service = new MockService($container->get(MockDependency::class)); + $service->setProperty('group.param'); + + return $service; + }); + + $container->set(MockDependency::class, function (Container $container) { + return new MockDependency('group.param'); + }); + + // Check retrieval of service + $service = $container->get(MockService::class); + $this->assertInstanceOf(MockService::class, $service); + + // Check retrieval of dependency + $dependency = $container->get(MockDependency::class); + $this->assertInstanceOf(MockDependency::class, $dependency); + + // Check that the dependency has been reused + $this->assertSame($dependency, $service->getDependency()); + + // Check the service calls have initialized + $this->assertEquals('group.param', $service->getProperty()); + } + + public function testHas(): void + { + $container = new Container(); + + $this->assertFalse($container->has(MockDependency::class)); + + $container->set(MockDependency::class, function (Container $container) { + return new MockDependency('group.param'); + }); + + $this->assertFalse($container->has(MockService::class)); + $this->assertTrue($container->has(MockDependency::class)); + } + + public function testServiceNotFound(): void + { + $container = new Container(); + + $this->expectException(EntryNotFoundException::class); + + $container->get('foo'); + } + + public function testBadServiceEntry(): void + { + $container = new Container(); + $container->set(\stdClass::class, ''); + + $this->expectException(ContainerException::class); + $this->expectExceptionMessage('entry must be callable'); + + $container->get(\stdClass::class); + } + + public function testCircularReference(): void + { + $container = new Container(); + + $container->set(MockService::class, function (Container $container) { + return new MockService($container->get(MockService::class)); + }); + + $container->set(MockService::class, function (Container $container) { + return new MockService($container->get(MockService::class)); + }); + + $this->expectException(ContainerException::class); + $this->expectExceptionMessage('circular reference'); + + $container->get(MockService::class); + } + + public function testParametersAndServices(): void + { + $container = new Container([ + 'foo' => 'bar', + 'baz' => function (Container $container) { + return $container->get('foo'); + }, + ]); + + $this->assertTrue($container->has('foo')); + $this->assertTrue($container->has('baz')); + $this->assertEquals('bar', $container->get('foo')); + $this->assertEquals('bar', $container->get('baz')); + } +} diff --git a/tests/Unit/Container/MockDependency.php b/tests/Unit/Container/MockDependency.php new file mode 100644 index 0000000..fe78b99 --- /dev/null +++ b/tests/Unit/Container/MockDependency.php @@ -0,0 +1,21 @@ +<?php declare(strict_types=1); + +namespace App\Tests\Unit\Container; + +/** + * Mock service dependency class for testing container. + */ +class MockDependency +{ + private $parameter; + + public function __construct(string $parameter) + { + $this->parameter = $parameter; + } + + public function getParameter(): string + { + return $this->parameter; + } +} diff --git a/tests/Unit/Container/MockService.php b/tests/Unit/Container/MockService.php new file mode 100644 index 0000000..a410bac --- /dev/null +++ b/tests/Unit/Container/MockService.php @@ -0,0 +1,32 @@ +<?php declare(strict_types=1); + +namespace App\Tests\Unit\Container; + +/** + * Mock service class for testing container. + */ +class MockService +{ + private $dependency; + private $property; + + public function __construct(MockDependency $dependency) + { + $this->dependency = $dependency; + } + + public function getDependency(): MockDependency + { + return $this->dependency; + } + + public function setProperty(string $value): void + { + $this->property = $value; + } + + public function getProperty(): string + { + return $this->property; + } +} diff --git a/tests/Unit/Template/ContextTest.php b/tests/Unit/Template/ContextTest.php new file mode 100644 index 0000000..8b82de7 --- /dev/null +++ b/tests/Unit/Template/ContextTest.php @@ -0,0 +1,81 @@ +<?php declare(strict_types=1); + +namespace App\Tests\Unit\Template; + +use PHPUnit\Framework\TestCase; +use App\Template\Context; + +class ContextTest extends TestCase +{ + /** @var Context */ + private $context; + + public function setUp(): void + { + $this->context = new Context(TEST_FIXTURES_DIRECTORY . '/templates'); + } + + public function testBlock(): void + { + $this->context->start('foo'); + echo 'bar'; + $this->context->end('foo'); + + $this->assertEquals($this->context->block('foo'), 'bar'); + + $this->context->append('foo'); + echo 'baz'; + $this->context->end('foo'); + + $this->assertEquals($this->context->block('foo'), 'barbaz'); + + $this->context->start('foo'); + echo 'overridden'; + $this->context->end('foo'); + + $this->assertEquals($this->context->block('foo'), 'overridden'); + } + + public function testInclude(): void + { + ob_start(); + $this->context->include('includes/banner.php'); + $content = ob_get_clean(); + + $this->assertEquals(file_get_contents(TEST_FIXTURES_DIRECTORY . '/templates/includes/banner.php'), $content); + } + + public function testIncludeReturn(): void + { + $variable = $this->context->include('includes/variable.php'); + + $this->assertEquals(include TEST_FIXTURES_DIRECTORY . '/templates/includes/variable.php', $variable); + } + + /** + * @dataProvider attacksProvider + */ + public function testEscaping(string $malicious, string $escaped, string $noHtml): void + { + $this->assertEquals($escaped, $this->context->e($malicious)); + } + + /** + * @dataProvider attacksProvider + */ + public function testNoHtml(string $malicious, string $escaped, string $noHtml): void + { + $this->assertEquals($noHtml, $this->context->noHtml($malicious)); + } + + public function attacksProvider(): array + { + return [ + [ + '<iframe src="javascript:alert(\'Xss\')";></iframe>', + '&lt;iframe src=&quot;javascript:alert(&#039;Xss&#039;)&quot;;&gt;&lt;/iframe&gt;', + '&lt;iframe src&equals;&quot;javascript&colon;alert&lpar;&apos;Xss&apos;&rpar;&quot;&semi;&gt;&lt;&sol;iframe&gt;' + ] + ]; + } +} diff --git a/tests/Unit/Template/EngineTest.php b/tests/Unit/Template/EngineTest.php new file mode 100644 index 0000000..30f8337 --- /dev/null +++ b/tests/Unit/Template/EngineTest.php @@ -0,0 +1,189 @@ +<?php declare(strict_types=1); + +namespace App\Tests\Unit\Template; + +use PHPUnit\Framework\TestCase; +use App\Template\Engine; + +class EngineTest extends TestCase +{ + /** @var Engine */ + private $template; + + public function setUp(): void + { + $this->template = new Engine(TEST_FIXTURES_DIRECTORY . '/templates'); + } + + public function testView(): void + { + $content = $this->template->render('pages/view.php', [ + 'foo' => 'Lorem ipsum dolor sit amet.', + 'sidebar' => 'PHP is a popular general-purpose scripting language that is especially suited to web development', + ]); + + $this->assertRegexp('/Lorem ipsum dolor sit amet/', $content); + $this->assertRegexp('/PHP is a popular general-purpose/', $content); + } + + public function testRegisterNew(): void + { + // Register callable function + $this->template->register('addAsterisks', function ($var) { + return '***'.$var.'***'; + }); + + // Register callable object and method + $object = new class { + public $property; + + public function doSomething($argument) {} + }; + $this->template->register('doSomething', [$object, 'doSomething']); + + $content = $this->template->render('pages/add_function.php', [ + 'foo' => 'Lorem ipsum dolor sit amet.', + ]); + + $this->assertRegexp('/\*\*\*Lorem ipsum dolor sit amet\.\*\*\*/', $content); + } + + public function testRegisterExisting(): void + { + $this->expectException(\Exception::class); + + $this->template->register('noHtml', function ($var) { + return $var; + }); + } + + public function testAssignments(): void + { + $this->template->assign([ + 'parameter' => 'FooBarBaz', + ]); + + $content = $this->template->render('pages/assignments.php', [ + 'foo' => 'Lorem ipsum dolor sit amet.', + ]); + + $this->assertRegexp('/Lorem ipsum dolor sit amet\./', $content); + $this->assertRegexp('/FooBarBaz/', $content); + } + + public function testMerge(): void + { + $this->template->assign([ + 'foo', + 'bar', + 'qux' => 'quux', + ]); + + $this->template->assign([ + 'baz', + 'qux' => 'quuz', + ]); + + $this->assertEquals(['baz', 'bar', 'qux' => 'quuz'], $this->template->getVariables()); + } + + public function testVariablesScope(): void + { + $this->template->assign([ + 'parameter' => 'Parameter value', + ]); + + $content = $this->template->render('pages/invalid_variables.php', [ + 'foo' => 'Lorem ipsum dolor sit amet', + ]); + + $expected = var_export([ + 'parameter' => 'Parameter value', + 'foo' => 'Lorem ipsum dolor sit amet', + ], true); + + $this->assertEquals($expected, $content); + } + + public function testInvalidVariables(): void + { + $this->template->assign([ + 'Invalid value with key 0', + 'parameter' => 'Parameter value', + 'Invalid value with key 1', + ]); + + $this->expectException(\Exception::class); + + $this->template->render('pages/invalid_variables.php', [ + 'foo' => 'Lorem ipsum dolor sit amet', + 1 => 'Invalid overridden value with key 1', + ]); + } + + public function testOverrides(): void + { + $this->template->assign([ + 'pageParameter_1' => 'Page parameter 1', + 'pageParameter_2' => 'Page parameter 2', + 'layoutParameter_1' => 'Layout parameter 1', + 'layoutParameter_2' => 'Layout parameter 2', + 'layoutParameter_3' => 'Layout parameter 3', + ]); + + $content = $this->template->render('pages/overrides.php', [ + 'pageParameter_2' => 'Overridden parameter 2', + 'layoutParameter_2' => 'Layout overridden parameter 2', + ]); + + $this->assertRegexp('/Page parameter 1/', $content); + $this->assertRegexp('/^((?!Page parameter 2).)*$/s', $content); + $this->assertRegexp('/Overridden parameter 2/', $content); + $this->assertRegexp('/Layout parameter 1/', $content); + $this->assertRegexp('/^((?!Layout parameter 2).)*$/s', $content); + $this->assertRegexp('/Layout overridden parameter 2/', $content); + } + + public function testAppending(): void + { + $content = $this->template->render('pages/appending.php'); + + $this->assertRegexp('/file\_1\.js/', $content); + $this->assertRegexp('/file\_2\.js/', $content); + } + + public function testIncluding(): void + { + $content = $this->template->render('pages/including.php'); + + $this->assertRegexp('/\<form method\=\"post\"\>/', $content); + $this->assertRegexp('/Banner inclusion/', $content); + } + + public function testNoLayout(): void + { + $content = $this->template->render('pages/no_layout.rss'); + + $this->assertEquals(file_get_contents(TEST_FIXTURES_DIRECTORY . '/templates/pages/no_layout.rss'), $content); + } + + public function testMissingTemplate(): void + { + $this->template->assign([ + 'parameter' => 'Parameter value', + ]); + + $this->expectException(\Exception::class); + + $this->template->render('pages/this/does/not/exist.php', [ + 'foo' => 'Lorem ipsum dolor sit amet', + ]); + } + + public function testExtending(): void + { + $this->expectException(\Exception::class); + + $this->template->render('pages/extends.php'); + } +} diff --git a/tests/Unit/Utils/CacheTest.php b/tests/Unit/Utils/CacheTest.php new file mode 100644 index 0000000..ab5dbc2 --- /dev/null +++ b/tests/Unit/Utils/CacheTest.php @@ -0,0 +1,44 @@ +<?php declare(strict_types=1); + +namespace App\Tests\Unit\Utils; + +use App\Utils\Cache; +use PHPUnit\Framework\TestCase; + +class CacheTest extends TestCase +{ + /** @var string */ + private $cacheDir = TEST_VAR_DIRECTORY . '/cache/test'; + + /** @var Cache */ + private $cache; + + public function setUp(): void + { + $this->cache = new Cache($this->cacheDir); + $this->cache->clear(); + } + + public function tearDown(): void + { + $this->cache->clear(); + rmdir($this->cacheDir); + } + + public function testHas(): void + { + $this->assertFalse($this->cache->has('foo')); + + $this->cache->set('foo', [1, 2, 3]); + $this->assertTrue($this->cache->has('foo')); + } + + public function testDelete(): void + { + $this->cache->set('bar', [1, 2, 3]); + $this->assertFileExists($this->cacheDir.'/bar.php'); + + $this->cache->delete('bar'); + $this->assertFalse(file_exists($this->cacheDir.'/bar.php')); + } +} diff --git a/tests/Unit/Utils/CaptchaTest.php b/tests/Unit/Utils/CaptchaTest.php new file mode 100644 index 0000000..acc41af --- /dev/null +++ b/tests/Unit/Utils/CaptchaTest.php @@ -0,0 +1,42 @@ +<?php declare(strict_types=1); + +namespace App\Tests\Unit\Utils; + +use PHPUnit\Framework\TestCase; +use App\Utils\Captcha; + +class CaptchaTest extends TestCase +{ + /** @var Captcha */ + private $captcha; + + public function setUp(): void + { + $this->captcha = new Captcha(); + } + + /** + * @dataProvider mathProvider + */ + public function testGetQuestion(int $first, int $last, string $operation, string $question, int $expected): void + { + $this->captcha->setFirst($first); + $this->captcha->setLast($last); + $this->captcha->setOperation($operation); + + $this->assertEquals($question, $this->captcha->getQuestion()); + $this->assertEquals($expected, $this->captcha->getAnswer()); + } + + public function mathProvider(): array + { + return [ + [1, 2, 'addition', '1 + 2 = ?', 3], + [10, 50, 'subtraction', '50 - 10 = ?', 40], + [90, 50, 'subtraction', '90 - 50 = ?', 40], + [14, 14, 'subtraction', '14 - 14 = ?', 0], + [10, 5, 'multiplication', '10 + 5 = ?', 15], + [12, 2, 'foo', '12 + 2 = ?', 14], + ]; + } +} diff --git a/tests/Unit/Utils/UploaderTest.php b/tests/Unit/Utils/UploaderTest.php new file mode 100644 index 0000000..07bd684 --- /dev/null +++ b/tests/Unit/Utils/UploaderTest.php @@ -0,0 +1,56 @@ +<?php declare(strict_types=1); + +namespace App\Tests\Unit\Utils; + +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; +use App\Utils\Uploader; + +class UploaderTest extends TestCase +{ + /** @var string */ + private $fixturesDirectory = TEST_FIXTURES_DIRECTORY . '/files'; + + /** + * @dataProvider filesProvider + */ + public function testUpload(string $validExtension, array $file): void + { + $_FILES = ['uploaded' => $file]; + + /** @var Uploader|MockObject $uploader */ + $uploader = $this->getMockBuilder(Uploader::class) + ->setMethods(['isUploadedFile', 'moveUploadedFile']) + ->getMock(); + + $uploader->expects($this->once()) + ->method('isUploadedFile') + ->will($this->returnValue(true)); + + $uploader->expects($this->once()) + ->method('moveUploadedFile') + ->will($this->returnValue(true)); + + $uploader->setMaxFileSize(100 * 1024); + $uploader->setValidExtension($validExtension); + $uploader->setDir(TEST_VAR_DIRECTORY . '/uploads'); + $tmpFile = $uploader->upload('uploaded'); + + $this->assertNotNull($tmpFile); + } + + public function filesProvider(): array + { + return [ + [ + 'txt', + [ + 'name' => 'patch.txt', + 'tmp_name' => $this->fixturesDirectory . '/patch.txt', + 'size' => filesize($this->fixturesDirectory . '/patch.txt'), + 'error' => UPLOAD_ERR_OK, + ] + ], + ]; + } +} diff --git a/tests/Unit/Utils/Versions/ClientTest.php b/tests/Unit/Utils/Versions/ClientTest.php new file mode 100644 index 0000000..3577939 --- /dev/null +++ b/tests/Unit/Utils/Versions/ClientTest.php @@ -0,0 +1,37 @@ +<?php declare(strict_types=1); + +namespace App\Tests\Unit\Utils\Versions; + +use PHPUnit\Framework\TestCase; +use App\Utils\Versions\Client; + +class ClientTest extends TestCase +{ + /** @var Client */ + private $client; + + public function setUp(): void + { + $this->client = new Client(); + + $reflection = new \ReflectionClass($this->client); + + $devVersionsUrl = $reflection->getProperty('devVersionsUrl'); + $devVersionsUrl->setAccessible(true); + $devVersionsUrl->setValue($this->client, TEST_MOCKS_DIRECTORY . '/responses/dev-body.txt'); + + $stableVersionsUrl = $reflection->getProperty('stableVersionsUrl'); + $stableVersionsUrl->setAccessible(true); + $stableVersionsUrl->setValue($this->client, TEST_MOCKS_DIRECTORY . '/responses/stable-body.txt'); + } + + public function testFetchDevVersions(): void + { + $this->assertIsArray($this->client->fetchDevVersions()); + } + + public function testFetchStableVersions(): void + { + $this->assertIsArray($this->client->fetchStableVersions()); + } +} diff --git a/tests/Unit/Utils/Versions/GeneratorTest.php b/tests/Unit/Utils/Versions/GeneratorTest.php new file mode 100644 index 0000000..d2e28a0 --- /dev/null +++ b/tests/Unit/Utils/Versions/GeneratorTest.php @@ -0,0 +1,77 @@ +<?php declare(strict_types=1); + +namespace App\Tests\Unit\Utils\Versions; + +use PHPUnit\Framework\TestCase; +use App\Utils\Versions\Generator; +use App\Utils\Versions\Client; +use App\Utils\Cache; + +class GeneratorTest extends TestCase +{ + /** @var string */ + private $cacheDir = TEST_VAR_DIRECTORY . '/cache/test'; + + /** @var Cache */ + private $cache; + + /** @var Client */ + private $client; + + /** @var Generator */ + private $generator; + + public function setUp(): void + { + $this->cache = new Cache($this->cacheDir); + $this->cache->clear(); + + // The results returned by the client depend on the remote URLs so we + // mock the returned results. + $this->client = $this->getMockBuilder(Client::class) + ->setMethods(['fetchDevVersions', 'fetchStableVersions']) + ->getMock(); + + $this->client->expects($this->once()) + ->method('fetchDevVersions') + ->will($this->returnValue(json_decode(file_get_contents(TEST_MOCKS_DIRECTORY . '/responses/dev-body.txt', true)))); + + $this->client->expects($this->once()) + ->method('fetchStableVersions') + ->will($this->returnValue(json_decode(file_get_contents(TEST_MOCKS_DIRECTORY . '/responses/stable-body.txt'), true))); + + $this->generator = $this->getMockBuilder(Generator::class) + ->setConstructorArgs([$this->client, $this->cache]) + ->setMethods(['getAffixes']) + ->getMock(); + + // The extra versions are always date dependant so we mock it to include + // static date done on the tests day. + $date = '2018-12-26'; + $this->generator->expects($this->any()) + ->method('getAffixes') + ->will($this->returnValue(['Git-' . $date . ' (snap)', 'Git-' . $date . ' (Git)',])); + } + + public function tearDown(): void + { + $this->cache->clear(); + rmdir($this->cacheDir); + } + + public function testVersions(): void + { + $versions = $this->generator->getVersions(); + + $this->assertIsArray($versions); + $this->assertGreaterThan(5, count($versions)); + + $fixture = require TEST_FIXTURES_DIRECTORY . '/versions/versions.php'; + $cached = require $this->cacheDir . '/versions.php'; + + $this->assertEquals($fixture[1], $cached[1]); + $this->assertContains('Next Major Version', $versions); + $this->assertContains('Irrelevant', $versions); + $this->assertContains('7.2.14RC1', $versions); + } +} diff --git a/tests/Utils/CacheTest.php b/tests/Utils/CacheTest.php deleted file mode 100644 index 0e045ed..0000000 --- a/tests/Utils/CacheTest.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php - -namespace App\Tests\Utils; - -use App\Utils\Cache; -use PHPUnit\Framework\TestCase; - -class CacheTest extends TestCase -{ - private $cacheDir = __DIR__.'/../../var/cache/test'; - private $cache; - - public function setUp() - { - $this->cache = new Cache($this->cacheDir); - $this->cache->clear(); - } - - public function tearDown() - { - $this->cache->clear(); - rmdir($this->cacheDir); - } - - public function testHas() - { - $this->assertFalse($this->cache->has('foo')); - - $this->cache->set('foo', [1, 2, 3]); - $this->assertTrue($this->cache->has('foo')); - } - - public function testDelete() - { - $this->cache->set('bar', [1, 2, 3]); - $this->assertFileExists($this->cacheDir.'/bar.php'); - - $this->cache->delete('bar'); - $this->assertFalse(file_exists($this->cacheDir.'/bar.php')); - } -} diff --git a/tests/Utils/CaptchaTest.php b/tests/Utils/CaptchaTest.php deleted file mode 100644 index 681da7a..0000000 --- a/tests/Utils/CaptchaTest.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php - -namespace App\Tests\Utils; - -use PHPUnit\Framework\TestCase; -use App\Utils\Captcha; - -class CaptchaTest extends TestCase -{ - private $captcha; - - public function setUp() - { - $this->captcha = new Captcha(); - } - - /** - * @dataProvider mathProvider - */ - public function testGetQuestion($first, $last, $operation, $question, $expected) - { - $this->captcha->setFirst($first); - $this->captcha->setLast($last); - $this->captcha->setOperation($operation); - - $this->assertEquals($question, $this->captcha->getQuestion()); - $this->assertEquals($expected, $this->captcha->getAnswer()); - } - - public function mathProvider() - { - return [ - [1, 2, 'addition', '1 + 2 = ?', 3], - [10, 50, 'subtraction', '50 - 10 = ?', 40], - [90, 50, 'subtraction', '90 - 50 = ?', 40], - [14, 14, 'subtraction', '14 - 14 = ?', 0], - [10, 5, 'multiplication', '10 + 5 = ?', 15], - [12, 2, 'foo', '12 + 2 = ?', 14], - ]; - } -} diff --git a/tests/Utils/UploaderTest.php b/tests/Utils/UploaderTest.php deleted file mode 100644 index 982cc7f..0000000 --- a/tests/Utils/UploaderTest.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php - -namespace App\Tests\Utils; - -use PHPUnit\Framework\TestCase; -use App\Utils\Uploader; - -class UploaderTest extends TestCase -{ - private $fixturesDirectory = __DIR__.'/../fixtures/files'; - - /** - * @dataProvider filesProvider - */ - public function testUpload($validExtension, $file) - { - $_FILES = []; - $_FILES['uploaded'] = $file; - - $uploader = $this->getMockBuilder(Uploader::class) - ->setMethods(['isUploadedFile', 'moveUploadedFile']) - ->getMock(); - - $uploader->expects($this->once()) - ->method('isUploadedFile') - ->will($this->returnValue(true)); - - $uploader->expects($this->once()) - ->method('moveUploadedFile') - ->will($this->returnValue(true)); - - $uploader->setMaxFileSize(100 * 1024); - $uploader->setValidExtension($validExtension); - $uploader->setDir(__DIR__.'/../../var/uploads'); - $tmpFile = $uploader->upload('uploaded'); - - $this->assertNotNull($tmpFile); - } - - public function filesProvider() - { - return [ - [ - 'txt', - [ - 'name' => 'patch.txt', - 'tmp_name' => $this->fixturesDirectory.'/patch.txt', - 'size' => filesize($this->fixturesDirectory.'/patch.txt'), - 'error' => UPLOAD_ERR_OK, - ] - ], - ]; - } -} diff --git a/tests/Utils/Versions/ClientTest.php b/tests/Utils/Versions/ClientTest.php deleted file mode 100644 index 54f3ec0..0000000 --- a/tests/Utils/Versions/ClientTest.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php - -namespace App\Tests\Utils\Versions; - -use PHPUnit\Framework\TestCase; -use App\Utils\Versions\Client; - -class ClientTest extends TestCase -{ - private $client; - - public function setUp() - { - $this->client = new Client(); - - $reflection = new \ReflectionClass($this->client); - - $devVersionsUrl = $reflection->getProperty('devVersionsUrl'); - $devVersionsUrl->setAccessible(true); - $devVersionsUrl->setValue($this->client, __DIR__.'/../../mock/responses/dev-body.txt'); - - $stableVersionsUrl = $reflection->getProperty('stableVersionsUrl'); - $stableVersionsUrl->setAccessible(true); - $stableVersionsUrl->setValue($this->client, __DIR__.'/../../mock/responses/stable-body.txt'); - } - - public function testFetchDevVersions() - { - $this->assertInternalType('array', $this->client->fetchDevVersions()); - } - - public function testFetchStableVersions() - { - $this->assertInternalType('array', $this->client->fetchStableVersions()); - } -} diff --git a/tests/Utils/Versions/GeneratorTest.php b/tests/Utils/Versions/GeneratorTest.php deleted file mode 100644 index 386a5b6..0000000 --- a/tests/Utils/Versions/GeneratorTest.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php - -namespace App\Tests\Utils\Versions; - -use PHPUnit\Framework\TestCase; -use App\Utils\Versions\Generator; -use App\Utils\Versions\Client; -use App\Utils\Cache; - -class GeneratorTest extends TestCase -{ - private $cacheDir = __DIR__.'/../../../var/cache/test'; - private $cache; - private $client; - private $generator; - - public function setUp() - { - $this->cache = new Cache($this->cacheDir); - $this->cache->clear(); - - // The results returned by the client depend on the remote URLs so we - // mock the returned results. - $this->client = $this->getMockBuilder(Client::class) - ->setMethods(['fetchDevVersions', 'fetchStableVersions']) - ->getMock(); - - $this->client->expects($this->once()) - ->method('fetchDevVersions') - ->will($this->returnValue(json_decode(file_get_contents(__DIR__.'/../../mock/responses/dev-body.txt', true)))); - - $this->client->expects($this->once()) - ->method('fetchStableVersions') - ->will($this->returnValue(json_decode(file_get_contents(__DIR__.'/../../mock/responses/stable-body.txt'), true))); - - $this->generator = $this->getMockBuilder(Generator::class) - ->setConstructorArgs([$this->client, $this->cache]) - ->setMethods(['getAffixes']) - ->getMock(); - - // The extra versions are always date dependant so we mock it to include - // static date done on the tests day. - $date = '2018-12-26'; - $this->generator->expects($this->any()) - ->method('getAffixes') - ->will($this->returnValue(['Git-'.$date.' (snap)', 'Git-'.$date.' (Git)',])); - } - - public function tearDown() - { - $this->cache->clear(); - rmdir($this->cacheDir); - } - - public function testVersions() - { - $versions = $this->generator->getVersions(); - - $this->assertInternalType('array', $versions); - $this->assertGreaterThan(5, count($versions)); - - $fixture = require __DIR__.'/../../fixtures/versions/versions.php'; - $cached = require $this->cacheDir.'/versions.php'; - - $this->assertEquals($fixture[1], $cached[1]); - $this->assertContains('Next Major Version', $versions); - $this->assertContains('Irrelevant', $versions); - $this->assertContains('7.2.14RC1', $versions); - } -} diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..f6b6db9 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,7 @@ +<?php declare(strict_types=1); + +require_once __DIR__ . '/../vendor/autoload.php'; + +define('TEST_FIXTURES_DIRECTORY', __DIR__ . '/Fixtures'); +define('TEST_MOCKS_DIRECTORY', __DIR__ . '/Mocks'); +define('TEST_VAR_DIRECTORY', __DIR__ . '/../var'); diff --git a/tests/mock/responses/dev-body.txt b/tests/mock/responses/dev-body.txt deleted file mode 100644 index 77697a6..0000000 --- a/tests/mock/responses/dev-body.txt +++ /dev/null @@ -1 +0,0 @@ -["5.6.40-dev","7.0.33-dev","7.1.25-dev","7.2.14-dev","7.2.14RC1","7.3.1-dev","7.3.1RC1"] diff --git a/tests/mock/responses/stable-body.txt b/tests/mock/responses/stable-body.txt deleted file mode 100644 index d4daa41..0000000 --- a/tests/mock/responses/stable-body.txt +++ /dev/null @@ -1 +0,0 @@ -{"5":{"5.6":{"announcement":true,"source":[{"filename":"php-5.6.39.tar.bz2","name":"PHP 5.6.39 (tar.bz2)","sha256":"b3db2345f50c010b01fe041b4e0f66c5aa28eb325135136f153e18da01583ad5","date":"06 Dec 2018"},{"filename":"php-5.6.39.tar.gz","name":"PHP 5.6.39 (tar.gz)","sha256":"127b122b7d6c7f3c211c0ffa554979370c3131196137404a51a391d8e2e9c7bb","date":"06 Dec 2018"},{"filename":"php-5.6.39.tar.xz","name":"PHP 5.6.39 (tar.xz)","sha256":"8147576001a832ff3d03cb2980caa2d6b584a10624f87ac459fcd3948c6e4a10","date":"06 Dec 2018"}],"version":"5.6.39"}},"7":{"7.0":{"announcement":true,"source":[{"filename":"php-7.0.33.tar.bz2","name":"PHP 7.0.33 (tar.bz2)","sha256":"4933ea74298a1ba046b0246fe3771415c84dfb878396201b56cb5333abe86f07","date":"06 Dec 2018"},{"filename":"php-7.0.33.tar.gz","name":"PHP 7.0.33 (tar.gz)","sha256":"d71a6ecb6b13dc53fed7532a7f8f949c4044806f067502f8fb6f9facbb40452a","date":"06 Dec 2018"},{"filename":"php-7.0.33.tar.xz","name":"PHP 7.0.33 (tar.xz)","sha256":"ab8c5be6e32b1f8d032909dedaaaa4bbb1a209e519abb01a52ce3914f9a13d96","date":"06 Dec 2018"}],"version":"7.0.33"},"7.1":{"announcement":true,"source":[{"filename":"php-7.1.25.tar.bz2","name":"PHP 7.1.25 (tar.bz2)","sha256":"002cdc880ac7cfaede2c389204d366108847db0f3ac72edf1ba95c0577f9aaac","date":"06 Dec 2018"},{"filename":"php-7.1.25.tar.gz","name":"PHP 7.1.25 (tar.gz)","sha256":"7dc40e202140e8b4fb3d992c15a68d98dc06b805e6b218497d260abbe51f5958","date":"06 Dec 2018"},{"filename":"php-7.1.25.tar.xz","name":"PHP 7.1.25 (tar.xz)","sha256":"0fd8dad1903cd0b2d615a1fe4209f99e53b7292403c8ffa1919c0f4dd1eada88","date":"06 Dec 2018"}],"version":"7.1.25"},"7.2":{"announcement":true,"source":[{"filename":"php-7.2.13.tar.bz2","name":"PHP 7.2.13 (tar.bz2)","sha256":"5b4a46fb76491bcd3eee1213773382e570f6ecf9b22d623b24e2822298b3e92d","date":"06 Dec 2018"},{"filename":"php-7.2.13.tar.gz","name":"PHP 7.2.13 (tar.gz)","sha256":"e563cee406b1ec96649c22ed2b35796cfe4e9aa9afa6eab6be4cf2fe5d724744","date":"06 Dec 2018"},{"filename":"php-7.2.13.tar.xz","name":"PHP 7.2.13 (tar.xz)","sha256":"14b0429abdb46b65c843e5882c9a8c46b31dfbf279c747293b8ab950c2644a4b","date":"06 Dec 2018"}],"version":"7.2.13"},"7.3":{"announcement":true,"source":[{"filename":"php-7.3.0.tar.bz2","name":"PHP 7.3.0 (tar.bz2)","sha256":"7a267daec9969a997c5c8028c350229646748e0fcc71e2f2dbb157ddcee87c67","date":"06 Dec 2018"},{"filename":"php-7.3.0.tar.gz","name":"PHP 7.3.0 (tar.gz)","sha256":"391bd0f91d9bdd01ab47ef9607bad8c65e35bc9bb098fb7777b2556e2c847b11","date":"06 Dec 2018"},{"filename":"php-7.3.0.tar.xz","name":"PHP 7.3.0 (tar.xz)","sha256":"7d195cad55af8b288c3919c67023a14ff870a73e3acc2165a6d17a4850a560b5","date":"06 Dec 2018"}],"version":"7.3.0"}}}
« previous php.webmaster (#28032) next »