DiUS/pact-jvm — pull request #38 by kenbot (2014-05-18 05:17:40+00:00)
Title: Service refactor

Oh boy. Here we go.

MockProvider
-------------

MockServiceProvider becomes MockProvider, with a core interface of

def runAndClose(pact: Pact)(code: => Unit): Try[PactSessionResults]

In other words, "something that runs your (possibly failing) code against a Pact, and returns the session results".

The process of accumulating and classifying responses is handled by PactSession, which builds up a PactSessionResult, striking off expected interactions as they occur and identifying "close misses" that users will be interested in. This is a synchronous and pure functional mechanism.

StatefulMockProvider is a stateful implementation of MockProvider, that handles starting and stopping a server session, piping responses into an updated PactSession. It is (ostensibly) independent of the server implementation. This is now the only place that interaction verification is done; there is no longer a redundant second pass after the server session is finished.

UnfilteredMockProvider provides Unfiltered plumbing underneath StatefulProvider to make it really work. User code should be totally agnostic to the implementation; currently there is a DefaultMockProvider object that spits out StatefulMockProviders that are actually (for the time being) UnfilteredMockProviders under the hood.

ConsumerPactRunner
-------------
ConsumerPact becomes ConsumerPactRunner. It is the basic interface that testing frameworks use Pact through; it coordinates running a server, running code against it, writing pacts to disk and returning feedback in a user-friendly format.

PactGenerator
----------------
PactGeneration becomes PactGenerator. While still (unfortunately) using global mutable state to aggregate test results as they happen, the mutability has now been restricted to a single pointer; the rest (afaict) is pure functional up to the point when it gets written to disk.

Better result modelling
-------------------
The final result, as seen by the testing framework, is now

VerificationResult = PactVerified | PactMismatch(PactSessionResults) | PactError(Throwable).

At a lower level, the result of each interaction is modelled by

RequestMatch = FullRequestMatch(Interaction) | PartialRequestMatch(Map[Interaction, Seq[RequestPartMismatch]]) | RequestMismatch

RequestPartMismatch is more familar -- it can be StatusMismatch, HeaderMismatch, BodyMismatch, etc, etc. The Matching code returns an Option[RequestPartMismatch] for each thing.