Skip to content

Commit

Permalink
feat, refactor: application with bootstrapper
Browse files Browse the repository at this point in the history
- add karnel register appliaction bootstrapper
- add BootProvider: to call `Application::bootProvider`
- add RegisterProvider: to call `Application::registerProvider`
  • Loading branch information
SonyPradana committed May 17, 2024
1 parent 64404de commit 8546412
Show file tree
Hide file tree
Showing 10 changed files with 190 additions and 6 deletions.
39 changes: 35 additions & 4 deletions src/System/Integrate/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ final class Application extends Container
*/
private $isBooted = false;

/**
* Detect application has been bootstrapped.
*/
private bool $isBootstrapped = false;

/**
* Terminate callback register.
*
Expand Down Expand Up @@ -198,10 +203,6 @@ public function __construct(string $base_path)
// register base provider
$this->register(IntegrateServiceProvider::class);

// boot provider
$this->registerProvider();
$this->bootProvider();

// register container alias
$this->registerAlias();
}
Expand Down Expand Up @@ -829,8 +830,38 @@ public function isDev()
return $this->environment() === 'dev';
}

/**
* Detect appliaction has been booted.
*/
public function isBooted(): bool
{
return $this->isBooted;
}

/**
* Detect application has been bootstrapped.
*/
public function isBootstrapped(): bool
{
return $this->isBootstrapped;
}

// core region

/**
* Bootstrapper.
*
* @param array<int, class-string> $bootstrappers
*/
public function bootstrapWith($bootstrappers): void
{
$this->isBootstrapped = true;

foreach ($bootstrappers as $bootstrapper) {
$this->make($bootstrapper)->bootstrap($this);
}
}

/**
* Boot service provider.
*
Expand Down
15 changes: 15 additions & 0 deletions src/System/Integrate/Bootstrap/BootProviders.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace System\Integrate\Bootstrap;

use System\Integrate\Application;

class BootProviders
{
public function bootstrap(Application $app): void
{
$app->bootProvider();
}
}
15 changes: 15 additions & 0 deletions src/System/Integrate/Bootstrap/RegisterProviders.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace System\Integrate\Bootstrap;

use System\Integrate\Application;

class RegisterProviders
{
public function bootstrap(Application $app): void
{
$app->registerProvider();
}
}
21 changes: 21 additions & 0 deletions src/System/Integrate/Console/Karnel.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,23 @@

use System\Console\Style\Style;
use System\Container\Container;
use System\Integrate\Bootstrap\BootProviders;
use System\Integrate\Bootstrap\RegisterProviders;

class Karnel
{
/** @var Container */
protected $app;

/** @var int concole exit status */
protected $exit_code;

/** @var array<int, class-string> Apllication bootstrap register. */
protected array $bootstrappers = [
RegisterProviders::class,
BootProviders::class,
];

/**
* Set instance.
*
Expand All @@ -37,6 +46,8 @@ public function handle($arguments)
$baseArgs = $arguments[1] ?? '--help';
$commands = [];

$this->bootstrap();

foreach ($this->commands() as $cmd) {
$commands = array_merge($commands, $cmd->patterns(), $cmd->cmd());

Expand Down Expand Up @@ -81,6 +92,16 @@ public function handle($arguments)
return $this->exit_code = 1;
}

/**
* Register bootstraper application.
*/
public function bootstrap(): void
{
if (method_exists($this->app, 'bootstrapWith')) {
$this->app->{'bootstrapWith'}($this->bootstrappers);
}
}

/**
* Return similar from given array, compare with key.
*
Expand Down
20 changes: 20 additions & 0 deletions src/System/Integrate/Http/Karnel.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use System\Container\Container;
use System\Http\Request;
use System\Http\Response;
use System\Integrate\Bootstrap\BootProviders;
use System\Integrate\Bootstrap\RegisterProviders;
use System\Integrate\Exceptions\Handler;
use System\Integrate\Http\Middleware\MaintenanceMiddleware;
use System\Router\Router;
Expand All @@ -24,6 +26,12 @@ class Karnel
/** @var array<int, class-string> Middleware has register */
protected $middleware_used = [];

