Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
b45e9c0
Use Rust FFI: Consumer
tienvx Dec 23, 2022
849efd5
Merge branch 'master' into use-rust-ffi-consumer
tienvx Jan 11, 2023
e1d49cc
Remove method BuilderInterface::writePact
tienvx Jan 11, 2023
0d7fe0a
Remove CHANGELOG.md. Add '@internal' to classes are not supposed to b…
tienvx Jan 15, 2023
0812b31
Add missing return type to method Matcher::regex
tienvx Jan 15, 2023
cf5144b
Add more details to UPGRADE-9.0.md
tienvx Jan 15, 2023
d20f1f5
Revert multiple values support in header and query parameter
tienvx Jan 16, 2023
7d57b25
Merge branch 'master' into use-rust-ffi-consumer
Feb 14, 2023
bb256ef
Support multiple values in header and query parameter
tienvx Mar 1, 2023
d6a9d0d
Update pact ffi library
tienvx Mar 1, 2023
ca46297
Rename method getCode to getHeader
tienvx Mar 2, 2023
39718b9
Revert breaking change that require to call createMockServer manually
tienvx Mar 12, 2023
ddc46e5
Remove composer/semver
tienvx Mar 2, 2023
5dae03a
Make sure every value of header and query parameter is string
tienvx Mar 14, 2023
52e9a99
Move exception message to exception
tienvx Mar 14, 2023
bff0f9b
Extract method getSpecification() to check for supporting plugin
tienvx Mar 14, 2023
312c45c
Extract, change visibility, and move methods to abstract class to sup…
tienvx Mar 14, 2023
e7675e6
Use Rust FFI: Support multiple provider states with params for intera…
tienvx Mar 7, 2023
1e0b409
Fix provider state without params not added
tienvx Mar 16, 2023
47b0a81
Remove jsonSerialize methods
tienvx Jan 5, 2023
2754f47
Rename pact to driver
tienvx Mar 17, 2023
18b85b2
Move log level config to trait for reusing
tienvx Mar 23, 2023
5a4b15f
Allow mock server write pact file
tienvx Mar 23, 2023
072cc93
Merge branch 'master' into use-rust-ffi-consumer
tienvx May 3, 2023
29b33ec
Revert removing semver
tienvx May 3, 2023
a0302bc
Extract services and helpers
tienvx May 4, 2023
7fbc58d
Make PR smaller
tienvx May 4, 2023
ff2120f
Extract drivers and factories
tienvx May 4, 2023
420f4c2
Extract set up method
tienvx May 5, 2023
7f472fe
Simplify default interaction registry factory
tienvx May 5, 2023
c87dd62
Move methods from AbstractDriver to InteractionDriver and rename
tienvx May 5, 2023
53cef3d
Group assertions together for better readability
tienvx May 5, 2023
d5a4b83
Remove condition to make code shorter
tienvx May 5, 2023
6cf8128
Update ffi library to 0.4.4
tienvx May 5, 2023
156f989
Remove not useful annotation
tienvx May 5, 2023
bd8b751
Rename ffi service and move it to FFI namespace
tienvx May 6, 2023
d41e1ac
Assign result to variable before asserting
tienvx May 8, 2023
cc7f14c
Change type hint from 'mixed' to 'string|array|null'
tienvx May 8, 2023
dfaa021
Add @throws annotation to setPactFileWriteMode() method declaration b…
tienvx May 8, 2023
693daad
Rename FFI Proxy to Client
tienvx May 8, 2023
d960221
Extract interaction part drivers
tienvx May 8, 2023
770e6e0
Extract interaction contents drivers
tienvx May 9, 2023
29f7b4c
Extract interaction part traits for reusing
tienvx May 9, 2023
768b772
Allow sub-class access properties
tienvx May 9, 2023
a96c56a
Move common code back to MockServer for reusing. Remove methods from …
tienvx May 9, 2023
264018a
Move code from registry to driver
tienvx May 9, 2023
3a3afda
Switch term 'Driver' <--> 'Registry'
tienvx May 10, 2023
02b7fc3
Merge branch 'master' into use-rust-ffi-consumer
tienvx May 11, 2023
1d6d39e
Inject driver factory into builder
tienvx May 12, 2023
f844be0
Revert namespace change
tienvx May 12, 2023
d5d14e8
Use Rust FFI: Message Consumer
tienvx Dec 28, 2022
6aad456
Use Rust FFI: Provider
tienvx Jan 2, 2023
e96453f
Use Rust FFI: Stub Server
tienvx Jan 3, 2023
6d19fa8
Use Rust FFI: Offload process
tienvx Jan 3, 2023
9dbbde1
Fix stub server always load pact files from pact broker
tienvx May 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Use Rust FFI: Message Consumer
  • Loading branch information
tienvx committed May 12, 2023
commit d5d14e8fee290b84255b5ca8fe093acf72f937aa
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,9 @@ $consumerMessage = new ExampleMessageConsumer();
$callback = [$consumerMessage, 'ProcessSong'];
$builder->setCallback($callback);

$builder->verify();
$verifyResult = $builder->verify();

