M .gitignore => .gitignore +2 -0
@@ 1,1 1,3 @@
composer.lock
+vendor
+.idea
D bin/tunit => bin/tunit +0 -114
@@ 1,114 0,0 @@
-#!/usr/bin/env php
-<?php
-declare(strict_types=1);
-
-namespace Thirdplace;
-
-function assertNull($value, string $message = null)
-{
- if ($value !== null) {
- fail(null, $value, $message);
- }
-}
-
-function assertTrue($value, string $message = null)
-{
- if ($value !== true) {
- fail(true, $value, $message);
- }
-}
-
-function assertFalse($value, string $message = null)
-{
- if ($value !== false) {
- fail(false, $value, $message);
- }
-}
-
-function assertEquals($expected, $actual, string $message = null)
-{
- if ($expected != $actual) {
- fail($expected, $actual, $message);
- }
-}
-
-function assertSame($expected, $actual, string $message = null)
-{
- if ($expected !== $actual) {
- fail($expected, $actual, $message);
- }
-}
-
-function expectException(\Closure $fn, string $expected = \Exception::class, string $message = null)
-{
- try {
- $fn();
- fail($expected, '', $message);
- } catch (\Exception $e) {
- if (! $e instanceof $expected) {
- fail($expected, get_class($e), $message);
- }
- }
-}
-
-function fail($expected, $actual, string $message = null)
-{
- $stackFrame = debug_backtrace()[1];
- printf("\nFAIL at %s line %s\n", $stackFrame['file'], $stackFrame['line']);
- if ($message) {
- printf("Message : %s\n", $message);
- }
- printf("Expected: %s\n", toString($expected));
- printf("Actual: %s\n", toString($actual));
-}
-
-function toString($value)
-{
- if ($value === null) {
- return '[null]';
- }
- if (is_bool($value)) {
- return $value ? '[true]' : '[false]';
- }
- if (is_string($value) || method_exists($value, '__toString')) {
- return "'$value'";
- }
- return print_r($value, true);
-}
-
-function main($argc, $argv): void
-{
- set_error_handler(function ($code, $message, $file, $line) {
- throw new \ErrorException($message, 0, $code, $file, $line);
- });
-
- $base = $argv[1] ?? './';
-
- if (!is_dir($base)) {
- exit(sprintf("Folder not found: %s\n", $base));
- }
-
- $autoloader = "$base/vendor/autoload.php";
- if (is_file($autoloader)) {
- require $autoloader;
- }
-
- $testsFolder = "$base/tests";
- if (!is_dir($testsFolder)) {
- exit(sprintf("Tests folder not found: %s\n", $testsFolder));
- }
-
- $tests = glob($testsFolder . '/*.php');
- if (!$tests) {
- exit("Tests folder is empty\n");
- }
-
- foreach ($tests as $test) {
- require $test;
- print '.';
- }
-
- print "\n";
-}
-
-main($argc, $argv);
M composer.json => composer.json +2 -5
@@ 35,9 35,6 @@
"./src/Url.php"
]
},
- "bin": [
- "./bin/tunit"
- ],
"require": {
"php" : ">=7.4",
"ext-json": "*",
@@ 47,7 44,7 @@
"ext-libxml": "*",
"ext-simplexml": "*"
},
- "scripts": {
- "test": "./bin/tunit"
+ "require-dev": {
+ "phpunit/phpunit": "^11"
}
}
R tests/cache.php => tests/CacheTest.php +31 -28
@@ 1,35 1,38 @@
<?php
+
declare(strict_types=1);
namespace Thirdplace;
-function test_cache(Cache $cache)
-{
- assertNull($cache->get('foo'));
- assertSame('default', $cache->get('foo', 'default'));
-
- $cache->set('foo', 'bar');
- assertSame('bar', $cache->get('foo'));
- assertSame('bar', $cache->get('foo', 'default'));
-
- $cache->set('is_cool');
- assertTrue($cache->get('is_cool'));
-
- $cache->set('is_bro', false);
- assertFalse($cache->get('is_bro'));
+use PHPUnit\Framework\TestCase;
- $cache->delete('foo');
- assertNull($cache->get('foo'));
-
- $cache->clear();
- assertNull($cache->get('is_bro'));
-}
-
-$caches = [
- new ArrayCache,
- new PdoCache(new \PDO('sqlite::memory:'))
-];
-
-foreach ($caches as $cache) {
- test_cache($cache);
+class CacheTest extends TestCase
+{
+ public function test_cache()
+ {
+ $caches = [
+ new ArrayCache,
+ new PdoCache(new \PDO('sqlite::memory:'))
+ ];
+ foreach ($caches as $cache) {
+ $this->assertNull($cache->get('foo'));
+ $this->assertSame('default', $cache->get('foo', 'default'));
+
+ $cache->set('foo', 'bar');
+ $this->assertSame('bar', $cache->get('foo'));
+ $this->assertSame('bar', $cache->get('foo', 'default'));
+
+ $cache->set('is_cool');
+ $this->assertTrue($cache->get('is_cool'));
+
+ $cache->set('is_bro', false);
+ $this->assertFalse($cache->get('is_bro'));
+
+ $cache->delete('foo');
+ $this->assertNull($cache->get('foo'));
+
+ $cache->clear();
+ $this->assertNull($cache->get('is_bro'));
+ }
+ }
}=
\ No newline at end of file
A tests/ContainerTest.php => tests/ContainerTest.php +28 -0
@@ 0,0 1,28 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Thirdplace;
+
+use PHPUnit\Framework\TestCase;
+
+class ContainerTest extends TestCase
+{
+ public function test()
+ {
+ $sut = new Container();
+
+ $sut['foo'] = 'bar';
+ $this->assertSame('bar', $sut['foo']);
+
+ $sut['two'] = fn() => 2;
+ $this->assertSame(2, $sut['two']);
+ $this->assertSame(2, $sut['two']);
+
+ $sut['test'] = fn($c) => $c['two'];
+ $this->assertSame(2, $sut['test']);
+
+ $this->expectException(\Exception::class);
+ $sut['foo'] = 'bar';
+ }
+}<
\ No newline at end of file
A tests/RouterTest.php => tests/RouterTest.php +33 -0
@@ 0,0 1,33 @@
+<?php
+declare(strict_types=1);
+
+namespace Thirdplace;
+
+use PHPUnit\Framework\TestCase;
+
+class RouterTest extends TestCase
+{
+ public function test()
+ {
+ $sut = new Router;
+
+ $this->assertSame([Router::NOT_FOUND, [], []], $sut->dispatch('GET', '/'));
+
+ $sut->addRoute('GET', '/', 'fn1');
+ $this->assertSame([Router::FOUND, 'fn1', []], $sut->dispatch('GET', '/'));
+
+ $sut->addRoute('GET', '/foo/bar', 'fn2');
+ $this->assertSame([Router::FOUND, 'fn2', []], $sut->dispatch('GET', '/foo/bar'));
+
+ $sut->addRoute(['GET', 'POST'], '/api', 'fn3');
+ $this->assertSame([Router::FOUND, 'fn3', []], $sut->dispatch('GET', '/api'));
+ $this->assertSame([Router::FOUND, 'fn3', []], $sut->dispatch('POST', '/api'));
+ $this->assertSame([Router::METHOD_NOT_ALLOWED, [], []], $sut->dispatch('DELETE', '/api'));
+
+ $sut->addRoute('GET', '/account/(\d+)', 'fn4');
+ $this->assertSame([Router::FOUND, 'fn4', ['2']], $sut->dispatch('GET', '/account/2'));
+
+ $sut->addRoute('GET', '/foo/(\d+)/(\w+)', 'fn5');
+ $this->assertSame([Router::FOUND, 'fn5', ['2', 'two']], $sut->dispatch('GET', '/foo/2/two'));
+ }
+}<
\ No newline at end of file
D tests/container.php => tests/container.php +0 -20
@@ 1,20 0,0 @@
-<?php
-declare(strict_types=1);
-
-namespace Thirdplace;
-
-$sut = new Container();
-
-$sut['foo'] = 'bar';
-assertSame('bar', $sut['foo']);
-
-$sut['two'] = fn() => 2;
-assertSame(2, $sut['two']);
-assertSame(2, $sut['two']);
-
-$sut['test'] = fn($c) => $c['two'];
-assertSame(2, $sut['test']);
-
-expectException(function() use ($sut) {
- $sut['foo'] = 'bar';
-});
D tests/http.php => tests/http.php +0 -10
@@ 1,10 0,0 @@
-<?php
-declare(strict_types=1);
-
-namespace Thirdplace;
-
-//$sut = Cookie::fromString('foo=bar');
-//assertEquals(['foo', 'bar'], [$sut->name, $sut->value]);
-
-$sut = Cookie::fromString('; foo=bar;');
-assertEquals(['foo', 'bar'], [$sut->name, $sut->value]);>
\ No newline at end of file
D tests/router.php => tests/router.php +0 -25
@@ 1,25 0,0 @@
-<?php
-declare(strict_types=1);
-
-namespace Thirdplace;
-
-$sut = new Router;
-
-assertSame([Router::NOT_FOUND, [], []], $sut->dispatch('GET', '/'));
-
-$sut->addRoute('GET', '/', 'fn1');
-assertSame([Router::FOUND, 'fn1', []], $sut->dispatch('GET', '/'));
-
-$sut->addRoute('GET', '/foo/bar', 'fn2');
-assertSame([Router::FOUND, 'fn2', []], $sut->dispatch('GET', '/foo/bar'));
-
-$sut->addRoute(['GET', 'POST'], '/api', 'fn3');
-assertSame([Router::FOUND, 'fn3', []], $sut->dispatch('GET', '/api'));
-assertSame([Router::FOUND, 'fn3', []], $sut->dispatch('POST', '/api'));
-assertSame([Router::METHOD_NOT_ALLOWED, [], []], $sut->dispatch('DELETE', '/api'));
-
-$sut->addRoute('GET', '/account/(\d+)', 'fn4');
-assertSame([Router::FOUND, 'fn4', ['2']], $sut->dispatch('GET', '/account/2'));
-
-$sut->addRoute('GET', '/foo/(\d+)/(\w+)', 'fn5');
-assertSame([Router::FOUND, 'fn5', ['2', 'two']], $sut->dispatch('GET', '/foo/2/two'));>
\ No newline at end of file
D tests/url.php => tests/url.php +0 -26
@@ 1,26 0,0 @@
-<?php
-declare(strict_types=1);
-
-namespace Thirdplace;
-
-assertEquals('https://example.com:81/foo?bar=baz#kek', (string)url('https://example.com:81/foo?bar=baz#kek'));
-assertEquals('https://example.com', (string)url('https://example.com'));
-assertEquals('https://example.com/foo', (string)url('https://example.com/foo'));
-assertEquals('https://example.com/foo/', (string)url('https://example.com/foo/'));
-assertEquals('https://example.com', (string)url('https://example.com/'));
-assertEquals('https://example.com', (string)url('https://example.com//'));
-assertEquals('https://example.com', (string)url('https://example.com/./'));
-assertEquals('https://example.com', (string)url('https://example.com//./'));
-assertEquals('https://example.com', (string)url('https://example.com/.///'));
-assertEquals('https://example.com/a', (string)url('https://example.com/../a'));
-assertEquals('https://example.com', (string)url('https://example.com/foo/..'));
-assertEquals('https://example.com/foo', (string)url('https://example.com/foo/bar/..'));
-assertEquals('https://example.com/foo?bar=', (string)url('https://example.com/foo?bar'));
-assertEquals('https://example.com/?baz=', (string)url('https://example.com/foo/..?baz='));
-assertEquals('https://example.com/foo/bar', (string)url('https://example.com/foo/bar/baz/..'));
-assertEquals('https://example.com/foo', (string)url('https://example.com/foo/bar/../baz/..'));
-//assertEquals('https://example.com', (string)url('https://example.com/foo/bar/../..'));
-assertEquals('https://example.com', (string)url('https://example.com/../..'));
-assertEquals('https://example.com/foo?foo=bar', (string) url('https://example.com/foo?foo=bar'));
-assertEquals('https://blog.zulip.com/2022/05/05/public-access-option', (string) url('https://blog.zulip.com/2022/05/05/public-access-option'));
-assertEquals('https://kevincox.ca/feed.atom', (string) url('https://kevincox.ca/2022/05/../../feed.atom'));