Skip to content

Commit

Permalink
Merge pull request #657 from tienvx/wrap-ffi-call-setup-pact-methods
Browse files Browse the repository at this point in the history
refactor: Wrap ffi call > setup pact methods
  • Loading branch information
tienvx authored Sep 27, 2024
2 parents f614d64 + d5d1465 commit 42d6aa8
Show file tree
Hide file tree
Showing 16 changed files with 341 additions and 68 deletions.
104 changes: 101 additions & 3 deletions helper/FFI/ClientTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
use PhpPact\Consumer\Driver\Exception\InteractionKeyNotSetException;
use PhpPact\Consumer\Driver\Exception\InteractionNotModifiedException;
use PhpPact\Consumer\Driver\Exception\InteractionPendingNotSetException;
use PhpPact\Consumer\Driver\Exception\PactFileNotWrittenException;
use PhpPact\Consumer\Driver\Exception\PactNotModifiedException;
use PhpPact\FFI\ClientInterface;
use PhpPact\Plugin\Exception\PluginNotLoadedException;
use PHPUnit\Framework\Constraint\Constraint;
use PHPUnit\Framework\Constraint\IsIdentical;
use PHPUnit\Framework\MockObject\MockObject;
Expand Down Expand Up @@ -152,7 +155,7 @@ protected function expectsGiven(int $interaction, string $name, bool $result): v
->willReturn($result);
if (!$result) {
$this->expectException(InteractionNotModifiedException::class);
$this->expectExceptionMessage("The interaction or Pact can't be modified (i.e. the mock server for it has already started)");
$this->expectExceptionMessage("The interaction can't be modified (i.e. the mock server for it has already started)");
}
}

Expand Down Expand Up @@ -180,7 +183,7 @@ protected function expectsGivenWithParam(int $interaction, string $name, array $
});
if (!$result) {
$this->expectException(InteractionNotModifiedException::class);
$this->expectExceptionMessage("The interaction or Pact can't be modified (i.e. the mock server for it has already started)");
$this->expectExceptionMessage("The interaction can't be modified (i.e. the mock server for it has already started)");
}
}

Expand All @@ -193,7 +196,7 @@ protected function expectsUponReceiving(int $interaction, string $description, b
->willReturn($result);
if (!$result) {
$this->expectException(InteractionNotModifiedException::class);
$this->expectExceptionMessage("The interaction or Pact can't be modified (i.e. the mock server for it has already started)");
$this->expectExceptionMessage("The interaction can't be modified (i.e. the mock server for it has already started)");
}
}

Expand Down Expand Up @@ -252,4 +255,99 @@ protected function expectsMessageGivenWithParam(int $message, string $name, arra
}
});
}

protected function expectsFreePactHandle(int $pact, int $result): void
{
$this->client
->expects($this->once())
->method('freePactHandle')
->with($pact)
->willReturn($result);
}

protected function expectsNewPact(string $consumer, string $provider, int $pact): void
{
$this->client
->expects($this->once())
->method('newPact')
->with($consumer, $provider)
->willReturn($pact);
}

protected function expectsWithSpecification(int $pact, int $specification, bool $result): void
{
$this->client
->expects($this->once())
->method('withSpecification')
->with($pact, $specification)
->willReturn($result);
if (!$result) {
$this->expectException(PactNotModifiedException::class);
$this->expectExceptionMessage("The pact can't be modified (i.e. the mock server for it has already started, or the version is invalid)");
}
}

protected function expectsInitWithLogLevel(?string $logLevel): void
{
if ($logLevel) {
$this->client
->expects($this->once())
->method('initWithLogLevel')
->with($logLevel);
} else {
$this->client
->expects($this->never())
->method('initWithLogLevel');
}
}

protected function expectsPactHandleWriteFile(int $pact, string $directory, bool $overwrite, int $result): void
{
$this->client
->expects($this->once())
->method('pactHandleWriteFile')
->with($pact, $directory, $overwrite)
->willReturn($result);
if ($result) {
$this->expectException(PactFileNotWrittenException::class);
$this->expectExceptionMessage(match ($result) {
1 => 'The function panicked.',
2 => 'The pact file was not able to be written.',
3 => 'The pact for the given handle was not found.',
default => 'Unknown error',
});
}
}

