Skip to content

Commit

Permalink
Added value object tests
Browse files Browse the repository at this point in the history
  • Loading branch information
xperiandri committed Feb 15, 2024
1 parent da609d0 commit 4f7c34c
Show file tree
Hide file tree
Showing 7 changed files with 422 additions and 9 deletions.
1 change: 1 addition & 0 deletions Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,6 @@
<PackageReference Update="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.*" />
<PackageReference Update="Microsoft.NETCore.Platforms" Version="6.0.*" />
<PackageReference Update="Newtonsoft.Json" Version="13.*" />
<PackageReference Update="Validus" Version="4.1.*" />
</ItemGroup>
</Project>
10 changes: 5 additions & 5 deletions tests/FSharp.Data.GraphQL.Tests/ErrorHelpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,23 @@ let ensureRequestError (result : GQLExecutionResult) (onRequestError : GQLProble
| RequestError errors -> onRequestError errors
| response -> fail $"Expected RequestError GQLResponse but got {Environment.NewLine}{response}"

let ensureValidationError (message : string) (path : FieldPath) (error) =
let ensureValidationError (message : string) (path : FieldPath) (error : GQLProblemDetails) =
equals message error.Message
equals (Include path) error.Path
match error.Extensions with
| Skip -> fail "Expected extensions to be present"
| Include extensions ->
equals Validation (unbox extensions[CustomErrorFields.Kind])

let ensureExecutionError (message : string) (path : FieldPath) (error) =
let ensureExecutionError (message : string) (path : FieldPath) (error : GQLProblemDetails) =
equals message error.Message
equals (Include path) error.Path
match error.Extensions with
| Skip -> fail "Expected extensions to be present"
| Include extensions ->
equals Execution (unbox extensions[CustomErrorFields.Kind])

let ensureInputCoercionError (errorSource : ErrorSource) (message : string) (``type`` : string) (error) =
let ensureInputCoercionError (errorSource : ErrorSource) (message : string) (``type`` : string) (error : GQLProblemDetails) =
equals message error.Message
match error.Extensions with
| Skip -> fail "Expected extensions to be present"
Expand All @@ -56,7 +56,7 @@ let ensureInputCoercionError (errorSource : ErrorSource) (message : string) (``t
equals name (unbox extensions[CustomErrorFields.ArgumentName])
equals ``type`` (unbox extensions[CustomErrorFields.ArgumentType])

let ensureInputObjectFieldCoercionError (errorSource : ErrorSource) (message : string) (inputObjectPath : FieldPath) (objectType : string) (fieldType : string) (error) =
let ensureInputObjectFieldCoercionError (errorSource : ErrorSource) (message : string) (inputObjectPath : FieldPath) (objectType : string) (fieldType : string) (error : GQLProblemDetails) =
equals message error.Message
match error.Extensions with
| Skip -> fail "Expected extensions to be present"
Expand All @@ -70,7 +70,7 @@ let ensureInputObjectFieldCoercionError (errorSource : ErrorSource) (message : s
equals objectType (unbox extensions[CustomErrorFields.ObjectType])
equals fieldType (unbox extensions[CustomErrorFields.FieldType])

let ensureInputObjectValidationError (errorSource : ErrorSource) (message : string) (inputObjectPath : FieldPath) (objectType : string) (error) =
let ensureInputObjectValidationError (errorSource : ErrorSource) (message : string) (inputObjectPath : FieldPath) (objectType : string) (error : GQLProblemDetails) =
equals message error.Message
match error.Extensions with
| Skip -> fail "Expected extensions to be present"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="BenchmarkDotNet" />
<PackageReference Include="Validus" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.utility" />
<PackageReference Include="xunit.runner.visualstudio" />
Expand Down Expand Up @@ -51,6 +52,8 @@
<Compile Include="MutationTests.fs" />
<Compile Include="ResolveTests.fs" />
<Compile Include="Variables and Inputs\CoercionTests.fs" />
<Compile Include="Variables and Inputs\OptionalsNormalizationTests.ValidString.fs" />
<Compile Include="Variables and Inputs\OptionalsNormalizationTests.fs" />
<Compile Include="Variables and Inputs\InputRecordTests.fs" />
<Compile Include="Variables and Inputs\InputObjectValidatorTests.fs" />
<Compile Include="Variables and Inputs\InputScalarAndAutoFieldScalarTests.fs" />
Expand Down
6 changes: 3 additions & 3 deletions tests/FSharp.Data.GraphQL.Tests/Helpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ let asts query =
["defer"; "stream"]
|> Seq.map (query >> parse)

let set (mre : ManualResetEvent) =
let setEvent (mre : ManualResetEvent) =
mre.Set() |> ignore

let reset (mre : ManualResetEvent) =
let resetEvent (mre : ManualResetEvent) =
mre.Reset() |> ignore

let wait (mre : ManualResetEvent) errorMsg =
let waitEvent (mre : ManualResetEvent) errorMsg =
if TimeSpan.FromSeconds(float 30) |> mre.WaitOne |> not
then fail errorMsg

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// The MIT License (MIT)
/// Copyright (c) 2015-Mar 2016 Kevin Thompson @kthompson
// Copyright (c) 2015-Mar 2016 Kevin Thompson @kthompson
// Copyright (c) 2016 Bazinga Technologies Inc

[<UseInvariantCulture>]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// The MIT License (MIT)

namespace FSharp.Data.GraphQL.Tests.OptionalsNormalizationTests

open System
open FSharp.Data.GraphQL

[<Struct>]
type ValidString<'t> = internal ValidString of string
with
static member internal CreateVOption<'t> (value: string option) : ValidString<'t> voption =
value |> ValueOption.ofOption |> ValueOption.map ValidString

module ValidString =

let value (ValidString text) = text

let vOption strOption : string voption = strOption |> ValueOption.map value

let vOptionValue strOption : string = strOption |> ValueOption.map value |> ValueOption.toObj

open Validus
open Validus.Operators

module String =

let notStartsWithWhiteSpace fieldName (s: string) =
if s.StartsWith ' ' then
Error
<| ValidationErrors.create fieldName [ $"'%s{fieldName}' field cannot start with whitespace" ]
else
Ok <| s

let notEndsWithWhiteSpace fieldName (s: string) =
if s.EndsWith ' ' then
Error
<| ValidationErrors.create fieldName [ $"'%s{fieldName}' field cannot end with whitespace" ]
else
Ok <| s

let notContainsWhiteSpace fieldName (s: string) =
if s.Contains ' ' then
Error
<| ValidationErrors.create fieldName [ $"'%s{fieldName}' field cannot contain whitespace" ]
else
Ok <| s

let notContainsBacktick fieldName (s: string) =
if s.Contains '`' then
Error
<| ValidationErrors.create fieldName [ $"'%s{fieldName}' field cannot contain backtick" ]
else
Ok <| s

let notContainsTilde fieldName (s: string) =
if s.Contains '~' then
Error
<| ValidationErrors.create fieldName [ $"'%s{fieldName}' field cannot contain tilde" ]
else
Ok <| s

let notContainsDash fieldName (s: string) =
if s.Contains '-' then
Error
<| ValidationErrors.create fieldName [ $"'%s{fieldName}' field cannot contain dash: '-'" ]
else
Ok <| s

let notContainsUmlauts fieldName (s: string) =
let umlauts = [ 'ä'; 'ö'; 'ü'; 'ß'; 'Ä'; 'Ö'; 'Ü' ] |> set

let contains = s |> Seq.exists (fun c -> umlauts |> Set.contains c)

if contains then
Error
<| ValidationErrors.create fieldName [
$"'%s{fieldName}' field cannot contain umlauts: ä, ö, ü, ß, Ä, Ö, Ü"
]
else
Ok <| s

open Validus.Operators

let allowEmpty = ValueOption.ofObj >> ValueOption.filter (not << String.IsNullOrWhiteSpace)

let validateStringCharacters =
notStartsWithWhiteSpace
<+> notEndsWithWhiteSpace
<+> notContainsTilde
<+> notContainsUmlauts
<+> notContainsBacktick

module Uri =

let isValid fieldName uriString =
if Uri.IsWellFormedUriString(uriString, UriKind.Absolute) then
Ok uriString
else
Error
<| ValidationErrors.create fieldName [ $"'%s{fieldName}' field is not a valid URI" ]


//module VOptionString =

// let allow (validator : Validator<string, string>) : Validator<string voption, string voption> =
// fun fieldName (value : string voption) ->
// match value with
// | ValueNone -> Ok ValueNone
// | ValueSome str -> (validator *|* ValueSome) fieldName str

// let toValidationResult _ value : ValidationResult<string voption> =
// let valueOption =
// value
// |> ValueOption.ofObj
// |> ValueOption.filter (not << String.IsNullOrWhiteSpace)
// match valueOption with
// | ValueSome str -> ValueSome str |> Ok
// | ValueNone -> ValueNone |> Ok

module ValidationErrors =

let toIGQLErrors (errors: ValidationErrors) : IGQLError list =
errors
|> ValidationErrors.toList
|> List.map (fun e -> { new IGQLError with member _.Message = e })

module Operators =

let vOption (v1: 'a -> 'a voption) (v2: Validator<'a, 'b>) : Validator<'a, 'b voption> =
fun x y ->
let value = v1 y
match value with
| ValueSome value -> (v2 *|* ValueSome) x y
| ValueNone -> Ok ValueNone

let (?=>) v1 v2 = vOption v1 v2
let (?=<) v2 v1 = vOption v1 v2

module Scalars =

open System.Text.Json
open FSharp.Data.GraphQL.Ast
open FSharp.Data.GraphQL.Types
open FSharp.Data.GraphQL.Types.SchemaDefinitions.Errors

type Define with

static member ValidStringScalar<'t>(typeName, createValid : Validator<string, 't voption>, ?description: string) =
let createValid = createValid typeName
Define.WrappedScalar
(name = typeName,
coerceInput =
(function
| Variable e when e.ValueKind = JsonValueKind.String -> e.GetString() |> createValid |> Result.mapError ValidationErrors.toIGQLErrors
| InlineConstant (StringValue s) -> s |> createValid |> Result.mapError ValidationErrors.toIGQLErrors
| Variable e -> e.GetDeserializeError typeName
| InlineConstant value -> value.GetCoerceError typeName),
coerceOutput =
(function
| :? ('t voption) as x -> x |> string |> Some
| :? 't as x -> Some (string x)
| :? string as s -> s |> Some
| null -> None
| _ -> raise <| System.NotSupportedException ()),
?description = description)
Loading

0 comments on commit 4f7c34c

Please sign in to comment.