Skip to content
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

Feature/add support and example messenger consumer using rust engine 380 #699

Closed
Changes from 1 commit
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
31bd379
Adding v3 and v4 message consumer tests
valkolovos May 16, 2024
c6dd880
created MessagePact, cleaned up the verify method to use interaction …
valkolovos May 16, 2024
2891e4a
removing write_message_file method as it is unecessary
valkolovos May 16, 2024
76e9ff2
lint cleanup
valkolovos May 22, 2024
1e62a37
lint cleanup
valkolovos May 22, 2024
d0daa48
revert change that shouldn't have been committed
valkolovos May 22, 2024
3d7dc66
moving message pact verification to interaction
valkolovos May 23, 2024
49f06ee
setting harder version on jsonpath_ng
valkolovos May 28, 2024
2e460f7
cleaning up ffi.py
valkolovos May 31, 2024
1645640
PR changes
valkolovos Jun 5, 2024
deec315
importing Self from typing_extensions for backwards compatibility
valkolovos Jun 5, 2024
9db0021
chore(examples): ensure docker compose is started
JP-Ellis Jun 6, 2024
9aef6b4
chore(examples): wait for servers to start
JP-Ellis Jun 6, 2024
dbcfe80
docs(examples): explain the purpose for fs class
JP-Ellis Jun 6, 2024
713e59d
chore(examples): remove redundant v3 in filename
JP-Ellis Jun 6, 2024
4070ecd
fix(examples): typing annotations
JP-Ellis Jun 6, 2024
cef8f21
chore(examples): silence deprecation warnings
JP-Ellis Jun 6, 2024
0f76c5f
refactor(v3): rename AsyncMessagePactResult to AsyncInteractionResult
JP-Ellis Jun 6, 2024
57d1a07
refactor(v3): merge Pact classes
JP-Ellis Jun 6, 2024
7bfa7b8
chore(v3): remove _pact_handle as it is never used
JP-Ellis Jun 6, 2024
07d413b
docs(v3): add some clarity about interaction parts
JP-Ellis Jun 6, 2024
a972986
docs(ffi): remove unnecessary safety message
JP-Ellis Jun 6, 2024
941f123
chore: use existing method
JP-Ellis Jun 6, 2024
7258455
chore(v3): minor refactor of with_contents
JP-Ellis Jun 6, 2024
dd4af8a
chore(v3): remove public reify
JP-Ellis Jun 6, 2024
8f0815d
chore(v3): use with_metadata_v2
JP-Ellis Jun 6, 2024
f79a20d
chore(v3): publicly export Pact and Verifier
JP-Ellis Jun 6, 2024
9326a90
chore(ffi): minor type/style fixes
JP-Ellis Jun 6, 2024
f777d0c
first pass at fixing tests
valkolovos Jun 11, 2024
ed26782
remove 'import pdb'
valkolovos Jun 11, 2024
4e13c37
chore(ffi): remove message handle
JP-Ellis Jun 11, 2024
1b14be1
chore(v3): add with_metadata
JP-Ellis Jun 12, 2024
73f82fc
style: use snake_case
JP-Ellis Jun 12, 2024
980565b
chore: remove with_content
JP-Ellis Jun 12, 2024
55b42ea
chore: remove interaction verify
JP-Ellis Jun 12, 2024
2d92f86
feat(ffi): use the new with_metadata
JP-Ellis Jun 12, 2024
e56f018
chore(ffi): add enum type alias
JP-Ellis Jun 16, 2024
aafeeda
chore: implement ffi
JP-Ellis Jun 16, 2024
466e107
feat(v3): implement interactions iterator
JP-Ellis Jun 16, 2024
ab3c02b
chore(v3): remove messages iterator
JP-Ellis Jun 16, 2024
5aaf1a7
feat(v3): add verify method for pact messages
JP-Ellis Jun 16, 2024
d64abb0
chore(v3): remove get_provider_states
JP-Ellis Jun 16, 2024
7ab24c8
fix(v3): various typing issues
JP-Ellis Jun 16, 2024
ee99af7
feat: optional freeing of memory
JP-Ellis Jun 18, 2024
d1c0d1b
chore(ffi): minor fixes and implementations
JP-Ellis Jun 18, 2024
5107a59
fix(ffi): ensure parent outline dependent objects
JP-Ellis Jun 18, 2024
d118431
feat(ffi): add `generate_contents` methods
JP-Ellis Jun 18, 2024
db2d343
feat(v3): add with_generators
JP-Ellis Jun 18, 2024
aeb2e95
chore(ffi): minor changes
JP-Ellis Jun 18, 2024
dccb863
feat(v3): add new exception types
JP-Ellis Jun 18, 2024
c3ddcd5
fix(v3): interactions iterator
JP-Ellis Jun 19, 2024
6f0eff6
chore(test): use named tuple more broadly
JP-Ellis Jun 19, 2024
cf6cfd7
refactor(test): v3 message consumer
JP-Ellis Jun 19, 2024
a9fa8f0
refactor(examples): v3 message consumer
JP-Ellis Jun 19, 2024
67f5322
fix(v3): typing issues
JP-Ellis Jun 19, 2024
654c904
feat(ffi): upgrade ffi library to v0.4.21
JP-Ellis Jun 19, 2024
999fb45
ci: add wheel target
JP-Ellis Jun 19, 2024
aed2e09
chore(v3): remove defunct test
JP-Ellis Jun 19, 2024
31b9ed4
refactor(tests): minor drying message consumer tests
JP-Ellis Jun 20, 2024
dd14a47
chore: ignore test outputs
JP-Ellis Jun 21, 2024
9e210f6
docs: fix discovery
JP-Ellis Jun 21, 2024
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
refactor(v3): merge Pact classes
From Pact V4, it is possible for a single Pact to mix different
interaction types; that is, to combine sync/async messages, and HTTP
interactions. As such, I think it is best to keep a single `Pact` class.