protected function expectsCleanupPlugins(int $pact): void
{
$this->client
->expects($this->once())
->method('cleanupPlugins')
->with($pact);
}

protected function expectsUsingPlugin(int $pact, string $name, ?string $version, int $result, bool $supported): void
{
if ($supported) {
$this->client
->expects($this->once())
->method('usingPlugin')
->with($pact, $name, $version)
->willReturn($result);
} else {
$this->client
->expects($this->never())
->method('usingPlugin');
}
if ($supported && $result) {
$this->expectException(PluginNotLoadedException::class);
$this->expectExceptionMessage(match ($result) {
1 => 'A general panic was caught.',
2 => 'Failed to load the plugin.',
3 => 'Pact Handle is not valid.',
default => 'Unknown error',
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ class InteractionNotModifiedException extends DriverException
{
public function __construct()
{
parent::__construct("The interaction or Pact can't be modified (i.e. the mock server for it has already started)");
parent::__construct("The interaction can't be modified (i.e. the mock server for it has already started)");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace PhpPact\Consumer\Driver\Exception;

class PactNotModifiedException extends DriverException
{
}
18 changes: 12 additions & 6 deletions src/PhpPact/Consumer/Driver/Pact/PactDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use PhpPact\Config\PactConfigInterface;
use PhpPact\Consumer\Driver\Exception\MissingPactException;
use PhpPact\Consumer\Driver\Exception\PactFileNotWrittenException;
use PhpPact\Consumer\Driver\Exception\PactNotModifiedException;
use PhpPact\Consumer\Model\Pact\Pact;
use PhpPact\FFI\ClientInterface;

Expand All @@ -22,15 +23,17 @@ public function __construct(
public function cleanUp(): void
{
$this->validatePact();
$this->client->call('pactffi_free_pact_handle', $this->pact->handle);
$success = $this->client->freePactHandle($this->pact->handle) === 0;
if (!$success) {
trigger_error('Can not free pact handle. The handle is not valid or does not refer to a valid Pact. Could be that it was previously deleted.', E_USER_WARNING);
}
$this->pact = null;
}

public function writePact(): void
{
$this->validatePact();
$error = $this->client->call(
'pactffi_pact_handle_write_file',
$error = $this->client->pactHandleWriteFile(
$this->pact->handle,
$this->config->getPactDir(),
$this->config->getPactFileWriteMode() === PactConfigInterface::MODE_OVERWRITE
Expand Down Expand Up @@ -89,17 +92,20 @@ private function initWithLogLevel(): void
{
$logLevel = $this->config->getLogLevel();
if ($logLevel) {
$this->client->call('pactffi_init_with_log_level', $logLevel);
$this->client->initWithLogLevel($logLevel);
}
}

private function newPact(): void
{
$this->pact = new Pact($this->client->call('pactffi_new_pact', $this->config->getConsumer(), $this->config->getProvider()));
$this->pact = new Pact($this->client->newPact($this->config->getConsumer(), $this->config->getProvider()));
}

private function withSpecification(): void
{
$this->client->call('pactffi_with_specification', $this->pact->handle, $this->getSpecification());
$success = $this->client->withSpecification($this->pact->handle, $this->getSpecification());
if (!$success) {
throw new PactNotModifiedException("The pact can't be modified (i.e. the mock server for it has already started, or the version is invalid)");
}
}
}
62 changes: 62 additions & 0 deletions src/PhpPact/FFI/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,68 @@ public function messageGivenWithParam(int $message, string $name, string $key, s
$this->call($method, $message, $name, $key, $value);
}

public function freePactHandle(int $pact): int
{
$method = 'pactffi_free_pact_handle';
$result = $this->call($method, $pact);
if (!is_int($result)) {
throw new InvalidResultException(sprintf('Invalid result of "%s". Expected "integer", but got "%s"', $method, get_debug_type($result)));
}
return $result;
}

public function newPact(string $consumer, string $provider): int
{
$method = 'pactffi_new_pact';
$result = $this->call($method, $consumer, $provider);
if (!is_int($result)) {
throw new InvalidResultException(sprintf('Invalid result of "%s". Expected "integer", but got "%s"', $method, get_debug_type($result)));
}
return $result;
}

public function withSpecification(int $pact, int $specification): bool
{
$method = 'pactffi_with_specification';
$result = $this->call($method, $pact, $specification);
if (!is_bool($result)) {
throw new InvalidResultException(sprintf('Invalid result of "%s". Expected "boolean", but got "%s"', $method, get_debug_type($result)));
}
return $result;
}

public function initWithLogLevel(string $logLevel): void
{
$method = 'pactffi_init_with_log_level';
$this->call($method, $logLevel);
}

public function pactHandleWriteFile(int $pact, string $directory, bool $overwrite): int
{
$method = 'pactffi_pact_handle_write_file';
$result = $this->call($method, $pact, $directory, $overwrite);
if (!is_int($result)) {
throw new InvalidResultException(sprintf('Invalid result of "%s". Expected "integer", but got "%s"', $method, get_debug_type($result)));
}
return $result;
}

public function cleanupPlugins(int $pact): void
{
$method = 'pactffi_cleanup_plugins';
$this->call($method, $pact);
}

public function usingPlugin(int $pact, string $name, ?string $version): int
{
$method = 'pactffi_using_plugin';
$result = $this->call($method, $pact, $name, $version);
if (!is_int($result)) {
throw new InvalidResultException(sprintf('Invalid result of "%s". Expected "integer", but got "%s"', $method, get_debug_type($result)));
}
return $result;
}

public function getInteractionPartRequest(): int
{
return $this->getEnum('InteractionPart_Request');
Expand Down
14 changes: 14 additions & 0 deletions src/PhpPact/FFI/ClientInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,20 @@ public function messageGiven(int $message, string $name): void;

public function messageGivenWithParam(int $message, string $name, string $key, string $value): void;

public function freePactHandle(int $pact): int;

public function newPact(string $consumer, string $provider): int;

public function withSpecification(int $pact, int $specification): bool;

public function initWithLogLevel(string $logLevel): void;

public function pactHandleWriteFile(int $pact, string $directory, bool $overwrite): int;

public function cleanupPlugins(int $pact): void;

public function usingPlugin(int $pact, string $name, ?string $version): int;

public function getInteractionPartRequest(): int;

public function getInteractionPartResponse(): int;
Expand Down
8 changes: 6 additions & 2 deletions src/PhpPact/Plugin/Driver/Pact/AbstractPluginPactDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
namespace PhpPact\Plugin\Driver\Pact;

use PhpPact\Consumer\Driver\Pact\PactDriver;
use PhpPact\Plugin\Exception\PluginNotLoadedException;
use PhpPact\Plugin\Exception\PluginNotSupportedBySpecificationException;

abstract class AbstractPluginPactDriver extends PactDriver
{
public function cleanUp(): void
{
$this->validatePact();
$this->client->call('pactffi_cleanup_plugins', $this->pact->handle);
$this->client->cleanupPlugins($this->pact->handle);
parent::cleanUp();
}

Expand All @@ -33,7 +34,10 @@ private function usingPlugin(): self
throw new PluginNotSupportedBySpecificationException($this->config->getPactSpecificationVersion());
}

$this->client->call('pactffi_using_plugin', $this->pact->handle, $this->getPluginName(), $this->getPluginVersion());
$error = $this->client->usingPlugin($this->pact->handle, $this->getPluginName(), $this->getPluginVersion());
if ($error) {
throw new PluginNotLoadedException($error);
}

return $this;
}
Expand Down
17 changes: 17 additions & 0 deletions src/PhpPact/Plugin/Exception/PluginNotLoadedException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace PhpPact\Plugin\Exception;

class PluginNotLoadedException extends PluginException
{
public function __construct(int $code)
{
$message = match ($code) {
1 => 'A general panic was caught.',
2 => 'Failed to load the plugin.',
3 => 'Pact Handle is not valid.',
default => 'Unknown error',
};
parent::__construct($message, $code);
}
}
2 changes: 1 addition & 1 deletion src/PhpPact/Standalone/ProviderVerifier/Verifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ private function setCustomHeaders(VerifierConfigInterface $config): void
private function setLogLevel(VerifierConfigInterface $config): void
{
if ($logLevel = $config->getLogLevel()) {
$this->client->call('pactffi_init_with_log_level', $logLevel);
$this->client->initWithLogLevel($logLevel);
}
}

Expand Down
Loading

0 comments on commit 42d6aa8

Please sign in to comment.