Refactor fluent interfaces

This commit is contained in:
Stef Heyenrath
2017-01-20 15:01:06 +01:00
parent 0d046daac5
commit 1b2d20fd69
15 changed files with 308 additions and 273 deletions

View File

@@ -28,7 +28,7 @@ namespace WireMock
/// The listener request.
/// </param>
/// <returns>
/// The <see cref="Request"/>.
/// The <see cref="AndPathRequest"/>.
/// </returns>
public RequestMessage Map(HttpListenerRequest listenerRequest)
{

View File

@@ -6,7 +6,7 @@ namespace WireMock.Matchers.Request
/// <summary>
/// The composite request matcher.
/// </summary>
public class RequestMessageCompositeMatcher : IRequestMatcher
public abstract class RequestMessageCompositeMatcher : IRequestMatcher
{
private readonly IEnumerable<IRequestMatcher> _requestMatchers;

View File

@@ -0,0 +1,6 @@
namespace WireMock.RequestBuilders
{
public interface IRequestBuilder : IUrlAndPathRequestBuilder
{
}
}

View File

@@ -0,0 +1,39 @@
using System;
using JetBrains.Annotations;
namespace WireMock.RequestBuilders
{
/// <summary>
/// IUrlAndPathRequestBuilder
/// </summary>
public interface IUrlAndPathRequestBuilder : IVerbRequestBuilder
{
/// <summary>
/// The with url.
/// </summary>
/// <param name="url">The url.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
IUrlAndPathRequestBuilder WithUrl([NotNull] string url);
/// <summary>
/// The with url.
/// </summary>
/// <param name="func">The url func.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
IUrlAndPathRequestBuilder WithUrl([NotNull] Func<string, bool> func);
/// <summary>
/// The with path.
/// </summary>
/// <param name="path">The path.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
IUrlAndPathRequestBuilder WithPath([NotNull] string path);
/// <summary>
/// The with path.
/// </summary>
/// <param name="func">The path func.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
IUrlAndPathRequestBuilder WithPath([NotNull] Func<string, bool> func);
}
}

View File

@@ -1,47 +1,32 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using JetBrains.Annotations;
using WireMock.Matchers;
using WireMock.Matchers.Request;
[module:
SuppressMessage("StyleCop.CSharp.ReadabilityRules",
"SA1101:PrefixLocalCallsWithThis",
Justification = "Reviewed. Suppression is OK here, as it conflicts with internal naming rules.")]
[module:
SuppressMessage("StyleCop.CSharp.ReadabilityRules",
"SA1126:PrefixCallsCorrectly",
Justification = "Reviewed. Suppression is OK here, as it conflicts with internal naming rules.")]
[module:
SuppressMessage("StyleCop.CSharp.NamingRules",
"SA1309:FieldNamesMustNotBeginWithUnderscore",
Justification = "Reviewed. Suppression is OK here, as it conflicts with internal naming rules.")]
[module:
SuppressMessage("StyleCop.CSharp.DocumentationRules",
"SA1633:FileMustHaveHeader",
Justification = "Reviewed. Suppression is OK here, as unknown copyright and company.")]
// ReSharper disable ArrangeThisQualifier
// ReSharper disable InconsistentNaming
namespace WireMock.RequestBuilders
{
/// <summary>
/// The requests.
/// </summary>
public class Request : RequestMessageCompositeMatcher, IVerbRequestBuilder
public class Request : RequestMessageCompositeMatcher, IRequestBuilder
{
/// <summary>
/// The _request matchers.
/// </summary>
private readonly IList<IRequestMatcher> _requestMatchers;
/// <summary>
/// Creates this instance.
/// </summary>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public static IRequestBuilder Create()
{
return new Request(new List<IRequestMatcher>());
}
/// <summary>
/// Initializes a new instance of the <see cref="Request"/> class.
/// </summary>
/// <param name="requestMatchers">
/// The request matchers.
/// </param>
/// <param name="requestMatchers">The request matchers.</param>
private Request(IList<IRequestMatcher> requestMatchers) : base(requestMatchers)
{
_requestMatchers = requestMatchers;
@@ -50,65 +35,45 @@ namespace WireMock.RequestBuilders
/// <summary>
/// The with url.
/// </summary>
/// <param name="url">
/// The url.
/// </param>
/// <returns>
/// The <see cref="IVerbRequestBuilder"/>.
/// </returns>
public static IVerbRequestBuilder WithUrl(string url)
/// <param name="url">The url.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
public IUrlAndPathRequestBuilder WithUrl(string url)
{
var specs = new List<IRequestMatcher> { new RequestMessageUrlMatcher(url) };
return new Request(specs);
_requestMatchers.Add(new RequestMessageUrlMatcher(url));
return this;
}
/// <summary>
/// The with url.
/// </summary>
/// <param name="func">
/// The url func.
/// </param>
/// <returns>
/// The <see cref="IVerbRequestBuilder"/>.
/// </returns>
public static IVerbRequestBuilder WithUrl(Func<string, bool> func)
/// <param name="func">The url func.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
public IUrlAndPathRequestBuilder WithUrl(Func<string, bool> func)
{
var specs = new List<IRequestMatcher> { new RequestMessageUrlMatcher(func) };
return new Request(specs);
_requestMatchers.Add(new RequestMessageUrlMatcher(func));
return this;
}
/// <summary>
/// The with path.
/// </summary>
/// <param name="path">
/// The path.
/// </param>
/// <returns>
/// The <see cref="IVerbRequestBuilder"/>.
/// </returns>
public static IVerbRequestBuilder WithPath(string path)
/// <param name="path">The path.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
public IUrlAndPathRequestBuilder WithPath(string path)
{
var specs = new List<IRequestMatcher> { new RequestMessagePathMatcher(path) };
return new Request(specs);
_requestMatchers.Add(new RequestMessagePathMatcher(path));
return this;
}
/// <summary>
/// The with path.
/// </summary>
/// <param name="func">
/// The path func.
/// </param>
/// <returns>
/// The <see cref="IVerbRequestBuilder"/>.
/// </returns>
public static IVerbRequestBuilder WithPath([NotNull] Func<string, bool> func)
/// <param name="func">The path func.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
public IUrlAndPathRequestBuilder WithPath(Func<string, bool> func)
{
var specs = new List<IRequestMatcher> { new RequestMessagePathMatcher(func) };
return new Request(specs);
_requestMatchers.Add(new RequestMessagePathMatcher(func));
return this;
}
/// <summary>
@@ -179,6 +144,12 @@ namespace WireMock.RequestBuilders
/// </returns>
public IHeadersRequestBuilder UsingAnyVerb()
{
var matchers = _requestMatchers.Where(m => m is RequestMessageVerbMatcher).ToList();
foreach (var matcher in matchers)
{
_requestMatchers.Remove(matcher);
}
return this;
}

View File

@@ -6,21 +6,21 @@ namespace WireMock.ResponseBuilders
/// <summary>
/// The BodyResponseBuilder interface.
/// </summary>
public interface IBodyResponseBuilder : IDelayResponseBuilder
public interface IBodyResponseBuilder : ITransformResponseBuilder
{
/// <summary>
/// The with body.
/// </summary>
/// <param name="body">The body.</param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithBody([NotNull] string body);
/// <returns>A <see cref="ITransformResponseBuilder"/>.</returns>
ITransformResponseBuilder WithBody([NotNull] string body);
/// <summary>
/// The with body as base64.
/// </summary>
/// <param name="bodyAsbase64">The body asbase64.</param>
/// <param name="encoding">The Encoding.</param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithBodyAsBase64([NotNull] string bodyAsbase64, [CanBeNull] Encoding encoding = null);
/// <returns>A <see cref="ITransformResponseBuilder"/>.</returns>
ITransformResponseBuilder WithBodyAsBase64([NotNull] string bodyAsbase64, [CanBeNull] Encoding encoding = null);
}
}

View File

@@ -10,12 +10,8 @@ namespace WireMock.ResponseBuilders
/// <summary>
/// The after delay.
/// </summary>
/// <param name="delay">
/// The delay.
/// </param>
/// <returns>
/// The <see cref="IResponseBuilder"/>.
/// </returns>
IResponseBuilder AfterDelay(TimeSpan delay);
/// <param name="delay">The delay.</param>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithDelay(TimeSpan delay);
}
}

View File

@@ -1,4 +1,6 @@
namespace WireMock.ResponseBuilders
using JetBrains.Annotations;
namespace WireMock.ResponseBuilders
{
/// <summary>
/// The HeadersResponseBuilder interface.
@@ -8,15 +10,9 @@
/// <summary>
/// The with header.
/// </summary>
/// <param name="name">
/// The name.
/// </param>
/// <param name="value">
/// The value.
/// </param>
/// <returns>
/// The <see cref="IResponseBuilder"/>.
/// </returns>
IResponseBuilder WithHeader(string name, string value);
/// <param name="name">The name.</param>
/// <param name="value">The value.</param>
/// <returns>The <see cref="IHeadersResponseBuilder"/>.</returns>
IHeadersResponseBuilder WithHeader([NotNull] string name, string value);
}
}

View File

@@ -3,7 +3,7 @@
/// <summary>
/// The ResponseBuilder interface.
/// </summary>
public interface IResponseBuilder : ITransformResponseBuilder
public interface IResponseBuilder : IStatusCodeResponseBuilder
{
}
}