Signed-off-by: JP-Ellis <josh@jpellis.me>
JP-Ellis committed Jun 6, 2024

Verified

This commit was signed with the committer’s verified signature.
JP-Ellis JP-Ellis
commit 57d1a0782d4a8b072b83557b3e2a1ea10c82c35b
165 changes: 62 additions & 103 deletions src/pact/v3/pact.py
Original file line number Diff line number Diff line change
@@ -68,6 +68,7 @@
from typing import (
TYPE_CHECKING,
Any,
Generator,
Literal,
Set,
overload,
@@ -93,7 +94,7 @@
logger = logging.getLogger(__name__)


class BasePact:
class Pact:
"""
A Pact between a consumer and a provider.
@@ -293,6 +294,65 @@ def upon_receiving(
msg = f"Invalid interaction type: {interaction}"
raise ValueError(msg)

def serve( # noqa: PLR0913
self,
addr: str = "localhost",
port: int = 0,
transport: str = "http",
transport_config: str | None = None,
*,
raises: bool = True,
verbose: bool = True,
) -> PactServer:
"""
Return a mock server for the Pact.
This function configures a mock server for the Pact. The mock server
is then started when the Pact is entered into a `with` block:
```python
pact = Pact("consumer", "provider")
with pact.serve() as srv:
...
```
Args:
addr:
Address to bind the mock server to. Defaults to `localhost`.
port:
Port to bind the mock server to. Defaults to `0`, which will
select a random port.
transport:
Transport to use for the mock server. Defaults to `HTTP`.
transport_config:
Configuration for the transport. This is specific to the
transport being used and should be a JSON string.
raises:
Whether to raise an exception if there are mismatches between
the Pact and the server. If set to `False`, then the mismatches
must be handled manually.
verbose:
Whether or not to print the mismatches to the logger. This works
independently of `raises`.
Returns:
A [`PactServer`][pact.v3.pact.PactServer] instance.
"""
return PactServer(
self._handle,
addr,
port,
transport,
transport_config,
raises=raises,
verbose=verbose,
)

def messages(self) -> pact.v3.ffi.PactMessageIterator:
"""
Iterate over the messages in the Pact.
@@ -389,108 +449,7 @@ def write_file(
overwrite=overwrite,
)


class Pact(BasePact):
"""
A Pact between a consumer and a provider.
This class defines a Pact between a consumer and a provider. It is the
central class in Pact's framework, and is responsible for defining the
interactions between the two parties.
One `Pact` instance should be created for each provider that a consumer
interacts with. The methods on this class are used to define the broader
attributes of the Pact, such as the consumer and provider names, the Pact
specification, any plugins that are used, and any metadata that is attached
to the Pact.
Each interaction between the consumer and the provider is defined through
the [`upon_receiving`][pact.v3.pact.Pact.upon_receiving] method, which
returns a sub-class of [`Interaction`][pact.v3.interaction.Interaction].
"""

def serve( # noqa: PLR0913
self,
addr: str = "localhost",
port: int = 0,
transport: str = "http",
transport_config: str | None = None,
*,
raises: bool = True,
verbose: bool = True,
) -> PactServer:
"""
Return a mock server for the Pact.
This function configures a mock server for the Pact. The mock server
is then started when the Pact is entered into a `with` block:
```python
pact = Pact("consumer", "provider")
with pact.serve() as srv:
...
```
Args:
addr:
Address to bind the mock server to. Defaults to `localhost`.
port:
Port to bind the mock server to. Defaults to `0`, which will
select a random port.
transport:
Transport to use for the mock server. Defaults to `HTTP`.
transport_config:
Configuration for the transport. This is specific to the
transport being used and should be a JSON string.
raises:
Whether to raise an exception if there are mismatches between
the Pact and the server. If set to `False`, then the mismatches
must be handled manually.
verbose:
Whether or not to print the mismatches to the logger. This works
independently of `raises`.
Returns:
A [`PactServer`][pact.v3.pact.PactServer] instance.
"""
return PactServer(
self._handle,
addr,
port,
transport,
transport_config,
raises=raises,
verbose=verbose,
)

HttpPact = Pact


class MessagePact(BasePact):
"""
A Message Pact between a consumer and a provider.
This class defines a Pact between a consumer and a provider for an
asynchronous message pattern. It is the central class in Pact's framework,
and is responsible for defining the interactions between the two parties.
One `Pact` instance should be created for each provider that a consumer
interacts with. The methods on this class are used to define the broader
attributes of the Pact, such as the consumer and provider names, the Pact
specification, any plugins that are used, and any metadata that is attached
to the Pact.
Each interaction between the consumer and the provider is defined through
the [`upon_receiving`][pact.v3.pact.Pact.upon_receiving] method, which
returns a sub-class of [`Interaction`][pact.v3.interaction.Interaction].
"""

def get_provider_states(self) -> list[dict[str, Any]]:
def get_provider_states(self) -> Generator[dict[str, Any], Any, None]:
"""
Get the provider states for the interaction.