q      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopNone&'+-136;<=>?AFQSTV Use q instance for r Since 0.0.0.0 ByteString q! instance over the response body. Since 0.0.0.0 Equality as sy. This means that if two bodies are equal as JSON (e.g., insignificant whitespace difference) they are considered equal. Since 0.0.3.0  None&'+-136;<=>?AFQSTV !"#$%&'( "#,* !+)$%&'( !"#None&'+,-136;<=>?AFQSTV|/fThis is the core Servant-Quickcheck generator, which, when given a `Proxy API` will return a pair of t and `Gen a`, where a is a function from  to a . The t! is a weight for the QuickCheck uN function which ensures a random distribution across all endpoints in an API.1This function returns a QuickCheck `Gen a` when passed a servant API value, typically a `Proxy API`. The generator returned is a function that accepts a  and returns a v:, which can then be used to issue network requests. This wA type makes it easier to compare distinct APIs across different s./011/0DCBA@?>=<;:98765432/0None&'+-136;<=>?AFQSTVqG(A set of predicates. Construct one with x and \.K>A predicate that depends on both the request and the response. Since 0.0.0.0N.A predicate that depends only on the response. Since 0.0.0.0Q  Best Practice500 Internal Server Error should be avoided - it may represent some issue with the application code, and it moreover gives the client little indication of how to proceed or what went wrong.7This function checks that the response code is not 500. Since 0.0.0.0R OptionalvThis function checks that the response from the server does not take longer than the specified number of nanoseconds. Since 0.0.2.1S  Best Practice\Returning anything other than an object when returning JSON is considered bad practice, as: Tit is hard to modify the returned value while maintaining backwards compatibility0many older tools do not support top-level arraysewhether top-level numbers, booleans, or strings are valid JSON depends on what RFC you're going by/there are security issues with top-level arraysThis function checks that any application/jsonf responses only return JSON objects (and not arrays, strings, numbers, or booleans) at the top level. References:JSON Grammar: -https://tools.ietf.org/html/rfc7159#section-2RFC 7159 Section 2JSON Grammar: -https://tools.ietf.org/html/rfc4627#section-2RFC 4627 Section 2 Since 0.0.0.0TOptional?When creating a new resource, it is good practice to provide a Location- header with a link to the created resource. This function checks that every  201 Created response contains a LocationG header, and that the link in it responds with a 2XX response code to GET requests.This is considered optional because other means of linking to the resource (e.g. via the response body) are also acceptable; linking to the resource in some way is considered best practice. References: 201 Created: 1https://tools.ietf.org/html/rfc7231#section-6.3.2RFC 7231 Section 6.3.2Location header: 1https://tools.ietf.org/html/rfc7231#section-7.1.2RFC 7231 Section 7.1.2 Since 0.0.0.0U OptionalThe  Last-Modifiedp header represents the time a resource was last modified. It is used to drive caching and conditional requests./When using this mechanism, the server adds the  Last-Modified? header to responses. Clients may then make requests with the If-Modified-Since header to conditionally request resources. If the resource has not changed since that date, the server responds with a status code of 304 ( Not Modified) without a response body.The  Last-Modified2 header can also be used in conjunction with the If-Unmodified-Since( header to drive optimistic concurrency.The  Last-Modified date must be in RFC 822 format. References:304 Not Modified: /https://tools.ietf.org/html/rfc7232#section-4.1RFC 7232 Section 4.1Last-Modified header: /https://tools.ietf.org/html/rfc7232#section-2.2RFC 7232 Section 2.2If-Modified-Since header: /https://tools.ietf.org/html/rfc7232#section-3.3RFC 7232 Section 3.3If-Unmodified-Since header: /https://tools.ietf.org/html/rfc7232#section-3.4RFC 7232 Section 3.4 Date format: /https://tools.ietf.org/html/rfc2616#section-3.3RFC 2616 Section 3.3 Since 0.0.2.1V RFC ComplianceWhen an HTTP request has a method that is not allowed, a 405 response should be returned. Additionally, it is good practice to return an Allow* header with the list of allowed methods. This function checks that every 405 Method Not Allowed response contains an Allow- header with a list of standard HTTP methods. Note that servant# itself does not currently set the Allow headers. References:Allow header: 7https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.htmlRFC 2616 Section 14.7 Status 405: 7https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.htmlRFC 2616 Section 10.4.6Servant Allow header issue: 5https://github.com/haskell-servant/servant/issues/489 Issue #489 Since 0.0.0.0W RFC ComplianceWhen a request contains an Accepti header, the server must either return content in one of the requested representations, or respond with 406 Not Acceptable.<This function checks that every *successful* response has a  Content-Type header that matches the AcceptV header. It does *not* check that the server matches the quality descriptions of the Accept header correctly. References:Accept header: 7https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.htmlRFC 2616 Section 14.1 Since 0.0.0.0X  Best PracticeQWhether or not a representation should be cached, it is good practice to have a  Cache-Control header for GET= requests. If the representation should not be cached, used Cache-Control: no-cache.This function checks that GET responses have  Cache-Control? header. It does NOT currently check that the header is valid. References: Cache-Control header: /https://tools.ietf.org/html/rfc7234#section-5.2RFC 7234 Section 5.2 Since 0.0.0.0Y  Best PracticeLike X , but for HEAD requests. Since 0.0.0.0Z RFC ComplianceAny 401 Unauthorized response must include a WWW-Authenticate header.MThis function checks that, if a response has status code 401, it contains a WWW-Authenticate header. References:WWW-Authenticate header: /https://tools.ietf.org/html/rfc7235#section-4.1RFC 7235 Section 4.1 Since 0.0.0.0[ RFC ComplianceAn HTML.document will start with exactly this string: !DOCTYPEhtmlThis function checks that HTML documents (those with `Content-Type: text/html...`) include a DOCTYPE declaration at the top. We do not enforce capital case for the string DOCTYPE. References:HTML5 Doctype:  /https://tools.ietf.org/html/rfc7992#section-6.1RFC 7992 Section 6.1  Since 0.3.0.0\Adds a new predicate (either N or K) to the existing predicates. $not500 <%> onlyJsonObjects <%> empty Since 0.0.0.0EFGHJIKLMNOPQRSTUVWXYZ[\]^_`!QRSTUVWXYZ[NOPaKLMbGHIJcEFed\]^_`EFGHIJKLMNOP\6None"#&'+-136;<=>?AFQSTVxicStart a servant application on an open port, run the provided function, then stop the application. Since 0.0.0.0jLike i, but allows passing in a y to the application. Since 0.0.0.0k6Check that the two servers running under the provided BaseUrls behave identically by randomly generating arguments (captures, query params, request bodies, headers, etc.) expected by the server. If, given the same request, the response is not the same (according to the definition of == for the return datatype), the z$ fails, printing the counterexample.The IntF argument specifies maximum number of test cases to generate and run.|Evidently, if the behaviour of the server is expected to be non-deterministic, this function may produce spurious failuresNote that only valid requests are generated and tested. As an example of why this matters, let's say your API specifies that a particular endpoint can only generate JSON.  serversEqual. will then not generate any requests with an Accept header _other_ than application/jsonN. It may therefore fail to notice that one application, when the request has Accept: text/html , returns a 406 Not Acceptable' HTTP response, and another returns a  200 Success , but with application/json as the content-type.qThe fact that only valid requests are tested also means that no endpoints not listed in the API type are tested. Since 0.0.0.0l>Check that a server satisfies the set of properties specified.Note that, rather than having separate tests for each property you'd like to test, you should generally prefer to combine all properties into a single test. This enables a more parsimonious generation of requests and responses with the same testing depth.Example usage: TgoodAPISpec = describe "my server" $ do it "follows best practices" $ do withServantServer api server $ \burl -> serverSatisfies api burl stdArgs (not500 <%> onlyJsonObjects <%> notAllowedContainsAllowHeader <%> mempty) Since 0.0.0.0ijklmnoijklmno None&'+-136;<=>?AFQSTV9 !"#$%&'(/01EFGHIJKLMNOPQRSTUVWXYZ[\]^_`ijklmnoNone&'+-136;<=>?AFQSTVpp QuickCheck Args& with 1000 rather than 100 test cases. Since 0.0.0.01  GKLMNOPQRSTUVWXYZ[\ijklp1lQRSWVZUXYT[\GNOPKLMkijp  {       !"##$%&'()*+,,--./0123456789:;<=>?@ABCDEFGHIJKLMNOPQQRSTTUVVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~x {| 1servant-quickcheck-0.0.6.0-Jrx7pY5dAOmIbTPtlUTtciServant.QuickCheck$Servant.QuickCheck.Internal.Equality&Servant.QuickCheck.Internal.ErrorTypes)Servant.QuickCheck.Internal.HasGenRequest&Servant.QuickCheck.Internal.Predicates&Servant.QuickCheck.Internal.QuickCheckNetwork.Http.ClientRequestServant.QuickCheck.Internal(QuickCheck-2.10.1-BUFYQzp5Pjm7JbQeTzW89lTest.QuickCheck.Test maxShrinkschattymaxSizemaxDiscardRatio maxSuccessreplayArgsbase Data.ProxyProxy/servant-client-core-0.13-DCvzKzA1mBvGLqBbRwhkUX$Servant.Client.Core.Internal.BaseUrl baseUrlPath baseUrlPort baseUrlHost baseUrlSchemeBaseUrlHttpsHttpSchemeJsonEqdecode'jsonEqResponseEqualitygetResponseEquality allEquality bodyEquality jsonEqualitycompareDecodedResponses$fMonoidResponseEquality$fJsonEqByteString$fJsonEqByteString0ServerEqualityFailurePredicateFailure prettyHeaders prettyReq prettyRespprettyServerEqualityFailureprettyPredicateFailure$fExceptionPredicateFailure$fShowPredicateFailure$fShowServerEqualityFailure $fExceptionServerEqualityFailure$fGenericPredicateFailure$fGenericServerEqualityFailure HasGenRequest genRequest runGenRequest$fHasGenRequestTYPE:>#$fHasGenRequestTYPEWithNamedContext$fHasGenRequestTYPE:>0$fHasGenRequestTYPE:>1$fHasGenRequestTYPE:>2$fHasGenRequestTYPE:>3$fHasGenRequestTYPEVerb$fHasGenRequestTYPE:>4$fHasGenRequestTYPE:>5$fHasGenRequestTYPE:>6$fHasGenRequestTYPE:>7$fHasGenRequestTYPE:>8$fHasGenRequestTYPE:>9$fHasGenRequestTYPE:>10$fHasGenRequestTYPE:>11$fHasGenRequestTYPE:>12$fHasGenRequestTYPEEmptyAPI$fHasGenRequestTYPE:>13$fHasGenRequestTYPE:<|> JoinPreds joinPreds PredicatesrequestPredicatesresponsePredicatesRequestPredicategetRequestPredicateResponsePredicategetResponsePredicatenot500 notLongerThanonlyJsonObjectscreateContainsValidLocationgetsHaveLastModifiedHeadernotAllowedContainsAllowHeaderhonoursAcceptHeadergetsHaveCacheControlHeaderheadsHaveCacheControlHeader#unauthorizedContainsWWWAuthenticatehtmlIncludesDoctype<%>finishPredicateshasValidHeader isRFC822Date status2XX$fMonoidResponsePredicate$fMonoidRequestPredicate$fMonoidPredicates$fJoinPredsResponsePredicate$fJoinPredsRequestPredicate$fGenericResponsePredicate$fGenericRequestPredicate$fGenericPredicateswithServantServerwithServantServerAndContext serversEqualserverSatisfiesserverDoesntSatisfy noCheckStatus defManager defaultArgsghc-prim GHC.ClassesEq(http-client-0.5.10-z3FPJAmvFa8V113toNejoNetwork.HTTP.Client.TypesResponse$aeson-1.2.4.0-2PFSnZzAtgo7DzIZ8LAqCgData.Aeson.Types.InternalValue GHC.TypesIntTest.QuickCheck.Gen frequencyGenGHC.Basemempty*servant-server-0.13-BOZo8GLoTgf70i45LCW8jqServant.Server.Internal.ContextContext.hspec-expectations-0.8.2-u0Nf5sZGE0ADGpjIcTPpITest.Hspec.Expectations Expectation