-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Aligned behavior using build #45
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -305,10 +305,14 @@ public function connect(Package $package): bool | |
throw new \Exception($error, 0, $this->lastError); | ||
} | ||
|
||
// Don't connect, if already booted or boot failed | ||
// Don't connect, if status is failed | ||
$failed = $this->statusIs(self::STATUS_FAILED); | ||
if ($failed || $this->statusIs(self::STATUS_BOOTED)) { | ||
$status = $failed ? 'errored' : 'booted'; | ||
// Don't allow connect if current package is already built | ||
if ($failed | ||
|| $this->statusIs(self::STATUS_INITIALIZED) // built | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same question as above: in the |
||
|| $this->statusIs(self::STATUS_BOOTED) // booted | ||
) { | ||
$status = $failed ? 'errored' : 'built_or_booted'; | ||
$error = "{$errorMessage} to a {$status} package."; | ||
do_action( | ||
$this->hookName(self::ACTION_FAILED_CONNECTION), | ||
|
@@ -330,14 +334,15 @@ static function () use ($package): Properties { | |
} | ||
); | ||
|
||
// If the other package is booted, we can obtain a container, otherwise | ||
// If the other package is built or booted, we can obtain a container, otherwise | ||
// we build a proxy container | ||
$container = $package->statusIs(self::STATUS_BOOTED) | ||
|| $package->statusIs(self::STATUS_INITIALIZED) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And again ssame question asked twice above. |
||
// || $package->statusIs(self::STATUS_READY) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this line commented? I think it makse sense to check for this status, and if we're sure it doesn't, the we should remove the line not comment it. |
||
? $package->container() | ||
: new PackageProxyContainer($package); | ||
|
||
$this->containerConfigurator->addContainer($container); | ||
|
||
do_action( | ||
$this->hookName(self::ACTION_PACKAGE_CONNECTED), | ||
$packageName, | ||
|
@@ -361,6 +366,9 @@ static function () use ($package): Properties { | |
*/ | ||
public function build(): Package | ||
{ | ||
if ($this->built) { | ||
return $this; | ||
} | ||
Comment on lines
+369
to
+371
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. First of all, I want to ask what is the reason for this lines. This allows for calling None of the other public API of this class ( So my questions are:
When we started this class, we thought about having specifc flags for different statuses (idle, ready, failed) but then we opted to have a single status property. Why is "built" a status special in this regard? Why can't we add a I already asked above: do we need to differentiate between
|
||
try { | ||
// Don't allow building the application multiple times. | ||
$this->assertStatus(self::STATUS_IDLE, 'build package'); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,6 +35,25 @@ public function testBasic(): void | |
static::assertEmpty($package->modulesStatus()[Package::MODULES_ALL]); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function testBasicUsingBuild(): void | ||
{ | ||
$expectedName = 'foo'; | ||
$propertiesStub = $this->mockProperties($expectedName); | ||
|
||
$package = Package::new($propertiesStub); | ||
|
||
static::assertTrue($package->statusIs(Package::STATUS_IDLE)); | ||
static::assertInstanceOf(Package::class, $package->build()); | ||
static::assertTrue($package->statusIs(Package::STATUS_INITIALIZED)); | ||
static::assertSame($expectedName, $package->name()); | ||
static::assertInstanceOf(Properties::class, $package->properties()); | ||
static::assertInstanceOf(ContainerInterface::class, $package->container()); | ||
static::assertEmpty($package->modulesStatus()[Package::MODULES_ALL]); | ||
} | ||
|
||
/** | ||
* @param string $suffix | ||
* @param string $baseName | ||
|
@@ -105,6 +124,32 @@ public function testBootWithEmptyModule(): void | |
static::assertFalse($package->boot()); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function testBuildWithEmptyModule(): void | ||
{ | ||
$expectedId = 'my-module'; | ||
|
||
$moduleStub = $this->mockModule($expectedId); | ||
$propertiesStub = $this->mockProperties('name', false); | ||
|
||
$package = Package::new($propertiesStub)->addModule($moduleStub); | ||
|
||
static::assertInstanceOf(Package::class, $package->build()); | ||
static::assertTrue($package->moduleIs($expectedId, Package::MODULE_NOT_ADDED)); | ||
static::assertFalse($package->moduleIs($expectedId, Package::MODULE_REGISTERED)); | ||
static::assertFalse($package->moduleIs($expectedId, Package::MODULE_REGISTERED_FACTORIES)); | ||
static::assertFalse($package->moduleIs($expectedId, Package::MODULE_EXTENDED)); | ||
static::assertFalse($package->moduleIs($expectedId, Package::MODULE_ADDED)); | ||
|
||
// build again should keep the status of the package. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've asked in another place, but here I also don't see a reasoning. Why it is important that we can call And again, I'm not necessarily againts this, I just want to understand what makes |
||
static::assertTrue($package->statusIs( Package::STATUS_INITIALIZED)); | ||
$package->build(); | ||
static::assertTrue($package->statusIs( Package::STATUS_INITIALIZED)); | ||
|
||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
|
@@ -127,6 +172,28 @@ public function testBootWithServiceModule(): void | |
static::assertTrue($package->container()->has($serviceId)); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function testBootWithServiceModuleUsingBuild(): void | ||
{ | ||
$moduleId = 'my-service-module'; | ||
$serviceId = 'service-id'; | ||
|
||
$module = $this->mockModule($moduleId, ServiceModule::class); | ||
$module->expects('services')->andReturn($this->stubServices($serviceId)); | ||
|
||
$package = Package::new($this->mockProperties())->addModule($module); | ||
|
||
static::assertInstanceOf(Package::class, $package->build()); | ||
static::assertFalse($package->moduleIs($moduleId, Package::MODULE_NOT_ADDED)); | ||
static::assertTrue($package->moduleIs($moduleId, Package::MODULE_REGISTERED)); | ||
static::assertFalse($package->moduleIs($moduleId, Package::MODULE_REGISTERED_FACTORIES)); | ||
static::assertFalse($package->moduleIs($moduleId, Package::MODULE_EXTENDED)); | ||
static::assertTrue($package->moduleIs($moduleId, Package::MODULE_ADDED)); | ||
static::assertTrue($package->container()->has($serviceId)); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
|
@@ -149,6 +216,28 @@ public function testBootWithFactoryModule(): void | |
static::assertTrue($package->container()->has($factoryId)); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function testBootWithFactoryModuleUsingBuild(): void | ||
{ | ||
$moduleId = 'my-factory-module'; | ||
$factoryId = 'factory-id'; | ||
|
||
$module = $this->mockModule($moduleId, FactoryModule::class); | ||
$module->expects('factories')->andReturn($this->stubServices($factoryId)); | ||
|
||
$package = Package::new($this->mockProperties())->addModule($module); | ||
|
||
static::assertInstanceOf(Package::class, $package->build()); | ||
static::assertFalse($package->moduleIs($moduleId, Package::MODULE_NOT_ADDED)); | ||
static::assertFalse($package->moduleIs($moduleId, Package::MODULE_REGISTERED)); | ||
static::assertTrue($package->moduleIs($moduleId, Package::MODULE_REGISTERED_FACTORIES)); | ||
static::assertFalse($package->moduleIs($moduleId, Package::MODULE_EXTENDED)); | ||
static::assertTrue($package->moduleIs($moduleId, Package::MODULE_ADDED)); | ||
static::assertTrue($package->container()->has($factoryId)); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
|
@@ -172,6 +261,29 @@ public function testBootWithExtendingModuleWithNonExistingService(): void | |
static::assertFalse($package->container()->has($extensionId)); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function testBuildWithExtendingModuleWithNonExistingService(): void | ||
{ | ||
$moduleId = 'my-extension-module'; | ||
$extensionId = 'extension-id'; | ||
|
||
$module = $this->mockModule($moduleId, ExtendingModule::class); | ||
$module->expects('extensions')->andReturn($this->stubServices($extensionId)); | ||
|
||
$package = Package::new($this->mockProperties())->addModule($module); | ||
|
||
static::assertInstanceOf(Package::class, $package->build()); | ||
static::assertFalse($package->moduleIs($moduleId, Package::MODULE_NOT_ADDED)); | ||
static::assertFalse($package->moduleIs($moduleId, Package::MODULE_REGISTERED)); | ||
static::assertFalse($package->moduleIs($moduleId, Package::MODULE_REGISTERED_FACTORIES)); | ||
static::assertTrue($package->moduleIs($moduleId, Package::MODULE_EXTENDED)); | ||
static::assertTrue($package->moduleIs($moduleId, Package::MODULE_ADDED)); | ||
// false because extending a service not in container | ||
static::assertFalse($package->container()->has($extensionId)); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
|
@@ -195,6 +307,29 @@ public function testBootWithExtendingModuleWithExistingService(): void | |
static::assertTrue($package->container()->has($serviceId)); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
public function testBuildWithExtendingModuleWithExistingService(): void | ||
{ | ||
$moduleId = 'my-extension-module'; | ||
$serviceId = 'service-id'; | ||
|
||
$module = $this->mockModule($moduleId, ServiceModule::class, ExtendingModule::class); | ||
$module->expects('services')->andReturn($this->stubServices($serviceId)); | ||
$module->expects('extensions')->andReturn($this->stubServices($serviceId)); | ||
|
||
$package = Package::new($this->mockProperties())->addModule($module); | ||
|
||
static::assertInstanceOf(Package::class, $package->build()); | ||
static::assertFalse($package->moduleIs($moduleId, Package::MODULE_NOT_ADDED)); | ||
static::assertTrue($package->moduleIs($moduleId, Package::MODULE_REGISTERED)); | ||
static::assertFalse($package->moduleIs($moduleId, Package::MODULE_REGISTERED_FACTORIES)); | ||
static::assertTrue($package->moduleIs($moduleId, Package::MODULE_EXTENDED)); | ||
static::assertTrue($package->moduleIs($moduleId, Package::MODULE_ADDED)); | ||
static::assertTrue($package->container()->has($serviceId)); | ||
} | ||
|
||
/** | ||
* @test | ||
*/ | ||
|
@@ -497,6 +632,38 @@ public function testPackageConnection(): void | |
static::assertInstanceOf(\ArrayObject::class, $package2->container()->get('service_1')); | ||
} | ||
|
||
/** | ||
* Test we can connect services across packages. | ||
* | ||
* @test | ||
*/ | ||
public function testPackageConnectionWhenOnePackageIsBuiltAndTheOtherDont(): void | ||
{ | ||
$module1 = $this->mockModule('module_1', ServiceModule::class); | ||
$module1->expects('services')->andReturn($this->stubServices('service_1')); | ||
$package1 = Package::new($this->mockProperties('package_1', false)) | ||
->addModule($module1); | ||
|
||
$module2 = $this->mockModule('module_2', ServiceModule::class); | ||
$module2->expects('services')->andReturn($this->stubServices('service_2')); | ||
$package2 = Package::new($this->mockProperties('package_2', false)) | ||
->addModule($module2); | ||
|
||
Monkey\Actions\expectDone($package2->hookName(Package::ACTION_PACKAGE_CONNECTED)) | ||
->once() | ||
->with($package1->name(), Package::STATUS_IDLE, false); | ||
|
||
$package1->build(); | ||
|
||
$connected = $package2->connect($package1); | ||
$package2->build(); | ||
|
||
static::assertTrue($connected); | ||
static::assertSame(['package_1' => true], $package2->connectedPackages()); | ||
// retrieve a Package 1's service from Package 2's container. | ||
static::assertInstanceOf(\ArrayObject::class, $package2->container()->get('service_1')); | ||
} | ||
|
||
/** | ||
* Test we can not connect services when the package how call connect is booted. | ||
* | ||
|
@@ -535,6 +702,44 @@ function (\Throwable $throwable): void { | |
static::assertSame(['package_1' => false], $package2->connectedPackages()); | ||
} | ||
|
||
/** | ||
* Test we can not connect services when the package that calls connect() is built. | ||
* | ||
* @test | ||
*/ | ||
public function testPackageConnectionFailsIfBuiltWithDebugOff(): void | ||
{ | ||
$module1 = $this->mockModule('module_1', ServiceModule::class); | ||
$module1->expects('services')->andReturn($this->stubServices('service_1')); | ||
$package1 = Package::new($this->mockProperties('package_1', false)) | ||
->addModule($module1); | ||
|
||
$module2 = $this->mockModule('module_2', ServiceModule::class); | ||
$module2->expects('services')->andReturn($this->stubServices('service_2')); | ||
$package2 = Package::new($this->mockProperties('package_2', false)) | ||
->addModule($module2); | ||
|
||
$package1->build(); | ||
$package2->build(); | ||
|
||
Monkey\Actions\expectDone($package2->hookName(Package::ACTION_FAILED_CONNECTION)) | ||
->once() | ||
->with($package1->name(), \Mockery::type(\WP_Error::class)); | ||
|
||
Monkey\Actions\expectDone($package2->hookName(Package::ACTION_FAILED_BUILD)) | ||
->once() | ||
->whenHappen( | ||
function (\Throwable $throwable): void { | ||
$this->assertThrowableMessageMatches($throwable, 'failed connect.+?built'); | ||
} | ||
); | ||
|
||
$connected = $package2->connect($package1); | ||
|
||
static::assertFalse($connected); | ||
static::assertSame(['package_1' => false], $package2->connectedPackages()); | ||
} | ||
|
||
/** | ||
* Test we can not connect services when the package how call connect is booted. | ||
* | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to differentiate between
STATUS_INITIALIZED
and an eventual newSTATUS_BUILT
or we can say thatSTATUS_INITIALIZED
previsely means that package is built?In that second case, should we as an
STATUS_BUILT
as an alias forSTATUS_INITIALIZED
? And maybe even deprecate the latter?Alos, I see you have introduced the flag
built
in this commit, and you use it in thebuild()
method to check the status. If there's a good reason for doing that instead of checking the status, why don't do it as well here?