View File

@@ -0,0 +1,40 @@
using System.Net;
namespace WireMock.ResponseBuilders
{
/// <summary>
/// The StatusCodeResponseBuilder interface.
/// </summary>
public interface IStatusCodeResponseBuilder : IHeadersResponseBuilder
{
/// <summary>
/// The with status code.
/// </summary>
/// <param name="code">
/// The code.
/// </param>
/// <returns>The <see cref="IHeadersResponseBuilder"/>.</returns>
IHeadersResponseBuilder WithStatusCode(int code);
/// <summary>
/// The with status code.
/// </summary>
/// <param name="code">
/// The code.
/// </param>
/// <returns>The <see cref="IHeadersResponseBuilder"/>.</returns>
IHeadersResponseBuilder WithStatusCode(HttpStatusCode code);
/// <summary>
/// The with Success status code (200).
/// </summary>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
IHeadersResponseBuilder WithSuccess();
/// <summary>
/// The with NotFound status code (404).
/// </summary>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
IHeadersResponseBuilder WithNotFound();
}
}

View File

@@ -3,14 +3,14 @@
/// <summary>
/// The BodyResponseBuilder interface.
/// </summary>
public interface ITransformResponseBuilder : IHeadersResponseBuilder
public interface ITransformResponseBuilder : IDelayResponseBuilder
{
/// <summary>
/// The with transformer.
/// </summary>
/// <returns>
/// The <see cref="IResponseBuilder"/>.
/// The <see cref="IDelayResponseBuilder"/>.
/// </returns>
IResponseBuilder WithTransformer();
IDelayResponseBuilder WithTransformer();
}
}

