Commit: f762db348dc0ef698bdbd3cd4c95530b1266e027
Author: Pieter Hordijk <[email protected]> Thu, 16 May 2019
16:05:18 +0300
Committer: Peter Kokot <[email protected]> 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>',
- '<iframe
src="javascript:alert('Xss')";></iframe>',
- '<iframe
src="javascript:alert('Xss')";></iframe>'
- ]
- ];
- }
-}
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>',
+ '<iframe
src="javascript:alert('Xss')";></iframe>',
+ '<iframe
src="javascript:alert('Xss')";></iframe>'
+ ]
+ ];
+ }
+}
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"}}}
--
PHP Webmaster List Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php