/** @var array<int, class-string> Apllication bootstrap register. */
protected array $bootstrappers = [
RegisterProviders::class,
BootProviders::class,
];

/**
* Set instance.
*
Expand All @@ -46,6 +54,8 @@ public function handle(Request $request)
$this->app->set(Request::class, $request);

try {
$this->bootstrap();

$dispatcher = $this->dispatcher($request);

$pipeline = array_reduce(
Expand All @@ -65,6 +75,16 @@ public function handle(Request $request)
return $response;
}

/**
* Register bootstraper application.
*/
public function bootstrap(): void
{
if (method_exists($this->app, 'bootstrapWith')) {
$this->app->{'bootstrapWith'}($this->bootstrappers);
}
}

/**
* Terminate Requesr and Response.
*/
Expand Down
23 changes: 23 additions & 0 deletions tests/Integrate/ApplicationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,21 @@ public function itCanAbortApplication()
(new Application(__DIR__))->abort(500);
}

/** @test */
public function itCanBootstrapWith()
{
$app = new Application(__DIR__);

ob_start();
$app->bootstrapWith([
TestBootstrapProvider::class,
]);
$out = ob_get_clean();

$this->assertEquals($out, 'TestBootstrapProvider::bootstrap');
$this->assertTrue($app->isBootstrapped());
}

/** @test */
public function itCanCallDeprecatedMethod()
{
Expand Down Expand Up @@ -238,3 +253,11 @@ private function defaultConfigs()
];
}
}

class TestBootstrapProvider
{
public function bootstrap(Application $app): void
{
echo __CLASS__ . '::' . __FUNCTION__;
}
}
20 changes: 20 additions & 0 deletions tests/Integrate/Bootstrap/BootProvidersTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace System\Integrate\Bootstrap;

use PHPUnit\Framework\TestCase;
use System\Integrate\Application;

class BootProvidersTest extends TestCase
{
public function testBootstrap(): void
{
$app = new Application(__DIR__);

$this->assertFalse($app->isBooted());
$app->bootstrapWith([BootProviders::class]);
$this->assertTrue($app->isBooted());
}
}
24 changes: 24 additions & 0 deletions tests/Integrate/Bootstrap/RegisterProvidersTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace System\Integrate\Bootstrap;

use PHPUnit\Framework\TestCase;
use System\Integrate\Application;
use System\Integrate\ServiceProvider;

class RegisterProvidersTest extends TestCase
{
public function testBootstrap(): void
{
$app = new Application(__DIR__);
$app->register(TestRegisterServiceProvider::class);
$app->bootstrapWith([BootProviders::class]);
$this->assertCount(2, (fn () => $this->{'looded_providers'})->call($app), '1 from defult provider, 1 from this test.');
}
}

class TestRegisterServiceProvider extends ServiceProvider
{
}
8 changes: 8 additions & 0 deletions tests/Integrate/Console/KarnelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,14 @@ public function itCanGivenClosetCommand()
$condition = Str::contains($out, 'use:full');
$this->assertTrue($condition);
}

/** @test */
public function itCanBootstrap()
{
$this->assertFalse($this->app->isBootstrapped());
$this->app->make(Karnel::class)->bootstrap();
$this->assertTrue($this->app->isBootstrapped());
}
}

class NormalCommand extends Karnel
Expand Down
11 changes: 9 additions & 2 deletions tests/Integrate/Http/KarnelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@

final class KarnelTest extends TestCase
{
private $app;
private Application $app;
private $karnel;
private $middleware;

protected function setUp(): void
{
Expand Down Expand Up @@ -80,4 +79,12 @@ public function itCanRedirectByMiddleware()
$test->__toString()
);
}

/** @test */
public function itCanBootstrap()
{
$this->assertFalse($this->app->isBootstrapped());
$this->app->make(Karnel::class)->bootstrap();
$this->assertTrue($this->app->isBootstrapped());
}
}

0 comments on commit 8546412

Please sign in to comment.