$this->assertTrue($verifyResult);
```


Expand Down
4 changes: 2 additions & 2 deletions example/src/MessageConsumer/ExampleMessageConsumer.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@

class ExampleMessageConsumer
{
public function ProcessText($message)
public function ProcessText(string $message): object
{
$obj = \json_decode($message);
print ' [x] Processed ' . \print_r($obj->contents->text, true) . "\n";

return $obj;
}

public function ProcessSong($message)
public function ProcessSong(string $message): object
{
$obj = \json_decode($message);
print ' [x] Processed ' . \print_r($obj->contents->song, true) . "\n";
Expand Down
32 changes: 5 additions & 27 deletions example/tests/MessageConsumer/ExampleMessageConsumerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

namespace MessageConsumer;

require_once __DIR__ . '/../../src/MessageConsumer/ExampleMessageConsumer.php';

use Exception;
use PhpPact\Consumer\MessageBuilder;
use PhpPact\Config\PactConfigInterface;
Expand All @@ -28,18 +26,6 @@ public static function setUpBeforeClass(): void
->setPactDir(__DIR__ . '/../../output/');
}

public static function tearDownAfterClass(): void
{
parent::tearDownAfterClass();

// build out brokerHttpService as your example
/*
$brokerHttpService = new BrokerHttpClient(new GuzzleClient(), new Uri($pactBrokerUri));
$brokerHttpService->publishJson($json, $consumerVersion);
$brokerHttpService->tag($this->mockServerConfig->getConsumer(), $consumerVersion, $tag);
*/
}

/**
* @throws Exception
*/
Expand All @@ -53,7 +39,7 @@ public function testProcessText()
$metadata = ['queue'=>'wind cries', 'routing_key'=>'wind cries'];

$builder
->given('a message', ['foo'])
->given('a message', ['foo' => 'bar'])
->expectsToReceive('an alligator named Mary exists')
->withMetadata($metadata)
->withContent($contents);
Expand All @@ -63,11 +49,9 @@ public function testProcessText()
$callback = [$consumerMessage, 'ProcessText'];
$builder->setCallback($callback);

$hasException = false;

$builder->verify();
$verifyResult = $builder->verify();

$this->assertTrue(true, 'Expects to reach this true statement by running verify()');
$this->assertTrue($verifyResult);
}

/**
Expand All @@ -93,14 +77,8 @@ public function testProcessSong()
$callback = [$consumerMessage, 'ProcessSong'];
$builder->setCallback($callback);

$hasException = false;

try {
$builder->verify();
} catch (Exception $e) {
$hasException = true;
}
$verifyResult = $builder->verify();

$this->assertFalse($hasException, 'Expects verification to pass without exceptions being thrown');
$this->assertTrue($verifyResult);
}
}
59 changes: 59 additions & 0 deletions src/PhpPact/Consumer/AbstractMessageBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace PhpPact\Consumer;

use PhpPact\Consumer\Model\Message;

abstract class AbstractMessageBuilder implements BuilderInterface
{
protected Message $message;

public function __construct()
{
$this->message = new Message();
}

/**
* @param string $name what is given to the request
* @param array<string, string> $params for that request
* @param bool $overwrite clear pass states completely and start this array
*/
public function given(string $name, array $params = [], bool $overwrite = false): self
{
$this->message->setProviderState($name, $params, $overwrite);

return $this;
}

/**
* @param string $description what is received when the request is made
*/
public function expectsToReceive(string $description): self
{
$this->message->setDescription($description);

return $this;
}

/**
* @param array<string, string> $metadata what is the additional metadata of the message
*/
public function withMetadata(array $metadata): self
{
$this->message->setMetadata($metadata);

return $this;
}

/**
* Make the http request to the Mock Service to register the message. Content is required.
*
* @param mixed $contents required to be in the message
*/
public function withContent(mixed $contents): self
{
$this->message->setContents($contents);

return $this;
}
}
37 changes: 37 additions & 0 deletions src/PhpPact/Consumer/Driver/Interaction/MessageDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace PhpPact\Consumer\Driver\Interaction;

use PhpPact\Consumer\Driver\Pact\PactDriverInterface;
use PhpPact\Consumer\Model\Message;
use PhpPact\Consumer\Registry\Interaction\MessageRegistryInterface;
use PhpPact\FFI\ClientInterface;

class MessageDriver implements MessageDriverInterface
{
public function __construct(
private ClientInterface $client,
private PactDriverInterface $pactDriver,
private MessageRegistryInterface $messageRegistry
) {
}

public function reify(): string
{
return $this->client->call('pactffi_message_reify', $this->messageRegistry->getId());
}

public function writePactAndCleanUp(): bool
{
$this->pactDriver->writePact();
$this->pactDriver->cleanUp();

return true;
}

public function registerMessage(Message $message): void
{
$this->pactDriver->setUp();
$this->messageRegistry->registerMessage($message);
}
}
14 changes: 14 additions & 0 deletions src/PhpPact/Consumer/Driver/Interaction/MessageDriverInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace PhpPact\Consumer\Driver\Interaction;

use PhpPact\Consumer\Model\Message;

interface MessageDriverInterface
{
public function registerMessage(Message $message): void;

public function reify(): string;

public function writePactAndCleanUp(): bool;
}
24 changes: 24 additions & 0 deletions src/PhpPact/Consumer/Factory/MessageDriverFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace PhpPact\Consumer\Factory;

use PhpPact\Consumer\Driver\Interaction\MessageDriver;
use PhpPact\Consumer\Driver\Interaction\MessageDriverInterface;
use PhpPact\Consumer\Driver\Pact\PactDriver;
use PhpPact\Config\PactConfigInterface;
use PhpPact\Consumer\Registry\Interaction\MessageRegistry;
use PhpPact\Consumer\Registry\Pact\PactRegistry;
use PhpPact\FFI\Client;

class MessageDriverFactory implements MessageDriverFactoryInterface
{
public function create(PactConfigInterface $config): MessageDriverInterface
{
$client = new Client();
$pactRegistry = new PactRegistry($client);
$pactDriver = new PactDriver($client, $config, $pactRegistry);
$messageRegistry = new MessageRegistry($client, $pactRegistry);

return new MessageDriver($client, $pactDriver, $messageRegistry);
}
}
11 changes: 11 additions & 0 deletions src/PhpPact/Consumer/Factory/MessageDriverFactoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace PhpPact\Consumer\Factory;

use PhpPact\Config\PactConfigInterface;
use PhpPact\Consumer\Driver\Interaction\MessageDriverInterface;

interface MessageDriverFactoryInterface
{
public function create(PactConfigInterface $config): MessageDriverInterface;
}
88 changes: 14 additions & 74 deletions src/PhpPact/Consumer/MessageBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,27 @@

namespace PhpPact\Consumer;

use PhpPact\Consumer\Model\Message;
use PhpPact\Consumer\Driver\Interaction\MessageDriverInterface;
use PhpPact\Config\PactConfigInterface;
use PhpPact\Standalone\PactMessage\PactMessage;
use PhpPact\Consumer\Factory\MessageDriverFactory;
use PhpPact\Consumer\Factory\MessageDriverFactoryInterface;

/**
* Build a message and send it to the Ruby Standalone Mock Service
*/
class MessageBuilder implements BuilderInterface
class MessageBuilder extends AbstractMessageBuilder
{
protected PactMessage $pactMessage;

protected PactConfigInterface $config;
protected MessageDriverInterface $driver;

/**
* @var array<mixed, callable>
*/
protected array $callback;

private Message $message;

public function __construct(PactConfigInterface $config)
public function __construct(PactConfigInterface $config, ?MessageDriverFactoryInterface $driverFactory = null)
{
$this->config = $config;
$this->message = new Message();
$this->pactMessage = new PactMessage();
parent::__construct();
$this->driver = ($driverFactory ?? new MessageDriverFactory())->create($config);
}

/**
Expand All @@ -45,56 +41,14 @@ public function setCallback(callable $callback, ?string $description = null): se
return $this;
}

/**
* @param string $name what is given to the request
* @param array<string, string> $params for that request
* @param bool $overwrite clear pass states completely and start this array
*/
public function given(string $name, array $params = [], bool $overwrite = false): self
{
$this->message->setProviderState($name, $params, $overwrite);

return $this;
}

/**
* @param string $description what is received when the request is made
*/
public function expectsToReceive(string $description): self
{
$this->message->setDescription($description);

return $this;
}

/**
* @param array<string, string> $metadata what is the additional metadata of the message
*/
public function withMetadata(array $metadata): self
{
$this->message->setMetadata($metadata);

return $this;
}

/**
* Make the http request to the Mock Service to register the message. Content is required.
*
* @param mixed $contents required to be in the message
*/
public function withContent($contents): self
{
$this->message->setContents($contents);

return $this;
}

/**
* Run reify to create an example pact from the message (i.e. create messages from matchers)
*/
public function reify(): string
{
return $this->pactMessage->reify($this->message);
$this->driver->registerMessage($this->message);

return $this->driver->reify();
}

/**
Expand All @@ -107,18 +61,16 @@ public function verifyMessage(callable $callback, ?string $description = null):
{
$this->setCallback($callback, $description);

return $this->verify($description);
return $this->verify();
}

/**
* Verify the use of the pact by calling the callback
* It also calls finalize to write the pact
*
* @param null|string $description description of the pact and thus callback
*
* @throws \Exception if callback is not set
*/
public function verify(?string $description = null): bool
public function verify(): bool
{
if (\count($this->callback) < 1) {
throw new \Exception('Callbacks need to exist to run verify.');
Expand All @@ -133,21 +85,9 @@ public function verify(?string $description = null): bool
\call_user_func($callback, $pactJson);
}

return $this->writePact();
return $this->driver->writePactAndCleanUp();
} catch (\Exception $e) {
return false;
}
}

/**
* Write the Pact without deleting the interactions.
* @throws \JsonException
*/
public function writePact(): bool
{
// you do not want to save the reified json
$pactJson = \json_encode($this->message, JSON_THROW_ON_ERROR);

return $this->pactMessage->update($pactJson, $this->config->getConsumer(), $this->config->getProvider(), $this->config->getPactDir());
}
}
Loading