@ -40,16 +40,16 @@ class EngineTest extends TestCase
};
};
$this->assertTrue($engine->getInitializedVar());
$this->assertTrue($engine->getInitializedVar());
// we need to setup a dummy route
// we need to setup a dummy route
$engine->route('/someRoute', function () { });
$engine->route('/someRoute', function () {});
$engine->request()->url = '/someRoute';
$engine->request()->url = '/someRoute';
$engine->start();
$engine->start();
$this->assertFalse($engine->router()->caseSensitive);
$this->assertFalse($engine->router()->caseSensitive);
$this->assertTrue($engine->response()->content_length);
$this->assertTrue($engine->response()->content_length);
}
}
public function testInitBeforeStartV2OutputBuffering(): void
public function testInitBeforeStartV2OutputBuffering(): void
{
{
$engine = new class extends Engine {
$engine = new class extends Engine {
public function getInitializedVar(): bool
public function getInitializedVar(): bool
@ -57,12 +57,12 @@ class EngineTest extends TestCase
return $this->initialized;
return $this->initialized;
}
}
};
};
$engine->set('flight.v2.output_buffering', true);
$engine->set('flight.v2.output_buffering', true);
$this->assertTrue($engine->getInitializedVar());
$this->assertTrue($engine->getInitializedVar());
$engine->start();
$engine->start();
// This is a necessary evil because of how the v2 output buffer works.
// This is a necessary evil because of how the v2 output buffer works.
ob_end_clean();
ob_end_clean();
$this->assertFalse($engine->router()->caseSensitive);
$this->assertFalse($engine->router()->caseSensitive);
$this->assertTrue($engine->response()->content_length);
$this->assertTrue($engine->response()->content_length);
@ -96,8 +96,7 @@ class EngineTest extends TestCase
$engine = new Engine();
$engine = new Engine();
$this->expectException(Exception::class);
$this->expectException(Exception::class);
$this->expectExceptionMessage('Cannot override an existing framework method.');
$this->expectExceptionMessage('Cannot override an existing framework method.');
$engine->map('_start', function () {
$engine->map('_start', function () {});
});
}
}
public function testRegisterExistingMethod(): void
public function testRegisterExistingMethod(): void
@ -111,7 +110,7 @@ class EngineTest extends TestCase
public function testSetArrayOfValues(): void
public function testSetArrayOfValues(): void
{
{
$engine = new Engine();
$engine = new Engine();
$engine->set([ 'key1' => 'value1', 'key2' => 'value2']);
$engine->set(['key1' => 'value1', 'key2' => 'value2']);
$this->assertEquals('value1', $engine->get('key1'));
$this->assertEquals('value1', $engine->get('key1'));
$this->assertEquals('value2', $engine->get('key2'));
$this->assertEquals('value2', $engine->get('key2'));
}
}
@ -153,8 +152,8 @@ class EngineTest extends TestCase
$this->expectOutputString('< h1 > 404 Not Found< / h1 > < h3 > The page you have requested could not be found.< / h3 > ');
$this->expectOutputString('< h1 > 404 Not Found< / h1 > < h3 > The page you have requested could not be found.< / h3 > ');
$engine->start();
$engine->start();
}
}
public function testStartWithRouteButReturnedValueThrows404V2OutputBuffering(): void
public function testStartWithRouteButReturnedValueThrows404V2OutputBuffering(): void
{
{
$_SERVER['REQUEST_METHOD'] = 'GET';
$_SERVER['REQUEST_METHOD'] = 'GET';
$_SERVER['REQUEST_URI'] = '/someRoute';
$_SERVER['REQUEST_URI'] = '/someRoute';
@ -165,7 +164,7 @@ class EngineTest extends TestCase
return $this->initialized;
return $this->initialized;
}
}
};
};
$engine->set('flight.v2.output_buffering', true);
$engine->set('flight.v2.output_buffering', true);
$engine->route('/someRoute', function () {
$engine->route('/someRoute', function () {
echo 'i ran';
echo 'i ran';
return true;
return true;
@ -185,18 +184,18 @@ class EngineTest extends TestCase
return $this->initialized;
return $this->initialized;
}
}
};
};
// First route that returns true (should continue routing)
// First route that returns true (should continue routing)
$engine->route('/someRoute', function () {
$engine->route('/someRoute', function () {
echo 'first route ran, ';
echo 'first route ran, ';
return true;
return true;
}, true);
}, true);
// Second route that should be found and executed
// Second route that should be found and executed
$engine->route('/someRoute', function () {
$engine->route('/someRoute', function () {
echo 'second route executed!';
echo 'second route executed!';
}, true);
}, true);
$this->expectOutputString('first route ran, second route executed!');
$this->expectOutputString('first route ran, second route executed!');
$engine->start();
$engine->start();
}
}
@ -211,13 +210,13 @@ class EngineTest extends TestCase
{
{
return $this->initialized;
return $this->initialized;
}
}
public function getLoader()
public function getLoader()
{
{
return $this->loader;
return $this->loader;
}
}
};
};
// Mock response to prevent actual headers
// Mock response to prevent actual headers
$engine->getLoader()->register('response', function () {
$engine->getLoader()->register('response', function () {
return new class extends Response {
return new class extends Response {
@ -227,23 +226,23 @@ class EngineTest extends TestCase
}
}
};
};
});
});
// First route that returns true and matches POST
// First route that returns true and matches POST
$engine->route('POST /someRoute', function () {
$engine->route('POST /someRoute', function () {
echo 'first POST route ran, ';
echo 'first POST route ran, ';
return true;
return true;
}, true);
}, true);
// Second route that matches URL but wrong method (GET) - should be captured for 405
// Second route that matches URL but wrong method (GET) - should be captured for 405
$engine->route('GET /someRoute', function () {
$engine->route('GET /someRoute', function () {
echo 'should not execute';
echo 'should not execute';
}, true);
}, true);
// Third route that matches POST and should execute
// Third route that matches POST and should execute
$engine->route('POST /someRoute', function () {
$engine->route('POST /someRoute', function () {
echo 'second POST route executed!';
echo 'second POST route executed!';
}, true);
}, true);
$this->expectOutputString('first POST route ran, second POST route executed!');
$this->expectOutputString('first POST route ran, second POST route executed!');
$engine->start();
$engine->start();
}
}
@ -259,46 +258,46 @@ class EngineTest extends TestCase
return $this->initialized;
return $this->initialized;
}
}
};
};
// Route that returns true (continues iteration)
// Route that returns true (continues iteration)
$engine->route('/someRoute', function () {
$engine->route('/someRoute', function () {
echo 'first route ran, ';
echo 'first route ran, ';
return true;
return true;
}, true);
}, true);
// Route with different URL that won't match
// Route with different URL that won't match
$engine->route('/differentRoute', function () {
$engine->route('/differentRoute', function () {
echo 'should not execute';
echo 'should not execute';
}, true);
}, true);
// No more matching routes - should reach end of iterator and return 404
// No more matching routes - should reach end of iterator and return 404
$this->expectOutputString('< h1 > 404 Not Found< / h1 > < h3 > The page you have requested could not be found.< / h3 > ');
$this->expectOutputString('< h1 > 404 Not Found< / h1 > < h3 > The page you have requested could not be found.< / h3 > ');
$engine->start();
$engine->start();
}
}
public function testDoubleStart(): void
public function testDoubleStart(): void
{
{
$engine = new Engine();
$engine = new Engine();
$engine->route('/someRoute', function () {
$engine->route('/someRoute', function () {
echo 'i ran';
echo 'i ran';
}, true);
}, true);
$engine->request()->url = '/someRoute';
$engine->request()->url = '/someRoute';
$engine->start();
$engine->start();
$request = $engine->request();
$request = $engine->request();
$response = $engine->response();
$response = $engine->response();
// This is pretending like this is embodied in a platform like swoole where
// This is pretending like this is embodied in a platform like swoole where
// another request comes in while still holding all the same state.
// another request comes in while still holding all the same state.
$_SERVER['REQUEST_METHOD'] = 'GET';
$_SERVER['REQUEST_METHOD'] = 'GET';
$_SERVER['REQUEST_URI'] = '/someRoute';
$_SERVER['REQUEST_URI'] = '/someRoute';
$engine->start();
$engine->start();
$this->assertFalse($request === $engine->request());
$this->assertFalse($request === $engine->request());
$this->assertFalse($response === $engine->response());
$this->assertFalse($response === $engine->response());
$this->expectOutputString('i rani ran');
$this->expectOutputString('i rani ran');
}
}
public function testStopWithCode(): void
public function testStopWithCode(): void
{
{
@ -323,7 +322,7 @@ class EngineTest extends TestCase
$this->assertEquals(500, $engine->response()->status());
$this->assertEquals(500, $engine->response()->status());
}
}
public function testStopWithCodeV2OutputBuffering(): void
public function testStopWithCodeV2OutputBuffering(): void
{
{
$engine = new class extends Engine {
$engine = new class extends Engine {
public function getLoader()
public function getLoader()
@ -340,13 +339,13 @@ class EngineTest extends TestCase
}
}
};
};
});
});
$engine->set('flight.v2.output_buffering', true);
$engine->set('flight.v2.output_buffering', true);
$engine->route('/testRoute', function () use ($engine) {
$engine->route('/testRoute', function () use ($engine) {
echo 'I am a teapot';
echo 'I am a teapot';
$engine->stop(500);
$engine->stop(500);
});
});
$engine->request()->url = '/testRoute';
$engine->request()->url = '/testRoute';
$engine->start();
$engine->start();
$this->expectOutputString('I am a teapot');
$this->expectOutputString('I am a teapot');
$this->assertEquals(500, $engine->response()->status());
$this->assertEquals(500, $engine->response()->status());
}
}
@ -409,7 +408,7 @@ class EngineTest extends TestCase
$this->expectOutputString('');
$this->expectOutputString('');
}
}
public function testOptionsRoute(): void
public function testOptionsRoute(): void
{
{
$engine = new Engine();
$engine = new Engine();
$engine->route('GET /someRoute', function () {
$engine->route('GET /someRoute', function () {
@ -421,7 +420,7 @@ class EngineTest extends TestCase
// No body should be sent
// No body should be sent
$this->expectOutputString('');
$this->expectOutputString('');
$this->assertEquals('GET, HEAD, OPTIONS', $engine->response()->headers()['Allow']);
$this->assertEquals('GET, HEAD, OPTIONS', $engine->response()->headers()['Allow']);
}
}
public function testHalt(): void
public function testHalt(): void
@ -498,46 +497,46 @@ class EngineTest extends TestCase
$engine->json(['key1' => 'value1', 'key2' => 'value2']);
$engine->json(['key1' => 'value1', 'key2' => 'value2']);
$this->assertEquals('application/json', $engine->response()->headers()['Content-Type']);
$this->assertEquals('application/json', $engine->response()->headers()['Content-Type']);
$this->assertEquals(200, $engine->response()->status());
$this->assertEquals(200, $engine->response()->status());
$this->assertEquals('{"key1":"value1","key2":"value2"}', $engine->response()->getBody());
$this->assertEquals('{"key1":"value1","key2":"value2"}', $engine->response()->getBody());
}
}
public function testJsonWithDuplicateDefaultFlags()
public function testJsonWithDuplicateDefaultFlags()
{
$engine = new Engine();
$flags = JSON_HEX_TAG | JSON_HEX_TAG | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;
// utf8 emoji
$engine->json(['key1' => 'value1', 'key2' => 'value2', 'utf8_emoji' => '😀'], 201, true, '', $flags);
$this->assertEquals('application/json', $engine->response()->headers()['Content-Type']);
$this->assertEquals(201, $engine->response()->status());
$this->assertEquals('{"key1":"value1","key2":"value2","utf8_emoji":"😀"}', $engine->response()->getBody());
}
public function testJsonThrowOnErrorByDefault(): void
{
$engine = new Engine();
$this->expectException(Exception::class);
$this->expectExceptionMessage('Malformed UTF-8 characters, possibly incorrectly encoded');
$engine->json(['key1' => 'value1', 'key2' => 'value2', 'utf8_emoji' => "\xB1\x31"]);
}
public function testJsonV2OutputBuffering(): void
{
{
$engine = new Engine();
$engine = new Engine();
$engine->response()->v2_output_buffering = true;
$flags = JSON_HEX_TAG | JSON_HEX_TAG | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;
// utf8 emoji
$engine->json(['key1' => 'value1', 'key2' => 'value2', 'utf8_emoji' => '😀'], 201, true, '', $flags);
$this->assertEquals('application/json', $engine->response()->headers()['Content-Type']);
$this->assertEquals(201, $engine->response()->status());
$this->assertEquals('{"key1":"value1","key2":"value2","utf8_emoji":"😀"}', $engine->response()->getBody());
}
public function testJsonThrowOnErrorByDefault(): void
{
$engine = new Engine();
$this->expectException(Exception::class);
$this->expectExceptionMessage('Malformed UTF-8 characters, possibly incorrectly encoded');
$engine->json(['key1' => 'value1', 'key2' => 'value2', 'utf8_emoji' => "\xB1\x31"]);
}
public function testJsonV2OutputBuffering(): void
{
$engine = new Engine();
$engine->response()->v2_output_buffering = true;
$engine->json(['key1' => 'value1', 'key2' => 'value2']);
$engine->json(['key1' => 'value1', 'key2' => 'value2']);
$this->expectOutputString('{"key1":"value1","key2":"value2"}');
$this->expectOutputString('{"key1":"value1","key2":"value2"}');
$this->assertEquals('application/json', $engine->response()->headers()['Content-Type']);
$this->assertEquals('application/json', $engine->response()->headers()['Content-Type']);
$this->assertEquals(200, $engine->response()->status());
$this->assertEquals(200, $engine->response()->status());
}
}
public function testJsonHalt(): void
public function testJsonHalt(): void
{
{
$engine = new Engine();
$engine = new Engine();
$this->expectOutputString('{"key1":"value1","key2":"value2"}');
$this->expectOutputString('{"key1":"value1","key2":"value2"}');
$engine->jsonHalt(['key1' => 'value1', 'key2' => 'value2']);
$engine->jsonHalt(['key1' => 'value1', 'key2' => 'value2']);
$this->assertEquals('application/json', $engine->response()->headers()['Content-Type']);
$this->assertEquals('application/json', $engine->response()->headers()['Content-Type']);
$this->assertEquals(200, $engine->response()->status());
$this->assertEquals(200, $engine->response()->status());
$this->assertEquals('{"key1":"value1","key2":"value2"}', $engine->response()->getBody());
$this->assertEquals('{"key1":"value1","key2":"value2"}', $engine->response()->getBody());
}
}
public function testJsonP(): void
public function testJsonP(): void
@ -547,13 +546,13 @@ class EngineTest extends TestCase
$engine->jsonp(['key1' => 'value1', 'key2' => 'value2']);
$engine->jsonp(['key1' => 'value1', 'key2' => 'value2']);
$this->assertEquals('application/javascript; charset=utf-8', $engine->response()->headers()['Content-Type']);
$this->assertEquals('application/javascript; charset=utf-8', $engine->response()->headers()['Content-Type']);
$this->assertEquals(200, $engine->response()->status());
$this->assertEquals(200, $engine->response()->status());
$this->assertEquals('whatever({"key1":"value1","key2":"value2"});', $engine->response()->getBody());
$this->assertEquals('whatever({"key1":"value1","key2":"value2"});', $engine->response()->getBody());
}
}
public function testJsonPV2OutputBuffering(): void
public function testJsonPV2OutputBuffering(): void
{
{
$engine = new Engine();
$engine = new Engine();
$engine->response()->v2_output_buffering = true;
$engine->response()->v2_output_buffering = true;
$engine->request()->query['jsonp'] = 'whatever';
$engine->request()->query['jsonp'] = 'whatever';
$engine->jsonp(['key1' => 'value1', 'key2' => 'value2']);
$engine->jsonp(['key1' => 'value1', 'key2' => 'value2']);
$this->expectOutputString('whatever({"key1":"value1","key2":"value2"});');
$this->expectOutputString('whatever({"key1":"value1","key2":"value2"});');
@ -570,10 +569,10 @@ class EngineTest extends TestCase
$this->assertEquals(200, $engine->response()->status());
$this->assertEquals(200, $engine->response()->status());
}
}
public function testJsonpBadParamV2OutputBuffering(): void
public function testJsonpBadParamV2OutputBuffering(): void
{
{
$engine = new Engine();
$engine = new Engine();
$engine->response()->v2_output_buffering = true;
$engine->response()->v2_output_buffering = true;
$engine->jsonp(['key1' => 'value1', 'key2' => 'value2']);
$engine->jsonp(['key1' => 'value1', 'key2' => 'value2']);
$this->expectOutputString('({"key1":"value1","key2":"value2"});');
$this->expectOutputString('({"key1":"value1","key2":"value2"});');
$this->assertEquals('application/javascript; charset=utf-8', $engine->response()->headers()['Content-Type']);
$this->assertEquals('application/javascript; charset=utf-8', $engine->response()->headers()['Content-Type']);
@ -608,7 +607,7 @@ class EngineTest extends TestCase
$engine = new Engine;
$engine = new Engine;
$_SERVER['HTTP_IF_MODIFIED_SINCE'] = 'Fri, 13 Feb 2009 23:31:30 GMT';
$_SERVER['HTTP_IF_MODIFIED_SINCE'] = 'Fri, 13 Feb 2009 23:31:30 GMT';
$engine->lastModified(1234567890);
$engine->lastModified(1234567890);
$this->assertTrue(empty($engine->response()->headers()['Last-Modified']));
$this->assertTrue(empty($engine->response()->headers()['Last-Modified']));
$this->assertEquals(304, $engine->response()->status());
$this->assertEquals(304, $engine->response()->status());
}
}
@ -618,7 +617,7 @@ class EngineTest extends TestCase
$engine->route('/path1/@param:[0-9]{3}', function () {
$engine->route('/path1/@param:[0-9]{3}', function () {
echo 'I win';
echo 'I win';
}, false, 'path1');
}, false, 'path1');
$url = $engine->getUrl('path1', [ 'param' => 123 ]);
$url = $engine->getUrl('path1', ['param' => 123]);
$this->assertEquals('/path1/123', $url);
$this->assertEquals('/path1/123', $url);
}
}
@ -628,7 +627,7 @@ class EngineTest extends TestCase
$engine->route('/item/@item_param:[a-z0-9]{16}/by-status/@token:[a-z0-9]{16}', function () {
$engine->route('/item/@item_param:[a-z0-9]{16}/by-status/@token:[a-z0-9]{16}', function () {
echo 'I win';
echo 'I win';
}, false, 'path_item_1');
}, false, 'path_item_1');
$url = $engine->getUrl('path_item_1', [ 'item_param' => 1234567890123456, 'token' => 6543210987654321 ]);
$url = $engine->getUrl('path_item_1', ['item_param' => 1234567890123456, 'token' => 6543210987654321]);
$this->assertEquals('/item/1234567890123456/by-status/6543210987654321', $url);
$this->assertEquals('/item/1234567890123456/by-status/6543210987654321', $url);
}
}
@ -666,8 +665,7 @@ class EngineTest extends TestCase
public function testMiddlewareCallableFunctionReturnFalse(): void
public function testMiddlewareCallableFunctionReturnFalse(): void
{
{
$engine = new class extends Engine {
$engine = new class extends Engine {};
};
$engine->route('/path1/@id', function ($id) {
$engine->route('/path1/@id', function ($id) {
echo 'OK' . $id;
echo 'OK' . $id;
})
})
@ -742,7 +740,7 @@ class EngineTest extends TestCase
$this->expectOutputString('OK123after123');
$this->expectOutputString('OK123after123');
}
}
public function testMiddlewareClassStringNoContainer(): void
public function testMiddlewareClassStringNoContainer(): void
{
{
$middleware = new class {
$middleware = new class {
public function after($params)
public function after($params)
@ -761,10 +759,10 @@ class EngineTest extends TestCase
$this->expectOutputString('OK123after123');
$this->expectOutputString('OK123after123');
}
}
public function testMiddlewareClassStringWithContainer(): void
public function testMiddlewareClassStringWithContainer(): void
{
{
$engine = new Engine();
$engine = new Engine();
$dice = new \Dice\Dice();
$dice = new \Dice\Dice();
$dice = $dice->addRule('*', [
$dice = $dice->addRule('*', [
'substitutions' => [
'substitutions' => [
@ -774,7 +772,7 @@ class EngineTest extends TestCase
$engine->registerContainerHandler(function ($class, $params) use ($dice) {
$engine->registerContainerHandler(function ($class, $params) use ($dice) {
return $dice->create($class, $params);
return $dice->create($class, $params);
});
});
$engine->route('/path1/@id', function ($id) {
$engine->route('/path1/@id', function ($id) {
echo 'OK' . $id;
echo 'OK' . $id;
@ -794,8 +792,7 @@ class EngineTest extends TestCase
return false;
return false;
}
}
};
};
$engine = new class extends Engine {
$engine = new class extends Engine {};
};
$engine->route('/path1/@id', function ($id) {
$engine->route('/path1/@id', function ($id) {
echo 'OK' . $id;
echo 'OK' . $id;
@ -850,7 +847,7 @@ class EngineTest extends TestCase
$engine = new Engine();
$engine = new Engine();
$engine->route('/path1/@id/subpath1/@another_id', function () {
$engine->route('/path1/@id/subpath1/@another_id', function () {
echo 'OK';
echo 'OK';
})->addMiddleware([ $middleware, $middleware2 ]);
})->addMiddleware([$middleware, $middleware2]);
$engine->request()->url = '/path1/123/subpath1/456';
$engine->request()->url = '/path1/123/subpath1/456';
$engine->start();
$engine->start();
@ -887,14 +884,15 @@ class EngineTest extends TestCase
$router->map('/@cool_id', function () {
$router->map('/@cool_id', function () {
echo 'OK';
echo 'OK';
});
});
}, [ $middleware, $middleware2 ]);
}, [$middleware, $middleware2]);
$engine->request()->url = '/path1/123/subpath1/456';
$engine->request()->url = '/path1/123/subpath1/456';
$engine->start();
$engine->start();
$this->expectOutputString('before456before123OKafter123456after123');
$this->expectOutputString('before456before123OKafter123456after123');
}
}
public function testContainerBadClass() {
public function testContainerBadClass()
{
$engine = new Engine();
$engine = new Engine();
$this->expectException(InvalidArgumentException::class);
$this->expectException(InvalidArgumentException::class);
@ -902,47 +900,50 @@ class EngineTest extends TestCase
$engine->registerContainerHandler('BadClass');
$engine->registerContainerHandler('BadClass');
}
}
public function testContainerDice() {
public function testContainerDice()
{
$engine = new Engine();
$engine = new Engine();
$dice = new \Dice\Dice();
$dice = new \Dice\Dice();
$dice = $dice->addRules([
$dice = $dice->addRules([
PdoWrapper::class => [
PdoWrapper::class => [
'shared' => true,
'shared' => true,
'constructParams' => [ 'sqlite::memory:' ]
'constructParams' => ['sqlite::memory:']
]
]
]);
]);
$engine->registerContainerHandler(function ($class, $params) use ($dice) {
$engine->registerContainerHandler(function ($class, $params) use ($dice) {
return $dice->create($class, $params);
return $dice->create($class, $params);
});
});
$engine->route('/container', Container::class.'->testTheContainer');
$engine->route('/container', Container::class . '->testTheContainer');
$engine->request()->url = '/container';
$engine->request()->url = '/container';
$engine->start();
$engine->start();
$this->expectOutputString('yay! I injected a collection, and it has 1 items');
$this->expectOutputString('yay! I injected a collection, and it has 1 items');
}
}
public function testContainerDicePdoWrapperTest() {
public function testContainerDicePdoWrapperTest()
{
$engine = new Engine();
$engine = new Engine();
$dice = new \Dice\Dice();
$dice = new \Dice\Dice();
$dice = $dice->addRules([
$dice = $dice->addRules([
PdoWrapper::class => [
PdoWrapper::class => [
'shared' => true,
'shared' => true,
'constructParams' => [ 'sqlite::memory:' ]
'constructParams' => ['sqlite::memory:']
]
]
]);
]);
$engine->registerContainerHandler(function ($class, $params) use ($dice) {
$engine->registerContainerHandler(function ($class, $params) use ($dice) {
return $dice->create($class, $params);
return $dice->create($class, $params);
});
});
$engine->route('/container', Container::class.'->testThePdoWrapper');
$engine->route('/container', Container::class . '->testThePdoWrapper');
$engine->request()->url = '/container';
$engine->request()->url = '/container';
$engine->start();
$engine->start();
$this->expectOutputString('Yay! I injected a PdoWrapper, and it returned the number 5 from the database!');
$this->expectOutputString('Yay! I injected a PdoWrapper, and it returned the number 5 from the database!');
}
}
public function testContainerDiceFlightEngine() {
public function testContainerDiceFlightEngine()
{
$engine = new Engine();
$engine = new Engine();
$engine->set('test_me_out', 'You got it boss!');
$engine->set('test_me_out', 'You got it boss!');
$dice = new \Dice\Dice();
$dice = new \Dice\Dice();
@ -954,44 +955,46 @@ class EngineTest extends TestCase
$engine->registerContainerHandler(function ($class, $params) use ($dice) {
$engine->registerContainerHandler(function ($class, $params) use ($dice) {
return $dice->create($class, $params);
return $dice->create($class, $params);
});
});
$engine->route('/container', ContainerDefault::class.'->echoTheContainer');
$engine->route('/container', ContainerDefault::class . '->echoTheContainer');
$engine->request()->url = '/container';
$engine->request()->url = '/container';
$engine->start();
$engine->start();
$this->expectOutputString('You got it boss!');
$this->expectOutputString('You got it boss!');
}
}
public function testContainerDiceBadClass() {
public function testContainerDiceBadClass()
{
$engine = new Engine();
$engine = new Engine();
$dice = new \Dice\Dice();
$dice = new \Dice\Dice();
$engine->registerContainerHandler(function ($class, $params) use ($dice) {
$engine->registerContainerHandler(function ($class, $params) use ($dice) {
return $dice->create($class, $params);
return $dice->create($class, $params);
});
});
$engine->route('/container', 'BadClass->testTheContainer');
$engine->route('/container', 'BadClass->testTheContainer');
$engine->request()->url = '/container';
$engine->request()->url = '/container';
$this->expectException(Exception::class);
$this->expectException(Exception::class);
$this->expectExceptionMessage("Class 'BadClass' not found. Is it being correctly autoloaded with Flight::path()?");
$this->expectExceptionMessage("Class 'BadClass' not found. Is it being correctly autoloaded with Flight::path()?");
$engine->start();
$engine->start();
}
}
public function testContainerDiceBadMethod() {
public function testContainerDiceBadMethod()
{
$engine = new Engine();
$engine = new Engine();
$dice = new \Dice\Dice();
$dice = new \Dice\Dice();
$dice = $dice->addRules([
$dice = $dice->addRules([
PdoWrapper::class => [
PdoWrapper::class => [
'shared' => true,
'shared' => true,
'constructParams' => [ 'sqlite::memory:' ]
'constructParams' => ['sqlite::memory:']
]
]
]);
]);
$engine->registerContainerHandler(function ($class, $params) use ($dice) {
$engine->registerContainerHandler(function ($class, $params) use ($dice) {
return $dice->create($class, $params);
return $dice->create($class, $params);
});
});
$engine->route('/container', Container::class.'->badMethod');
$engine->route('/container', Container::class . '->badMethod');
$engine->request()->url = '/container';
$engine->request()->url = '/container';
$this->expectException(Exception::class);
$this->expectException(Exception::class);
@ -1000,46 +1003,49 @@ class EngineTest extends TestCase
$engine->start();
$engine->start();
}
}
public function testContainerPsr11(): void {
public function testContainerPsr11(): void
{
$engine = new Engine();
$engine = new Engine();
$container = new \League\Container\Container();
$container = new \League\Container\Container();
$container->add(Container::class)->addArgument(Collection::class)->addArgument(PdoWrapper::class);
$container->add(Container::class)->addArgument(Collection::class)->addArgument(PdoWrapper::class);
$container->add(Collection::class);
$container->add(Collection::class);
$container->add(PdoWrapper::class)->addArgument('sqlite::memory:');
$container->add(PdoWrapper::class)->addArgument('sqlite::memory:');
$engine->registerContainerHandler($container);
$engine->registerContainerHandler($container);
$engine->route('/container', Container::class.'->testTheContainer');
$engine->route('/container', Container::class . '->testTheContainer');
$engine->request()->url = '/container';
$engine->request()->url = '/container';
$engine->start();
$engine->start();
$this->expectOutputString('yay! I injected a collection, and it has 1 items');
$this->expectOutputString('yay! I injected a collection, and it has 1 items');
}
}
public function testContainerPsr11ClassNotFound() {
public function testContainerPsr11ClassNotFound()
{
$engine = new Engine();
$engine = new Engine();
$container = new \League\Container\Container();
$container = new \League\Container\Container();
$container->add(Container::class)->addArgument(Collection::class);
$container->add(Container::class)->addArgument(Collection::class);
$container->add(Collection::class);
$container->add(Collection::class);
$engine->registerContainerHandler($container);
$engine->registerContainerHandler($container);
$engine->route('/container', 'BadClass->testTheContainer');
$engine->route('/container', 'BadClass->testTheContainer');
$engine->request()->url = '/container';
$engine->request()->url = '/container';
$this->expectException(Exception::class);
$this->expectException(Exception::class);
$this->expectExceptionMessage("Class 'BadClass' not found. Is it being correctly autoloaded with Flight::path()?");
$this->expectExceptionMessage("Class 'BadClass' not found. Is it being correctly autoloaded with Flight::path()?");
$engine->start();
$engine->start();
}
}
public function testContainerPsr11MethodNotFound(): void {
public function testContainerPsr11MethodNotFound(): void
{
$engine = new Engine();
$engine = new Engine();
$container = new \League\Container\Container();
$container = new \League\Container\Container();
$container->add(Container::class)->addArgument(Collection::class)->addArgument(PdoWrapper::class);
$container->add(Container::class)->addArgument(Collection::class)->addArgument(PdoWrapper::class);
$container->add(Collection::class);
$container->add(Collection::class);
$container->add(PdoWrapper::class)->addArgument('sqlite::memory:');
$container->add(PdoWrapper::class)->addArgument('sqlite::memory:');
$engine->registerContainerHandler($container);
$engine->registerContainerHandler($container);
$engine->route('/container', Container::class.'->badMethod');
$engine->route('/container', Container::class . '->badMethod');
$engine->request()->url = '/container';
$engine->request()->url = '/container';
$this->expectException(Exception::class);
$this->expectException(Exception::class);
@ -1048,7 +1054,8 @@ class EngineTest extends TestCase
$engine->start();
$engine->start();
}
}
public function testRouteFoundButBadMethod(): void {
public function testRouteFoundButBadMethod(): void
{
$engine = new class extends Engine {
$engine = new class extends Engine {
public function getLoader()
public function getLoader()
{
{
@ -1068,30 +1075,30 @@ class EngineTest extends TestCase
};
};
});
});
$engine->route('POST /path1/@id', function ($id) {
$engine->route('POST /path1/@id', function ($id) {
echo 'OK' . $id;
echo 'OK' . $id;
});
});
$engine->route('GET /path2/@id', function ($id) {
$engine->route('GET /path2/@id', function ($id) {
echo 'OK' . $id;
echo 'OK' . $id;
});
});
$engine->route('PATCH /path3/@id', function ($id) {
$engine->route('PATCH /path3/@id', function ($id) {
echo 'OK' . $id;
echo 'OK' . $id;
});
});
$engine->request()->url = '/path1/123';
$engine->request()->url = '/path1/123';
$engine->request()->method = 'GET';
$engine->request()->method = 'GET';
$engine->start();
$engine->start();
$this->expectOutputString('Method Not Allowed. Allowed Methods are: POST, OPTIONS');
$this->expectOutputString('Method Not Allowed. Allowed Methods are: POST, OPTIONS');
$this->assertEquals(405, $engine->response()->status());
$this->assertEquals(405, $engine->response()->status());
$this->assertEquals('Method Not Allowed. Allowed Methods are: POST, OPTIONS', $engine->response()->getBody());
$this->assertEquals('Method Not Allowed. Allowed Methods are: POST, OPTIONS', $engine->response()->getBody());
$this->assertEquals('POST, OPTIONS', $engine->response()->headers()['Allow']);
$this->assertEquals('POST, OPTIONS', $engine->response()->headers()['Allow']);
}
}
public function testDownload(): void
public function testDownload(): void
{
{
$engine = new class extends Engine {
$engine = new class extends Engine {
public function getLoader()
public function getLoader()
@ -1102,26 +1109,26 @@ class EngineTest extends TestCase
// doing this so we can overwrite some parts of the response
// doing this so we can overwrite some parts of the response
$engine->getLoader()->register('response', function () {
$engine->getLoader()->register('response', function () {
return new class extends Response {
return new class extends Response {
public $headersSent = [];
public $headersSent = [];
public function setRealHeader(
public function setRealHeader(
string $header_string,
string $header_string,
bool $replace = true,
bool $replace = true,
int $response_code = 0
int $response_code = 0
): self {
): self {
$this->headersSent[] = $header_string;
$this->headersSent[] = $header_string;
return $this;
return $this;
}
}
};
};
});
});
$tmpfile = tmpfile();
$tmpfile = tmpfile();
fwrite($tmpfile, 'I am a teapot');
fwrite($tmpfile, 'I am a teapot');
$streamPath = stream_get_meta_data($tmpfile)['uri'];
$streamPath = stream_get_meta_data($tmpfile)['uri'];
$this->expectOutputString('I am a teapot');
$this->expectOutputString('I am a teapot');
$engine->download($streamPath);
$engine->download($streamPath);
$this->assertContains('Content-Disposition: attachment; filename="'.basename($streamPath).'"', $engine->response()->headersSent);
$this->assertContains('Content-Disposition: attachment; filename="' . basename($streamPath) . '"', $engine->response()->headersSent);
}
}
public function testDownloadWithDefaultFileName(): void
public function testDownloadWithDefaultFileName(): void
{
{
$engine = new class extends Engine {
$engine = new class extends Engine {
public function getLoader()
public function getLoader()
@ -1132,30 +1139,30 @@ class EngineTest extends TestCase
// doing this so we can overwrite some parts of the response
// doing this so we can overwrite some parts of the response
$engine->getLoader()->register('response', function () {
$engine->getLoader()->register('response', function () {
return new class extends Response {
return new class extends Response {
public $headersSent = [];
public $headersSent = [];
public function setRealHeader(
public function setRealHeader(
string $header_string,
string $header_string,
bool $replace = true,
bool $replace = true,
int $response_code = 0
int $response_code = 0
): self {
): self {
$this->headersSent[] = $header_string;
$this->headersSent[] = $header_string;
return $this;
return $this;
}
}
};
};
});
});
$tmpfile = tmpfile();
$tmpfile = tmpfile();
fwrite($tmpfile, 'I am a teapot');
fwrite($tmpfile, 'I am a teapot');
$streamPath = stream_get_meta_data($tmpfile)['uri'];
$streamPath = stream_get_meta_data($tmpfile)['uri'];
$this->expectOutputString('I am a teapot');
$this->expectOutputString('I am a teapot');
$engine->download($streamPath, 'something.txt');
$engine->download($streamPath, 'something.txt');
$this->assertContains('Content-Disposition: attachment; filename="something.txt"', $engine->response()->headersSent);
$this->assertContains('Content-Disposition: attachment; filename="something.txt"', $engine->response()->headersSent);
}
}
public function testDownloadBadPath() {
public function testDownloadBadPath()
$engine = new Engine();
{
$this->expectException(Exception::class );
$engine = new Engine( );
$this->expectExceptionMessage("/path/to/nowhere cannot be found." );
$this->expectException(Exception::class );
$engine->download('/path/to/nowhere' );
$this->expectExceptionMessage("/path/to/nowhere cannot be found." );
}
$engine->download('/path/to/nowhere');
}
}
}