View File

@@ -1,45 +1,33 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using HandlebarsDotNet;
using JetBrains.Annotations;
using WireMock.Validation;
[module:
SuppressMessage("StyleCop.CSharp.ReadabilityRules",
"SA1101:PrefixLocalCallsWithThis",
Justification = "Reviewed. Suppression is OK here, as it conflicts with internal naming rules.")]
[module:
SuppressMessage("StyleCop.CSharp.NamingRules",
"SA1309:FieldNamesMustNotBeginWithUnderscore",
Justification = "Reviewed. Suppression is OK here, as it conflicts with internal naming rules.")]
[module:
SuppressMessage("StyleCop.CSharp.DocumentationRules",
"SA1633:FileMustHaveHeader",
Justification = "Reviewed. Suppression is OK here, as unknown copyright and company.")]
// ReSharper disable ArrangeThisQualifier
// ReSharper disable InconsistentNaming
namespace WireMock.ResponseBuilders
{
/// <summary>
/// The responses.
/// The Response.
/// </summary>
public class Response : IResponseBuilder
{
/// <summary>
/// The _response.
/// </summary>
private readonly ResponseMessage _responseMessage;
private TimeSpan _delay = TimeSpan.Zero;
private bool _useTransformer;
/// <summary>
/// The _delay.
/// Creates this instance.
/// </summary>
private TimeSpan _delay = TimeSpan.Zero;
private bool _useTransformer;
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
[PublicAPI]
public static IResponseBuilder Create([CanBeNull] ResponseMessage responseMessage = null)
{
var message = responseMessage ?? new ResponseMessage { StatusCode = (int) HttpStatusCode.OK };
return new Response(message);
}
/// <summary>
/// Initializes a new instance of the <see cref="Response"/> class.
@@ -47,42 +35,120 @@ namespace WireMock.ResponseBuilders
/// <param name="responseMessage">
/// The response.
/// </param>
public Response(ResponseMessage responseMessage)
private Response(ResponseMessage responseMessage)
{
_responseMessage = responseMessage;
}
/// <summary>
/// The with Success status code.
/// The with status code.
/// </summary>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
public static IResponseBuilder WithSuccess()
/// <param name="code">The code.</param>
/// <returns>A <see cref="IHeadersResponseBuilder"/>.</returns>\
[PublicAPI]
public IHeadersResponseBuilder WithStatusCode(int code)
{
return WithStatusCode(200);
}
/// <summary>
/// The with NotFound status code.
/// </summary>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
public static IResponseBuilder WithNotFound()
{
return WithStatusCode(404);
_responseMessage.StatusCode = code;
return this;
}
/// <summary>
/// The with status code.
/// </summary>
/// <param name="code">
/// The code.
/// </param>
/// <param name="code">The code.</param>
/// <returns>A <see cref="IHeadersResponseBuilder"/>.</returns>
[PublicAPI]
public IHeadersResponseBuilder WithStatusCode(HttpStatusCode code)
{
return WithStatusCode((int) code);
}
/// <summary>
/// The with Success status code (200).
/// </summary>
/// <returns></returns>
[PublicAPI]
public IHeadersResponseBuilder WithSuccess()
{
return WithStatusCode((int) HttpStatusCode.OK);
}
/// <summary>
/// The with NotFound status code (404).
/// </summary>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
[PublicAPI]
public IHeadersResponseBuilder WithNotFound()
{
return WithStatusCode((int)HttpStatusCode.NotFound);
}
/// <summary>
/// The with header.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="value">The value.</param>
/// <returns>The <see cref="IHeadersResponseBuilder"/>.</returns>
public IHeadersResponseBuilder WithHeader(string name, string value)
{
Check.NotNull(name, nameof(name));
_responseMessage.AddHeader(name, value);
return this;
}
/// <summary>
/// The with body.
/// </summary>
/// <param name="body">The body.</param>
/// <returns>A <see cref="ITransformResponseBuilder"/>.</returns>
public ITransformResponseBuilder WithBody(string body)
{
Check.NotNull(body, nameof(body));
_responseMessage.Body = body;
return this;
}
/// <summary>
/// The with body as base64.
/// </summary>
/// <param name="bodyAsbase64">The body asbase64.</param>
/// <param name="encoding">The Encoding.</param>
/// <returns>A <see cref="ITransformResponseBuilder"/>.</returns>
public ITransformResponseBuilder WithBodyAsBase64(string bodyAsbase64, Encoding encoding = null)
{
Check.NotNull(bodyAsbase64, nameof(bodyAsbase64));
_responseMessage.Body = (encoding ?? Encoding.UTF8).GetString(Convert.FromBase64String(bodyAsbase64));
return this;
}
/// <summary>
/// The with transformer.
/// </summary>
/// <returns>
/// The <see cref="IResponseBuilder"/>.
/// </returns>
public static IResponseBuilder WithStatusCode(int code)
public IDelayResponseBuilder WithTransformer()
{
var response = new ResponseMessage { StatusCode = code };
return new Response(response);
_useTransformer = true;
return this;
}
/// <summary>
/// The after delay.
/// </summary>
/// <param name="delay">
/// The delay.
/// </param>
/// <returns>
/// The <see cref="IProvideResponses"/>.
/// </returns>
public IResponseBuilder WithDelay(TimeSpan delay)
{
_delay = delay;
return this;
}
/// <summary>
@@ -120,81 +186,5 @@ namespace WireMock.ResponseBuilders
return _responseMessage;
}
/// <summary>
/// The with header.
/// </summary>
/// <param name="name">
/// The name.
/// </param>
/// <param name="value">
/// The value.
/// </param>
/// <returns>
/// The <see cref="IResponseBuilder"/>.
/// </returns>
public IResponseBuilder WithHeader(string name, string value)
{
_responseMessage.AddHeader(name, value);
return this;
}
/// <summary>
/// The with body.
/// </summary>
/// <param name="body">
/// The body.
/// </param>
/// <returns>
/// The <see cref="IResponseBuilder"/>.
/// </returns>
public IResponseBuilder WithBody(string body)
{
Check.NotNull(body, nameof(body));
_responseMessage.Body = body;
return this;
}
/// <summary>
/// The with body as base64.
/// </summary>
/// <param name="bodyAsbase64">The body asbase64.</param>
/// <param name="encoding"></param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
public IResponseBuilder WithBodyAsBase64(string bodyAsbase64, Encoding encoding = null)
{
Check.NotNull(bodyAsbase64, nameof(bodyAsbase64));
_responseMessage.Body = (encoding ?? Encoding.UTF8).GetString(Convert.FromBase64String(bodyAsbase64));
return this;
}
/// <summary>
/// The with transformer.
/// </summary>
/// <returns>
/// The <see cref="IResponseBuilder"/>.
/// </returns>
public IResponseBuilder WithTransformer()
{
_useTransformer = true;
return this;
}
/// <summary>
/// The after delay.
/// </summary>
/// <param name="delay">
/// The delay.
/// </param>
/// <returns>
/// The <see cref="IProvideResponses"/>.
/// </returns>
public IResponseBuilder AfterDelay(TimeSpan delay)
{
_delay = delay;
return this;
}
}
}
}