Skip to content

Commit

Permalink
Included and fixed FSharp.Data.GraphQL.Tests.Sql
Browse files Browse the repository at this point in the history
  • Loading branch information
xperiandri committed Nov 4, 2024
1 parent b904b04 commit b7cbcf9
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 159 deletions.
41 changes: 28 additions & 13 deletions FSharp.Data.GraphQL.sln
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{ED8079DD
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.GraphQL.Tests", "tests\FSharp.Data.GraphQL.Tests\FSharp.Data.GraphQL.Tests.fsproj", "{54AAFE43-FA5F-485A-AD40-0240165FC633}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Data.GraphQL.Tests.Sql", "tests\FSharp.Data.GraphQL.Tests.Sql\FSharp.Data.GraphQL.Tests.Sql.fsproj", "{AC3963FE-427B-4E49-A1BF-EA6B024B2CE8}"
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Data.GraphQL.Benchmarks", "tests\FSharp.Data.GraphQL.Benchmarks\FSharp.Data.GraphQL.Benchmarks.fsproj", "{A6A162DF-9FBB-4C2A-913F-FD5FED35A09B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{B0C25450-74BF-40C2-9E02-09AADBAE2C2F}"
Expand Down Expand Up @@ -210,6 +212,18 @@ Global
{225B0790-C6B6-425C-9093-F359A4C635D3}.Release|x64.Build.0 = Release|Any CPU
{225B0790-C6B6-425C-9093-F359A4C635D3}.Release|x86.ActiveCfg = Release|Any CPU
{225B0790-C6B6-425C-9093-F359A4C635D3}.Release|x86.Build.0 = Release|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Debug|x64.ActiveCfg = Debug|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Debug|x64.Build.0 = Debug|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Debug|x86.ActiveCfg = Debug|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Debug|x86.Build.0 = Debug|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Release|Any CPU.Build.0 = Release|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Release|x64.ActiveCfg = Release|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Release|x64.Build.0 = Release|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Release|x86.ActiveCfg = Release|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Release|x86.Build.0 = Release|Any CPU
{6768EA38-1335-4B8E-BC09-CCDED1F9AAF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6768EA38-1335-4B8E-BC09-CCDED1F9AAF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6768EA38-1335-4B8E-BC09-CCDED1F9AAF6}.Debug|x64.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -342,18 +356,18 @@ Global
{A6A162DF-9FBB-4C2A-913F-FD5FED35A09B}.Release|x64.Build.0 = Release|Any CPU
{A6A162DF-9FBB-4C2A-913F-FD5FED35A09B}.Release|x86.ActiveCfg = Release|Any CPU
{A6A162DF-9FBB-4C2A-913F-FD5FED35A09B}.Release|x86.Build.0 = Release|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Debug|x64.ActiveCfg = Debug|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Debug|x64.Build.0 = Debug|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Debug|x86.ActiveCfg = Debug|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Debug|x86.Build.0 = Debug|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Release|Any CPU.Build.0 = Release|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Release|x64.ActiveCfg = Release|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Release|x64.Build.0 = Release|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Release|x86.ActiveCfg = Release|Any CPU
{C24EB38E-326C-4770-BB20-9838694EE5E6}.Release|x86.Build.0 = Release|Any CPU
{AC3963FE-427B-4E49-A1BF-EA6B024B2CE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AC3963FE-427B-4E49-A1BF-EA6B024B2CE8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AC3963FE-427B-4E49-A1BF-EA6B024B2CE8}.Debug|x64.ActiveCfg = Debug|Any CPU
{AC3963FE-427B-4E49-A1BF-EA6B024B2CE8}.Debug|x64.Build.0 = Debug|Any CPU
{AC3963FE-427B-4E49-A1BF-EA6B024B2CE8}.Debug|x86.ActiveCfg = Debug|Any CPU
{AC3963FE-427B-4E49-A1BF-EA6B024B2CE8}.Debug|x86.Build.0 = Debug|Any CPU
{AC3963FE-427B-4E49-A1BF-EA6B024B2CE8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AC3963FE-427B-4E49-A1BF-EA6B024B2CE8}.Release|Any CPU.Build.0 = Release|Any CPU
{AC3963FE-427B-4E49-A1BF-EA6B024B2CE8}.Release|x64.ActiveCfg = Release|Any CPU
{AC3963FE-427B-4E49-A1BF-EA6B024B2CE8}.Release|x64.Build.0 = Release|Any CPU
{AC3963FE-427B-4E49-A1BF-EA6B024B2CE8}.Release|x86.ActiveCfg = Release|Any CPU
{AC3963FE-427B-4E49-A1BF-EA6B024B2CE8}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -363,6 +377,7 @@ Global
{78D10788-601D-4D53-808B-36661911EDD1} = {56640EAF-82A6-4439-AD14-69F44A90DA99}
{B837B3ED-83CE-446F-A4E5-44CB06AA6505} = {B0C25450-74BF-40C2-9E02-09AADBAE2C2F}
{225B0790-C6B6-425C-9093-F359A4C635D3} = {B0C25450-74BF-40C2-9E02-09AADBAE2C2F}
{C24EB38E-326C-4770-BB20-9838694EE5E6} = {B0C25450-74BF-40C2-9E02-09AADBAE2C2F}
{6768EA38-1335-4B8E-BC09-CCDED1F9AAF6} = {BEFD8748-2467-45F9-A4AD-B450B12D5F78}
{474179D3-0090-49E9-88F8-2971C0966077} = {BEFD8748-2467-45F9-A4AD-B450B12D5F78}
{554A6833-1E72-41B4-AAC1-C19371EC061B} = {BEFD8748-2467-45F9-A4AD-B450B12D5F78}
Expand All @@ -385,7 +400,7 @@ Global
{A8F031E0-2BD5-4BAE-830A-60CBA76A047D} = {600D4BE2-FCE0-4684-AC6F-2DC829B395BA}
{6EEA0E79-693F-4D4F-B55B-DB0C64EBDA45} = {600D4BE2-FCE0-4684-AC6F-2DC829B395BA}
{7AA3516E-60F5-4969-878F-4E3DCF3E63A3} = {A8F031E0-2BD5-4BAE-830A-60CBA76A047D}
{C24EB38E-326C-4770-BB20-9838694EE5E6} = {B0C25450-74BF-40C2-9E02-09AADBAE2C2F}
{AC3963FE-427B-4E49-A1BF-EA6B024B2CE8} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C5B9895C-9DF8-4557-8D44-7D0C4C31F86E}
Expand Down
1 change: 1 addition & 0 deletions Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
<PackageReference Update="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.*" />
<PackageReference Update="Microsoft.NETCore.Platforms" Version="6.0.*" />
<PackageReference Update="Newtonsoft.Json" Version="13.*" />
<PackageReference Update="SQLProvider" Version="1.4.*" />
<PackageReference Update="System.Data.Common" Version="4.3.0" />
<PackageReference Update="Thoth.Json.Net" Version="12.0.0" />
<PackageReference Update="Validus" Version="4.1.*" />
Expand Down
24 changes: 12 additions & 12 deletions src/FSharp.Data.GraphQL.Server/Linq.fs
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ type Track =
type Tracker =
/// Leaf of the tree. Marks a direct field/property access with no sub-trees.
/// Consists of <see cref="Track"/> record and (neglible in this case) list of arguments.
| Direct of Track * Arg list
| Direct of Track * Arg Set
/// Marks branched field/property access - property value withh possible sub-trees.
/// Consists of <see cref="Track"/> record list of arguments used to parametrize GraphQL
/// field definition and set of subtrees.
| Compose of Track * Arg list * Set<Tracker>
| Compose of Track * Arg Set * Tracker Set
member x.Track =
match x with
| Direct(track, _) -> track
Expand Down Expand Up @@ -134,7 +134,7 @@ type CallableArg =
Argument: Arg
/// List of all other arguments resolved as part of other possible
/// applications on the current property track.
AllArguments: Arg list
AllArguments: Arg Set
/// Track describing field or property access.
Track: Track
/// Source type of the property - in case when track returns a collection or option,
Expand Down Expand Up @@ -219,7 +219,7 @@ let private applyFirst: ArgApplication = fun expression callable ->
let orderBy = methods.OrderBy.MakeGenericMethod [| tSource; idAccess.ReturnType |]
let ordered = Expression.Call(null, orderBy, expression, idAccess)

let afterOption = callable.AllArguments |> List.tryFind (fun a -> a.Name = "after")
let afterOption = callable.AllArguments |> Seq.tryFind (fun a -> a.Name = "after")
let result =
match afterOption with
| Some(after) ->
Expand All @@ -244,7 +244,7 @@ let private applyLast: ArgApplication = fun expression callable ->
let orderByDesc = methods.OrderByDesc.MakeGenericMethod [| tSource; idAccess.ReturnType |]
let ordered = Expression.Call(null, orderByDesc, expression, idAccess)

let beforeOption = callable.AllArguments |> List.tryFind (fun a -> a.Name = "after")
let beforeOption = callable.AllArguments |> Seq.tryFind (fun a -> a.Name = "after")
let result =
match beforeOption with
| Some(before) ->
Expand All @@ -262,13 +262,13 @@ let private applyLast: ArgApplication = fun expression callable ->
/// from a given ExecutionInfo and variables collection
let private linqArgs vars info =
let argDefs = info.Definition.Args
if Array.isEmpty argDefs then []
if Array.isEmpty argDefs then Set.empty
else
let args = info.Ast.Arguments
argDefs
|> Array.map (fun a -> (a.Name, a, args |> List.tryFind (fun x -> x.Name = a.Name)))
|> Array.choose (resolveLinqArg vars)
|> Array.toList
|> Seq.map (fun a -> (a.Name, a, args |> List.tryFind (fun x -> x.Name = a.Name)))
|> Seq.choose (resolveLinqArg vars)
|> Set.ofSeq

let rec private track set e =
match e with
Expand Down Expand Up @@ -388,7 +388,7 @@ let rec private infoComposer (root: Tracker) (allTracks: Set<Tracker>) : Set<Tra
|> Set.filter (fun track ->
match track with
| Direct (track, _) -> canJoin grandpaType track.ParentType && isOwn track
| x -> failwith <| sprintf "Expected Direct Track, but got %A" x)
| x -> failwithf "Expected Direct Track, but got %A" x)
if Set.isEmpty members
then root |> Set.singleton
else
Expand Down Expand Up @@ -426,7 +426,7 @@ let rec private getTracks alreadyFound info =
| _ -> failwith <| sprintf "Unexpected Resolve Definition Expression!"
let tracks =
track Set.empty expr
|> Set.map(fun track -> Direct(track, []))
|> Set.map(fun track -> Direct(track, Set.empty))
|> flip Set.difference alreadyFound
match info.Kind with
| ResolveDeferred inner -> getTracks alreadyFound inner
Expand Down Expand Up @@ -568,7 +568,7 @@ and private constructCollection argApplicators tracker (inParam: Expression) : E
Expression.Convert(inParam, methods.Type.MakeGenericType [| tSource |]),
// `mapFunc` param - (p0 => body )
Expression.Lambda(body, p0))
let final = args |> List.fold (fun acc (arg: Arg) ->
let final = args |> Set.fold (fun acc (arg: Arg) ->
match Map.tryFind (arg.Name.ToLowerInvariant()) argApplicators with
| Some apply -> apply acc { AllArguments = args; Argument = arg; Track = track; Fields = fields; Type = tSource }
| None -> acc) call
Expand Down
41 changes: 0 additions & 41 deletions tests/FSharp.Data.GraphQL.Tests.Sql/AssemblyInfo.fs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="FSharp.NET.Sdk;Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net47</TargetFrameworks>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<TargetFramework>$(DotNetVersion)</TargetFramework>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateProgramFile>false</GenerateProgramFile>
<OutputType>Exe</OutputType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
</PropertyGroup>

<ItemGroup>
<Compile Include="AssemblyInfo.fs" />
<Compile Include="Helpers.fs" />
<Compile Include="LinqToSqlTests.fs" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="BenchmarkDotNet" />
<PackageReference Include="SQLProvider" />
<PackageReference Include="Validus" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.utility" />
<PackageReference Include="xunit.runner.visualstudio" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="FSharp.NET.Sdk" Version="1.0.*" PrivateAssets="All" />
<Compile Include="Helpers.fs" />
<Compile Include="LinqToSqlTests.fs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\FSharp.Data.GraphQL.Shared\FSharp.Data.GraphQL.Shared.fsproj" />
<ProjectReference Include="..\..\src\FSharp.Data.GraphQL.Server\FSharp.Data.GraphQL.Server.fsproj" />
</ItemGroup>
<Import Project="..\..\.paket\Paket.Restore.targets" />
</Project>
31 changes: 14 additions & 17 deletions tests/FSharp.Data.GraphQL.Tests.Sql/Helpers.fs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// The MIT License (MIT)
/// Copyright (c) 2016 Bazinga Technologies Inc
// The MIT License (MIT)
// Copyright (c) 2016 Bazinga Technologies Inc
[<AutoOpen>]
module Helpers

Expand All @@ -11,26 +11,23 @@ open FSharp.Data.GraphQL.Types
open FSharp.Data.GraphQL.Types.Introspection
open FSharp.Data.GraphQL.Execution

let equals (expected : 'x) (actual : 'x) =
Assert.True((actual = expected), sprintf "expected %+A\nbut got %+A" expected actual)
let noErrors (result: IDictionary<string, obj>) =
match result.TryGetValue("errors") with
let equals (expected : 'x) (actual : 'x) =
Assert.True ((actual = expected), sprintf "expected %+A\nbut got %+A" expected actual)
let noErrors (result : IDictionary<string, obj>) =
match result.TryGetValue ("errors") with
| true, errors -> failwithf "expected ExecutionResult to have no errors but got %+A" errors
| false, _ -> ()
let throws<'e when 'e :> exn> (action : unit -> unit) = Assert.Throws<'e>(action)
let throws<'e when 'e :> exn> (action : unit -> unit) = Assert.Throws<'e> (action)
let sync = Async.RunSynchronously
let is<'t> (o: obj) = o :? 't
let hasError errMsg (errors: string seq) =
let containsMessage =
errors
|> Seq.exists (fun e -> e.Contains(errMsg))
Assert.True (containsMessage, sprintf "expected to contain message '%s', but no such message was found. Messages found: %A" errMsg errors)
let is<'t> (o : obj) = o :? 't
let hasError (errMsg : string) (errors : string seq) =
let containsMessage = errors |> Seq.exists (fun e -> e.Contains (errMsg))
Assert.True (containsMessage, $"expected to contain message '%s{errMsg}', but no such message was found. Messages found: %A{errors}")

let (<??) opt other =
let (<??) opt other =
match opt with
| None -> Some other
| _ -> opt

let undefined (value: 't) =
Assert.True((value = Unchecked.defaultof<'t>), sprintf "Expected value to be undefined, but was: %A" value)

let undefined (value : 't) =
Assert.True ((value = Unchecked.defaultof<'t>), $"Expected value to be undefined, but was: %A{value}")
75 changes: 52 additions & 23 deletions tests/FSharp.Data.GraphQL.Tests.Sql/LinqToSqlTests.fs
Original file line number Diff line number Diff line change
@@ -1,42 +1,71 @@
/// The MIT License (MIT)
/// Copyright (c) 2016 Bazinga Technologies Inc
// The MIT License (MIT)
// Copyright (c) 2016 Bazinga Technologies Inc

module FSharp.Data.GraphQL.Tests.LinqToSqlTests

open System
open System.Linq
open Xunit
open FSharp.Data.TypeProviders
open FSharp.Data.Sql
open FSharp.Data.GraphQL
open FSharp.Data.GraphQL.Parser
open FSharp.Data.GraphQL.Types
open FSharp.Data.GraphQL.Execution
open FSharp.Data.GraphQL.Linq

type Db = SqlDataConnection<"Server=.;Database=NORTHWND;Trusted_Connection=True;">
// https://github.com/microsoft/sql-server-samples/blob/master/samples/databases/northwind-pubs/instnwnd.sql
type Db =
SqlDataProvider<
Common.DatabaseProviderTypes.MSSQLSERVER,
"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Northwnd;Integrated Security=True;Encrypt=False;"
>

let Order = Define.Object("Order", [
Define.Field("orderId", ID, fun _ (o: Db.ServiceTypes.Orders) -> o.OrderID)
Define.Field("shipAddress", String, fun _ o -> o.ShipAddress)
Define.Field("shipCity", String, fun _ o -> o.ShipCity)
Define.Field("shipCountry", String, fun _ o -> o.ShipCountry) ])
let OrderType =
Define.Object<Db.dataContext.``dbo.OrdersEntity``> (
"Order",
[
Define.Field ("orderId", IDType, resolve = (fun _ o -> o.OrderId |> string))
Define.Field ("shipAddress", StringType, resolve = (fun _ o -> o.ShipAddress))
Define.Field ("shipCity", StringType, resolve = (fun _ o -> o.ShipCity))
Define.Field ("shipCountry", StringType, resolve = (fun _ o -> o.ShipCountry))
]
)

let Customer =
Define.Object<Db.dataContext.``dbo.CustomersEntity``> (
"Customer",
[
Define.Field ("customerID", IDType, resolve = (fun _ c -> c.CustomerId))
Define.Field ("contactName", StringType, resolve = (fun _ c -> c.ContactName))
Define.Field ("orders", ListOf OrderType, resolve = (fun _ c -> c.``dbo.Orders by CustomerID``))
]
)

let Customer = Define.Object("Customer", [
Define.Field("customerID", ID, fun _ (c: Db.ServiceTypes.Customers) -> c.CustomerID)
Define.Field("contactName", String, fun _ c -> c.ContactName)
Define.Field("orders", ListOf Order, fun _ c -> c.Orders) ])

[<Fact>]
let ``LINQ: should create an executable flat SQL query`` () =
let schema = Schema(Define.Object("RootQuery", [
Define.Field("customers", ListOf Customer, fun ctx (dbContext: Db.ServiceTypes.SimpleDataContextTypes.NORTHWND) ->
let query = ctx.ExecutionPlan.ToLinq(dbContext.Customers)
query |> Seq.toList) ]))
let query = parse """{
let schema =
Schema (
Define.Object (
"RootQuery",
[
Define.Field (
"customers",
ListOf Customer,
fun ctx (dbContext : Db.dataContext) ->
let query = dbContext.Dbo.Customers.Apply (ctx.ExecutionInfo, ctx.Variables)
query |> Seq.toList
)
]
)
)
let query =
parse
"""query {
customers {
contactName
}
}
}"""
use db = Db.GetDataContext()
let result = sync <| schema.AsyncExecute(query, db)
()
let db = Db.GetDataContext ()
let executor = Executor<Db.dataContext> (schema)
let result = sync <| executor.AsyncExecute (query, db)
()
Loading

0 comments on commit b7cbcf9

Please sign in to comment.